3、看门狗超时机制详解:超时时间计算、喂狗窗口概念、早期预警中断(EWI)机制
看门狗这东西,说白了就是系统的一个「保底机制」。你程序跑飞了?死循环了?它帮你一把——直接复位。但这里有个关键问题:你得多长时间喂一次狗?喂早了行不行?喂晚了行不行?
嗯,这就要聊到超时时间计算、喂狗窗口,还有那个很多人忽略的早期预警中断(EWI)。我在做一款工业控制器时,就因为在EWI上栽过跟头,今天一并讲清楚。
3.1 超时时间计算:不是拍脑袋定的
看门狗的超时时间,就是「最后一次喂狗到系统被复位」之间的时间窗口。这个值怎么算?我见过不少新手直接拿手册里的最大值一填,结果系统频繁误复位。
我个人习惯这样算:
- 先摸清主循环的最长执行时间——包括中断响应、任务切换、异常分支。
- 留出 1.5 到 2 倍的余量。比如主循环最长 50ms,那我设 100ms 的超时。
- 考虑最恶劣情况:比如 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,跟预期差了好几倍——因为他没算分频系数。
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 只是预警,超时后看门狗依然会复位
}
3.4 三种机制的配合使用
实际项目中,我通常这样搭配:
| 场景 | 超时时间 | 窗口 | EWI |
|---|---|---|---|
| 简单裸机程序 | 主循环 × 2 | 不用 | 可选 |
| RTOS 任务监控 | 最差任务时间 × 1.5 | 建议开启 | 强烈建议 |
| 安全关键系统 | 严格计算 + 20% 余量 | 必须开启 | 必须开启 |
你想想看,如果只设超时时间,那系统只能被动复位。加上窗口,能防住异常快速绕回。再加上 EWI,你还能在复位前做点「善后工作」——三层防护,才算完整。
嗯,这里要注意一点:EWI 不是所有看门狗都支持。选型时一定要看芯片手册,别像我之前那样,画完板子才发现型号不支持——那叫一个尴尬。
总结一下:
- 超时时间要留余量,别卡着极限算
- 窗口看门狗能防「假正常」状态
- EWI 是最后的救命稻草,用好它
下一章我会讲看门狗在 Bootloader 中的具体应用——怎么在升级过程中既保证安全,又不被看门狗打断。到时候见。