3、看门狗超时机制详解:超时时间计算、喂狗窗口概念、早期预警中断(EWI)机制

看门狗这东西,说白了就是系统的一个「保底机制」。你程序跑飞了?死循环了?它帮你一把——直接复位。但这里有个关键问题:你得多长时间喂一次狗?喂早了行不行?喂晚了行不行?

嗯,这就要聊到超时时间计算、喂狗窗口,还有那个很多人忽略的早期预警中断(EWI)。我在做一款工业控制器时,就因为在EWI上栽过跟头,今天一并讲清楚。

3.1 超时时间计算:不是拍脑袋定的

看门狗的超时时间,就是「最后一次喂狗到系统被复位」之间的时间窗口。这个值怎么算?我见过不少新手直接拿手册里的最大值一填,结果系统频繁误复位。

我个人习惯这样算:

  1. 先摸清主循环的最长执行时间——包括中断响应、任务切换、异常分支。
  2. 留出 1.5 到 2 倍的余量。比如主循环最长 50ms,那我设 100ms 的超时。
  3. 考虑最恶劣情况:比如 Flash 写入时 CPU 被挂起,或者外部设备响应延迟。

举个例子,STM32 的独立看门狗(IWDG)超时时间公式是这样的:

Tout = (4 × 2^PR) × RLR / LSI

其中:

  • PR 是预分频器值(0~7)
  • RLR 是重装载寄存器(0~4095)
  • LSI 是低速内部时钟,通常 32kHz

假设 PR=2(即 16 分频),RLR=1000,LSI=32kHz:

Tout = (4 × 2^2) × 1000 / 32000 = 16 × 1000 / 32000 = 0.5 秒

你看,算出来就是 500ms。我在项目中遇到过有人把 RLR 填成 4095,PR 设成 0,结果超时时间只有 512ms,跟预期差了好几倍——因为他没算分频系数。

注意:LSI 精度通常只有 ±10% 甚至更差。你算出来 500ms,实际可能在 450ms~550ms 之间。所以余量一定要留够。

3.2 喂狗窗口概念:不是随时都能喂

你可能会想:「我只要在超时前喂狗不就行了?」

嗯,早期的看门狗确实是这样。但后来大家发现一个问题——如果程序跑飞了,但碰巧在超时前又跳回来喂了狗,那看门狗就形同虚设了。

所以就有了「窗口看门狗」(WWDG)。它规定了一个时间窗口:

  • 太早喂狗 → 复位(因为可能程序跑飞后快速绕回来了)
  • 太晚喂狗 → 复位(超时了)
  • 只有在窗口内喂狗 → 正常

说白了,就是给喂狗加了个「时间锁」。我做过一个车载项目,要求系统必须在 10ms~50ms 之间喂狗。早了说明逻辑异常,晚了说明卡顿——两边都掐死。

窗口看门狗的超时计算稍微复杂点:

Tout = (4096 × 2^WDGTB) × (T[5:0] + 1) / PCLK

其中 T[5:0] 是递减计数器的当前值,WDGTB 是分频系数。窗口上限由 W[6:0] 寄存器设定。

关键点:喂狗必须在计数器值大于窗口值且小于 0x40 时进行。早了不行,晚了也不行。

3.3 早期预警中断(EWI):给你一次补救机会

这个机制我特别喜欢。EWI 允许在看门狗超时之前触发一个中断,让你有机会做最后的处理——比如保存关键数据、记录错误日志、或者尝试恢复。

我记得有一次做电力终端,系统在极端电磁干扰下偶尔会卡死。如果直接复位,正在写入的 Flash 数据就全毁了。后来我启用了 EWI,在中断里先完成 Flash 写入,再让系统复位——数据保住了。

EWI 的触发时机通常是:

  • 对于独立看门狗(IWDG):在计数器递减到 0x000 之前触发
  • 对于窗口看门狗(WWDG):在计数器递减到 0x40 时触发

配置示例(以 STM32 IWDG 为例):

// 使能早期预警中断
IWDG->KR = 0x5555;  // 解锁寄存器
IWDG->IER |= IWDG_IER_EWIE;  // 使能 EWI
NVIC_EnableIRQ(IWDG_EWI_IRQn);

// 中断处理函数
void IWDG_EWI_IRQHandler(void) {
    // 清除中断标志
    IWDG->SR &= ~IWDG_SR_EWIF;
    
    // 在这里做紧急处理
    // 比如:保存上下文、关闭外设、记录错误码
    save_critical_data();
    
    // 注意:这里不要喂狗!
    // EWI 只是预警,超时后看门狗依然会复位
}
经验之谈:EWI 中断里千万别喂狗。我见过有人想在 EWI 里「续命」,结果喂狗后系统继续运行,但错误状态没清除——最后故障越积越多,反而更难排查。

3.4 三种机制的配合使用

实际项目中,我通常这样搭配:

场景 超时时间 窗口 EWI
简单裸机程序 主循环 × 2 不用 可选
RTOS 任务监控 最差任务时间 × 1.5 建议开启 强烈建议
安全关键系统 严格计算 + 20% 余量 必须开启 必须开启

你想想看,如果只设超时时间,那系统只能被动复位。加上窗口,能防住异常快速绕回。再加上 EWI,你还能在复位前做点「善后工作」——三层防护,才算完整。

嗯,这里要注意一点:EWI 不是所有看门狗都支持。选型时一定要看芯片手册,别像我之前那样,画完板子才发现型号不支持——那叫一个尴尬。

总结一下:

  • 超时时间要留余量,别卡着极限算
  • 窗口看门狗能防「假正常」状态
  • EWI 是最后的救命稻草,用好它

下一章我会讲看门狗在 Bootloader 中的具体应用——怎么在升级过程中既保证安全,又不被看门狗打断。到时候见。