一、看门狗基础概念

什么是看门狗定时器(WDT)

看门狗定时器,英文叫 Watchdog Timer,简称 WDT。说白了,它就是一个特殊的计数器。

这个计数器会一直往下数。数到零的时候,它就干一件事——复位系统。嗯,就是这么简单粗暴。

我刚开始接触嵌入式开发时,觉得这东西没啥技术含量。后来在制动系统项目里吃过亏,才明白它有多重要。

看门狗的核心机制是这样的:

  • 系统正常运行时,软件要定期「喂狗」——也就是重置计数器
  • 如果系统卡死了,没人喂狗,计数器就会归零
  • 归零那一刻,看门狗直接拉复位引脚,重启系统

你想想看,这不就是个「心跳检测器」吗?系统活着,它就不断被重置。系统死了,它就帮你重启。

关键点:看门狗不是用来检测「程序跑飞」的,它是用来检测「程序不跑了」的。这两者有本质区别。

看门狗在嵌入式系统中的作用

在汽车电子领域,看门狗的作用远比你想象的重要。我做过几个制动系统的项目,每次评审时,看门狗都是必查项。

它的主要作用有这几个:

  1. 防止系统死锁——这是最基础的功能。程序卡在某个循环里出不来?看门狗帮你解决。
  2. 检测任务超时——比如制动响应必须在 10ms 内完成,超时了说明有问题。
  3. 监控关键路径——不是所有代码都需要喂狗,只有关键路径才需要。
  4. 提供最后防线——其他安全机制都失效了,看门狗是最后一道屏障。

我记得有一次,客户反馈制动踏板偶尔没反应。查了三天,发现是某个中断服务程序里有个死循环。要不是看门狗把系统拉回来,后果不堪设想。

我的经验:看门狗不是万能的。它只能检测「程序不跑了」,检测不了「程序跑错了」。比如你算错了制动压力,看门狗可不管这个。

看门狗与系统复位的关系

这个问题很多人搞混。看门狗复位和上电复位,不是一回事。

复位类型 触发条件 影响范围 恢复时间
上电复位 电源重新上电 全部寄存器清零 较长(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 秒内都没人喂狗,系统肯定出问题了。

嗯,这里要注意:喂狗的位置很关键。别在主循环开头喂,要在关键任务执行完后喂。这样才能确保关键路径是通的。

避坑指南:我曾经在中断里喂狗,结果主循环卡死了,看门狗却一直没复位。因为中断还在正常触发。所以记住——喂狗要放在主循环里,别放中断里。

总结一下今天的内容:看门狗就是个简单的计数器,但它承载着系统最后的安全防线。在制动系统这种安全关键应用中,看门狗不是可选项,是必选项。

下一章我会讲看门狗在制动系统中的具体应用场景,包括如何设计多级看门狗、如何避免误复位等问题。到时候我会拿实际项目中的案例来讲,保证干货满满。