YMODEMを使う

マイコンのメモリ上にプログラムデータを書き込むのは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さえ動けば、後は思ったように動いたのでよかったんだけどね。

もうちょっとまともなサンプルコードだったらなぁ……

デバッグ用にサクッと使えるとうれしかったんだけどね。