AVR ヒューズビット BOOTRSTについて(その1)
ATMEL AVRマイコンにはFUSEビットがあって、デバイスの機能を設定することができますが、特徴的なものの一つが、ブートローダーを最初から意識したリセットベクタアドレスの選択ができることだと思います。
コンパイルしたコードをICEやROMライタで焼きこむのが一般的ですが、ブートローダがあればUARTなどの別ラインからコードを流し込むことや、ブートローダにモニタ機能も入れると一般的なデバッグ操作もできることになります。
AVRマイコンのなかでも有名なのはATmega328Pを使った、Arduino UNOだと思いますが、これなどは一番AVRマイコンをうまく使っているお手本のようなハードとソフトではないでしょうか。
純正Arduino UNOのヒューズビット設定を確認すると
EXTENDED=FD、 HIGH=D6、 LOW=FF
になってます。
主題がBOOTRSTなので、ここではHIGHのbit0なので0です。
ということなので、0なら Boot Reset Address (0x7800とか)になります。 1なら当然 0x0000からのスタートですね。
ですからブートローダを使わない通常の応用プログラムを焼く場合は、.textセクションは0x0000に設定して、ROMとして0x0000から焼きこみ、FUSEビットのBOOTRSTは1にすることになります。このBOOTRSTは初期値は1です。
ここまでは通常の使い方ですが、ちょっとした実験などで、0x0000からと0x7800からスタートする2種類のプログラムがあれば便利なことがあり、以下実験してみました。
BOOTRSTビットを変更するだけで2種類のプログラムが一つのマイコンで使い分けできるという意味です。
まずプログラムとして0x0000から開始するプログラムを作成してHEXファイルを生成します。例として短いコードで。
左が0x0000から始まるHEX、右が0x7800から始めるHEXファイル。
右側の0x7800から始めるHEXファイルを生成するには、.textセクションの開始アドレスを変更する必要があります。
ここでAVRのトリッキーなややこしい問題が顔をだしてきます。例のハーバードアーキテクチャとやらの流れで、ROMメモリは2バイトWORD単位でプログラムカウンタが動作するAVRなので、GCCコンパイラ上のアドレスは、実バイトアドレスの半分の値になります。
なのでLinkerで指定するSection開始アドレスは、0x3c00(実際のバイトアドレスは0x7800)になります。
この2つのHEXファイルはいわゆるスタートアップもちゃんと含んでいますので、それぞれは単独で動作します。
これを連結するには、ローテクで解決します。HEXファイルの最終行
:00000001FF
はレコードタイプ 01 でEndOfFileなので、これを連結した最後の部分だけにしてそれ以外は削除します。
テキストエディタで編集した結果が以下
0x0000から開始のプログラムと0x7800から開始のプログラムが合体して、最後に 01FFのEndOfFileを置くと正規のHEXファイルフォーマットになっているのでこれをROMライタで焼き付ければOKです。
これで、BOOTRSTビットを1にするか0にするかで異なるプログラムを走らせることができます。