一、看门狗基础概念
什么是看门狗定时器(WDT)
看门狗定时器,英文叫 Watchdog Timer,简称 WDT。说白了,它就是一个特殊的计数器。
这个计数器会一直往下数。数到零的时候,它就干一件事——复位系统。嗯,就是这么简单粗暴。
我刚开始接触嵌入式开发时,觉得这东西没啥技术含量。后来在制动系统项目里吃过亏,才明白它有多重要。
看门狗的核心机制是这样的:
- 系统正常运行时,软件要定期「喂狗」——也就是重置计数器
- 如果系统卡死了,没人喂狗,计数器就会归零
- 归零那一刻,看门狗直接拉复位引脚,重启系统
你想想看,这不就是个「心跳检测器」吗?系统活着,它就不断被重置。系统死了,它就帮你重启。
关键点:看门狗不是用来检测「程序跑飞」的,它是用来检测「程序不跑了」的。这两者有本质区别。
看门狗在嵌入式系统中的作用
在汽车电子领域,看门狗的作用远比你想象的重要。我做过几个制动系统的项目,每次评审时,看门狗都是必查项。
它的主要作用有这几个:
- 防止系统死锁——这是最基础的功能。程序卡在某个循环里出不来?看门狗帮你解决。
- 检测任务超时——比如制动响应必须在 10ms 内完成,超时了说明有问题。
- 监控关键路径——不是所有代码都需要喂狗,只有关键路径才需要。
- 提供最后防线——其他安全机制都失效了,看门狗是最后一道屏障。
我记得有一次,客户反馈制动踏板偶尔没反应。查了三天,发现是某个中断服务程序里有个死循环。要不是看门狗把系统拉回来,后果不堪设想。
我的经验:看门狗不是万能的。它只能检测「程序不跑了」,检测不了「程序跑错了」。比如你算错了制动压力,看门狗可不管这个。
看门狗与系统复位的关系
这个问题很多人搞混。看门狗复位和上电复位,不是一回事。
| 复位类型 | 触发条件 | 影响范围 | 恢复时间 |
|---|---|---|---|
| 上电复位 | 电源重新上电 | 全部寄存器清零 | 较长(ms级) |
| 看门狗复位 | WDT超时 | 部分寄存器保留 | 较短(us级) |
| 软件复位 | 程序主动触发 | 可配置 | 可控 |
看门狗复位有个好处——它保留了部分调试信息。比如复位原因寄存器里会写「我是被看门狗复位的」。这对排查问题很有帮助。
我曾经遇到一个坑:某款 MCU 的看门狗复位后,GPIO 状态不恢复。结果制动阀一直保持打开状态,差点出事故。从那以后,我每次选型都会仔细看复位后的引脚状态。
注意:看门狗复位不是万能的解决方案。如果系统频繁被看门狗复位,说明软件有严重问题。别指望看门狗帮你兜底,它只是给你一个「重新开始」的机会。
在实际项目中,我一般这样配置看门狗:
/* 看门狗初始化示例 - 基于STM32 */
void WDT_Init(void)
{
/* 设置超时时间为 1000ms */
IWDG_HandleTypeDef hiwdg;
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_64; /* 分频系数 */
hiwdg.Init.Reload = 1250; /* 重装载值 */
if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
{
/* 初始化失败,进入错误处理 */
Error_Handler();
}
}
/* 喂狗函数 - 在关键路径中调用 */
void Feed_WDT(void)
{
HAL_IWDG_Refresh(&hiwdg);
}
为什么超时设 1000ms?因为制动系统的主循环周期是 10ms,我给了 100 倍的余量。你想想看,如果 1 秒内都没人喂狗,系统肯定出问题了。
嗯,这里要注意:喂狗的位置很关键。别在主循环开头喂,要在关键任务执行完后喂。这样才能确保关键路径是通的。
避坑指南:我曾经在中断里喂狗,结果主循环卡死了,看门狗却一直没复位。因为中断还在正常触发。所以记住——喂狗要放在主循环里,别放中断里。
总结一下今天的内容:看门狗就是个简单的计数器,但它承载着系统最后的安全防线。在制动系统这种安全关键应用中,看门狗不是可选项,是必选项。
下一章我会讲看门狗在制动系统中的具体应用场景,包括如何设计多级看门狗、如何避免误复位等问题。到时候我会拿实际项目中的案例来讲,保证干货满满。