独立看门狗 vs 窗口看门狗:选型与喂狗策略设计
扫描二维码
随时随地手机看文章
在嵌入式系统的可靠性设计中,看门狗(Watchdog)是防止程序跑飞或死锁的最后一道防线。STM32等MCU通常提供两种硬件看门狗:独立看门狗(IWDG)和窗口看门狗(WWDG)。选错类型或喂狗策略不当,轻则导致频繁误复位,重则让看门狗形同虚设。本文将深入对比两者差异,并提供RTOS环境下的实战喂狗方案。
一、本质差异:粗犷保安 vs 精细质检员
特性 独立看门狗 (IWDG) 窗口看门狗 (WWDG)
时钟源 独立LSI (~32-40kHz),不依赖主时钟 PCLK1 (APB1时钟),依赖系统时钟
复位条件 超时未喂狗 喂早、喂晚、不喂 均复位
时间精度 低(LSI受温漂影响) 高(与系统时钟同步)
中断能力 无中断,直接复位 支持提前唤醒中断(EWI),可预警
适用场景 防系统彻底死机(死循环、时钟故障) 防程序逻辑紊乱(任务卡死但没死透)
选型黄金法则:
• IWDG:用于“保底”。只要系统还能动,就必须喂狗,防止设备变砖。
• WWDG:用于“监控”。监控关键任务是否在预期时间窗内完成,防止程序跑飞但仍在喂狗。
二、IWDG实战:裸机与RTOS的喂狗策略
IWDG配置简单,核心在于喂狗位置的合理性。
1. 基础配置(HAL库)
// IWDG超时时间 ≈ 1.6秒 (LSI=32kHz, 分频64, 重载800)
void MX_IWDG_Init(void) {
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_64; // 分频系数
hiwdg.Init.Reload = 800; // 重装载值
HAL_IWDG_Init(&hiwdg);
}
避坑:IWDG一旦启动,无法通过软件关闭,只能通过复位或断电清除。
2. RTOS下的“心跳汇总”喂狗法
在RTOS中,严禁在定时器中断或高优先级任务中单独喂狗,否则即使低优先级任务卡死,狗依然能被喂饱,失去监控意义。
推荐方案:建立“喂狗守护任务”,收集各核心任务的心跳。
// 定义任务心跳标志
volatile uint32_t g_task_heartbeat = 0;
// 核心任务每隔一段时间“报平安”
void Critical_Task(void *pv) {
while(1) {
// ... 业务逻辑 ...
g_task_heartbeat |= (1 << TASK_ID); // 设置心跳位
vTaskDelay(pdMS_TO_TICKS(100));
}
}
// 独立的喂狗任务(低优先级)
void IWDG_Feed_Task(void *pv) {
const uint32_t ALL_TASK_MASK = (1 << TASK_NUM) - 1;
TickType_t xLastWakeTime = xTaskGetTickCount();
while(1) {
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(500)); // 每500ms检查一次
// 检查所有任务心跳是否到位
if ((g_task_heartbeat & ALL_TASK_MASK) == ALL_TASK_MASK) {
HAL_IWDG_Refresh(&hiwdg); // 只有所有任务正常才喂狗
g_task_heartbeat = 0; // 清零心跳标志
}
// 若有任务未上报心跳,则不喂狗,触发IWDG复位
}
}
此策略确保:任一任务卡死 → 心跳缺失 → 停止喂狗 → 系统复位。
三、WWDG实战:窗口期喂狗与预警机制
WWDG的计数器是7位(0x40-0x7F),当计数器值小于窗口值(Window)且大于0x3F时,才是合法的喂狗窗口。
1. 初始化与喂狗
// WWDG配置:窗口值=0x60,计数器初值=0x7F
void MX_WWDG_Init(void) {
hwwdg.Instance = WWDG;
hwwdg.Init.Prescaler = WWDG_PRESCALER_8; // 预分频
hwwdg.Init.Window = 0x60; // 窗口上限
hwwdg.Init.Counter = 0x7F; // 初始计数值
hwwdg.Init.EWIMode = WWDG_EWI_ENABLE; // 使能早期唤醒中断
HAL_WWDG_Init(&hwwdg);
}
// 必须在窗口期内(计数器值在0x40~0x60之间)调用
void feed_wwdg(void) {
if (__HAL_WWDG_GET_FLAG(&hwwdg, WWDG_FLAG_EWIF)) {
// 已进入预警状态,通常不在此处喂狗,而是处理异常
return;
}
HAL_WWDG_Refresh(&hwwdg, 0x7F); // 重置计数器
}
2. 早期唤醒中断(EWI)的应用
WWDG计数器减到0x40时会触发EWI中断,此时距离复位还有一段时间(约几个毫秒),这是最后的数据保存机会。
void WWDG_IRQHandler(void) {
HAL_WWDG_IRQHandler(&hwwdg); // 处理标志位
// 紧急保存关键数据到Backup SRAM或Flash
save_critical_data();
// 注意:EWI中通常不喂狗,让系统复位以恢复秩序
}
四、混合部署策略:IWDG + WWDG 双保险
对于高可靠性工业设备,推荐“IWDG保底 + WWDG抓异常”的组合拳。
1. IWDG:设置较长的超时时间(如3-5秒),作为系统彻底死机的最后屏障。
2. WWDG:设置精细的窗口(如100-200ms),监控关键控制循环的执行周期。若程序跑飞但仍在喂IWDG,WWDG会因喂狗时机错乱而触发复位。
五、常见喂狗陷阱与避坑指南
1. 在中断中喂狗:这是最常见的错误。中断可能正常执行而主循环已卡死,导致看门狗失效。
2. 喂狗周期等于超时时间:LSI有温漂,若喂狗间隔太接近超时时间,低温下可能因时钟变慢导致意外复位。安全余量至少50%。
3. WWDG窗口计算错误:使用CubeMX的自动计算功能,避免手动算错窗口值导致一启动就复位。
六、结语
看门狗不是简单的“初始化+定时刷新”,而是系统级的健康监控机制。IWDG是“防猝死”的保险丝,WWDG是“测心率”的监护仪。在RTOS中,务必采用“心跳汇总”策略,让看门狗真正监控到每一个核心任务的生存状态,才能构建起坚不可摧的嵌入式系统防线。





