今回は、以下のソースコード(リスト1)をベースに話を進めます。まずはこのプログラムを実行できるようにし、その後で重要なポイントの解説を行います。さらに、いくつかの改良を施すことにします。
なお、プログラムを実行するまでの一連の作業は、基本的に前回の「計数器プログラムのコンパイル&実行」とほぼ同じです。今回は要点のみにとどめますので、詳しくは前回を参照ください。
/* * スロットマシン(簡易版) (T-Kernel ベース) */ #include <tk/tkernel.h> volatile ID tid_left, tid_right; volatile int time_left, time_right; /* 7セグメントLEDの各パターン */ const int p[] = {0xff - 0x01, 0xff - 0x80, 0xff - 0x40, 0xff - 0x10, 0xff - 0x08, 0xff - 0x02}; /* 左ドラムの処理タスク */ void task_left( INT stacd, VP exinf ) { ER er; int count_left; time_left = 30; count_left = 0; for (;;) { /* スリープ */ er = tk_slp_tsk( time_left ); /* タイムアウトの場合 */ if (er == E_TMOUT) { /* 左ドラムを次へ進める */ count_left++; if (count_left >= 6) count_left = 0; /* 左7セグメントLEDに表示する */ out_h( 0x16100002, p[count_left] ); /* 割り込みハンドラから起床された場合 */ } else if (er == E_OK) { /* 左ドラムを止める */ if (time_left == 30) time_left = TMO_FEVR; /* 左ドラムの回転を再スタートさせる */ else if (time_left == TMO_FEVR) time_left = 30; } } } /* 右ドラムの処理タスク */ void task_right( INT stacd, VP exinf ) { ER er; int count_right; time_right = 30; count_right = 0; for (;;) { /* スリープ */ er = tk_slp_tsk( time_right ); /* タイムアウトの場合 */ if (er == E_TMOUT) { /* 右ドラムを次へ進める */ count_right++; if (count_right >= 6) count_right = 0; /* 右7セグメントLEDに表示する */ out_h( 0x16100000, p[count_right] ); /* 割り込みハンドラから起床された場合 */ } else if (er == E_OK) { /* 右ドラムを止める */ if (time_right == 30) time_right = TMO_FEVR; /* 右ドラムの回転を再スタートさせる */ else if (time_right == TMO_FEVR) time_right = 30; } } } /* 左ボタンに対する割り込みハンドラ */ void int_left( UINT dintno ) { /* 割り込み要求クリア */ ClearInt( dintno ); /* 左ドラムの処理タスクを起床 */ if (time_left == 30) tk_wup_tsk( tid_left ); } /* 右ボタンに対する割り込みハンドラ */ void int_right( UINT dintno ) { /* 割り込み要求クリア */ ClearInt( dintno ); /* 右ドラムの処理タスクを起床 */ if (time_right == 30) tk_wup_tsk( tid_right ); } /* トグルスイッチ(SW7)に対する割り込みハンドラ */ void int_toggle( UINT dintno ) { /* 割り込み要求クリア */ ClearInt( dintno ); /* 左ドラムの処理タスクを起床 */ if (time_left == TMO_FEVR) tk_wup_tsk( tid_left ); /* 右ドラムの処理タスクを起床 */ if (time_right == TMO_FEVR) tk_wup_tsk( tid_right ); } /* メイン関数 */ ER main( INT ac, UB **av ) { T_CTSK ct_left = { NULL, TA_HLNG | TA_RNG0, task_left, 130, 4096 }; T_CTSK ct_right = { NULL, TA_HLNG | TA_RNG0, task_right, 130, 4096 }; T_DINT di_left = { TA_HLNG, int_left }; T_DINT di_right = { TA_HLNG, int_right }; T_DINT di_toggle = { TA_HLNG, int_toggle }; if (ac >= 0) { /* ロード時 */ /* 左ドラムの処理タスクを生成, 起動 */ tid_left = tk_cre_tsk( &ct_left ); tk_sta_tsk( tid_left, 0 ); /* 右ドラムの処理タスクを生成, 起動 */ tid_right = tk_cre_tsk( &ct_right ); tk_sta_tsk( tid_right, 0 ); /* 左ボタンに対する割り込みハンドラを定義 */ tk_def_int( 164, &di_left ); SetIntMode( 164, IM_EDGE | IM_LOW ); ClearInt( 164 ); EnableInt( 164, 0 ); /* 右ボタンに対する割り込みハンドラを定義 */ tk_def_int( 165, &di_right ); SetIntMode( 165, IM_EDGE | IM_LOW ); ClearInt( 165 ); EnableInt( 165, 0 ); /* トグルスイッチ(SW7)に対する割り込みハンドラを定義 */ tk_def_int( 182, &di_toggle ); SetIntMode( 182, IM_EDGE | IM_LOW ); ClearInt( 182 ); EnableInt( 182, 0 ); return 0; } else { /* アンロードは未サポートとする */ return E_NOSPT; } }
「簡易版」としているのは、ソースを理解しやすくするために次の2つの処理を省略しているからです。
T-Kernelベースのプログラムですので、前回と同じく/usr/local/te/kappl下にslotディレクトリ、その下にsrcおよびtbmx1を新規作成します。
$ cd /usr/local/te/kappl $ mkdir slot slot/src slot/tbmx1
ディレクトリを作成したら、リスト1の内容のソースファイルを作成してC:\cygwin\usr\local\te\kappl\slot\src\slot.cに保存してください。
リスト2の内容のMakefileを作成し、C:\cygwin\usr\local\te\kappl\slot\src\Makefileに保存してください。
include ../../etc/makerules VPATH = ../src slot: slot.o
リスト2 Makefile C:\cygwin\usr\local\te\kappl\slot\src\Makefile |
次に、メイクを行います。Cygwin上で、以下のコマンドを実行します。
$ cd /usr/local/te/kappl/slot/tbmx1 $ ln -s ../src/Makefile $ gmake
自動的にコンパイル/リンクが行われ、実行ファイルslotが生成されます。
作成した実行ファイルslotをTeaboardに転送します。詳しい手順は前回を参照してください。今回転送するファイルはslotなので、TeaboardのCLIで以下のコマンドを実行します。
[/SYS]% recv -c slot
ファイル転送が完了したら、早速実行してみましょう。
[/SYS]% lodspg slot
左右のプッシュボタンを押すと、各LEDの回転が止まります。また、右端のトグルスイッチを上に戻してから下に倒すと、左右のLEDが再び回転を始めます。ただし、現時点ではチャタリング防止処理を行っていないため、トグルスイッチをゆっくり上に戻すと、その瞬間も信号を拾ってしまう場合があります。
Copyright © ITmedia, Inc. All Rights Reserved.