例えば、こんなプログラムがあったとする。
int main() |
スイッチ1(SW1)を押したらLEDが1秒間隔で点滅し、スイッチ2(SW2)を押したら、点滅を止めるという単純なプログラムである。
一見すると、何の問題も無いように見える。(少なくともロジックは間違っていない) ...が、しかしこのプログラムは操作性が極めて悪い。
プログラムの動作を、時間軸に沿ってみてみると、下の様になる。
一見して分かるように、スイッチの状態を読み取る動作は、処理時間のほんの僅かしかない。従って、
の操作をしない限り、プログラムは反応しないことになる。
問題は、LEDの点灯時間を決めているwait()で、この処理が動いている間は、他の処理を受け付けないという所にある。
従って、応答性の良いシステムを作ろうとしたら、長時間のwait()や、処理を作ってはいけない。
この例では、以下の様にプログラミングすると、問題を解決できる。(ただし、点灯時間はアバウト)
int main() { int time; // 変数の値の範囲に注意 while(1) { time++; if (SW1==TRUE) { // スイッチ1ON? LED_BLINK=TRUE; // LED点滅開始 } if (SW2==TRUE) { // スイッチ2ON? LED_BLINK=FALSE; } if (LED_BLINK==TRUE) { if (time > 99999) { // 99999は一秒に相当する数。ループを回る回数で時間を計る。 LED ~= LED; // LED点灯/消灯切り替え time = 0; } } } return 0; } |
このプログラムでは、下図の様に、スイッチの読み取り動作が短い時間間隔で行われるので、スイッチを押す動作(=イベント)の取りこぼしが無い。
プログラムを設計する際は、
に対して、イベントを読み取る周期が十分短い様に設計しなければならない。
ループを使ってスイッチなどの状態を繰り返し確認する手法は「ポーリング」と呼ばれている。ポーリングに対する手法として、割り込みがある。
ポーリングの手法としての長所・短所は以下の通り。
ポーリングの欠点を解消する手段として、割り込みを使って実装が行われることも多い。ただし、割り込みでポーリングをすべて代替出来る訳ではないし、割り込みの方がポーリングより優れているという訳でもない。ケースバイケースで使い分けを行うことが肝要である。