🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习
🎬擅长领域:驱动开发,嵌入式软件开发,BSP开发
❄️作者主页:一个平凡而乐于分享的小比特的个人主页
✨收录专栏:硬件知识,本专栏为记录项目中用到的知识点,以及一些硬件常识总结
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

嵌入式中硬件定时器----看门狗
看门狗(Watchdog Timer,简称WDT)是嵌入式系统中的一种硬件定时器 ,它像一只忠诚的"看门狗"一样监视系统的运行状态。如果系统出现故障或程序"跑飞",看门狗会自动复位整个系统,使其恢复到一个已知的、正常的工作状态。
一、核心工作原理:"喂狗"机制
看门狗的核心是一个递减计数器,工作流程如下:
正常情况:
[系统启动] → [看门狗开始计时] → [程序正常执行] → [定期"喂狗"(重置计时器)] → [看门狗始终不会溢出] → [系统持续运行]
异常情况:
[系统启动] → [看门狗开始计时] → [程序卡死/跑飞] → [无法按时"喂狗"] → [计时器溢出] → [看门狗触发复位] → [系统重启]
关键概念:
- 喂狗(Kick the dog / Refresh):程序正常运行时,定期重置看门狗计时器
- 超时时间(Timeout):从最后一次喂狗到复位触发的时间间隔
- 窗口看门狗(WWDG):必须在特定时间窗口内喂狗,增加安全性
二、看门狗的分类和特点
1. 独立看门狗(IWDG - Independent Watchdog)
- 特点:完全独立于主系统时钟
- 时钟源:通常使用独立的低速内部/外部RC振荡器(LSI/LSE)
- 优点 :
- 即使主时钟失效也能工作
- 抗干扰能力强
- 配置简单
- 应用场景:防止由于外部干扰、电源波动等导致的程序跑飞
2. 窗口看门狗(WWDG - Window Watchdog)
-
特点:必须在特定时间窗口内喂狗
-
工作原理:
过早喂狗 → [复位] // 防止程序提前进入喂狗代码绕过检查 正常喂狗 → [继续运行] // 在时间窗口内 过晚喂狗 → [复位] // 程序执行过慢或卡死 -
优点:
- 能检测程序执行过快(异常加速)
- 更高的安全性
-
应用场景:对实时性要求高、需要检测程序执行时序的系统
三、技术实现细节
典型寄存器配置(以STM32为例):
// 独立看门狗初始化示例
void IWDG_Init(uint16_t timeout_ms) {
// 1. 使能IWDG(写入0xCCCC)
IWDG->KR = 0xCCCC;
// 2. 设置预分频器和重装载值
// 计算公式:Timeout = (Reload值 * 预分频) / LSI频率
IWDG->KR = 0x5555; // 允许访问PR和RLR寄存器
IWDG->PR = 4; // 预分频器:64分频
IWDG->RLR = 625; // 重装载值:约1秒超时
// 3. 等待寄存器更新
while(IWDG->SR & 0x02); // 等待RVU位清零
// 4. 喂狗(启动看门狗)
IWDG->KR = 0xAAAA;
}
喂狗操作:
// 在主循环或定时器中定期调用
void feed_dog(void) {
// 写入0xAAAA到键值寄存器
IWDG->KR = 0xAAAA; // STM32的喂狗操作
// 或使用厂商提供的库函数
HAL_IWDG_Refresh(&hiwdg);
}
四、实际应用中的关键考量
1. 超时时间设置
- 太短:频繁误复位,系统不稳定
- 太长:故障响应慢,可能造成数据损坏
- 经验值:通常100ms-10s,根据具体应用调整
2. 喂狗策略设计
// 多任务系统中的喂狗策略
volatile uint8_t task_flags[NUM_TASKS] = {0};
void Task1(void) {
while(1) {
// 执行任务1工作
task_flags[0] = 1; // 标记任务1正常执行
osDelay(100);
}
}
void Watchdog_Task(void) {
while(1) {
// 检查所有关键任务是否正常
if (task_flags[0] && task_flags[1] && task_flags[2]) {
feed_dog(); // 只有所有任务正常才喂狗
memset(task_flags, 0, sizeof(task_flags));
}
osDelay(50);
}
}
3. 常见陷阱与解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 频繁误复位 | 喂狗间隔设置不当 | 调整超时时间,优化喂狗位置 |
| 看门狗失效 | 在中断中喂狗 | 确保在主任务中喂狗 |
| 死锁检测不到 | 喂狗代码仍在执行 | 使用窗口看门狗或多级看门狗 |
| 关键数据丢失 | 复位前未保存状态 | 添加掉电保护或非易失存储 |
五、高级应用模式
1. 分级看门狗系统
// 两级看门狗:软件看门狗 + 硬件看门狗
void Software_WDT(void) {
static uint32_t counter = 0;
counter++;
if (counter > MAX_COUNT) {
// 软件检测到异常,执行恢复流程
recover_from_fault();
counter = 0;
}
}
void Hardware_WDT(void) {
// 硬件看门狗作为最后保障
feed_hardware_wdt();
}
2. 智能复位策略
void watchdog_handler(void) {
static uint8_t reset_count = 0;
reset_count++;
if (reset_count > 3) {
// 连续复位多次仍失败,进入安全模式
enter_safe_mode();
} else {
// 保存错误信息到EEPROM
log_error_to_eeprom();
// 执行正常复位
system_reset();
}
}
六、在实际项目中的最佳实践
- 启动时初始化:系统启动后尽早启用看门狗
- 喂狗位置选择:放在主循环的关键路径上
- 异常处理:复位前保存必要的诊断信息
- 测试验证:故意跳过喂狗,测试复位功能是否正常
- 文档记录:明确记录超时时间和喂狗策略
七、看门狗 vs 其他容错机制
| 机制 | 检测内容 | 响应速度 | 实现复杂度 |
|---|---|---|---|
| 看门狗 | 程序执行流 | 快(硬件级) | 低 |
| ECC内存 | 内存位错误 | 即时 | 中 |
| 心跳检测 | 进程活性 | 中 | 中 |
| 冗余设计 | 硬件故障 | 慢 | 高 |
总结
看门狗是嵌入式系统的"最后一道防线",它以极低的硬件成本提供了基本的系统可靠性保障。正确使用看门狗需要:
- 理解硬件特性
- 合理设计喂狗策略
- 与软件错误处理机制结合
- 进行充分的测试验证
在实际工程中,看门狗常与软件异常检测、日志记录、状态恢复等机制协同工作,共同构建健壮的嵌入式系统。