ソースコードをみたいと思います.
BlueLabをインストールすると、tutorialフォルダができています.
その中のLEDチカチカのソースコードをみてみます.
C:\BlueLab41\apps\tutorials\blinking_lights\part1
わたしはイベントドリブンプログラムって初体験なので面食らってしまいます.
メッセージと呼ばれる謎の変数が飛び交っていて、プログラムの構造がいまいちわからんとです.
#include <message.h>
これは、イベントドリブンプログラムを書くための関数などが定義されています.
#include <pio.h> /* Peripheral Input/Output */
chipのPIOを使うための関数などが定義されています.
#define LED1 0x01 /* bit 1 */
#define DELAY1 200 /* ms */
#define LED2 0x02 /* bit 2 */
#define DELAY2 400 /* ms */
PIO0をLED1に、PIO1をLED2に割り当てています.
static void led_controller1( Task t, MessageId id, Message payload ) {
PioSet( LED1, (PioGet() ^ LED1) );
MessageSendLater( t, 0, 0, DELAY1 );
}
まず、PioSet()がLEDをチカチカさせているのは、感覚的に理解しやすいでしょう.
ですが2つわからないことがあります.
1)引数に使われないidとpayloadがある
2)MessageSendLater()
ここにすでに、イベントドリブンプログラムの片鱗が見えています.
まず1)ですが、イベントドリブンプログラムにおいては、あるイベントが発生したら、led_controller1()を起動せよとひもづけるというプログラミングスタイルをとります.
そのひもづけのために、TaskData構造体にled_controller1()を登録するんです.
なので、TaskData構造体と同じ構造のled_controller1()の引数にしておく必要があるんです.
ちなみに、taskData構造体は、message_.hというファイルで定義されていまして、こうなっています.
typedef struct TaskData { void (*handler)(Task, MessageId, Message); } TaskData;
実際に、
void (*handler)(Task, MessageId, Message);
の部分と、led_controller1()の構造とは完全に同じになっています.
led_controller1( Task t, MessageId id, Message payload )
つぎに2)ですが、引数tにはled_controller1()がコードの後の方で当てはめられます.
DELAY1は200mSec遅延させよという意味です.
意味深長なのは、ひとたびled_controller1()をコールすると、再帰的に200mSecごとにled_controller1()がコールされつづけるということです.
その結果、LEDが永久にチカチカしつづけることになります.
static void led_controller2( Task t, MessageId id, Message payload )
{
PioSet( LED2, (PioGet() ^ LED2) );
MessageSendLater( t, 0, 0, DELAY2 );
}
この関数はLED2をチカチカさせています.中身はled_controller1()と同じです.
static TaskData led_controller1_task = { led_controller1 };
static TaskData led_controller2_task = { led_controller2 };
ここは重要です.
自作した関数である(イベントハンドラといいます)を、TaskData構造体にひもづけします.
さらりと書かれていますけど、イベントドリブンプログラムにおいて重要な意味のある操作です.
int main(void)
{
PioSetDir(0xFF, 0xFF); /* Set all PIO to be output */
PIOを全部出力に設定しています.
本来ここではPIO0とPIO1だけを出力に設定すれば事足りますが.
PioSet(0xFF, 0); /* Set all PIO off (0) */
PIOに1を出力します.LEDが消灯になります.
MessageSend( &led_controller1_task, 0 , 0 );
MessageSend( &led_controller2_task, 0 , 0 );
MessageSend()というのは、いますぐled_controller_taskに起動メッセージを送る関数です.
引数の0は、起動するにあたって、なにをやれと指定するための修飾子なんですが、ここではその機能を使ってません.
MessageLoop();
イベントドリブンループをグルグルと回っていてくれと言ってるんだと思います.
return 0;
どこへリターンするのかは知りません
}
release 2012.3.4