AVRISP mkIIは便利なのですがオンフィールドで書き換えるには不便ですし、ユーザに書き変えを頼むわけにもいきません。
Atmelが公開しているアプリケーションノートAVR109に自己プログラミングがありましたので試してみました。ターゲットMPUはATmega8とATmega328Pです。
preprocessor.shを使うとdefines.hに記述する内容を吐き出してくれるようになっています。
usage: preprocessor.sh device bootsize progport prog_no cpu_freq baud_rate
デバイス名とブートコードサイズ、プログラミングモードに入るポート名とポート番号、CPU周波数とUSARTのボーレートを指定します。
ATmega8の例では
preprocessor.sh atmega8 1024 PORTB 0 8000000 9600 > defines.h
と言った感じです。
このケースの場合、PORTBのビット0がLOWレベルになっていたらプログラミングモードに入ります。ブートローダ内部では対象ポートのプルアップレジスタを有効にしますので、外付け抵抗は必要ありません。ピンにスイッチを付けておくだけでこの機能をサポートするボードが完成します。
(ブートローダはこれ以外のI/O設定は一切行いません。要するにすべてのピンが入力のままです。)
ターゲットにブートローダを書き込んで一度電源を切り、PORTBのビット0をLOWにして電源を入れます。ブートローダが起動したはずですのでminicomを使って接続してみましょう。
コンソールに大文字Sを入力した時にAVRBOOTという文字列が帰ってくればブートローダが期待通りに動作しています。ホストは特定のプロトコルに従って書き換え対象プログラムをブートローダに渡すことで、ブートローダが自身のフラッシュを書き換えてくれるというわけです。
ここで疑問が湧いてきます。
- ユーザプログラムはどこに配置するのでしょう?
- 何か特別な配慮が必要になるのでしょうか?
- ブートローダは上書きできないようにできるのでしょうか?
さて、疑問を一つずつみていきましょう。
試しに、ブートローダのことを意識せず従来のユーザプログラムを書き込んでみましょう。
avrdude -c ?とすると対応しているプログラマを表示できます。
この中に「avr109 = Atmel AppNote AVR109 Boot Loader」というのがあります。
sudo avrdude -c avr109 -b 9600 -P /dev/ttyUSB0 -p m8 -U flash:w:sdcmod.hex
書き込んでみました。
Connecting to programmer: .
Found programmer: Id = "AVRBOOT"; type = S
Software Version = 1.5; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=64 bytes.
Programmer supports the following devices:
Device code: 0x77
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e9307
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: butterfly_recv(): programmer is not responding
あれれ。
プログラマIDやソフトウェアバージョンは取得できているようです。
でも書き込めませんでしたね。
プログラマからの応答がないようです。
ここで言うプログラマとはまさにブートローダの事です。
おかしいですね。
プロトコルの仕様では0x13を返すようになっています。
ブートローダのソースを見るとまさにそういう実装になっています。
あれれ?
ちょっと何か思い違いがありそうですね。
ここからは次回のデバッグ編に続くことになりそうです。