Arduino使用watchdog方法

作者: cheng3100 | 来源:发表于2017-02-01 13:25 被阅读245次

    bug修补者-watchdog

    最近在自己的一个Arduino项目中发现了一个很奇怪的异常,系统开机一段时间后出现死机,死机出现的时间和触发原因看起来似乎没有任何规律,检查程序也找不到任何错误,同时因为死机出现的随机性,也很难进行调试。问题可能是程序中的一些隐藏bug,或者与硬件有关,但无论如何,一直没有找到确切原因。因此在其中加入watchdog作为一种修补,至少每次出现异常后系统可以自动复位总比一直卡在那好。


    Arduino的WDT

    Arduino的语法参考中没有包括WDT,但相关开发板的atmega系列单片机的数据手册均显示是支持wdt的,同时因为Arduino IDE本身是基于AVR GCC编译器,因此可以直接在Arduino IDE中使用AVR的原生语句与函数库。需要包含头文件#include <avr/wdt.h>。可以参考avr的详细库函数说明

    avr的WDT 的基本功能语句有三个:

    • WDT使能定时间隔设置wdt_enable(),参数可以从几十ms到几s之间调整,当超过这个时间而单片机又没有复位WDT定时器时,单片机就会进行复位操作,一般来说不要设置过低的时间间隔。
    • WDT禁用语句wdt_disable(),为防止再次烧写程序时复位后反复进入
      wdt复位,需要在初始化程序的最开始位置禁用wdt,这在wdt定时间隔设置过短时尤为重要,否则可能会导致无法再次烧写。
    • WDT定时器复位语句wdt_reset(),如果在WDT的定时间隔内没有使用该语句复位定时器,则WDT会自动复位单片机,该语句的位置根据具体程序的耗时决定,可能需要多处加入。

    下面给出了一个wdt的测试程序,主循环内的led闪烁频率会越来越慢,当闪烁间隔超过wdt定时后,会触发wdt复位,在setup()中led快速闪烁三次以标志进入复位。

    #include <avr/wdt.h>
    const int onboardLED = 13; 
    
    void setup() {
     wdt_disable();  //disable wdt at the first of code to prevent it always reboot
    
      //the WDT time can be choose from
      //WDTO_25MS  WDTO_30MS  WDTO_60MS  WDTO_250MS  WDTO_500MS
      //WDTO_1S  WDTO_3S  WDTO_4S  WDTO_8S
      //be very carfully when use too short time value because  most avr's WDT still on work even after reboot
      wdt_enable(WDTO_4S);
    
      pinMode(onboardLED, OUTPUT);
    
      for (int k = 1; k <= 10; k = k + 1) {
        digitalWrite(onboardLED, HIGH);
        delay(50);
        digitalWrite(onboardLED, LOW);
        delay(50);
      }
      delay(750L);
    }
    
    void loop() {
      for (int k = 1; k <= 10000; k = k + 1) {
         wdt_reset();  //reset the watchdog timer every loop to prevent reboot
        digitalWrite(onboardLED, HIGH);
        delay(k * 250L);
        digitalWrite(onboardLED, LOW);
        delay(250L);
      }
    }
    

    bootloader 与WDT冲突解决

    用上面的代码实际测试中发现当自己用的arduino产生触发wdt复位的条件时,单片机并没有复位而是直接卡死,指示灯快速闪烁或者无反应。且再次烧写程序时出现了问题,强制上电复位才成功。查阅了一些资料后可能原因在于旧版本的arduino的bootloader与wdt间有冲突。
    我拿来一块新买的mega2560测试了同样的程序,发现果然可以正常使用wdt。于是我又用avr的usb asp烧写器烧写了新版本的bootloader进我的旧的arduino中,结果显示mega2560使用新的bootloader后可以正常工作,但pro mini仍然无法正常工作。关于如何烧写bootloader已经超过了本篇的范围,请参考我的另外一篇博客Arduino烧写bootloader


    参考资料:

    相关文章

      网友评论

        本文标题:Arduino使用watchdog方法

        本文链接:https://www.haomeiwen.com/subject/mpgkittx.html