这一节,我们要学习的内容是 STM32 里的看门狗。STM32 内置两个看门狗,分别是独立看门狗(IWDG)和窗口看门狗(WWDG),两者的作用基本相同,只是侧重点不一样。
那看门狗,简单来说,就是程序运行的一个保障措施,我们得在程序中定期的喂狗,如果程序出问题卡死了,没有在规定的时间里喂狗,那么看门狗硬件电路就会自动帮我们复位一下,防止程序长时间卡死。这就像是我们写了个程序,然后突然没动静了,我们就会习惯性的去按一下复位;或者说手机、电脑,卡死不动了,我们也会习惯性的重启来解决。那看门狗就是完成这样一个操作的硬件电路,在程序卡死的情况下,自动帮我们复位一下。
好,然后我们还是先看一下本节程序的现象。本节一共两个程序:独立看门狗和窗口看门狗。
先看一下独立看门狗的程序,简单看一下程序内容,程序进来,首先执行判断,看一下这个程序是因为看门狗复位而从头执行的,还是因为刚上电或者按复位键而从头执行的,如果是看门狗复位,OLED 第二行显示独立看门狗 RST 的字符串;如果是正常复位,OLED 第三行显示正常 RST 的字符串。之后是独立看门狗初始化,设定的最大喂狗时间是 1000 ms,这样,我们在主循环里就得不断的调用喂狗函数执行喂狗,且喂狗的间隔不能超过上面配置的 1000 ms,目前喂狗的间隔是 200+600 = 800ms,这样主循环不断运行起来,独立看门狗就不会执行复位。最后在主循环开始的这个位置,加入了一个按键获取键码,在这个函数里面,我们采用的是阻塞式写法,也就是按键按下不放的话,程序就会卡死在这个函数,所以,我们把这个函数放在这里,按下按键不放,模拟程序卡死的状况,返回值,按键键码暂时不需要,这样,喂狗程序无法及时执行,独立看门狗就会复位,让程序从头开始执行。那我们下载看一下现象,复位一下,这是正常复位,所以第三行显示正常复位的 RST 字符串,之后,主循环不断执行,并在第四行显示 FEED,表示喂狗,然后我们按上面的按键,按住不放,这时主循环卡死,第二行就会显示独立看门狗 RST,这个复位就是独立看门狗产生的了,那这就是独立看门狗的程序现象。
简单来说,就是如果不及时喂狗,程序就会复位。
接着我们来看第二个程序,窗口看门狗。这个窗口看门狗和独立看门狗类似,都是不喂狗,就复位,但是窗口看门狗对喂狗时间要求更严格一些,它有个喂狗时间的窗口,必须在这个时间窗口内喂狗,喂狗晚了,复位,喂狗早了,也复位。看一下,程序进来,首先还是判断复位来源,是窗口看门狗导致的复位,还是正常上电和复位键的复位;之后,窗口看门狗初始化,这里设置的喂狗时间窗口时 30~50ms,喂狗的间隔必须在 30~50ms 之间,喂早喂晚都不行,然后看主循环里。WWDG_SetCounter
这一条是喂狗程序,上面 Delay 的时间间隔是 20+20 = 40 ms,目前的间隔,位于时间窗口内;然后获取键码,还是模拟程序卡死。这个程序,下载看一下,首先还是正常复位,第三行显示正常的 RST,之后主循环,第四行一直闪烁 FEED,表示喂狗,然后按上面的按键,程序卡死,没有及时喂狗,这样第二行就会显示,窗口看门狗产生复位了,当然,按按键只能模拟晚喂狗,早喂狗,也会复位,这个现象,我们写程序的时候再来演示吧。
好,程序现象就演示到这里。看完这两个代码的演示,相信大家对看门狗就已经了解的大差不差了吧。其实看门狗也不是很复杂,就是个自动复位电路。
那接下来先看一下看门狗的简介。
WDG(Watchdog)看门狗
它的作用,顾名思义,其实就是“看大门”,不过这里的大门,表示的是程序。
看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性。
那写过程序代码的都知道,程序的设计是非常讲究逻辑的。每一种状态,每一种可能,都要在写程序的时候预先注意到,否则,一旦出现了程序没有预料到的情况,程序经常就会出现卡死、跑飞、胡乱运行的状况。这一点,在我们当前这些简单的测试程序中还很少出现,因为这些程序其实并不复杂,任务也很简单;但是,对于一些大型项目,各种状态和可能,都是非常非常多的,在写程序的时候,一不小心,就会留下 bug;或者说,在大型项目中,bug 根本无法避免,因为可能的状态太多了,总有那么些意想不到的情况发生,让你的程序卡死或崩溃。那解决办法呢?
- 第一,就是我们程序员要有丰富的经验,避免一些常见的 bug;
- 第二,就是程序要经常迭代,发现 bug 后及时修补;
- 第三,就是我们的看门狗了,出现卡死崩溃现象后,帮我们按一下复位,虽然说不能解决 bug 本身吧,但是也可以极大的提高程序的健壮性,因为很多 bug 都是偶然发生的,简单的复位一下,就会有很大概率,让程序走向正轨。
那在这里写的除了程序本身的设计漏洞呢?还会有硬件故障、电磁干扰等原因,让程序出问题。比如硬件故障,我们想读取传感器的数据,结果传感器坏了,总是死等,那程序不就卡死了嘛;电磁干扰,这个一般出现在恶劣的环境中,我们都知道,很强的电磁干扰,可能会让这些电子元器件失灵,也就是程序跑飞现象,程序不知道跑到哪个奇怪的地方了。那假设你的设备遇到了一阵强电磁干扰,有看门狗的话,干扰过后,程序复位,回到正轨;没有看门狗的话,可能受到干扰,程序就永远地卡死在某个地方了,对吧。所以,出现状况时,我们需要看门狗及时复位程序,避免程序陷入长时间的罢工状态。
最后,再说两点,一个是对于硬件故障,如果是关键的设备故障,复位也没用的话,那看门狗也无法力挽狂澜,因为看门狗就是简单的复位一下;第二个是对于程序设计漏洞,这里主要针对的是无法预料的漏洞,而不是说,我有看门狗了,我就在程序中,写大量的死循环,或者不规划程序,到处跳来跳去,然后卡死了,就用看门狗来托底,这样恐怕不太好,合理规划程序是第一,然后可以预料的漏洞,尽量直接写好处理方法,最后,才是看门狗托底,这样才是比较好的思路。
看门狗本质上是一个定时器,当指定时间范围内,程序没有执行喂狗(重置计数器)操作时,看门狗硬件电路就自动产生复位信号
这里,说的就是看门狗的工作逻辑了。看门狗,其实就是定时器,看一下结构,它的结构和定时器是非常相似的,只不过是,定时器溢出,产生中断;而看门狗定时器溢出,直接产生复位信号。然后喂狗操作,其实也就是重置这个计数器,这是一个递减计数器,减到 0 之后就复位,那程序正常运行时,为了避免复位,就得在这个计数器减到 0 之前,及时把计数值加大点,对吧,这个操作,就是喂狗。如果你程序卡死了,没有及时加大这个计数器,那么减到 0 之后,就自动复位了,这就是看门狗的工作逻辑,是不是也不难。
STM32内置两个看门狗
独立运行,就是独立看门狗的时钟是专用的 LSI,内部低速时钟,即使主时钟出现问题了,看门狗也能正常工作,这也是独立看门狗,独立的得名原因。对时间精度要求较低就是独立看门狗只有一个最晚时间界限,你喂狗间隔只要不超过这个最晚界限就行了,你说 我很快的喂,疯狂的喂,连续不断的喂,那都没问题。
它相比较独立看门狗,就严格一些了。要求看门狗在精确计时窗口起作用,意思就是喂狗的时间有个最晚的界限,也有个最早的界限,必须在这个界限的窗口内喂狗,这也是窗口看门狗,窗口的得名原因。因为对于独立看门狗来说,可能程序就卡死在喂狗的部分了;或者程序跑飞,但是喂狗代码也意外执行了;或者程序有时候很快喂狗,有时候又比较慢喂狗,那这些状态,独立看门狗就检测不到了,但是窗口看门狗是可以检测到这些问题的,因为它对喂狗的时间,可以卡的很死,快了,慢了,都不行。
最后,窗口看门狗使用的是 APB1 的时钟,它没有专用的时钟,所以不算是独立。好,这些,就是看门狗的基本介绍了。
接下来,先看一下独立看门狗。