WatchDogもMbedOSなら簡単!
- マイコンの状態異常を監視するwatchdogの機能もmbedOSでは簡単に実装できました。
WatchDogとは
そもそもWatchDogとはマイコンの動作異常を検知するもので、WatchDogタイマーが定期的にリセットされないとマイコンの異常と判断して、マイコンを強制的にリセットします。
マイコンにWatchDog用のタイマーが必要ですが、STM32L496ZGT6にはWatchDog用のタイマーがついています。


WatchDogのサンプルプログラム
9秒以内にボードのuserスイッチ(左下の青色スイッチ)を押さないとWatchDogタイマーが0となりマイコンがリセットされるサンプルプログラムがmbedのAPI reference and tutorialsに載っています。そのチュートリアルを基板に載っている3個のLEDを光らせるようにちょっと変更すると以下のようになります。何回も秒数の表示を呼び出しているのがダサいですが、ご容赦下さい。

コードの左側に注釈を書いています。あくまで私の理解なので、間違っているところがあればご指摘頂けると幸いです。
#include "mbed.h" //mbed 使います宣言
DigitalOut led1(LED1); //LED1端子をDigitalOutで定義し、led1と名付ける
DigitalOut led2(LED2); //LED2端子をDigitalOutで定義し、led2と名付ける
DigitalOut led3(LED3); //LED3端子をDigitalOutで定義し、led3と名付ける
const uint32_t TIMEOUT_MS = 5000; //WatchDogのタイムアウト時間
InterruptIn button(BUTTON1); //BUTTON1端子をInterruptInで定義し、buttonと名付ける
volatile int countdown = 9; // 表示用の数値の定義
void trigger() //triggerという関数の定義
{
Watchdog::get_instance().kick(); //WatchDogタイマーのリセット
countdown = 9; //表示用の数値のリセット
}
int main()
{
printf("This is the bare metal blinky example running on Mbed OS %d.%d.%d.\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
printf("\r\nTarget started.\r\n");
Watchdog &watchdog = Watchdog::get_instance(); //Watchdogのget_instance()をwatchdogという名前に割り当て
watchdog.start(TIMEOUT_MS); //WatchDogタイマーのスタート。実際はWatchdog::get_instance().start(TIMEOUT_MS)
button.rise(&trigger); //BUTTON1が押されたらtrigger関数を稼働し、watchdogリセット
uint32_t watchdog_timeout = watchdog.get_timeout(); //watchdog_timeout時の時間の取得(ms)
printf("Watchdog initialized to %lu ms.\r\n", watchdog_timeout);
printf("Press BUTTON1 at least once every %lu ms to kick the "
"watchdog and prevent system reset.\r\n", watchdog_timeout);
while (true)
{
printf("\r%3i", countdown--);
fflush(stdout); //即座にデータを吐き出す処理。本当は全部のprintfの前に入れるべきだったか
thread_sleep_for(TIMEOUT_MS / 10);
led1 = !led1;
printf("\r%3i", countdown--);
thread_sleep_for(TIMEOUT_MS / 10);
led1 = !led1;
led2 = !led2;
printf("\r%3i", countdown--);
thread_sleep_for(TIMEOUT_MS / 10);
led2 = !led2;
led3 = !led3;
printf("\r%3i", countdown--);
thread_sleep_for(TIMEOUT_MS / 10);
led3 = !led3;
}
}
上記のコードをnucleoに焼きこむと、9秒以内にボタンを押さないとLEDの点滅がリセットされるはずです。
今回はここまでです。ご覧いただきありがとうございました。