nucleo-L496ZGとMbed OS6でWatchDog

WatchDogもMbedOSなら簡単!

  • マイコンの状態異常を監視するwatchdogの機能もmbedOSでは簡単に実装できました。

WatchDogとは

 そもそもWatchDogとはマイコンの動作異常を検知するもので、WatchDogタイマーが定期的にリセットされないとマイコンの異常と判断して、マイコンを強制的にリセットします。
 マイコンにWatchDog用のタイマーが必要ですが、STM32L496ZGT6にはWatchDog用のタイマーがついています。

WatchDog Timer on board!

WatchDogのサンプルプログラム

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

LED1,2,3が光ります。

 コードの左側に注釈を書いています。あくまで私の理解なので、間違っているところがあればご指摘頂けると幸いです。

#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の点滅がリセットされるはずです。

今回はここまでです。ご覧いただきありがとうございました。