4. 看门狗基础原理

看门狗(Watchdog)是嵌入式与 RTOS 系统中最基础、也最有效的故障恢复机制之一。它的核心思想非常朴素:让一个独立的计时器持续倒计时,系统软件必须在计时器溢出前“喂狗”(刷新计时器);如果软件因死锁、跑飞、中断风暴或优先级反转而无法按时喂狗,计时器溢出就会触发复位或中断,把系统从异常状态中拉回来。理解硬件看门狗、软件看门狗和窗口看门狗三者的工作机制与差异,是设计可靠故障恢复架构的第一步。

一、核心原理:三种看门狗的本质差异

硬件看门狗是芯片内部或外部的独立计时电路,通常由专用低速时钟(如 LSI 内部低速 RC 或独立晶振)驱动,不依赖系统主时钟和 CPU 执行。即使 CPU 主频异常、程序跑飞,只要看门狗电路供电正常,它仍会继续计数并最终溢出复位。硬件看门狗的关键价值在于“独立性”——它不依赖被监控对象本身。

软件看门狗则完全由系统内的定时器中断或任务实现。它通常利用 RTOS 的软件定时器或一个低优先级任务,周期性地检查各关键任务是否按时“报到”。软件看门狗灵活、可监控多个任务、能定位到具体任务,但它与被监控系统共享 CPU 和时钟资源,一旦系统整体死锁或中断被关闭,软件看门狗本身也会失效。

窗口看门狗在硬件看门狗基础上增加了一个“时间窗口”约束:喂狗不能太晚,也不能太早。只有在窗口期内喂狗才有效,过早喂狗会被视为异常并触发复位。它主要用来检测程序“跑得太快”或“喂狗逻辑被错误地放在循环中频繁执行”这类问题,能发现普通看门狗无法发现的时序异常。

三种看门狗工作机制对比 硬件看门狗 独立低速时钟 LSI 递减计数器 溢出 → 复位 CPU 喂狗:写 WDT 寄存器 不依赖 CPU 主时钟 特点:独立、可靠、单一 无法定位故障任务 软件看门狗 系统定时器 / 低优先级任务 检查各任务“报到”标志 超时 → 记录 / 复位 喂狗:任务置位标志 依赖 CPU 与系统时钟 特点:灵活、可多任务监控 可定位故障任务 窗口看门狗 独立时钟 + 窗口比较器 上窗口 / 下窗口界定 过早 / 过晚 → 复位 喂狗:仅窗口期内有效 检测时序异常 特点:防过早喂狗 时序约束最严格

二、方法流程:喂狗策略与任务监控设计

在实际 RTOS 工程中,硬件看门狗通常作为最后一道防线,软件看门狗作为第一层任务级监控,两者常配合使用。典型流程如下:

  1. 系统启动后初始化硬件看门狗,设定超时时间(如 1s),并启动软件监控定时器。
  2. 每个关键任务在自身主循环中调用 task_report(),置位对应的“存活标志”。
  3. 软件看门狗任务以较低优先级周期运行,检查所有标志是否在各自截止时间内被置位。
  4. 若全部正常,软件看门狗任务执行一次硬件喂狗;若有任务超时,则记录故障任务 ID 并触发复位或降级处理。
  5. 窗口看门狗则要求喂狗动作落在指定窗口内,防止喂狗代码被错误地高频执行。
/* 软件看门狗任务伪代码 */
void watchdog_task(void *arg) {
    while (1) {
        for (int i = 0; i < TASK_NUM; i++) {
            if (!task_alive[i]) {
                log_error("task %d timeout", i);
                system_reset();
            }
            task_alive[i] = 0;   /* 清除标志,等待下一轮报到 */
        }
        HAL_IWDG_Refresh(&hiwdg);  /* 全部正常才喂硬件狗 */
        osDelay(WDT_CHECK_PERIOD);
    }
}

三、案例场景:三种看门狗的实际选择

在一个工业数据采集终端中,主控运行 FreeRTOS,包含采集任务、通信任务和显示任务。若只使用硬件看门狗,当通信任务因等待信号量而永久阻塞时,其他任务仍可能正常喂狗,硬件看门狗无法发现该任务已死。此时引入软件看门狗,由监控任务检查通信任务的报到标志,即可在 200ms 内发现异常并复位。

若系统对“喂狗过早”敏感,例如喂狗代码被误放在一个高频中断中,普通看门狗永远不会溢出,系统实际上已失去保护。窗口看门狗要求喂狗必须落在窗口期内,一旦喂狗过早立即复位,从而暴露这类设计缺陷。因此,高可靠性场景常采用“软件看门狗监控任务 + 窗口看门狗监控喂狗时序”的组合。

四、误区与复盘:常见设计陷阱

误区一:在中断中喂狗。 若喂狗放在高优先级中断中,即使主循环死锁,中断仍可能触发喂狗,看门狗形同虚设。喂狗应放在受监控的任务逻辑中。

误区二:软件看门狗任务优先级过高。 若监控任务优先级过高,它可能抢占故障任务,导致故障任务永远无法运行,反而掩盖问题。监控任务应低于被监控任务。

误区三:窗口看门狗窗口设置过窄。 窗口过窄会导致正常抖动也触发复位,需根据任务最坏执行时间留足余量。

对比维度 硬件看门狗 软件看门狗 窗口看门狗
时钟来源 独立低速时钟 系统定时器 独立低速时钟
是否依赖 CPU 否 是 否
监控粒度 整机 多任务 整机 + 时序
能否定位故障任务 不能 能 不能
防过早喂狗 否 否 是
典型用途 最后防线 任务级监控 时序异常检测

复盘建议:在系统设计阶段就明确“谁喂狗、何时喂、喂狗失败后做什么”。建议将硬件看门狗超时设为软件监控周期的 3~5 倍,软件监控周期设为被监控任务最坏响应时间的 2 倍以上,并为窗口看门狗预留足够的窗口宽度。只有把三种看门狗的分工和参数关系理清,故障恢复架构才真正可靠。