Mbed OS6のEventQueueを使ってみる

定時でマイコンを動作させたい時のevent関数について

  • EventQueue を使えば定時処理が簡単に書ける
  • EventQueue は優先度に対応していないので、定時処理の優先度をつけたい場合は優先度ごとにそれぞれのEventQueueのインスタンスを立ち上げる必要がある。

 EventQueueのtutrialはこちら

https://os.mbed.com/docs/mbed-os/v6.15/apis/scheduling-tutorials.html

event関数でwatchdogとLチカ

 先日公開したがあまりに不格好なWatchDogのサンプルをevent関数ですっきりさせてみる。今回はLED1, LED2のみの点灯とした。WatchDogのリセットは相変わらずuserスイッチです。

#include "mbed.h"
#include <cstdint>
#include <stdio.h>

DigitalOut led1(LED1);
DigitalOut led2(LED2);

const uint32_t TIMEOUT_MS = 5000;
InterruptIn button(BUTTON1);
volatile int countdown = 9;

void trigger()
{
    Watchdog::get_instance().kick();
    countdown = 9;
}

void led1_toggle()
{
    led1 = !led1;
}

void led2_toggle()
{
    led2 = !led2;
}

void PrintCountdown()
{
    printf("\r%3i", countdown--);
    fflush(stdout);
}

int main()
{
    printf("\r\nTarget started.\r\n");

    Watchdog &watchdog = Watchdog::get_instance();
    watchdog.start(TIMEOUT_MS);
    button.rise(&trigger);

    unsigned long watchdog_timeout = watchdog.get_timeout();
    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);

    // creates a queue with the default size
    EventQueue queue;

    // events are simple callbacks
    queue.call_every(500ms, &PrintCountdown);
    queue.call_every( 10ms, &led1_toggle);
    queue.call_every(500ms, &led2_toggle);

    // events are executed by the dispatch method
    queue.dispatch_forever();
}

変わっているところは48行目以下のところです。
48行目:EventQueueの立ち上げをしています。
51行目:WatchDogのカウントダウンをデバッグコンソールに表示する処理です。
52行目:LED1を10ms間隔でON/OFFします。
53行目:LED2を500ms間隔でON/OFFします。
56行目:queueを実行するための宣言です。queue.dispatch()としているとcautionがでるようなので、queue.dispatch_forever()としています。

51-53行目の処理は関数として18-32行目で定義しています。
12行目から定義しているtrigger()をqueue.call_everyで呼び出せば、リセット処理を定期的に実行できます。

割り込みの優先度をつけられないのは困るので、今後は優先度をつけつつ実装していきたいと思います。
今回はここまでです。ご覧いただきありがとうございました。