[Atmel-ICE on Linux] Debianからavrdudeを使ってブレッドボード上でAtmega328pのプログラムを書き込む
※ 当ページには【広告/PR】を含む場合があります。
2021/03/09
Arduinoでマイコン開発に慣れてきたら、やはりブートローダーを毎回書き込んでから、さらにArduino用のプログラムを書き込む...という手順は面倒になりますし、製品の量産には向きません。
また簡単にチェックするためだけで、毎度毎度マイコンを剥がしていてはいつかボード表面をピンセットで滑っちゃって大切な部品を損傷させる危険性もあります。
ということで今回は新品のAtmega328pを題材に、Debian Linux & Atmel-ICEでavrdudeを使ったプログラムをブレッドボード上で書き込みする手順を特集します。
準備 ~ ハード編
まずは今回の作業でつかう材料に関してメモをしておきます。
Atmega328p(AVRマイコン)のプログラム書き込みに必要なもの
まず今回の作業ではMicrochip(旧Atmel)製品でAVRマイコンのライターが最低でも必要になります。
どのようなAVRマイコンでも安定して書き込めるように、また何かあったらヒューズビットも書き込みできるように、「
著者の場合はAVRだけでなくSAMも使いたいので、正規品のAtmel-ICEを使っていますが、ロイヤリティもありこちらはかなり高めです。
セールスで出ているのを狙って買うか、以下のようなサードパーティ製の互換品・「
ちなみに付属品のJTAGケーブルのアクセサリーは失くすと、色んなプログラミングモードでピンの番号の対応を確認しなくてはならないという地味に辛い作業をしなくてはならないので、大切にしまっておきましょう。
次に今回プログラムの書き込み使う素材ですが、
+ ATMEGA328Pマイコン(※未使用もしくは初期化された状態のもの)
+ ブレッドボード
+ 5V供給用のUSBアダプター
+ 抵抗 10kΩ
となっています。
書き込み前のピン配線
次に書き込み前の準備の中で、もっとも重要な項目である、
Atmel-ICEとマイコンとの配線接続
Atmega328pをSPI(ISP)モードでAtmel-ICE上のavrdudeから使うためには以下のような配線の模式図になります。

ここでの注意点として、JTAGの10ピンケーブルの向きを良く観察すると、このケーブルがストレートですので、両端のピンヘッダのアサインメントが異なります。

