List3をご覧ください。forループを何回か繰り返すことにより、発光ダイオードの点滅間隔を得ています。そのループの中でシリアルポートへの入力をチェックし、入力があればその文字を取り出し、送信します。
いちいち入力をチェックしなければならない理由は、pc.getc()はシリアルポートに対して入力があるまで処理がブロック(待たされる)されるからです。
1:DigitalOut led1(LED1); 2:Serial pc(USBTX,USBRX); 3:int main(){ 4: char c; 5: while(1){ 6: led1=!led1; 7: for(int i=0;i++;i<1000){ 8: if (pc.readable()==1) { 9: c=pc.getc(); 10: pc.putc(c); 11: } 12: } 13: } 14:}
このプログラムのイケてないところは、forループで点滅間隔を調整しなければならず、CPUの性能やクロックによって個別の調整が必要となる点です。また、シリアルポートに入力があった場合とそうでない場合で、点滅の間隔が微妙に変わってしまいます。
今回の例は発光ダイオードを点滅させている間に、1ポートのシリアルポートの受信のあるなしをチェックし、受信した文字があれば送信するというものでした。しかしもっと応答するデバイスが増えたらどうでしょう。
今のような手法では、応答するデバイスが増えればメインループのコードがだんだん長くなっていきます。それはメンテナンス面でも負担が増えてきます。また、対応しなければならないデバイスが増えればその分、応答するスピードもに影響が出てきます。
ちなみに、このプログラムの8行目のように、プログラムからデバイスの状態を確認する方法をポーリング方式と呼びます。
デバイス側からCPUに対して要求を伝える手段を「割り込み」と呼びますが、割り込みが発生するデバイスや事象はプログラムの初期段階で設定します。I/Oデバイスであれば特定のピンにかかる電圧がしきい値を超えた場合、通信デバイスであれば1文字受信した場合など、外部環境の変化をCPUに割り込みとして伝えます。
ここで紹介するタイマー割り込みは、時間の経過を割り込みとして伝えます。mbedのクラスライブラリーの中にはタイマーを利用するためのクラスがいくつかありますが、今回は「Ticker」を使います。Tickerはある一定間隔で割り込み処理関数を呼び出し、それを繰り返すクラスです。
1: #include "mbed.h" 2: Ticker timer; 3: DigitalOut led1(LED1); 4: Serial pc(USBTX,USBRX); 5: void attime(){ 6: led1 = !led1; 7: } 8: int main(){ 9: led1 = 1; 10: timer.attach(&attime,0.5); 11: while(1){pc.putc(pc.getc());} 12: }
list4にTickerを用いたプログラムを示します。先に示したlist1とlist2のプログラムを、タイマー割り込みを使って1つのCPUで動作させるためのプログラムです。メインループでシリアルポートのハンドリングを行います。発光ダイオードの点滅操作はTickerにより、ある一定間隔で呼び出される割り込み処理関数で行っています。
Copyright © ITmedia, Inc. All Rights Reserved.