2020年8月16日日曜日

avrdudeでleonardo(ATmega32U4)にUSBシリアル経由でelfファイルを書き込むには、ブートローダーを書き込みモードにしておく必要がある


背景

avrdudeでleonardoにelfファイルを書き込もうとしたところ、ATmega328Pと同じ方法では書き込めませんでした。
調べた所、leonardoに書き込まれたブートローダーを書き込みモードにしないとavrdudeでの書き込みを受け付けないことが分かりました。
備忘録を兼ねて書き込み手順を共有します。

用語の説明
avrdude: AVRマイコンへの書き込みを行えるプログラムです。
leonardo: AVRマイコンが使われたArduinoという電子工作に便利なプログラミングボードのひとつです。
elfファイル: avrgccというコンパイラを利用してAVRマイコン向けに生成されるバイナリファイルです。avrdudeを利用してAVRマイコンにelfファイルを書き込めます。

使ったもの

  • ATmega32U4が使われた開発ボード
    背景でも紹介したとおりleonardoを利用しました。
  • avrdudeをインストールしたPC
    Ubuntu20.04にavrdudeをインストールした環境を利用しました。


avrdudeの書き込みコマンドの説明

下記のようなコマンドで書き込みを行います。

ELF_FILE=./path-of/file.elf # 書き換えてください
ARDUINO_PORT=/dev/ttyACM0
avrdude -v -p atmega32u4 -c avr109 -P $ARDUINO_PORT -b 57600 -D -U flash:w:$ELF_FILE:e


leonardoに書き込まれているブートローダーはavr109という種類なので、-cオプションで指定しています。
leonardoへのアップロード速度は57600に設定されているので、-bオプションで指定しています。

何も意識せずに書き込みコマンドを実行すると、下記のようなエラーが発生して書き込めません。

Connecting to programmer: .
Found programmer: Id = "Scannin"; type = n
Software Version = S.c; Hardware Version = a.n
avrdude: error: buffered memory access not supported. Maybe it isn't
a butterfly/AVR109 but a AVR910 device?
avrdude: initialization failed, rc=-1
Double check connections and try again, or use -F to override
this check.

avrdude: error: programmer did not respond to command: leave prog mode
avrdude: error: programmer did not respond to command: exit bootloader

上記のエラーはブートローダーが書き込みモードになっていないleonardoに対してelfファイルを書き込もうとすると発生するようです。

ブートローダーを書き込みモードにした後、上記のコマンドを実行することでelfファイルを書き込めます。

書き込み方法1: リセットボタンを2連打して書き込みモードにしてから書き込む


leonardoに付いているリセットボタン2連打するとブートローダーが書き込みモードで起動します。
その状態になると、L13に接続されたLEDががフワフワ光ります。

書き込みモードは約8秒維持されるので、その間に先ほど説明した書き込みコマンドを実行することで書き込めます。

書き込み方法2: USBポートを1200bpsで開いて閉じて書き込みモードにしてから書き込む

avr109のブートローダーは、USBシリアルを1200bpsで開いて閉じると書き込みモードになる仕様のようです。
参考: How can I force an Arduino Leonardo to reset with AVRDUDE?

そのため、1200bpsでポートを開閉し、そのポートが認識されたあとで先ほど説明したavrdudeのコマンドを実行することで、elfファイルを書き込めます。
ポートの開閉にはsttyコマンドを利用しました。

ARDUINO_PORT=/dev/ttyACM0

# 1200bpsで開いて閉じる
stty -F $ARDUINO_PORT 1200

# ポートが再認識されるまで待つ
while :; do
sleep 0.5
[ -c $ARDUINO_PORT ] && break
done

# ここでavrdudeでの書き込みができると思います
ELF_FILE=./path-of/file.elf # 書き換えてください
avrdude -v -p atmega32u4 -c avr109 -P $ARDUINO_PORT -b 57600 -D -U flash:w:$ELF_FILE:e


まとめ

ブートローダーを書き込みモードにしたleonardoに対して、avrdudeコマンドを利用してelfファイルを書き込めました。

ちなみに、Arduino IDEやPlatformIOではleonardoに向けてプログラムを書き込む時に1200bpsでのポート開閉を自動で行ってくれているため、書き込む際にブートローダーのモード切替を気にする必要が無いようです。

0 件のコメント :