次にやることは、このUARTプログラムを、PCからUARTを経由してコマンドを受け入れ、色々なことをさせるモニターに仕立てることである。デバッグの強力なツールになる。ソースを本格的に読み始めた。ふーむ、このUARTのソースは、割り込みルーチンに、殆どのアプリケーション処理が入っている。この程度の規模のソースでは目くじらたてることでもないし、参考にさせて貰ってこういうことを言うのも少し気が引けるが、普通はこういう書き方はしない。速度の速くない、メモリの少ない組み込み系プログラムでは、割り込みルーチンはなるべく身軽にしておき、メインルーチンに処理を集めるのが鉄則である。いう習慣をつけておくとあとあとの開発が楽になる。割り込みルーチンに処理を入れてはいけないかと言うと、普通、割り込み中は別の割り込みを禁止しているので、余り長い間ひとつの割り込みルーチンに居ると、別の割り込みを待たせることになり、同時性が失われたり、動作がおかしくなる可能性がある(多重割り込みは処理がはるかに複雑になるので余程の時以外は使わない)。割り込みとは現在の処理を強引に中断して別の処理を始めることなので、そのときのレジスターを全てどこかに保存してから、帰るときに元へ戻す余分なコードを必要とする。割り込みルーチンにはなるべく処理(たくさんのレジスターを使う処理)を入れないほうが良い。フラッシュの少ないマイコンではプログラムが(無駄に)大きくなるだけでなく、C言語を使うと、このレジスターのsave/restoreだけで(無駄な)数十ステップを使い、このオーバーヘッドは無視できない性能の低下をきたす。それならどうするかと言うと、一番簡便な方法は、割り込みルーチンにはフラグを立てるだけの処理などにしてなるべく身軽に作る。メインルーチンのループで、このフラグをキーに割り込みでやりたかった処理を行う。することで様々なメリットが生まれる。フラグを立てるだけなので、セイブすべきレジスターを最小限にでき、オーバーヘッドを減らせる(Cコンパイラーの最適化も効く)。フラグをテストする順番を工夫(短いウェイトやsleepを入れるなど)すれば、メインルーチンで複数の割り込みの優先順位をつけることも出来る。別々の割り込みルーチンだとこういう芸当はできない。それにメインルーチンの中にアプリケーションがすべて入ってくるので、何をやっているのか一望できるメリットも大きい。ソースコードの一覧性というのは、みんなが思っているより重要な要素で、メンテナンスしやすいプログラムの大きな条件のひとつである。良いことばかりではない。フラグでメインに処理を持ち込む方法は、時間にシビアな処理(いわゆるリアルタイム処理)には使えない。音声のデコードや、周波数の測定などに、これを使うことは無意味である。メインの中での処理は結局は順序処理になるので厳密な同時処理は難しい。OSを使った多重割り込み機能が必要になってくる。うんちくを垂れながら、鼻歌まじりでソースコードを入れ替えた。ついでにUARTからのコマンドで、タイマーを使ったLEDの点滅の入り切りが出来るようにする。STM8Sのペリフェラルライブラリーの書式は、STM32にそっくりなので進行が早い。タイマーや、GPIOの制御も簡単に書けた。これが動かないのである。送信は問題ない(変えてないのだから当然だ)が、UARTの受信が出来ない。STVDは、単にプログラムを走らせることは出来なくて、必ずデバッガーを経由するのだが、このステップ実行では、受信割り込みルーチンを抜けてメインに来てもフラグが立っておらず、受信データがないことになっている。サンプルソースにある割り込みルーチンの書式が良くわからない。このあたりはコンパイラーの独自仕様なので、Raisonanceのコンパイラー仕様をネットで探すが見つからない。この割り込みは何を契機に起きているのか資料が見つからないのである。オリジナルのソースコードを見ると割り込みルーチンに来てから、さらにUARTのレジスターの受信フラグを調べている。それなら、この割り込みは何なのだ。他の割り込みというのはあるのか。ここは受信割り込みだけのルーチンのはずだが。お粗末な勘違いだった。UART動く(12/5/2012)少しづつステートメントをメイン側から割り込み側に戻して様子を見る。デバッガーにもう少し慣れれば、もっと楽に原因究明ができるのだろうが、こういうタイムディペンダント(UARTのキー入力)な処理のデバッグは容易ではない。UARTの受信関数を割り込みルーチンに入れれば、動くことは確認できた。受信だけさせておいて、フラグを立てて受信バッファーをメインで処理すれば、正常に動く。コマンドも受け付ける。何かやっていることが重複している感じで美しくない。フラグだけにすると、全く動かなくなる。フラグが換わらなくなる。色々なところにテスト出力をUARTにさせて原因を探る。一文字出力関数で'*'を割り込み関数の頭に入れてみる。おおー、画面一杯に*が埋め尽くされる。ふーむ、受信割り込み以外にも、何か割り込みが起きているのか。一文字出力を、受信割り込みを特定してからのプロセスにも入れてみる。ありゃりゃー、変わらない、同じように画面が*で一杯になった。わかった、わかったぞー、このSTM8Sの割り込みルーチンは、割り込みフラグは明示的にクリアしないと、割り込みルーチンに飛んできただけでは解除されないのだ。このままでは、割り込みから抜ける度に、また割り込みが入って延々とループを続ける。割り込みルーチンの中で、データ受信をすれば、このとき割り込みフラグがクリアされるので問題ない。