喂狗在操作系统(rtos)上面的正确用法
·
喂狗在操作系统(rtos)上面的正确用法。
不能在定时器喂狗,也不能在idle任务喂狗,也不能用定时任务去喂狗。因为,会出现,其他任务都卡死了,但喂狗还在执行。
应该检查所有任务,都没有卡死,才能喂狗。
示例程序,如下。
//不能在定时器喂狗,也不能在idle任务喂狗,也不能用定时任务去喂狗。因为,会出现,其他任务都卡死了,但喂狗还在执行。
//默认1s,1000 tick hz。如果要,用ms延时,请加上对应的宏。
//假设,tick类型为32位。
//如果某个任务,卡死。那么,会出现,不喂狗。长时间,不喂狗,会硬件重启。
//如果某些出现,死锁现象。也就是,执行不到最后,心跳停止。那么,也会检测到心跳异常,出现不喂狗。长时间不喂狗,会硬件重启。
//演示值,实际值为除喂狗任务外,所有任务的数量值。
#define N 8
//心跳数组。除喂狗任务外,所有任务。
volatile uint32_t taskHeartBeat[N] = {0};
//具体任务1,任务优先级>1。
void taskXXX(void *pv)
{
while(1)
{
//判断是否需要执行功能。
if (flag)
{
//执行完所需的操作,就设置心跳。
//由于是示例程序,只有一个任务,所以,下标是0。每一个任务,都有一个对应的下标。
taskHeartBeat[0] = xTaskGetTickCount();
xTaskDelay(10);
}
else
{
//只设置心跳
taskHeartBeat[0] = xTaskGetTickCount();
//由于是示例程序,只有一个任务,所以,下标是0。每一个任务,都有一个对应的下标。
xTaskDelay(10);
}
}
}
//喂狗任务,任务优先级=1。
void taskWatchDog(void *pv)
{
//这个只是示例,具体请参考看门狗超时时间的设置和手册。
const uint32_t timeOut = 1000;
//
uint32_t i = 0;
while(1)
{
//
uint32_t tick = xTaskGetTickCount();
//loop全部任务,除喂狗任务外。
// 用临界区防止检查过程中被高优先级任务抢占更新心跳
taskENTER_CRITICAL(); // 或 vTaskSuspendAll() / xTaskResumeAll()
for (i = 0; i < N; i++)
{
if (tick - taskHeartBeat[i] >= timeOut)
break;
}
taskEXIT_CRITICAL();
//全部检查完,没有一个任务出现超时或卡死。
if (i == N)
{
//喂狗
freeDog();
}
//如果i!=N,不喂狗。多次后,自动触发硬件复位。
//这个时间,要比超时时间要小,一般是超时时间的/2或/3。
xTaskDelay(300);
}
}
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)