(H8移植編第3回)XMODEMでファイル転送してみる

2009/09/02

あなたは 人目のお客様です.

前回でシリアル送受信ができるようになったのだけど,次はシリアル経由での ファイル転送ができるようにしたい.で,ファイル転送用の独自プロトコルを 作るか適当な既存のプロトコルを実装するかだが,まあ独自プロトコルにして しまうと送信アプリを書く必要が出てきてしまい,さらにその送信用アプリを Linuxでコンパイルして使うにはとかWindowsから使うにはどうすればいいかとか いった話になってしまって,それはそれでとっつきづらいと思うので, 適当な既存のプロトコルを実装することにする.

で,プロトコルなのだけど,XMODEMというのが簡単そうなのでそれにしよう. まあXMODEMならLinuxとかWindowsとかでもいっぱい送信用アプリがあるだろうし. (WindowsならたぶんTeraTermでファイル転送できるだろうと思う)

ちなみにXMODEMにはファイルの終端が Ctrl-Z で終ってしまっている場合に それを検出できないという問題があるようだが,実行形式ファイルのお尻が わからないだけで,実行形式ファイルの展開という意味ではとくに問題は無い. (実行形式は内部に独自にヘッダ情報を持っていて,それを見てメモリ上に別途 展開するので,終端に余計なものが付いていても別に問題ない)

XMODEMについては,以下が参考になる.

他にも改良版のYMODEMとかZMODEMとかあるらしいが,まあ転送するファイルのサイズも それほど大きくはならないだろうから転送効率とかあんまし考えなくていいし, エラー時再送とかきちんとしなくても(信頼性が低くても)もう一度やりなおすだけ だし,とりあえず実装が一番楽そうなXMODEMを実装する.

で,上のホームページを見て実装したのがこんなかんじ.

xmodem.c というファイルを追加してあってその中でファイル受信しているのだけど, xmodem.c はなんとたったの89行.うーん,簡単なプロトコルなので楽でいいのう. ちなみにファイルの転送先なのだけど,とりあえず loadbuf[] というバッファを 適当なサイズで定義して,そこにそのままコピーするようにしてある. まあ対して難しいプログラムではないので,詳しくはソースを見てちょうだい. (現状,Cファイルとヘッダファイルだけで400行程度なので,十分に読み切れると思う)

あと細かいところをいろいろ修正してある.

で,ビルドしてフラッシュROMに焼いて実行してみる.フラッシュROMへの転送の しかたは第1回を参照.

ちなみにフラッシュROMへの転送なのだけど,以下の手順で電源のOFF/ON無しで できるようだ.

上のような感じで,ディップスイッチを切替えてリセットボタンを押すだけで, 電源のOFF/ON無しでフラッシュへの書き込みとプログラムの実行を繰り返すことが できる.

で,以下,実行結果.

teapot# cu -l /dev/cuad0
Connected
Hello World!
> 
cuでつないでからリセットボタンを押して起動すると,まず Hello World が 表示される.

ここでXMODEMでのファイル受信用の「load」コマンドを実行する.

> load

コマンド実行すると,XMODEMでの受信待ちに入る.

で,FreeBSD側からのXMODEMでのファイル転送なのだけど,PowerPCのときも使った 「lrzsz」を使う.インストールされていない場合はまずインストールする. (FreeBSDでは packages になっているので,パッケージインストールできます)

で,ファイル転送なのだけど,cuは「~C」を入力することで別コマンドを fork して その入出力を繋げることができるので,その機能を利用して lrzsz にXMODEMプロトコル をしゃべってもらってファイル転送する.まあ手っ取り早く言うと, loadコマンド実行後に,まず「~」「C」のようにキーボードから入力する.

> load
~CLocal command? 
「Local command?」のように実行するコマンドを聞いてくる. lrzszでは,「lsx」というコマンドがXMODEMのためのコマンドなので, lsxを指定する.さらに,送信するファイルを引数として指定する. ここでは a.txt という適当なテキストファイルを作成して指定してみる.
> load
~CLocal command? lsx a.txt
ちなみにa.txtの内容は以下の通り.ほんとてきとう.
abcdefg
hijklmn
これで Enter を押すと,ファイル転送が開始される.
> load
~CLocal command? lsx a.txt
Sending a, 0 blocks: Give your local XMODEM receive command now.
Bytes Sent:    128   BPS:142                             

Transfer complete
                 eceive succeeded.
ちなみにWindowsとかだとXMODEMでファイル転送するためのアプリがきっといっぱい あるだろうから,それを使えばいいだろう.その場合,転送プロトコルは「XMODEM」 で,転送ブロックサイズは128バイト,チェックサムは1バイト(8ビット)の単なる 加算のもの(CRCチェックサムではない)を指定する. 正式には「XMODEM/SUM」というらしい. (「XMODEM/CRC」とか「XMODEM/1k」だとダメなので注意)

ファイルが転送できたら,dumpコマンドでファイルの内容を確認してみる.

> dump
size: 128
61 62 63 64 65 66 67 0a  68 69 6a 6b 6c 6d 6e 0a
1a 1a 1a 1a 1a 1a 1a 1a  1a 1a 1a 1a 1a 1a 1a 1a
1a 1a 1a 1a 1a 1a 1a 1a  1a 1a 1a 1a 1a 1a 1a 1a
1a 1a 1a 1a 1a 1a 1a 1a  1a 1a 1a 1a 1a 1a 1a 1a
1a 1a 1a 1a 1a 1a 1a 1a  1a 1a 1a 1a 1a 1a 1a 1a
1a 1a 1a 1a 1a 1a 1a 1a  1a 1a 1a 1a 1a 1a 1a 1a
1a 1a 1a 1a 1a 1a 1a 1a  1a 1a 1a 1a 1a 1a 1a 1a
1a 1a 1a 1a 1a 1a 1a 1a  1a 1a 1a 1a 1a 1a 1a 1a

> 
a.txtの内容がばっちり書き込まれている. (128バイト単位で,お尻はCtrl-Zで埋められる)

今回は実は最初はぜんぜんうまく動作しなかったのだけど,シリアルの受信処理に 問題があっておかしなデータが受信されていたのが原因で,そこを直したらXMODEMの 処理自体はあっさりと動いた.うーん楽でいいねえ.

これでシリアルからのコマンドを受け付けて,XMODEMでファイル転送できるように なった.なんかモニタっぽくなってきたね. 次は実際にプログラムを転送して,動作できるようにしたい.オブジェクトファイル フォーマットを何にしようかなあ...やっぱしELFかなあ...


メールは kozos(アットマーク)kozos.jp まで