Mbed OS Watchdog 的实现
看门狗是嵌入式设备的常用功能,当时程序飞掉的时候,系统会自动复位。硬件实现上,watchdog 是一个特别的定时器,应用程序必须不断地重装定时器计数值(俗称喂狗),当程序没有及时喂狗的话,硬件定时器溢出,产生系统复位信号。
由于watchdog和硬件有关,mbed OS 目前没有实现看门狗功能。本文讨论如何在modular-2的STM32F4 平台上实现MbedOS应用程序的看门狗功能。
STM32F4 的watchdog硬件
STM32F4系列MCU有一个独立看门狗(IWDG)和一个窗口看门狗(WWDG)。
STM32F4的独立看门狗由内部专门的32Khz低速时钟(LSI)驱动,即使主时钟发生故障,它也仍然有效。这里需要注意独立看门狗的时钟是一个内部RC时钟,所以并不是准确的32Khz,而是在15~47Khz之间的一个可变化的时钟,只是我们在估算的时候,以40Khz的频率来计算,看门狗对时间的要求不是很精确.
溢出时间计算
Tout=((4×2^prer)×rlr) /40
其中Tout为看门狗溢出时间(单位为ms);prer为看门狗时钟预分频值(IWDG_PR值 )范围为0~7;rlr为看门狗的重装载值(IWDG_RLR的值)。
比如我们设定prer值为4,rlr值为625,那么就可以得到Tout=64×625/40=1000ms,这样,看门狗的溢出时间就是1s,只要你在一秒钟之内,喂一次狗,就不会导致看门狗复位。
时间关系(LSI时钟40KHz)
预分频系数(4×2^prer) | PR[2:0]位 | 最短时间(ms) | 最长时间(ms) |
/4 | 0 | 0.1 | 409.6 |
/8 | 1 | 0.2 | 819.2 |
/16 | 2 | 0.4 | 1638.4 |
/32 | 3 | 0.8 | 3276.8 |
/64 | 4 | 1.6 | 6553.6 |
/128 | 5 | 3.2 | 13107.2 |
/256 | 6 或7 | 6.4 | 26214.4 |
Mbed WatchDog 的实现
在MbedOS 下实现看门狗,需要使用HAL库函数实现。
预分频系数
IWDG_PRESCALER_4
IWDG_PRESCALER_8
IWDG_PRESCALER_16
IWDG_PRESCALER_32
IWDG_PRESCALER_64
IWDG_PRESCALER_128
IWDG_PRESCALER_256
reload 的最大值位12位,0xFFF
定时周期的计算简化为:
Tout=预分频系数*reload/40,单位为ms。
在mbed OS 下,我们编写了一个类来实现watchdog,将hal 的底层封装在类中。
#include "mbed.h"
#include "stm32f4xx_hal.h"
DigitalOut led1(LED1);
class WatchDog {
private:
IWDG_HandleTypeDef hiwdg;
public:
WatchDog(uint32_t prescaler = IWDG_PRESCALER_256, uint32_t reload = 0xfff) {
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = prescaler;
hiwdg.Init.Reload = reload;
HAL_IWDG_Init(&hiwdg);
}
void feed() {
HAL_IWDG_Refresh(&hiwdg);
}
};
int main() {
WatchDog wdg(IWDG_PRESCALER_64, 625);
while (true) {
led1 = !led1;
wdg.feed();
wait(0.5);
}
}
上面的程序在Mbed OS 下调试成功的。