第一讲:看门狗基础概念
什么是看门狗?
看门狗,英文叫 Watchdog Timer,简称 WDT。说白了,它就是一个计时器。这个计时器有个特点——你得不停地去“喂”它,也就是复位它的计数值。如果你忘了喂,它就会超时,然后触发一个系统复位信号。
我经常跟团队里的新人打个比方:看门狗就像你家养的一条狗,你得定时给它扔块骨头(喂狗)。要是你忙忘了,它就会叫(超时),然后把你家拆了(系统复位)。嗯,这个比喻虽然糙了点,但道理是一样的。
为什么会需要这么个东西?你想想看,嵌入式系统跑在车上,环境恶劣得很。电磁干扰、电源波动、温度变化,随便来一下,程序就可能跑飞了。程序跑飞了怎么办?没人管它,它就在那死循环,或者执行一些莫名其妙的操作。这在 ADAS 系统里是绝对不能接受的。
看门狗在嵌入式系统中的作用
看门狗的核心作用就一个:保证系统在出现故障后能自动恢复。我把它总结为三个层次:
- 检测异常:程序跑飞、死锁、任务卡死,这些异常看门狗都能检测到。怎么检测?就是看你还喂不喂它。正常程序会定期喂狗,异常程序就忘了。
- 触发恢复:一旦检测到异常,看门狗就会触发复位。这个复位是硬件级别的,优先级很高,能把系统从任何异常状态拉回来。
- 提供安全状态:复位后系统进入一个已知的初始状态。这个状态是安全的,比如刹车系统复位后默认是松开状态,不会误触发。
重要概念:看门狗不是用来防止故障的,而是用来处理故障的。它假设故障一定会发生,然后提供一个兜底方案。
我在做某个 L2 级 ADAS 项目时遇到过一件事。当时系统在高速上跑了几个小时,突然 MCU 的一个中断服务程序卡死了。原因很隐蔽——某个外设的 FIFO 溢出,导致中断标志位一直置位,主循环根本进不去。如果没有看门狗,这车就彻底失控了。幸好看门狗在 500ms 后触发了复位,系统重启后恢复正常。嗯,那次之后我对看门狗的重要性有了切身体会。
硬件看门狗与软件看门狗的区别
这个问题我经常被问到。很多新手觉得,软件看门狗不就是个定时器中断吗?其实没那么简单。我列个表格,大家一看就明白:
| 对比项 | 硬件看门狗 | 软件看门狗 |
|---|---|---|
| 实现方式 | 独立硬件模块,通常集成在 MCU 内部或外挂芯片 | 基于软件定时器或任务调度机制 |
| 可靠性 | 高,不受软件故障影响 | 低,软件本身出问题时可能失效 |
| 复位能力 | 能触发硬件复位,强制重启系统 | 只能触发软件复位,如果 CPU 死锁则无效 |
| 超时精度 | 由硬件时钟决定,精度高 | 受系统负载影响,精度较低 |
| 功耗 | 低,硬件模块独立运行 | 需要 CPU 参与,功耗较高 |
| 灵活性 | 配置选项有限,通常只有超时时间和复位方式 | 高度灵活,可以自定义检测逻辑 |
从这张表能看出来,硬件看门狗和软件看门狗各有优劣。我个人习惯的做法是:硬件看门狗做最后一道防线,软件看门狗做日常监控。
硬件看门狗的典型用法
硬件看门狗一般是这样用的:
// 伪代码示例:硬件看门狗初始化
void WDT_Init(void) {
// 设置超时时间为 1000ms
WDT_SetTimeout(1000);
// 使能看门狗
WDT_Enable();
}
// 主循环中喂狗
void main_loop(void) {
while(1) {
// 执行各种任务
process_sensor_data();
execute_control_algorithm();
send_can_messages();
// 喂狗
WDT_Feed();
}
}
这里有个关键点:喂狗的位置要选对。不能放在中断里喂,否则主循环卡死了,中断还在跑,看门狗就被骗过去了。我曾经见过一个项目,工程师把喂狗放在定时器中断里,结果主循环死锁了,看门狗一直没复位。嗯,这是个典型的坑。
软件看门狗的典型用法
软件看门狗更灵活,可以监控多个任务:
// 伪代码示例:软件看门狗监控多个任务
typedef struct {
uint32_t last_feed_time;
uint32_t timeout_ms;
bool is_alive;
} SW_WDT_Task;
SW_WDT_Task tasks[5]; // 监控5个任务
void SW_WDT_Check(void) {
uint32_t now = GetSystemTick();
for(int i = 0; i < 5; i++) {
if((now - tasks[i].last_feed_time) > tasks[i].timeout_ms) {
// 任务超时,记录错误并尝试恢复
LogError("Task %d timeout", i);
tasks[i].is_alive = false;
// 触发软件复位或任务重启
RestartTask(i);
}
}
}
经验之谈:软件看门狗的超时时间要设置得比硬件看门狗短。这样软件看门狗先发现问题,可以尝试优雅恢复。如果软件恢复失败,硬件看门狗再兜底。我一般设置软件看门狗超时 300ms,硬件看门狗超时 1000ms。
什么时候只用软件看门狗就够了?
有些低成本系统可能没有硬件看门狗,或者硬件看门狗被其他功能占用了。这时候能不能只用软件看门狗?我的建议是:看场景。
- 如果系统对安全性要求不高,比如一个简单的温度采集器,软件看门狗够用了。
- 如果是 ADAS 系统,必须用硬件看门狗。这是功能安全的要求,ISO 26262 里明确说了。
- 如果系统有多个 MCU,可以互相监控,这叫“双机互看门狗”,也是一种折中方案。
警告:在 ADAS 系统中,绝对不要只用软件看门狗。我曾经评审过一个项目,他们为了省成本,只用了软件看门狗。结果在 EMC 测试时,CPU 被干扰后程序跑飞,软件看门狗根本来不及响应。最后还是加了外挂硬件看门狗芯片才通过测试。
看门狗在 ADAS 系统中的特殊要求
ADAS 系统对看门狗的要求比普通嵌入式系统高得多。我总结了几点:
- 超时时间要短:普通系统可能设置几秒的超时,ADAS 系统一般要求 100ms-500ms。因为车辆在高速行驶时,几百毫秒就能跑出几十米。
- 喂狗逻辑要严谨:不能简单地在主循环喂狗。要监控关键任务的执行情况,比如感知算法是否按时输出结果、控制指令是否及时发送。
- 复位后要记录故障:看门狗复位后,系统要能记录复位原因,方便后续排查。我习惯在复位后检查复位标志寄存器,把信息存到非易失存储器里。
- 要考虑窗口看门狗:有些 MCU 支持窗口看门狗,要求必须在特定时间窗口内喂狗。喂早了或喂晚了都会触发复位。这能防止程序在错误的时间点喂狗。
我记得有一次,一个同事问我:“为什么我的看门狗总是复位?明明我每 50ms 就喂一次狗啊。”我一看代码,发现他把喂狗放在了中断里,而那个中断的优先级很低,被高优先级中断一直抢占。结果喂狗时间间隔超过了 100ms,看门狗就复位了。嗯,这种问题很隐蔽,排查起来挺费劲的。
小结
看门狗是嵌入式系统的最后一道防线。硬件看门狗可靠但死板,软件看门狗灵活但不可靠。在 ADAS 系统中,两者要配合使用。记住一句话:硬件看门狗保命,软件看门狗保质量。
下一讲我会详细讲看门狗在功能安全中的具体应用,包括如何满足 ISO 26262 的要求。到时候我会分享一些实际项目中的设计案例,敬请期待。