分享

怎么避开嵌入式看门狗的那些“坑”?

 知芯世界 2023-09-22 发布于黑龙江

嵌入式开发中,我们时常会接触一条“狗”——看门狗(WDT,Watch Dog Timer)。它并不是真的狗,而是一种形象的比喻,即程序跑飞时就会叫的狗,有点类似时刻看家门的狗,在主人走神的时候咬他一口,把他咬醒,因此得名。 

从原理上来看,看门狗就是定时器电路,又称电压监控器电路,当MCU运行过程中,在某处进入了死循环,或者受到干扰造成PC指针指向了无程序区,都会导致程序没反应,按键失效,屏幕内容不变等问题。这时如果正确使用了看门狗,就会让PC指针复位,从头开始执行程序。

比如,IMP813L、X25045等。它是单片机的组成部分,一般在产品化嵌入式系统中,如MCU、DSP等应用中,为使系统在异常情况下能够自动复位,都需引入看门狗。对嵌入式工程师来说,掌握看门狗是基础技能。

看门狗看似简单,也蕴含许多技巧和“坑”。今天,EEWorld就来盘点一下看门狗的相关知识与工程师的精化观点。(如果有任何其它想法与工程师沟通,可移步EEWorld原贴进行讨论:http://bbs./thread-1252461-1-1.html

王兆楠、付斌丨编辑

电子工程世界(ID:EEworldbbs)丨出品

 用好看门狗,能救命 

在一切开始前,我们要知道,看门狗很重要。

看门狗本身不是用来解决系统出现的问题,在调试过程中发现的故障应该要查改设计本身的错误。加入看门狗目的是对一些程序潜在错误和恶劣环境干扰等因素导致系统死机而在无人干预情况下自动恢复系统正常工作状态。看门狗也不能完全避免故障造成的损失,毕竟从发现故障到系统复位恢复正常这段时间内怠工。同时一些系统也需要复位前保护现场数据,重启后恢复现场数据,这可能也需要一笔软硬件的开销。

当程序没有跑飞时,我们并不会感受到看门狗的作用。程序总是一条一条执行,无论是“n多判断循环”,还是跳转,还是调用,还是中断。不会产生“死循环”。

但如果单片机受到外部干扰,包括电源电压跌落等,就可能出错。可能是程序计数器错误,本来应该加一的加了五,那就可能取到的不是指令操作码,而是操作数,例如把XXXXXXXX中后一字节当成一条指令的操作码了。也可能是取出的指令错误,例如把LCALL  XXXXXXXX当成了RET指令。这叫程序跑飞。

程序一旦跑飞,后果不可预料,什么样的操作都可能出现。

例如单片机控制一座电梯。本来电梯正在三楼向一楼运行,此时电梯门必定是关闭的。由于外部干扰使程序跑飞后,单片机执行了开门程序,或者执行了停止程序,这就可能造成危险。

为防止单片机程序跑飞造成的危险,就会加入看门狗。

对应看门狗,也有很多专有名词:

  • 喂狗:触发看门狗,计数器会被刷新,重新开始计算。按喂狗频率,分为快狗Fast-Mode与慢狗Slow-Mode。实际使用中,WDT初始化后会先设置WDT运行模式为慢狗,在周期任务正式运行后再切换为快狗;

  • 杀狗:禁用/关闭看门狗;

  • 咬狗:当看门狗启动后,计数器开始自动计数,经过一定时间,计数器溢出就会对CPU产生一个复位信号使系统重启(俗称“被狗咬”)。

看门狗的原理其实很简单:给看门狗一个数字,程序开始运行后看门狗开始计数。如果程序运行正常,过一段时间CPU应发出指令让看门狗置零,重新开始计数。如果看门狗增加到设定值就认为程序没有正常工作,强制整个系统复位。

看起来有点懵,但翻译一下就是:一个输入就是“喂狗”,一个输出到MCU的RST端,MCU正常工作的时候,每隔一段时间输出一个信号到喂狗端,给WDT清零。如果超过规定的时间不喂狗(一般在程序跑飞时),WDT 定时超过,就会给出一个复位信号到MCU,使MCU复位,防止MCU死机。 看门狗的作用就是防止程序发生死循环,或者说程序跑飞。

看门狗原理流程图,图源丨白开电子

看门狗分为CPU内部自带和独立看门狗两种,前者可以通过程序改变溢出时间,也可以随时禁用;后者无须配置,上电即用,但无法禁用,同时必须按时喂狗。

另外,看门狗还分硬件看门狗和软件看门狗。硬件看门狗是利用一个定时器电路,其定时输出连接到电路的复位端,程序在一定时间范围内对定时器清零(喂狗),因此程序正常工作时, 定时器总不能溢出,也就不能产生复位信号。如果程序出现故障,不在定时周期内复位看门狗,就使得看门狗定时器溢出产生复位信号并重启系统。软件看门狗原理上一样,只是将硬件电路上的定时器用处理器的内部定时器代替,这样可以简化硬件电路设计,但在可靠性方面不如硬件定时器,比如系统内部定时器自身发生故障 就无法检测到。当然也有通过双定时器相互监视,这不仅加大系统开销,也不能解决全部问题,比如中断系统故障导致定时器中断失效。

仍以电梯为例。如果控制电梯的单片机程序跑飞,就可能发生各种危险。这时看门狗在没有及时“喂狗”情况下使单片机复位。而单片机复位后初始化,必定关掉电动机信号,发出刹车信号,发出关门信号……这样即使电梯停到了两层楼之间,也没有什么危险。

所以看门狗的作用是在程序跑飞时及时制止单片机的疯狂行为使单片机复位。单片机并不能消灭由于干扰造成的“死循环”。

由于看门狗是程序跑飞之后最后的防御手段,单片机正常工作时看门狗应该不工作才对。

防止单片机因外部干扰而使程序跑飞,应该对单片机加以屏蔽,把所有外部干扰挡在外面,不会影响单片机工作。机箱的输入输出线上都应该加滤波电路,机箱的缝隙应该具有良好的导电性。机箱内部的各设备如为单片机供电的电源也要仔细设计,不能具有过大纹波,不会产生强电磁干扰。这些预防措施,在强烈的电磁干扰环境中特别要注意。

 不可忽视的细节 

看门狗确实不错,但在设计时费事,报警逻辑、检测门禁权限、实时监测周围环境、记录异常事件等都要考虑,EEWorld论坛中,有工程师总结为以下四点:

  1. 设置合适的计数值:根据系统的实时性要求和程序的运行时间,需要合理设置看门狗的计数值。如果计数值设置得过小,可能会导致过早触发复位;如果设置得过大,可能无法及时检测到程序异常。通常需要根据具体的应用场景和系统需求进行调整。

  1. 喂狗的时间间隔:为了避免被复位,需要在看门狗计数值达到阈值之前周期性地喂狗。这个喂狗的时间间隔应该足够短,但也不能过于频繁,避免给系统带来额外的负担。一般建议在计数值的一半到三分之二之间进行喂狗。

  1. 处理异常情况:如果程序发生异常或者进入死循环等无法正常响应的状态,会导致无法及时喂狗,并最终触发复位。为了保证程序的稳定性,需要在代码中处理各种可能的异常情况,尽量避免出现无法正常运行的情况。

  1. 确保喂狗的可靠性:为了确保喂狗的准时和可靠性,可以使用硬件定时器或者软件定时器来定时喂狗。硬件定时器可以提供更高的精确度和稳定性,但在某些系统中可能没有硬件定时器可用,这时可以通过软件定时器来实现。

从具体参数上来看则是:

  1. 系统电压:选择看门狗依据系统内部的电压轨,也就是说,根据MCU或DSP的驱动电压来选择电压监控器;

  2. 看门狗输入端(WDI):一旦MCU无法正常工作时,而且其片内看门狗功能也无法复位,软件进入死循环。这时,具有集成看门狗功能的监控器可触发复位,从而提高系统的可靠性;

  3. 手动复位(MR)功能:借助该功能,可对电路进行手动复位,或者通过应用中的另一个器件来主动控制监控器电路;

  4. 有效高电平输出:如果处理器需要采用有效高电平复位输入,无需增加额外的器件就可实现;

  5. 电源故障输入/输出(PFI/PFO):利用该比较器能够提供更大的灵活性,例如用来实现电池电量的长时间监测和电压跌落预警;

  6. 延迟时间:一定的延迟时间使得电压和电路中的其它器件能够在正常操作重新开始之前先稳定先来,降低电压波动,提高系统的可靠性;

  7. 通道数:一般而言,系统中所需的监控器功能的数量取决于处理器及外围器件的电压。例如,独立电压的处理器有可能需要对两个电源轨进行监控,与此同时,系统中的存储器可能也需要进行监控并工作在第三个(不同的)电压轨上;

  8. 芯片启动选通作用:一旦电源电压处于欠压状态时,看门狗电路的芯片启动选通功能能够防止错误数据使CMOS RAM发生劣化。

防止单片机因外部干扰而使程序跑飞,应该对单片机加以屏蔽,把所有外部干扰挡在外面,不会影响单片机工作。机箱的输入输出线上都应该加滤波电路,机箱的缝隙应该具有良好的导电性。机箱内部的各设备如为单片机供电的电源也要仔细设计,不能具有过大纹波,不会产生强电磁干扰。这些预防措施,在强烈的电磁干扰环境中特别要注意。

需要强调的是,网上和书里对喂狗的介绍不多,大部分都只说使用“WDTCTL = WDTPW + WDTCNTCL;”即可。一般使用起来没什么问题,但是当不使用默认的看门狗时钟源和分频系数之后,问题就来了。(以G2XXX系列,SMCLK=1M,ACLK=32K为例)直接使用“WDTCTL = WDTPW + WDTCNTCL;”喂狗之后,看门狗就被重置成复位状态,看门狗复位时间就变成了32ms,如果远小于你的喂狗时间,程序就没法正常工作了,典型表现为定时重新启动。仔细查看WDTCTL寄存器之后,就能发现问题。

 看门狗复位的技巧 


看门狗复位时,也拥有诸多技巧,EEWorld论坛工程师总结为以下三点:

判断是否需要使用:如果要使用看门狗的话,需要做一些寄存器的配置,在程序区的某些地方也要加入喂狗指令来防止看门狗复位,有一定的工作量,所以用与不用需要考虑一下。能不使用看门狗的场合,要求是系统即使死机也问题不大,等待人过来断电复位即可的情况。但是这种情况已经很少了,所以绝大多数情况下看门狗都要加上。比如有温控功能的电热水器,假如电加热已经启动,但是系统死机了,温控失效,电加热也不会关闭,这时水温就会一直升高,直到水被蒸干,然后电加热损坏或引发火灾,或者人被开水烫伤。这时有看门狗复位,系统就会恢复正常,检测到温度够了,就会关闭电加热的。

保证看门狗工作正常:看门狗除了进行寄存器配置之外,喂狗函数的位置也很重要,没处理好就会发生不该复位时复位了,或改复位的时候没有复位,可能的原因是在可能出现的死循环里喂狗了。

保证看门狗复位时不会引起系统异常:能否做到这一点,是工程师水平高低的重要体现。单片机系统一般都是和某个外在的系统连接的,可以是机械系统,水系统,电气系统等,要保证单片机系统的复位不会造成这些外接系统的异常。主要的问题点在于单片机复位时IO口状态会改变为初始值,寄存器会复位,内存会清空。比如电梯,单片机发出一个向上的信号,于是轿厢开始向上,但是这时因为某种干扰,单片机死机触发看门狗复位,IO初始化为关闭,轿厢失去了向上信号,这时是让轿厢迅速下坠?还是单片机反应过来之后重新输出向上信号,又拉住了轿厢?工程师需要去思考并解决这些问题,做控制的人需要对安全性有充足的认识。

利用以上三点,还能发挥出许多创意的技巧。比如,有些工程师设计的软件一般会定时主动地进行自复位,目的是让变量清零,消除一些长时间运行可能造成的问题。这个功能有些型号的单片机提供了便利的设计,直接赋值给某个寄存器就可以立刻复位了,大部分芯片不支持这个功能。那怎么办?这时可以活用看门狗功能,

就是通过一个标志来控制某个地方是否喂狗,软件想主动复位的时候,关闭标志,然后系统就不喂狗了。这样到了看门狗复位的时间,就会发生复位了。这里主要要处理好停止喂狗和看门狗复位之间的时间,可进行一些变量保存,IO关闭等。

 写在最后 


看门狗在嵌入式系统中发挥着及其重要的作用,虽然不同的硬件设计选择不同类型的看门狗,实现的方式也千差万别,但它们的作用都是一样的:保证系统在出现不可恢复得错误时,自动让系统重启。在实际应用中,我们应该活用看门狗这个技巧。

如果您在使用看门狗中遇到什么问题,也欢迎来到EEWorld论坛(bbs.)来交流。

参考文献

[1] EEworld论坛:关于嵌入式软件开发中使用看门狗的注意事项.http://bbs./thread-1248362-1-1.html

[2] EEworld论坛:看门狗电路应用基本技巧和注意事项.http://bbs./thread-1252461-1-1.html

[3] EEworld论坛:看门狗复位的应用技巧.http://bbs./thread-1102962-1-1.html

[4] EEworld论坛:多任务看门狗及喂狗方法.http://bbs./thread-1102963-1-1.html

[5] EEworld论坛:MSP430单片机看门狗面面观.http://bbs./thread-644606-1-1.html

[6] 白开电子:一文深度理解看门狗(WatchDog).https://mp.weixin.qq.com/s/i1kann4JgWgQ8YjwOcJTBg




· END ·




    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多