Skip to content

窗口看门狗的使用方法

1. 窗口看门狗简介

窗口看门狗(Window Watchdog)是一种定时器,用于检测系统是否正常运行。当系统正常运行时,需要定期向看门狗定时器发送复位信号(即喂狗),否则看门狗定时器会溢出,触发系统复位。

窗口看门狗定时器的主要特点如下:

  1. 窗口看门狗定时器是硬件定时器,不需要软件控制。
  2. 窗口看门狗定时器有窗口功能,即窗口看门狗定时器在溢出之前,可以接受复位信号,从而避免系统复位。

2.如何设置窗口看门狗?

通过CubeMX配置窗口看门狗定时器,设置窗口看门狗定时器的溢出时间和窗口时间。

  1. 在STM32CubeMX中打开窗口看门狗定时器配置界面。
  2. 介绍窗口看门狗定时器配置界面:
    这是 STM32CubeMX 中 WWDG 的配置界面,以下是图中 “Parameter Settings” 标签页下各个参数的详细说明:

1. WWDG counter clock prescaler (WWGD计数器时钟预分频器)

  • 作用:用于对 WWDG 的时钟源进行分频,以设置看门狗递减计数器的计数频率。
  • 工作方式
    • WWDG 的时钟源通常来自 APB1 总线时钟 (PCLK1)。
    • 此分频值(图中为 8)决定了 PCLK1 被分频多少次后才作为计数器计数的时钟。
    • 计算公式:计数器时钟频率 = PCLK1 / 预分频值。
  • 设置建议
    • 结合窗口值和计数器初值,共同决定看门狗超时的“窗口期”和“最大超时时间”。
    • 分频值越大,计数器递减越慢,超时时间越长。

2. WWDG window value (WWDG窗口值)

  • 作用:设定一个窗口上限值。喂狗(刷新 WWDG)操作必须在这个值以下高于 0x40 的计数范围内进行才有效,否则将触发复位。
  • 工作方式
    • 计数器从设定的初始值开始递减。当计数器的值高于此窗口值时进行刷新,会触发复位(“过早喂狗”)。
    • 只有当计数器值低于此窗口值并高于 0x40 时,刷新操作才是合法的。
    • 图中值为 0x60 (十进制96)。
  • 设置建议
    • 必须小于 WWDG free-running downcounter value (初始值),否则整个窗口无效。
    • 需要根据程序中计划喂狗的最早时间和最晚时间来计算,以确保程序在预期的稳定执行阶段内完成喂狗。

3. WWDG free-running downcounter value (初始值)

  • 作用:设置看门狗递减计数器的初始值
  • 工作方式
    • 看门狗一旦激活,计数器就从该值开始递减,直到 0x40 时,如果还未被刷新,将产生看门狗复位。
    • 图中值为最大值 0x7F (十进制127),意味着从开始到超时,允许的递减步数最多,即超时时间最长
  • 设置建议
    • 此值需大于 0x40 且大于 WWDG window value
    • 通常设置为最大值 0x7F,以获得最长的超时时间。如果需要更短的超时时间,可以减小此值。

4. Early wakeup interrupt (提前唤醒中断)

  • 作用:使能或禁用 WWDG 的提前唤醒中断
  • 工作方式
    • 当递减计数器的值达到 0x40 时,如果此中断已使能,将产生一个中断请求。
    • 这给程序一个最后的警告机会:在计数器从 0x40 递减到 0x3F 从而触发复位前,有短暂的时间(通常等于一个计数器时钟周期)可以在中断服务程序中进行紧急处理(如保存关键数据、记录错误日志)或执行最后一次喂狗。
  • 设置建议
    • 调试期间:建议启用,有助于定位程序是跑飞还是单纯喂狗不及时。
    • 量产发布:通常建议禁用,因为中断响应和处理本身也需要时间,在最危急的时刻可能增加不确定性。应将喂狗逻辑严格放在主循环或监控任务的正常流程中,而非依赖此“最后一搏”。
    • 如果启用,中断服务程序必须极其精简高效,并确保能在此中断后、复位发生前完成操作。

5.参数设置核心关系与总建议

  1. 超时时间计算
    • 超时时间 ≈ (计数器初始值 - 0x40) × (计数器时钟周期)
    • 计数器时钟周期 = (预分频值) / (PCLK1频率)
  2. 窗口期
    • 合法的喂狗时间窗口是:从计数器递减到 (窗口值) 开始,到计数器递减到 0x40 之前结束。
  3. 配置黄金法则
    • 必须满足0x40 < 窗口值 < 计数器初始值0x7F
    • 图中的设置 (0x7F, 0x60) 是典型的安全配置,提供了从96到64(即 0x600x40)的32个计数步长的窗口期。
  4. 设计流程
    • 首先根据系统要求确定最大允许的超时时间。
    • 然后结合 PCLK1 频率和预分频器选项,计算出合适的计数器初始值
    • 最后分析程序正常运行时的关键路径或任务周期,确定一个安全的喂狗点,并据此设置窗口值,既要避免过早喂狗,也要确保在超时前完成。

6.总结看门狗的时间配置的含义

计数器值:  0x7F → ... → 0x61 → 0x60 → 0x5F → ... → 0x40 → 0x3F
状态:      [过早喂狗区]    [窗口期开始]    [窗口期内]    [窗口期结束] [复位!]
              └── 喂狗则复位 ──┘            └── 可安全喂狗 ──┘    └── 不喂狗则复位
  • 过早喂狗区:计数器值在 0x60 以下时,喂狗无效,立即复位。
  • 窗口期开始:计数器值达到 0x60
  • 窗口期内:计数器值在 0x600x40 之间,喂狗有效,确保系统在超时前恢复。
  • 窗口期结束:计数器值达到 0x40
  • 复位:计数器值在 0x40 以下时,喂狗无效,立即复位。

3.配置中断

在Early wakeup interrupt中启用了中断,就必须将看门狗的中断全部打开才行. 另外,如果需要使用回调函数来响应中断,也必须要将中断全部打开才行.

4.允许中断回调

5.代码

通过以上配置后,要手动写的代码就很简单了. 只需要编写中断回调函数,函数名称及参数都也是固定的.

c
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{
    /* USER CODE BEGIN Callback 0 */

    /* USER CODE END Callback 0 */

    /* USER CODE BEGIN WWDG_EarlyWakeupCallback */

    /* USER CODE END WWDG_EarlyWakeupCallback */
}

简单的说, 只要在这个函数中写入喂狗的代码就行了. HAL_WWDG_Refresh(hwwdg); 即可.

6.要注意的点

  1. 程序会在 main 函数中调用 HAL_WWDG_Init 函数初始化看门狗。一旦初始化成功,看门狗定时器将开始运行,并开始递减计数器。如果程序在窗口期之前没有喂狗,看门狗定时器将溢出,触发系统复位。
  2. 所以需要找一到一个合适的时机来初始化,避免整个程序还没有启动起来,就触发复位了.