はじめに
この記事はmbed Advent Calendar 2016の4日目の記事です。
mbed OS 5でイベント駆動なプログラムを書くためのライブラリ mbed-events-library の使い方を紹介します。 なお、ドキュメントに書いてあるコードは古いのか正常に動かないところがあったので、GithubのREADMEを参照して検証しました。
mbed-events-libraryが追加されたことで、従来の RtosTimer
はdeprecated*1となったようです。
動かしてみる
青mbed(LPC1768)を使って実験しました。
p18
にPullUpでタクトスイッチをつけています。
1. 即実行されるイベント
EventQueue
のインスタンスを作成し、call
メソッドを呼び出すことで即実行されるイベントを追加することができます。
dispatch
メソッドを実行するとイベントループが廻り続けるため、最後に while(true)
といった記述は必要ありません。
サンプルコードと実際の動作
#include "mbed.h" DigitalOut led1(LED1); InterruptIn sw1(p18); // イベントキューを作成する EventQueue queue; // LEDのON/OFFを切り替える関数 void toggle_led() { led1 = !led1; } // タクトスイッチが押されたときに実行される関数 void pushed() { // 即実行されるイベント queue.call(&toggle_led); } int main() { // スイッチピンをPullUpにする sw1.mode(PullUp); // タクトスイッチが押されたときの割り込み処理 sw1.fall(&pushed); // イベントループが廻り続ける queue.dispatch(); }
動作させたのが以下の動画です。スイッチを押すとLEDがON/OFFします。
2. 指定時間後に実行されるイベント
EventQueue
のインスタンスに対して call_in
メソッドを呼び出すことで 指定ミリ秒後に実行されるイベントを作成することができます。
サンプルコードと実際の動作
先ほどのコードに queue.call_in(2000, &toggle_led);
を追加し、ボタンを押してから2000ミリ秒(2秒)後に消える処理を追加しました。
#include "mbed.h" DigitalOut led1(LED1); InterruptIn sw1(p18); // イベントキューを作成する EventQueue queue; // LEDのON/OFFを切り替える関数 void toggle_led() { led1 = !led1; } // タクトスイッチが押されたときに実行される関数 void pushed() { // 即実行されるイベント queue.call(&toggle_led); // 2000ms後に実行されるイベント queue.call_in(2000, &toggle_led); } int main() { // スイッチピンをPullUpにする sw1.mode(PullUp); // タクトスイッチが押されたときの割り込み処理 sw1.fall(&pushed); // イベントループが廻り続ける queue.dispatch(); }
動作させたのが以下のようになります。スイッチを押すとLEDがONし、2秒後にOFFになります。
なお、ON/OFFするイベントをひたすらキューに積んでいる形になるため、連打するとON/OFFの順番は崩れます・・・
3. 指定時間ごとに定期実行されるイベント
EventQueue
のインスタンスに対して call_every
メソッドを呼び出すことで 指定ミリ秒ごとに実行されるイベントを作成することができます。
サンプルコードと実際の動作
先ほどのコードからスイッチの処理を取り除き、call_every
で1秒ごとに実行されるイベントを追加したものになります。
#include "mbed.h" DigitalOut led1(LED1); // イベントキューを作成する EventQueue queue; // LEDのON/OFFを切り替える関数 void toggle_led() { led1 = !led1; } int main() { // 1000msごとに定期実行するイベント queue.call_every(1000, &toggle_led); // イベントループが廻り続ける queue.dispatch(); }
動作させると以下のように、1秒ごとにLEDのON/OFFを繰り返します。
おわりに
今回のコードは以下のリポジトリに公開しています。 mbed import
してお使いください。
以前、mbed OSのTechnical Preview版のときはMINARと呼ばれるイベントスケジューラーがあり、それを検証したことがありました。
そのときは結構な行数のコードが必要だったのですが、mbed-events-library は非常に簡潔なで直感的なコードで同様のことが実現できるようになったようです。
どんどん進化していますね。