つまり、同じような見た目でも、Atmel-ICE側に付けるヘッダ(上の図では右側)と、マイコン側に付けるヘッダ(上の図では左側)には区別があります。
ケーブル逆に取り付けた場合には正しく動作しませんので、取付方向は良く確認しましょう。
準備 ~ ソフト編
次にソフトウェア周りの内容を説明していきます。
Linux(Debian)にavrdudeをインストール
LinuxでAtmel-ICEなどの専用デバッガーからマイコンに書き込みを行う際には、
$ sudo apt-get install binutils-avr gcc-avr avr-libc avrdude
現在ではLinuxの主要なパッケージマネージャからインストールすることができるようになっています。 Debianだと、aptで簡単にインストールできるようになっています。
USBドライバをインストール
LinuxでAtmel-ICEを使うためにもっとも苦労するのが、LinuxカーネルにUSBデバイスマネージャを正しく設定する作業です。
USBドライバのインストールはLinuxの各ディストリビューションごとに作法が違いますので、ここではDebian系OSのドライバ構築手順のみを説明させていただきます。
まずは追加のUSBドライバのライブラリの
libusb-dev
libusb-1.0-0-dev
$ sudo apt-get install libusb-dev
#👇ドライバ・ライブラリが追加されていることを確認
$ dpkg -L libusb-dev | grep /usr/include
/usr/include
/usr/include/usb.h
$ sudo apt-get install libusb-1.0-0-dev
#👇ドライバ・ライブラリが追加されていることを確認
$ dpkg -L libusb-1.0-0-dev | grep /usr/include
/usr/include
/usr/include/libusb-1.0
/usr/include/libusb-1.0/libusb.h
なお、
Windows:
Atmel-ICEをUSB接続すると自動でUSBドライバがロードされる
Mac:
インストールは不要
Linux:
99-platformio-udev.rulesというudevルールを設定する必要あり。
もし過去に入れている場合には、最新のドライバにするためにアップデート推薦
WindowsやMacOSで試す分には、USBドライバのことをさほどシビアに考慮する必要も無いのですが、LinuxだけはUSBドライバをインストールしないと、Atmel-ICE側を正しく認識してくれない仕様になっています。
なお、udevルールの解説はここでは省きますが、詳しく知りたい方は
Atmel-ICEはCMSIS-DAP準拠デバッグアダプタですので、たとえば
$ curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/master/scripts/99-platformio-udev.rules \
| sudo tee /etc/udev/rules.d/99-platformio-udev.rules
$ ls /etc/udev/rules.d/
#👇ルールが追加されている
... 99-platformio-udev.rules ...
$ sudo service udev restart
もしくは
$ curl -L -O https://raw.githubusercontent.com/artynet/arduino-linux-setup/master/arduino-linux-setup-12.sh
$ chmod +x arduino-linux-setup-12.sh
$ ./arduino-linux-setup-12.sh <your_username>
ターゲットデバイス名&書き込み装置名の確認
それでは、パソコンとAtmel-ICEを接続して、avrdudeの動作確認を行います。
まずはAVRマイコンを設定するときに割り当てる名前を探します。
$ avrdude -p ?
Valid parts are:
uc3a0512 = AT32UC3A0512
c128 = AT90CAN128
c32 = AT90CAN32
#...
m328p = ATmega328P
#...
x8e5 = ATxmega8E5
ucr2 = deprecated, use 'uc3a0512'
これでATmega328Pマイコンはm328pという表記で利用できることが分かります。
また書き込み装置も同じように探せます。
$ avrdude -c ?
Valid programmers are:
2232HIO = FT2232H based generic programmer
#...
atmelice = Atmel-ICE (ARM/AVR) in JTAG mode
atmelice_dw = Atmel-ICE (ARM/AVR) in debugWIRE mode
atmelice_isp = Atmel-ICE (ARM/AVR) in ISP mode
atmelice_pdi = Atmel-ICE (ARM/AVR) in PDI mode
atmelice_updi = Atmel-ICE (ARM/AVR) in UPDI mode
#...
xplainedpro_updi = Atmel AVR XplainedPro in UPDI mode
Atmel-ICE用の書き込みモードがいくつかありますが、ここでは
atmelice_isp
SPI(ISP)設定のピン配置
上記の配線図では説明をスキップしていましたが、SPIモードによるAVRマイコンへの書き込みでは、以下のようなピンアサインメントが対応しています。
となっていますので、書き込み前には配線をもう一度確認しましょう。
マイコンへの接続テスト
とりあえずAtmel-ICEが正しくマイコン側へ繋がっているかをテストするためにメモリ情報を出力します。
$ sudo avrdude -c atmelice_isp -P usb -p m328p -v
avrdude: Version 6.3-20171130
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "/etc/avrdude.conf"
User configuration file is "/root/.avrduderc"
User configuration file does not exist or is not a regular file, skipping
Using Port : usb
Using Programmer : atmelice_isp
avrdude: Found CMSIS-DAP compliant device, using EDBG protocol
AVR Part : ATmega328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
Programmer Type : JTAG3_ISP
Description : Atmel-ICE (ARM/AVR) in ISP mode
Vtarget : 5.0 V
SCK period : 8.00 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as FF
avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as FF
avrdude: safemode: Fuses OK (E:FF, H:D9, L:62)
avrdude done. Thank you.
はじめての接続ではなにやらズラズラと設定値が出てきますが、通信が成功しているということのようです。
またもし、Atmel Iceのボード上に青いLEDが点灯せずに通信エラーなどが出ていたらJTAGケーブルなどのピン配線に間違いがないかを確認しましょう。
特に注意が必要なのは、一度利用履歴のあるAtmega328pは既にROMにブートローダーが書き込まれているので、そのままではAtmel-ICEを使った通信が以下のようなエラーを吐いて上手くいきません。
$ sudo avrdude -c atmelice_isp -P usb -p m328p -v
avrdude: Version 6.3-20171130
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "/etc/avrdude.conf"
User configuration file is "/root/.avrduderc"
User configuration file does not exist or is not a regular file, skipping
Using Port : usb
Using Programmer : atmelice_isp
avrdude: usbhid_open(): No response from device
avrdude: usbdev_open(): Found Atmel-ICE CMSIS-DAP, serno: J41800091527
avrdude: Found CMSIS-DAP compliant device, using EDBG protocol
avrdude: jtag3_edbg_prepare(): failed to read from serial port (-1)
avrdude: failed to sync with the JTAGICE3 in ISP mode
avrdude done. Thank you.
つまりは
元Arduino Uno
Atmel-ICEとマイコンの通信が正常に構築されているようであれば、いよいよ以降でプログラムの書き込み作業に進みます。
簡単なプログラムの書き込み
まずは
以下はAtmega328PのPORTBのピン全部を一斉にチカチカさせるコードになります。
#ifndef F_CPU
#define F_CPU 16000000UL // 16 MHz clock speed
#endif
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB = 0xFF; //Makes PORTB an Output.
while(1) {
PORTB = 0xFF; //Turns ON All LEDs
_delay_ms(1000); //1 second delay
PORTB= 0x00; //Turns OFF All LEDs
_delay_ms(1000); //1 second delay
}
}
このソースコードを
sample_program.c
#👇コンパイル
$ avr-gcc -Wall -g -Os -mmcu=atmega328p ./sample_program.c -o ./sample_program.out
$ ls
sample_program.c sample_program.out
#👇実行ファイルのサイズをチェック
$ avr-size -C ./sample_program.out
AVR Memory Usage
----------------
Device: Unknown
Program: 178 bytes
(.text + .data + .bootloader)
Data: 0 bytes
(.data + .bss + .noinit)
#👇hexファイルに書き込み形式を変更
$ avr-objcopy -j .text -j .data -O ihex ./sample_program.out ./sample_program.hex
$ ls
sample_program.c sample_program.hex sample_program.out
これで書き込み用の
hex
ではこれを早速書き込んでみましょう。
$ sudo avrdude -c atmelice_isp -P usb -p m328p -U flash:w:sample_program.hex:i
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "sample_program.hex"
avrdude: writing flash (178 bytes):
Writing | ################################################## | 100% 0.05s
avrdude: 178 bytes of flash written
avrdude: verifying flash memory against sample_program.hex:
avrdude: load data flash data from input file sample_program.hex:
avrdude: input file sample_program.hex contains 178 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.07s
avrdude: verifying ...
avrdude: 178 bytes of flash verified
avrdude: safemode: Fuses OK (E:FF, H:D9, L:62)
avrdude done. Thank you.
とすると、PORTBのどのポートからでも1秒感覚でチカチカさせるプログラムが作成できました。
余談 ~ avrdudeのフューズの書き換え方
debugWIREでの書き込み方法はこの記事では詳しくは解説しませんが、RESETとVTGとGNDの3線だけで書き込みが出来るシンプルな配線構成でプログラムが書き込めるのがdebugWIREのメリットです。
まずはSPIモードに戻せるように現在のフューズ値を控えておきます。
Ext:0xFF
High:0xD9
Low:0x62
debugWIREモードにするフューズの組み合わせは、マイコンの取説を読み込む必要があります。 なお
今回はAtmega328pに限ると、最低限DWENを1に設定する必要があるので、例えば元の
0xD9
0x99
$ sudo avrdude -c atmelice_dw -P usb -p m328p -U hfuse:w:0x99:m -v
というようにします。
書き込みたいフューズ値を間違えて、一度SPIモードに戻したいときには、
$ sudo avrdude -c atmelice_isp -P usb -p m328p -U hfuse:w:0xd9:m -U lfuse:w:0x62:m -U efuse:w:0xff:m -v
などとすると良いでしょう。
なおdebugWIREを使う際の注意点としては、間違ったフューズビットを送ってしまった場合、設定を間違ったマイコンと通信が不能になってしまう恐れがあります。
もしメーカー純正のHVPPに対応したデバッガーではない自作の書き込み装置でこのフューズビットを元の状態にレスキューする場合には、色々と策を絞る必要があります。
debugWIREは配線がシンプルで便利な分、それ相応のリスクがあるのを覚悟の上で利用してください。
...君子危うきに近寄らず、純正ライターを持っていないのなら、debugWIREは使わないのが賢明と言えるでしょう。
Lチカで動作確認
では正常にプログラムが書き込めいるかを、適当なPORTBのポートのどこかにLEDを使って確認してみます。
確認方法とは言っても、LEDを適当に配線したら、5V電源をマイコン側に供給するだけです。

書き込みが成功していると上の画像のようにLチカしていることが見て取れます。 Windowsではだいたい上手く行くのですが、Linuxからでもavrdudeが機能して、プログラムが書き込めているなんて!
感動もひとしおでした😋
まとめ
以上、今回は
Atmel-ICE
Linuxで専用の書き込み装置をつかってプログラムをマイコンに転送する最大のポイントとしては、
USBドライバを正常にインストール
もし書き込みに失敗している場合には、まずLinuxカーネルのUSBデバイスの設定をきちんと見直すなど、それなりに手探りで不足しているライブラリなどを探したり、干渉しているドライバ周りのファイルを良く読み込んでみたりなどしてみてください。