看门狗与异常复位:让设备自己爬起来
StarMapCoder
4 分钟阅读
看门狗是嵌入式系统最后一道保险:当软件因 bug、干扰或死锁跑飞,正常喂狗逻辑失效,看门狗计数器溢出后强制复位,让设备自己爬起来。它不防止错误,只防止错误变成永久瘫痪。没有看门狗的设备一旦死机,只能靠人去断电重启,这在无人值守的现场是不可接受的。
两类看门狗
独立看门狗(IWDG)由专用低速时钟(如 LSI)驱动,主时钟挂了它照常计时,适合系统彻底死掉的兜底。窗口看门狗(WWDG)由主时钟驱动,且要求喂狗必须在时间窗口内——太早或太晚都算违规复位,能挡住程序卡在某个循环但仍在喂狗的假活。前者管有没有喂,后者管喂得对不对。
初始化与喂狗
// 独立看门狗:预分频 32,重装载 1000 -> 约 1s 超时(依 LSI 频率)
IWDG->KR = 0x5555; // 解锁
IWDG->PR = 0x03;
IWDG->RLR = 1000;
IWDG->KR = 0xCCCC; // 启动
// 主循环定期喂狗
IWDG->KR = 0xAAAA;
注意喂狗写的是 0xAAAA 而非解锁值,解锁序列 0x5555 只用于改参数。写错值等于没喂,超时后照常复位。
边界与坑
喂狗过频会掩盖真实 bug:系统已经卡死在某个异常分支,却因为另一条路径偶尔喂了狗而看似正常。正确做法是让代表系统健康的关键任务去喂狗,而不是随便一处定时器中断。喂狗过慢则正常流程也会被复位,超时时间要大于最坏情况下的主循环周期,但也不能太长,否则真死机时恢复太慢。
低功耗是大坑:部分 MCU 进入深度睡眠后独立看门狗仍在跑,若唤醒间隔长于超时就会在睡眠中被复位,需要在睡前喂狗或选用可随睡眠暂停的看门狗模式。还有,复位后应通过状态寄存器判断是否是看门狗导致的复位,否则每次异常重启都从零初始化,丢掉了定位线索。把复位原因打印或记录到非易失存储,是现场排查死机最划算的投入。
窗口看门狗的窗口机制
窗口看门狗比独立看门狗多了一道约束:喂狗必须落在一个时间窗口内,太早(还在窗口外)或太晚(已经溢出)都算违规并复位。这就挡住了一类特殊故障——程序卡死在某个空循环里,但恰好每圈都顺手喂了狗,系统看起来"活着"却什么都不干。窗口上下限由预分频和比较值决定,设置时要估准任务的实际执行周期,窗口太窄反而会把正常程序误杀。
喂狗的软件架构
单点喂狗风险在于:只在一个地方喂,其他地方卡死时它也没机会喂,这是对的;但如果随便一个低优先级任务都能喂,就失去了保护作用。更稳妥的架构是设一个独立的看门狗任务,它只负责汇总各业务模块的心跳——每个关键任务定期上报"我还活着",只要有一个心跳超时,看门狗任务就故意不喂狗,触发整体复位。这样把"系统健康"从单一喂狗点上升为整体监控。
启动期的特殊时序
设备刚上电要做初始化、连网络、挂载文件系统,这些启动任务可能耗时远长于看门狗超时。如果启动阶段就开着看门狗,会因来不及喂狗而反复重启、永远起不来。做法是在启动完成前先暂停看门狗或把超时设得很长,等系统进入稳态主循环后再切到正常超时。同样,执行固件升级、整片擦写这类长操作时也要临时关闭或延长看门狗,否则升级中途被复位会变成砖。
浏览 0
点赞 0
评论 0