思いつき
bootloader という機能があって、起動時にファームウェアイメージを PC と通信してとってきて、ファームウェアに書いてから、起動。が、普通。起動時のベクタで bootloader mode にはいって、そこから書き込む専用と思いこんでた。
データシートみてたら、そんなモードはなくて好きなときにファームウェアを更新できるみたい。AVR の内部 RAM が 0x400 byte くらいで、ファームウェアが 0x4000 byte くらいなので通信しながら書き込まないと使えない。と、思いこんでた。
UNROM のキャラクタ RAM が 0x2000 byte もあるからいけるな。ってことで下記の流れで USB だけでファームウェアの更新が完結できる!
というわけで実装してみた
なぜか、更新できない... なんでだーと思ってたら、データシートにこう書いてある。
- ブートローダ領域からでないと書き込めない
- これはわかってたので関数にセクションを貼って、リンカの設定をかえる
- ブートローダ領域が 0x1c00 から 0x1fff
- fuse の設定するブートローダ領域が 0x1c00, 0x1e00 からとなっている
これがまちがいで mega16/164p の領域は 0x3c00 から 0x3fff だっつーの!!! これで1日使った。どのデータシートも間違ってる。
容量の問題
そこを直したら USB と UNROM 経由でファームウェアの更新完了!! それはいいんだが、 0x2000 byte だと思いこんでたので、残りの0x2000 byte を更新する方法を作ってない。現状のファームウェアだとそれで足りるんでいいけど、将来性はない。
セーブデータが消えてもいいなら、 TNROM, SNROM あたりを使って、 CHR-RAM と W-RAM を併用するのもあり。本当は RAM アダプタとか ETROM, EWROM を使えばいいんだけど、現状はアクセスできないし、UNROM という手軽さにかける。
AVR の書き込み手段一覧
AVR ライタなしでファームウェアを更新する手段をもうちょいもみます。販売はもうちょっとまっていただきたい。ihex を読み込むのを C で作ります。こーゆーときに C は弱いからやりたくない。