一次"看门狗形同虚设"的事故
某款工业控制器,MCU 是 STM32F407,跑 FreeRTOS,有三个任务:通信任务(优先级 5)、控制任务(优先级 4)、日志任务(优先级 2)。产品在客户现场运行,偶尔出现通信中断但系统没死机的情况——设备还在跑,但上位机收不到数据。
排查发现,根因是通信任务卡死了,但看门狗没有复位系统。
看门狗是怎么喂的呢?代码是这样的:
void vControlTask(void *pvParameters) { for (;;) { // 控制逻辑 Control_Update(); // 喂狗 HAL_IWDG_Refresh(&hiwdg); vTaskDelay(pdMS_TO_TICKS(10)); } }看门狗在控制任务里喂。控制任务优先级 4,它正常运行,看门狗就不会超时。但通信任务优先级 5,如果它卡死在一个 while 循环里,不会阻塞控制任务(因为控制任务优先级低,但通信任务卡死时不会主动让出 CPU,除非有更高优先级任务抢占……等等,这里通信任务优先级 5 高于控制任务 4,如果通信任务卡死在一个死循环里,它会一直占用 CPU,控制任务根本无法运行,看门狗也不会被喂)。
等一下,这个场景需要仔细分析:
如果通信任务卡死在死循环里,它优先级最高,会一直占用 CPU。
控制任务优先级低,无法运行,