2. 看门狗工作原理:定时器基础、喂狗机制、超时复位流程、窗口看门狗与独立看门狗的区别
看门狗这东西,说白了就是一个会咬人的定时器。你如果不按时去喂它,它就咬你——把整个系统复位。听起来有点暴力,但嵌入式系统里,这反而是最温柔的守护者。
我刚开始做嵌入式那几年,总觉得看门狗是个累赘。直到有一次,一个工业控制项目在现场跑着跑着就死机了,客户半夜打电话过来骂人。从那以后,我设计的每一块板子,看门狗都是标配。
2.1 定时器基础:看门狗的“心脏”
看门狗的核心就是一个递减计数器。它从某个初始值开始,每个时钟周期减1。减到0的时候,就触发复位信号。
关键参数:
- 计数初值:决定超时时间的长短
- 时钟源:独立看门狗用内部RC振荡器,窗口看门狗用系统时钟
- 分频系数:调整计数速度,扩展超时范围
举个例子,STM32的独立看门狗(IWDG),时钟源是40kHz的内部RC振荡器。如果设置分频系数为64,那么计数频率就是40kHz / 64 = 625Hz。再设置计数初值为1000,超时时间就是1000 / 625 = 1.6秒。
// STM32 IWDG 初始化示例
void IWDG_Init(void)
{
// 使能写访问
IWDG->KR = 0x5555;
// 设置分频系数为64
IWDG->PR = IWDG_Prescaler_64;
// 设置计数初值为1000
IWDG->RLR = 1000;
// 启动看门狗
IWDG->KR = 0xCCCC;
}
我的经验:独立看门狗的时钟精度不高,一般误差在5%~10%左右。设计超时时间时,要留够余量。我习惯把超时时间设为主循环周期的3~5倍,既不会误触发,也不会让系统长时间失控。
2.2 喂狗机制:定时器“续命”操作
喂狗,就是把计数器的值重新装回初始值。这样计数器就不会减到0,系统也就不会被复位。
喂狗操作通常放在主循环里,或者放在某个周期性执行的任务中。但这里有个坑——喂狗的位置和频率,直接决定了看门狗的保护效果。
// 正确的喂狗方式
void main(void)
{
// 系统初始化
System_Init();
IWDG_Init();
while(1)
{
// 执行关键任务
Task_Communication();
Task_SensorRead();
Task_ControlOutput();
// 所有任务执行完毕后喂狗
IWDG->KR = 0xAAAA;
}
}
我曾经踩过的坑:有次我把喂狗操作放在了一个中断服务函数里。结果主程序卡死了,中断还在正常触发,看门狗一直没复位。系统死得悄无声息,现场调试了两天才发现。记住:喂狗一定要放在主循环的关键路径上,不能放在中断里。
2.3 超时复位流程:从计数到复位的完整路径
看门狗的超时复位流程,其实就三步:
- 计数递减:每个时钟周期,计数器减1
- 超时触发:计数器减到0,产生复位信号
- 系统复位:复位信号拉低MCU的复位引脚,系统重新启动
这里有个细节要注意——复位信号持续的时间。不同芯片的复位脉冲宽度不一样,STM32的IWDG复位脉冲大约是5个RC时钟周期。如果复位脉冲太短,某些外设可能来不及复位干净。
复位后的处理:
- 检查复位原因寄存器,确认是否由看门狗触发
- 记录复位次数,判断系统是否频繁复位
- 如果是看门狗复位,不要立即喂狗,先排查问题
// 复位原因检查
void Check_ResetSource(void)
{
if (RCC->CSR & RCC_CSR_IWDGRSTF)
{
// 独立看门狗复位
printf("System reset by IWDG!\n");
// 清除标志位
RCC->CSR |= RCC_CSR_RMVF;
}
}
2.4 窗口看门狗与独立看门狗的区别
这两种看门狗,虽然都叫看门狗,但脾气完全不同。我画了一张对比图,方便你理解。
两种看门狗的核心区别,我整理成了表格:
| 对比项 | 独立看门狗(IWDG) | 窗口看门狗(WWDG) |
|---|---|---|
| 时钟源 | 内部RC振荡器(独立) | 系统时钟(APB总线) |
| 时钟精度 | 低(5%~10%误差) | 高(与系统时钟一致) |
| 喂狗窗口 | 0 ~ 超时值(任意时刻) | 上窗口 ~ 下窗口(限定范围) |
| 超时范围 | 宽(毫秒到秒级) | 窄(微秒到毫秒级) |
| 复位方式 | 系统复位 | 系统复位 + 早期唤醒中断 |
| 典型应用 | 系统死机保护 | 任务超时检测 |
选型建议:
- 独立看门狗:适合对时间精度要求不高,但需要绝对可靠的场景。比如工业控制、汽车电子。
- 窗口看门狗:适合对任务执行时间有严格要求的场景。比如通信协议栈、实时操作系统。
我个人习惯,在大多数项目里同时使用两种看门狗。独立看门狗做最后一道防线,窗口看门狗做任务级的超时检测。这样既保证了系统的可靠性,又能及时发现任务异常。
一个实用技巧:窗口看门狗的早期唤醒中断(EWI)特别好用。在计数器即将超时前,可以触发中断,记录现场信息。这样即使系统最终复位了,也能知道问题出在哪里。我在一个电机控制项目里就用这个功能抓到了好几次任务调度异常。
嗯,看门狗的工作原理其实不复杂。但真正用好它,需要理解它的脾气秉性。独立看门狗像个粗犷的保安,只要按时打卡就行;窗口看门狗像个严格的监工,必须在规定时间内完成任务。选哪个,怎么用,全看你的系统需求。