最後にLT-R6を公開してから数年が過ぎた。その間にいくつかのバグレポートをいただき、修正も済んでいるがリリースする気になれないまま月日が経った。時間が経つと、それに見合った機能追加をしないと格好がつかない、と考えたまま今日に至っている。アイデアはあるが気力が続かない。
そんなこともあり、とりあえずここでLT-R6についてこれまで書かなかった中身を少し公開しよう。CI-Vは1本の線を共用して双方向の通信を行うため、CI-V上を流れる個々のデータからはそれが何かは判別できない。通信の内容を解析するには先ずCI-Vの調歩同期信号を受信・UARTで再生し(ここまではクローニングケーブルの仕事)、その後バイト単位で受信したデータからフレーム(以下、CI-Vの基本フォーマットのプリアンブル (0xFE)からEOM (0xFD)までをこう表現する)を再構成し、その中身を解析することで誰が何の目的で送信したフレームかを判別する。このときIC-R6とLT-R6の双方がランダムにデータを送信することで起きる信号の衝突や、衝突を検出した場合に送出される連続したJammer(0xFC)、及びその後のフレームの再送に対応した処理を行う必要がある。実際にCI-VをモニターしているとJammerはよく見られる。
フレームの再構成にはステートマシンを使う。LT-R6には3つのステートマシンを内蔵している。通信用、メモリーデータ受信用、及びCI-Vプロトコル解析用だ。通信用は通常のLT-R6の動作に使う。この場合正常にフレームを受信した時だけ結果を上位ソフトに上げればよいが、ただし自分が送信したデータをモニターし、もし潰れていた時は衝突が起きているのでJammerを送出してアボート(中断)処理を行い双方の状態を整合させるようにしている。メモリーデータ受信用も同様だが制御に使うコードが違う。通信用、メモリーデータ受信用は送信部との連携がある分だけややこしい。
一方プロトコル解析用はCI-Vの全てのデータを抜けなくキャプチャーするのみで単純である。解析用ステートマシンの状態遷移表を抜き出すと次のようになっている(作者独自の書式)。
* STATE MACHINE
* State OUTFR SYNC INFR ABT
* /Input(event)
* SYN(FE) +/SYNC +/SYNC x]+/SYNC x]+/SYNC
* EOM(FD) +/OUTFR x]+/OUTFR +]]/OUTFR x]+/OUTFR
* JAM(FC) x]+/ABT x]+/ABT x]+/ABT +/ABT
* ELSE +/OUTFR +/INFR +/INFR x]+/OUTFR
* TM-OUT x]/OUTFR x]/OUTFR x]/OUTFR x]/OUTFR
*
* SYMBOLS:
* -: abandon data
* +: accept data
* ]]: complete with success
* x]: complete with error
ステートマシンは状態を持ち、通信に伴って発生するイベントに対しアクション/次の状態を記述する。 OUTFR,SYNC,INFR,ABTが状態であり、SYN,EOM,JAM,ELSE,TM-OUTがイベントである。例えばフレーム受信中(INFR)にフレーム開始(SYN)を受信すると、受信は異常終了し(x])データ(SYN)は取り込み(+)、次の状態をプリアンブル部(SYNC)とする。
TM-OUTはフレーム受信中の一定時間内にフレームが完結しない場合の処理である。
ステートマシンは通信ライブラリから渡されるCI-V受信データを処理する。通信ライブラリはCI-Vデータを受信するとそれを受信バッファに積み、次にデータが入ったというイベントを発生する。このイベントを受けてスレッド(イベントディスパッチングスレッド)が実行され、その中でステートマシンを実行することになる(少し専門的ですがご勘弁)。スレッドを実行中に通信ライブラリは次のデータを受信する可能性があり、1バイト受信する度にイベントが発生する訳ではない事を含めてロジックを組む必要がる。リアルタイム処理ではここら辺りがややこしくていまだに理解不十分な点があるかもしれないが結果オーライで実装している。
リアルタイム処理のデバッグは処理を止めて解析できないので厄介である。とくに以前ci-vの受信に使っていたrxtxライブラリーには受信したデータがライブラリーの中に詰まるような現象を起こす問題があり、それを発見し対処するのには長期間を要した。現在のjSSCライブラリーに変えてからはこれまでそのような問題はない。
続く
0 件のコメント:
コメントを投稿