2018年3月24日 星期六

【Ameba特異功能集(二)】忠實看門狗:WatchDog Timer (WDT)

作者:柯大
物聯網裝置對於感測資料的蒐集常需1年365天、1天24小時不間斷地,將感測值透過不同的通訊網路傳輸至雲端,但因網路狀態不穩或因其他外在的雜訊、電磁干擾,以及程式本身長時間運作的問題等各種情況,導致裝置系統無法如預期正常運作,結果當機,碰到這種情形,也只能靠人工重新開機裝置,或按下重新開機鈕「Reset」。
在萬物聯網的情形下,您的裝置可能安裝於一些外部環境,例如:架設於高架道路上,用來偵測與累計每天有多少輛車輛,以及超過多少高度,若這樣的系統當機了,就得派人去現場按重新開機,造成很大的不便、危險性及人力成本;或是在工廠輸送帶的生產線上,設置一個控制或感測生產線運作狀況的裝置,每當這個裝置當機了,就必須停止整條生產線,等待重新開機,才能恢復原有生產程序,這些影響都造成很大的不便,為了解決這個問題,可以嘗試在裝置上加入看門狗的功能,以下提供解決方案:

在裝置中加入看門狗 (WatchDog Timer)功能

Ameba物聯網開發板針對Arduino IDE開發環境,在V1.0.5版加入了WDT(Watch Dog Timer)功能,因應上述狀況,讓開發者利用此API功能自動偵測裝置運作情形,並在程式中加入WDT自動計時,當遇到系統故障或連網沒回應超過所要求的時間,就可自動reset裝置重新開機。

看門狗計時器就會對系統發出重設、重新開機或關閉的信號,使系統從懸停狀態回復到正常運作狀態。
有關對WatchDog Timer的說明可參考下列網站:
  1.  維基百科
  2.  Arduino.cc網站

3組自動Reset的API

2016年12月19日Realtek IoT/Arduino Solution (Version 1.0.5) ,新增開發板可設定自動Reset 的「Watchdog Timer」API功能:

void wdt_enable(timeout);  //開啟看門狗Watchdog計時器功能,並設定重新timeout reset時間
void wdt_reset();         //清除watchdog計時器的值,重新依前面wdt_enable(timeout)所設定timeout reset時間倒數計時
void wdt_disable()        //關閉看門狗Watchdog功能
要使用Ameba Watchdog API功能需於程式中加入 library:
#include "wiring_watchdog.h"

範例一


#include "wiring_watchdog.h"   // 加入Watchdog API library 
int timeout = 3500;           // 設定Watchdog Timeout 自動Software reset 功能,
最大值是8000ms = 8 秒。
void setup() {
  Serial.print("set watchdog timeout: "); 
  Serial.print(timeout);
  Serial.println(" ms");
  wdt_enable(timeout);   //開啟watchdog計時器功能,並設定重新timeout reset時間
}
 
void loop() {
  for (int i=1; i<=8; i++) {
    Serial.print("delay ");
    Serial.print(i);
    Serial.println("s");
    delay(i*1000);     //當delay 超過所設定timeout 值,Ameba的watchdog 自動對Ameba 板做software reset 
    Serial.println("feed watchdog");
    wdt_reset();      //清除watchdog計時器的值,重新計算timeout reset時間
  }
}

範例二


#include "wiring_watchdog.h"   // 加入WatchDog Timer API library 
int timeout = 3500;           // 設定Watchdog Timeout 自動Software reset 功能,
最大值是8000ms = 8 秒。
void setup() {
  Serial.print("set watchdog timeout: "); 
  Serial.print(timeout);
  Serial.println(" ms");
  wdt_enable(timeout);   //開啟watchdog計時器功能,並設定重新timeout reset時間
}

void loop() {
  wdt_reset();    // 進入Ameba執行廻圈,清除watchdog計時器的值,重新計算timeout reset時間
  getSystemDatetime();
  wdt_enable(1000); //開啟watchdog計時器功能,並設定重新timeout rese時間=1秒
wdt_reset();      // 進入一段SD卡存取程式,加入wdt_reset()清除watchdog計時器的值,重新計算timeout reset時間,如果下面讀取錯誤造成當機,系統即會自動reset
  if (SD.exists(logDir)) {   // SD卡偵測目錄是否存在
    }
  else {
    SD.mkdir(logDir);    // SD卡建立log目錄
  }

Serial.println(F("Start state#1."));
wdt_enable(3000); //開啟watchdog計時器功能,並設定重新timeout rese時間=3秒
 wdt_reset();     // 進入一段讀取電表程式,加入wdt_reset()清除watchdog計時器的值,重新計算timeout reset時間,如果下面讀取錯誤造成當機,系統即會自動reset
Meter_no =1 ;
readAPMRdata();   // 讀取電表副程式
trans2value();
displayData();

Serial.println(F("Start state#2.")); 
wdt_enable(2000); //開啟watchdog計時器功能,並設定重新timeout rese時間=2秒
 wdt_reset();     // 進入一段寫入記錄程式,加入wdt_reset()清除watchdog計時器的值,重新計算timeout reset時間,如果下面讀取錯誤造成當機,系統即會自動reset
 writelogFile();    // 寫入記錄副程式

Serial.println(F("Start state#3."));
wdt_enable(2000);   //開啟watchdog計時器功能,並設定重新timeout rese時間=2秒
wdt_reset();        // 進入ftp傳輸程式,加入wdt_reset()清除watchdog計時器的值,重新計算timeout reset時間,如果下面讀取錯誤造成當機,系統即會自動reset
 ftpBackup();       // ftp 上傳資料副程式
wdt_disable();     //廻圈結束關閉看門狗Watchdog功能

}   // End of Loop() 

小結

物聯網裝置受到外擾因素的影響很多,但並不是所有裝置都適合人工去重開,「WatchDog Timer」提供了我們解法,以後「Reset」不需要人工操控,也能自動重啟呢!

沒有留言:

張貼留言