マイコンのメモリ上にプログラムデータを書き込むのはICEからやればよいと思ったが、
どうにも思ったようにいかない部分があって、別の転送方法を考えることに。
それで昔、TeraTermからデータ転送する方法を見たことあるなと思ったら、
そのマイコンのサンプルコードにYMODEMのコードがあった。
なるほど。YMODEMか。と使ってみることに。
YMODEMというのはシリアル通信などでバイナリデータを転送する方式の1つである。
元々XMODEMというのがあって、それの改良版がYMODEMだと。
で、さらなる改良版にはZMODEMがあるが、かなり複雑な仕組みである。
デバッグ用のコンソールではYMODEMぐらいが使いやすいのかも知れない。
で、サンプルコードから移植すると「C」という文字が表示されて、なんだこれと。
というわけでYMODEMというのはどういう方式かということである。
受信側は準備が整えば「C」という文字を送る。
これを見た送信側はブロック0としてファイル名やデータサイズを送信する。
1ブロックで128バイトまたは1024バイトのデータを転送できて、
これにヘッダとCRC16が付いているという。
で、データの受信が完了すると受信側はACK(06H)を返す。
続いてブロック1以降でデータ本体を送信して、受信側はACKを返すを繰り返すが、
ブロック1だけは受信側からの「C」を待つよう。(XMODEMとの互換性のため?)
全ブロックの送信を完了したら、送信側はEOT(04H)を送る。
これに対してACKではなく、NAK(15H:通常時に送ると再送要求になる)を返すと、
2個以上のファイルを連続受信できるが、サンプルコードではファイル1個で終わるということで、ACKを返していた。
YMODEMの本来の仕様とは異なるが、XMODEMとの互換性で通じるようだ。
ところでXMODEMに対するYMODEMの改良点なのだが、
1つ目はブロック0の存在で、ファイル名も伝達できるという特徴がある。
プログラムデータのファイル名は今回は特に必要ない要素だが。
ただ、ファイルサイズをブロック0で転送できることは活用している。
2つ目はブロックのチェックサムがCRC16であることと、1024バイトのブロックが使用できること。
受信側から送る「C」はCRCをチェックに使うという意味を表してるらしい。
3つ目は複数ファイルの連続転送ができること。これも今回は使ってない。
ただ、これがなかなかうまくいかなかったんだな。
ぶっちゃけサンプルプログラムの出来がよくなかった。
タイムアウトになってもTeraTermはYMODEMに占有されっぱなしで、
なんとかならんのかと調べるとCAN(18H)を2個送ると、中断の意味になるので、とりあえずこれを送りつけたり、
TeraTermでYMODEMのログを出力できる機能があるのでこれを使ったり。
そうやって掘っていくと、ブロック0の後に「C」を送信する部分がうまく作れていなかったり、
そんな修正をしてなんとか使えるようになった。
で、YMODEMの動作説明を見てもわかるが、受信側が送信を要求するという構造なので、
シリアルポートからマイコン側に受信開始を要求すると「C」が届く。
この受信要求を数秒周期で何度か繰り返すように作っておく。
で、この間にTeraTermをYMODEMの送信モードにして「C」が受信できたところからデータ転送が始まるというわけである。
データサイズは大きくないので、115200bpsですぐに転送は終わる。
という風な使い方をするわけですね。
バイナリデータを転送する方法はいろいろ考えられるわけだけど、
TeraTermでそのまま使えるという点でデバッグには便利な仕組みである。
実際のシステムでは使わないけど、実験用には好都合だね。
YMODEMさえ動けば、後は思ったように動いたのでよかったんだけどね。
もうちょっとまともなサンプルコードだったらなぁ……
デバッグ用にサクッと使えるとうれしかったんだけどね。