まぁ当然ながら、いくつか問題があった。それらについて書こうと思う。
1)USBに接続しただけで、リセットを繰り返す
これでは、全然デバッグができない。とりあえず エコーバックだけするコードを動かしてみた。これは問題なく動いた。いろいろ試行錯誤したところ、最初に "login:" を表示するとリセットしてしまうことがわかった。メインループに入る前に usbcdc_getc() で1文字入力を入れたら、とりあえず "login:" が出るようになった。
AVR-CDC そのものか AVR-CDC の最新版をマージしたときのバグらしい。いまは、USBNIX を動かしたいので、(バグを追求しないで)最初に入力するという回避策のままにすることにした。
追記:
ひといきついたので、改めて動作を調べてみた。
最初にいきなり Type any.. という 38バイトのメッセージを出力していたのだが、その動作にしたら再現した。(Linux 2.4.31 + UCHI )
これを "login: "の 6バイトにした場合、 ほとんど正常に動作する。正常といっても、"login: "のメッセージを全部または一部ロストする場合がある。
それはともかく、デバイス側がいきなりデータを垂れ流すという設計は普通しない。デバイスはホストから要求があって初めてなんらかの動作を開始するようにするのが普通。
というわけで、↑は回避策ではなく正しい設計にしただけなのだ。
2)ENTER で改行ができない
なさけないミス。Linux 版は、ICRNL が効いていたので、ENTER が LF だったが、ターミナルソフトでは、CR 。
3)I2C ROM の READ/WRITE が動かない
0.2では、適当に書いただけのものだったので、これはある意味予定どおり。
デバッグがなかなか面倒で、結局 I2C ROM にデータを書くコマンド と ダンプするコマンドを作ってテストすることになった。あと、エラー処理を全然していなかったので、どこでエラーになっているかわからなかった。プリミティブだけでも エラーコードが判るようにしてデバッグすることになった。
本来の処理ではまだエラー処理ができていない。これはボチボチやっていくことにして、先に進むことにした。
4)EEPROM が勝手に書き換わる
これは、低電圧検出リセットを有効にしていないため。...というのは知っていた。しかし、2回に1回ぐらいの高い頻度で EEPROM が書き換わるとは思っていなかった。USBNIX は、EEPROM が少しでも違えば login できなくなるしくみなので、書き換わったのがよくわかる。
あといくつか改良をしたが、問題点としてはこんなところ。あともうすこしで完成か。
ちなみにいまのプログラムサイズは、
text data bss dec hex filename
7228 32 234 7494 1d46 usbnix.elf(+デバッグコマンド)
6790 32 234 7056 1b90 usbnix.elf
だいぶ厳しくなってきた。
TODO
1) 最初に文字出力するケースのバグの修正
2)MinGW 版 (キー入力を termios から WIN32API に変更して、バイナリファイルの指定をいれるぐらいで OK のはず)
3)I2CROM の I/O エラー対応
EIO をエラーコードに追加して、ちゃんと処理する。
4)ハイパーターミナルでの漢字の扱い
上で書かなかったけども、ハイパーターミナルで漢字が扱えていない。Linux では、ファイル名やデータに漢字が使えている。(といっても 8bit スルーなだけで環境が変わると文字化けしてしまう)
追記: ちゃんと漢字は扱えた -- 勘違い。ところで、ハイパーターミナルの漢字コードは、SJIS デフォルトだし、Linux でも問題なく SJIS は扱えるから、SJIS 専用ということにして、文字化け対策をしたほうがよいかも知れない。
追記2:ちなみに、TeraTerm Proや後継ソフトである UTF-8 TeraTerm Pro with TTSSH2 も期待どおりに動作した。(SJISのみ評価)
5)format コマンド
低電圧検出リセットを有効にしても EEPROM が本当に書き換わらないか自信がない。EEPROM が書き換わるとデータがすべて失われてしまうので、EEPROM はバックアップしておいたほうが良さそうだ。... そうなると I2CROM との整合性について保証できなくなる。せめて I2CROM を初期化するコマンドはつけておきたい。ただし、オペミスで format してしまう可能性をなくすために、yes を入力させるとかの考慮は必要か。