EventQueueについてThe EventQueue API Tutorialの序文を読んでみた前回の記事に続いて、今回は、イベントループのコードを書きます。
題材について
この記事で題材として取り上げたのは、The EventQueue APIというTutorialです。
イベントループを作る(Creating an event loop)
お待たせしました。コードが出てきますよ。
You must create and start the event loop manually.
イベントループは手作業で作成して実行を始めなくてはなりません。
The simplest way to achieve that is to create a Thread and run the event queue's
dispatch
method in the thread:
実現のための一番簡単な方法は、Threadを作成し、そのスレッドでイベントキューの
dispatch
メソッドを実行することです。
手作業(manually)とは書いてありますが、実際にはもちろんプログラムで実行します。
スレッドを作って、dispatch
を呼び出して、細かいことはいいからコードを見てみましょう。
#include "mbed.h"
// Create a queue that can hold a maximum of 32 events
EventQueue queue(32 * EVENTS_EVENT_SIZE);
// Create a thread that'll run the event queue's dispatch function
Thread thread;
int main () {
// Start the event queue's dispatch thread
thread.start(callback(&queue, &EventQueue::dispatch_forever));
}
まず、EventQueue
オブジェクトのインスタンスqueue
を作っています。引数には、このインスタンスで使用するキューのバイト数を指定しています。キューの要素一つ当たりEVENTS_EVENT_SIZE
の大きさが必要なので、それを32倍して32要素分の領域を確保しています。
次にThread
オブジェクトのthread
を作っています。引数を与えてスタックサイズなどを指定できるのですが、ここではデフォルトの値を使用するので、引数はありません。
main()
の中では、thread
インスタンスにcallback関数を与えて実行させています。ここでcallback()
と書かれているのは、callback関数を返すtemplateのようで、要は、こういうことを意味しているようです。
#include "mbed.h"
// Create a queue that can hold a maximum of 32 events
EventQueue queue(32 * EVENTS_EVENT_SIZE);
// Create a thread that'll run the event queue's dispatch function
Thread thread;
void dispatchTask(void) {
queue.dispatch_forever();
}
int main () {
// Start the event queue's dispatch thread
thread.start(dispatchTask);
}
ここで呼び出しているdispatch_forever
メソッドは、キューからイベントを取り出して実行するという手続きを繰り返す無限ループになっています。このループそのものを制御したいときには、別のdispatch
メソッドも使用できます。
void dispatchTask(void) {
DigitalOut led1(LED1);
for (;;) {
queue.dispatch(500);
led1 = !led1;
}
}
dispatch
メソッドの引数には、timeoutの時間をミリ秒単位で与えます。このようにすると、イベントの到着が無かった場合には、dispatch
メソッドを抜けて別の処理、例えばLEDを点滅させるなどの処理を行うことができます。
void dispatchTask(void) {
queue.dispatch(-1);
}
また、負の値を与えた場合には、永遠にイベントの到着を待ちます。これは、dispatch_forever
メソッドと同じ振る舞いになります。
void dispatchTask(void) {
for (;;) {
queue1.dispatch(0);
queue2.dispatch(0);
}
}
引数にゼロを与えると、イベントキューにイベントが到着していない場合、すぐにdispatch
メソッドを抜けてきます。そのため、このように複数のイベント処理を並べる書き方もできます。しかしながら、これではイベントを検出するためのループにCPUを喰われてしまいます。メモリに余裕があれば、それぞれのイベントキューに独立したThreadを与えた方が良いでしょう。
Note that though this document assumes the presence of a single event loop in the system, there's nothing preventing the programmer from running more than one event loop, simply by following the create/start pattern above for each of them.
この文書では、システムに単一のイベントループが存在すると仮定していますが、複数のイベントループを実行するのを妨げる理由は全くありません。それぞれのイベントループに対して「作成して・実行する」という手順を踏むだけです。
次は、作ったイベントループを使います。
関連サイト
Mbed OSのページ
EventQueueのTutorial
Mbed対応Cypress製品のページ
関連記事
EventQueueを使ってみたよ (1)
EventQueueを使ってみたよ (2)
EventQueueを使ってみたよ (3)
EventQueueを使ってみたよ (4)
EventQueueを使ってみたよ (5)
EventQueueを使ってみたよ (6)
EventQueueを使ってみたよ (7)
EventQueueを使ってみたよ (8)
EventQueueを使ってみたよ (9)