月別アーカイブ: 2023年10月

AVR のヒューズ設定を hex ファイルに入れる方法 (Microchip Studio)

ATtiny202 は使いやすいマイコンで、8 ピンでやりたいようなことはだいたい何でもできるので、他の8ピンマイコンは不要と言っても過言ではないというのはやはり言い過ぎでしょうか(?)。
8ピンに 32bit マイコンなんて初期化が面倒なだけで、そんなものは 8bit で十分なんです。クロックも 20MHz, 20MIPS で動けば十分です。そう思います。まあもうちょっとアナログ系が充実したら言うことないのですが。

ところで、プロジェクトジェネレータの Atmel Start を使うために Microchip Studio でプロジェクトを作っているわけですが、
* Microchip は Studio の開発凍結と MPLAB X IDE への統一を明言していますが、MPLAB はいろいろダメなので、Studio が使えるうちは Studio で開発する所存です。
ヒューズ設定は自動で作ってくれないため、デフォルト値から変える場合は
ユーザが指定する必要があります。

Microchip 製のデバッガを使う場合、メニューの Tools -> Device Programming で
ヒューズを手動で書き換えることができます。
しかし、頒布や量産を考えると、プログラムファイルにヒューズ設定を入れることが望ましいです。
pymcuprog なんかでも、hex ファイルの中で指定しないとヒューズが書き換えられなさそうです。

tiny202 のヒューズ設定が必要になるとき

tiny202/402 のヒューズ設定が必要になるときは、例えば
– CPU クロックを 16MHz に設定する
(これは Start から設定できますが、そのままではクロックのキャリブレーション設定が 20MHz のままなので、正確な周波数にするためには Fuse の FREQSEL 設定が必要)
– BOD, WDT の初期設定を変える
– UPDI のプログラム書き換えで EEPROM の内容を書き換えないようにする
– スタートアップ時間を変える(出荷時は最大値 64ms)
などが挙げられます。

ヒューズ設定をプログラム中に書く

avr/io.h をインクルードして、avr/fuse.h (これは io.h からインクルードされる) の説明に従って
ヒューズの設定値をソースコード中に記述します。tiny202 なら、たとえば下記のように。
使わないヒューズ部分は _DEFAULT を指定しないと、0x00 になってしまいます。
avr/io.h をインクルードしないと、fuse なしの .elf が出来上がります。

#include <avr/io.h>
FUSES =
{
.WDTCFG = FUSE_WDTCFG_DEFAULT,
.BODCFG = FUSE_BODCFG_DEFAULT,
.OSCCFG = FUSE_OSCCFG_DEFAULT,
.TCD0CFG = FUSE_TCD0CFG_DEFAULT,
.SYSCFG0 = FUSE_SYSCFG0_DEFAULT,
.SYSCFG1 = 0x01, // SUT = 1ms
.APPEND = FUSE_APPEND_DEFAULT,
.BOOTEND = FUSE_BOOTEND_DEFAULT,
};

FUSES の中身はデバイスごとに異なるため、デバイス定義 (iotn202.h)ファイルを参照します。(tiny202 ならば下記のような感じ)

/* Fuses */
typedef struct FUSE_struct
{
register8_t WDTCFG; /* Watchdog Configuration */
register8_t BODCFG; /* BOD Configuration */
register8_t OSCCFG; /* Oscillator Configuration */
register8_t reserved_1[1];
register8_t TCD0CFG; /* TCD0 Configuration */
register8_t SYSCFG0; /* System Configuration 0 */
register8_t SYSCFG1; /* System Configuration 1 */
register8_t APPEND; /* Application Code Section End */
register8_t BOOTEND; /* Boot Section End */
} FUSE_t;

これでビルドすると、コンパイル結果の .elf ファイル中に fuse セクションが入るようになります。
たとえば

avr-objdump --section-headers ~~~.elf

で確認できます。

hex ファイルにヒューズ設定を入れる

AVR マイコンのプログラマには .hex ファイルでバイナリを渡すことが一般的ですが、まだ .hex ファイル中にヒューズビットは入っていません。

Makefile から実行される objcopy で、fuse や lockbit などを無視して hex ファイルを作るオプションが指定されています。
これはプロジェクトのビルド設定で変更できないので、(参考資料) のようにプロジェクトの Post-build event で下記のように指定して、hex ファイルを作成します。この場合、(プロジェクト名)_with_fuse.hex というファイルが生成されます。

"$(ToolchainDir)\avr-objcopy.exe" -O ihex -R .eeprom -R .lock -R .signature -R user_signatures "$(OutputDirectory)\$(OutDir)\$(OutputFileName)$(OutputFileExtension)" "$(OutputDirectory)\$(OutputFileName)_with_fuse.hex"

これで、pymcuprog でもヒューズビットが書けるようになりました。

参考資料

https://microchipdeveloper.com/8avr:avrfuses