LEDを点滅(チカチカ)させることをLチカと言います。電子工作、特にマイコン回路においては始めの一歩、つまり、プログラミング言語で言う"Hello World!"と言われています。このジャンクレポートではLチカからマイコンシステムにおけるデバッグ手法に至るまでを簡単に解説します。
Hello World!相当とは言っても、PC上のそれとは違い、Lチカに到達するまでには次に示すようにクリアしなければならないハードルがたくさんあります。
まずは、ハードウェアがないことには何も始まらないので、部品を買ってきてマイコン基板を組み立てます。電子工作の中核となる作業ですが、入門者にとってはここでリタイヤすることもある難関(笑)です。最近は、基本的な機能を組み込んだ出来合いのマイコン基板が安く売られているので、ビギナーのみならずベテランもそれを利用することが多いようです。どちらにしても手間とお金がかかるので、低くはないハードルといえます。
次にクロス開発環境をPC上にインストールし、プログラムを開発できる環境を準備します。最近はマイコンメーカが機能を制限した試用版(といっても趣味で使うには十分)を提供することが多く、無い場合も大抵はGCCがサポートしているので、これらを利用すれば無償で開発環境を構築できます。
そして、実際にLチカプログラムを作成します。これが最大の難関で、マイコンのマニュアルを読み込んでその機能を理解しプログラムを書く必要があります。マイコンのマニュアルは多くが英文ですが、英語がどうしても苦手ならマイコン攻略本を併せて読むのも良いでしょう。まず、ピンの電圧を操作するため、GPIOの機能を設定し制御しなければなりません。そして正確な周期でLEDを点滅させるため、タイマ割り込みによるタイミング制御も必要になります。このように、Lチカだけでも少なくともGPIO、カウンタ、割り込み(これら3つはマイコンの最も基本的な周辺機能)の理解が必須です。開発環境にお仕着せのスタートアップルーチンが用意されていない場合は、プロセッサアーキテクチャやブートプロセスの知識も必要になります。
作成したプログラムバイナリを対象とするマイコンチップに書き込みます。8ビットマイコンでは書き込みに特殊な装置(ライタとかISPケーブルと呼ばれる)とその制御ツールが必要で、ハードウェア同様に自作か購入して入手しておく必要があり、ある程度のコストがかかります。32ビットマイコンの多くはライタのような特殊な装置は必要ありません。
プログラムを書き込めたらターゲットを実行モードで起動し、Lチカ動作を確認します。不幸にもうまくいかなかったら(というか一発で動かないのが普通)、意図した動作をするまでデバッグを繰り返します。
たかがLチカなどと小馬鹿にされることがあるようですが、それに至るまでにはマイコンシステムの開発に最低限必要なプロセスが全て含まれているのです。攻略本に頼らず自力でLチカを達成できたら、もはやそのマイコンはマスタしたも同然と言えるでしょう。安心してジャンク箱に放り込んで新たなマイコンの攻略に進むことができます。
マイコンシステムでは、PCのコンソール入出力のような高級な入出力デバイスを持たないことが殆どなため、PCアプリとは異なったデバッグ方法が必要になります。マイコンシステムのデバッガとしては次に示すような物が使われます。
ICEというのは、ターゲットマイコンをソケットから外し、そこに代わりに接続してマイコンチップをエミュレーションする専用ハードウェアでデバッグするものです。これはフルICEとも呼ばれ、とても高価で数十万円から100万円以上もします。昔(90年代)はデバッガといえばこれだったのですが、マイコンの多品種・高集積化や短縮する製品サイクルに追いつけず、衰退していきました。
ROMエミュレータは、プログラムROMを差し替えてエミュレーションするものです。単にROMを代替するだけの物から、ステップ/ブレークなどICEに匹敵するデバッグ機能を持つものもありました。これもROMがマイコンに内蔵されるようになって消えていきました。
ICEやROMエミュレータに代わって現在の主流になっているのがOCD(オンチップデバッガ)です。最近のマイコンにはデバッグ回路が内蔵されているので、その機能を使ってデバッグを行うのです。JTAGとかSWDというのはテスト/デバッグ用インターフェース規格の一つで、多くのマイコンでサポートされています。OCDでは、ICEと同様なステップ/ブレークなど、PCアプリのデバッグと比べても遜色のないレベルでのデバッグが可能になっています。
printfデバッグというのは、デバッガが使えないときに使われる手法です。プログラムの要所に変数などの動作状態を外部に出力するコードを仕込んでおき、その出力を見て意図した動作をしているか確認します。出力先はUARTなどのシリアルポートやLCDなどのディスプレイデバイスです。
Lチカデバッグは、printfデバッグの簡易版で、LEDの点滅でプログラムの動作状態を知るものです。表示できる情報は非常に限られていますが、それでも無いよりははるかにマシです。テスタやオシロスコープで出力端子を見るのもLチカデバッグの一種といえるでしょう。
実際のところ、マイコンシステムがPCシステムと異なる点はデバッグ環境だけではありません。プログラムの性質からして異なっているのです。これは簡単に言うと、バッチ処理(PCアプリの多く)とリアルタイム処理(制御プログラム)の違いから来るもので、当然ながらデバッグ手法も異なってきます。例えば、リアルタイム処理が必要なコードをステップ実行したりしたら、システムは正常動作できずデバッグになりません。このような時は、printfデバッグやLチカを組み合わせるなど柔軟な対応が必要になってきます。
LEDの状態は点灯か消灯、つまり1個あたり1ビットの情報量しかありません。しかし、それでもデバッグの初期段階では意外に役立つものです。例えば、LEDを点灯させるコードを仕込んでおけば、LEDの点灯でプログラムの実行がそこに至ったことが分かります。光らなければその手前で止まっているかどこか別に進んでいることになります。printfデバッグするにもその出力デバイスを正しく初期化しなければならないので、そこに到達するまではLチカデバッグに頼ることになります。また、正常動作のループで点滅するようにしておけば暴走などの異常で点滅が止まるのでそれが分かります。
printfデバッグではデバッグ中のコードに仕込んだprintf関数などで確認したい情報を外部に出力します。しかし、組み込みシステムでは標準のprintf関数をそのまま使用することはありません。フル機能のprintfは数十KB以下の小規模なマイコンにとっては重すぎるし、そもそもマイコンには標準出力デバイスが存在しないからです。このため、printfに代わる簡単なデバッグ出力関数を組んでそれを使用することになります(例:組み込み向け汎用文字列出力モジュール)。
デバッグ情報の出力先は大抵の場合はUART(非同期シリアルポート)になります。非同期シリアルなら簡単にPCに接続でき、プログラムの書き込みに使用するポートと共用できる場合が多いので、デバッグ出力としてよく使われます。また、ごく小規模なマイコンではUARTさえ無い場合もあり、このようなときはソフトウェアUARTで出力するしかありません。ソフトウェアUARTならハードウェアUARTに比べていくらかの制限があるものの、空いている任意のGPIOポートを使えます。
ターゲットが7セグLED、CLCD、GLCDなどの表示器を持つ場合は、そこへデバッグ情報を出力することもよくあります。ただ、7セグLEDやCLCDではその表示能力から得られるデバッグ情報はUARTに比べて限定的です。
printfデバッグの発展型として、システムの1タスクとしてデバッグモジュールを組み込み、対話型インターフェースでより高度なデバッグを実現する方法もあり、大規模なプロジェクトでよく使われています。デバッグモジュールは邪魔でなければプロジェクト完成後も組み込まれたままにされ、後のメンテナンスに活用されることが多いようです。
Lチカとprintfを組み合わせれば、ターゲットと電気的に接続せずとも通信できてしまいます。どういう事かというと、UART出力でLEDを駆動し、そのパルス光を光センサで拾うのです。つまり、LEDインジケータを光トランスミッタとして使うわけですね。右の図にLチカを拾ってCOMポートからPCに入力するアダプタと、実際にLPC2388ジャンク基板で実験したLチカ送信コードを示します。この場合、115kbpsまで問題なく受信できました。
既存のLEDインジケータは普通はGPIOポートに接続されているので、Lチカ通信ではソフトウェアUARTを使用することになります。PCからターゲットへの通信はできませんが、ターゲットの内部動作をモニタする程度なら片方向で十分でしょう。そのほか、電気的に絶縁されていることで、非絶縁電源の回路の動作を安全にモニタできるというメリットがあります。LEDが装置の表示器になっているときは、ケーブル等を接続するためにケースを開ける必要もありません。案外、そこいら辺にある機器のLEDの点滅はLチカ通信だったなんてことが...無いと思います。
