最終更新日 2021年4月26日
Arduino環境でWebServerを構築し、外部から適当に間違ったURLをCallすると無限ループに入ってしまい、メインループが止まってしまう事があります。この場合、ハードウエアリセットを実行するのが一般的ですが、マイコンの場合はWatchDogTimerによる監視を行い、規定時間でWatchDogTimerResetが掛からなければ自動でリセットが掛かる機能を採用するのが一般かと思います。
ablic社のWebSiteが詳しく書かれているように感じました。
https://www.ablic.com/jp/semicon/products/automotive/automotive-watchdog-timer/intro/ArduinoのWDT機能の使い方は以下のように書かれていました。
//WDTのリセット動作はどこでも良いというわけでもなく、ハングアップを検出できる位置を慎重に選ぶ必要があります。 #include <avr/wdt.h> void setup(){ wdt_enable(WDTO_4S); //WDTを4秒で設定し有効化 //wdt_disable(); //WDTの無効化 } void loop(){ wdt_reset(); //WDTのリセット } |
//ウオッチドックタイマーの設定時間はヘッダーの中で次のように定義されており、適当なものを使用します。 #define WDTO_15MS 0 #define WDTO_30MS 1 #define WDTO_60MS 2 #define WDTO_120MS 3 #define WDTO_250MS 4 #define WDTO_500MS 5 #define WDTO_1S 6 #define WDTO_2S 7 #define WDTO_4S 8 #define WDTO_8S 9 |
WDTはハードウエア依存なので、STM32duinoの場合はコードは異なります。
STM32Fのchipには、ドキュメントによると7つのタイマが搭載されていることが判ります。そのうち2つがWDTです。
ライブラリで対応していないか調査したのですが、作者のRoger Clark氏がライブラリを作るべきと言うようなpostをしていました。残念ながらCoreでは対応していない様です。ただ、汎用タイマの流用は避けたいので、WDT用のタイマを使いたいです。Mapleのライブラリを見ていたところ、#include <libmaple/iwdg.h>が有効であることが判りました。これでWDTが使えそうです。サンプルスケッチを検索しました。
leaflabs社は現在でもAPI等の資料提供しています。素晴らしいです。
https://docs.leaflabs.com/static.leaflabs.com/pub/leaflabs/maple-docs/0.0.12/libmaple/api/iwdg.html
独立したウォッチドッグを使用するには、最初に、アプリケーションに適切なプリスケーラーとIWDGカウンターのリロード値を指定してiwdg_init()を呼び出します。
その後、IWDGカウンターが0に達する前に、定期的にiwdg_feed()を呼び出して 、カウンターをリロード値にリセットする必要があります。そうしないと、チップがリセットされます。
一度開始すると、独立ウォッチドッグをオフにすることはできません。この点はAVRとは異なります。
STM32のWDTは2つ有ります。この点に触れておきたいと思います。
|
/* * 2021/01/07 T.Wanibe STM32でWDTを使う検証コードです。 * 資料によると、wdtのBaseClockは40kHzだと有ります。 * 最大131072バイトのフラッシュメモリのうち、スケッチが16124バイト(12%)を使っています。 * 最大20480バイトのRAMのうち、グローバル変数が3128バイト(15%)を使っていて、ローカル変数で17352バイト使うことができます。 */ #include <libmaple/iwdg.h> #define LED1 PB8 #define LED2 PB9 #define iwdg_init_ms(N) iwdg_init(IWDG_PRE_256,((N)/6)) //--------------- void setup() { Serial.begin(115200); pinMode(LED1,OUTPUT); pinMode(LED2,OUTPUT); iwdg_init_ms(5000); //ウォッチドッグをオンにして、オーバーフロー時間を設定します。 //実測値で5000だと6000m秒弱でリセットが掛かります。 //6000だと6000m秒ではリセットが掛かりません。 //25usec×256×5000/6=5.3秒でリセットが掛かるという計算になります。 //25usec×256×6000/6=6.4秒でリセットが掛かるという計算になります。 } //--------------- void loop() { Serial.println(millis()); digitalWrite(LED1,HIGH); delay(1000); digitalWrite(LED2,HIGH); delay(1000); digitalWrite(LED1,LOW); delay(1000); digitalWrite(LED2,LOW); delay(1000); digitalWrite(LED1,HIGH); digitalWrite(LED2,HIGH); delay(1000); digitalWrite(LED1,LOW); digitalWrite(LED2,LOW); delay(1000); Serial.println(millis()); iwdg_feed(); //ウォッチドッグタイマーをリセットするには、ドッグ操作をフィードします } |
/* Key register */ #define IWDG_KR_UNLOCK 0x5555 #define IWDG_KR_FEED 0xAAAA #define IWDG_KR_START 0xCCCC /* Prescaler register */ #define IWDG_PR_DIV_4 0x0 #define IWDG_PR_DIV_8 0x1 #define IWDG_PR_DIV_16 0x2 #define IWDG_PR_DIV_32 0x3 #define IWDG_PR_DIV_64 0x4 #define IWDG_PR_DIV_128 0x5 #define IWDG_PR_DIV_256 0x6 /* Status register */ #define IWDG_SR_RVU_BIT 1 #define IWDG_SR_PVU_BIT 0 #define IWDG_SR_RVU (1U << IWDG_SR_RVU_BIT) #define IWDG_SR_PVU (1U << IWDG_SR_PVU_BIT) |
ESP32の場合も調べました。Arduino core for the ESP32が正式にインストールされたArdinoIDE環境であれば、esp_task_wdt.h をインクルードすることで実現可能です。使い方例です。https://iotassistant.io/esp32/enable-hardware-watchdog-timer-esp32-arduino-ide/を参照しました。
#include <esp_task_wdt.h> //3 seconds WDT #define WDT_TIMEOUT 3 void setup() { Serial.begin(115200); Serial.println("Configuring WDT..."); esp_task_wdt_init(WDT_TIMEOUT, true); //enable panic so ESP32 restarts esp_task_wdt_add(NULL); //add current thread to WDT watch } int i = 0; int last = millis(); void loop() { // resetting WDT every 2s, 5 times only if (millis() - last >= 2000 && i < 5) { Serial.println("Resetting WDT..."); esp_task_wdt_reset(); last = millis(); i++; if (i == 5) { Serial.println("Stopping WDT reset. CPU should reboot in 3s"); } } } |
免責事項
本ソフトウエアは、あなたに対して何も保証しません。本ソフトウエアの関係者(他の利用者も含む)は、あなたに対して一切責任を負いません。
あなたが、本ソフトウエアを利用(コンパイル後の再利用など全てを含む)する場合は、自己責任で行う必要があります。本ソフトウエアの著作権はToolsBoxに帰属します。
本ソフトウエアをご利用の結果生じた損害について、ToolsBoxは一切責任を負いません。
ToolsBoxはコンテンツとして提供する全ての文章、画像等について、内容の合法性・正確性・安全性等、において最善の注意をし、作成していますが、保証するものではありません。
ToolsBoxはリンクをしている外部サイトについては、何ら保証しません。
ToolsBoxは事前の予告無く、本ソフトウエアの開発・提供を中止する可能性があります。
商標・登録商標
Microsoft、Windows、WindowsNTは米国Microsoft Corporationの米国およびその他の国における登録商標です。
Windows Vista、Windows XPは、米国Microsoft Corporation.の商品名称です。
LabVIEW、National Instruments、NI、ni.comはNational Instrumentsの登録商標です。
I2Cは、NXP Semiconductors社の登録商標です。
その他の企業名ならびに製品名は、それぞれの会社の商標もしくは登録商標です。
すべての商標および登録商標は、それぞれの所有者に帰属します。