喂狗在操作系统(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);
	}
}
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