Arduinoからバイナリファイルをダウンロードする

# Arduinoからバイナリファイルをダウンロードする

## AVRDUDE

Microchip社製AVRマイクロコントローラー用アップロード/ダウンロードツール、だそうです。
[https://github.com/avrdudes/avrdude](https://github.com/avrdudes/avrdude)

### ダウンロード

今回はWindowsで作業するためにビルド済みWindows版を持ってきます。
[https://github.com/avrdudes/avrdude/releases](https://github.com/avrdudes/avrdude/releases)

- x64用はこれ
  - avrdude-v7.3-windows-x64.zip

### 展開

適当な場所に展開しておきます。(今回は C:\avrdude に展開します)

## 使用方法

詳細は [AVRDUDE documentation](https://avrdudes.github.io/avrdude/7.3/avrdude.html) を読みましょう。

### ダウンロードしてみる

まずArduinoをUSBケーブルでPCと繋いでおきます。
今回はCOM5で接続されています。

移動してファイルがそろっているか確認します。

```
C:\>cd c:\avrdude
C:\avrdude>dir /b
avrdude.conf
avrdude.exe
avrdude.pdb
```

接続はCOM5、対象のボードは[前回](https://qiita.com/cactanaka/items/c580e5aa27035d893fc4)使用したELEGOO MEGA 2560です。

[AVIDUDE Intoroduction](https://avrdudes.github.io/avrdude/7.0/avrdude.html#Introduction)によると
> Wiring boards (e.g. Arduino Mega 2560 Rev3) are supported, utilizing STK500 V2.x protocol, but a simple DTR/RTS toggle to set the boards into programming mode. The programmer type is “wiring”.

ということなのでMega2560はwiringを指定するとよいようです。

```
avrdude -p m2560 -c wiring -P COM5 -U flash:r:"c:\avrdude\test1.bin":r
```

こんな感じでダウンロードが進みます。

```
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9801 (probably m2560)

avrdude: processing -U flash:r:c:\avrdude\test1.bin:r
avrdude: reading flash memory ...
Reading | ################################################## | 100% 33.56 s
avrdude: writing output file c:\avrdude\test1.bin

avrdude done.  Thank you.
```

## ダウンロードしたバイナリを覗いてみる

c:\avrdude\test1.bin にRaw Binaryでダウンロードされたファイルをちょっと覗いてみることにしましょう。
といってもそのままではヘックスコードなので16進数の羅列です。
16進数を2進数に置き換えてCPU命令セットと突き合わせるのは大変なので、逆アセンブルを仕掛けます。

### AVR-GCC/OBJDUMP

AVRに対応したGCCに付随するobjdumpを使います。
Windows環境で構築すると大変なのでLinux環境としてUbuntu on WSLを使用します。

#### インストール

Ubuntuではコンパイル済みバイナリがありますのでapt-getでインストールします。

```bash
sudo apt-get install gcc-avr
```

インストールが終わったら念のため場所を確認しておきます。

```bash
puipui@poepoeyo:~$ which avr-gcc
/usr/bin/avr-gcc

puipui@poepoeyo:~$ ls /usr/bin/avr-*
/usr/bin/avr-addr2line  /usr/bin/avr-elfedit    /usr/bin/avr-gcc-ranlib  /usr/bin/avr-nm       /usr/bin/avr-strings
/usr/bin/avr-ar         /usr/bin/avr-g++        /usr/bin/avr-gcov        /usr/bin/avr-objcopy  /usr/bin/avr-strip
/usr/bin/avr-as         /usr/bin/avr-gcc        /usr/bin/avr-gcov-tool   /usr/bin/avr-objdump
/usr/bin/avr-c++        /usr/bin/avr-gcc-5.4.0  /usr/bin/avr-gprof       /usr/bin/avr-ranlib
/usr/bin/avr-c++filt    /usr/bin/avr-gcc-ar     /usr/bin/avr-ld          /usr/bin/avr-readelf
/usr/bin/avr-cpp        /usr/bin/avr-gcc-nm     /usr/bin/avr-ld.bfd      /usr/bin/avr-size
```

バイナリファイルをダウンロードした場所に移動します。

```bash
cd /mnt/c/avrdude
```

avr-objdumpで逆アセンブルします。CPU命令セットがどれかわからないので今回は適当に107を指定してありますが、Aruinoでは25あたりがよくつかわれるようです。

```bash
avr-objdump -D -m avr:107 -b binary test1.bin > test1.txt
```

これでtest1.txtに逆アセンブリしたコードが出力されます。
(こんな感じ)

```assembly
test1.bin:     file format binary

Disassembly of section .data:

00000000 <.data>:
       0:	0c 94 28 01 	jmp	0x250	;  0x250
       4:	0c 94 59 01 	jmp	0x2b2	;  0x2b2
       8:	0c 94 59 01 	jmp	0x2b2	;  0x2b2
       c:	0c 94 59 01 	jmp	0x2b2	;  0x2b2
      10:	0c 94 59 01 	jmp	0x2b2	;  0x2b2
      14:	0c 94 59 01 	jmp	0x2b2	;  0x2b2
(中略)
     148:	00 00       	nop
     14a:	21 00       	.word	0x0021	; ????
     14c:	24 00       	.word	0x0024	; ????
     14e:	27 00       	.word	0x0027	; ????
     150:	2a 00       	.word	0x002a	; ????
     152:	2d 00       	.word	0x002d	; ????
     154:	30 00       	.word	0x0030	; ????
     156:	33 00       	.word	0x0033	; ????
     158:	01 01       	movw	r0, r2
     15a:	00 00       	nop
(中略)
     250:	11 24       	eor	r1, r1
     252:	1f be       	out	0x3f, r1	; 63
     254:	cf ef       	ldi	r28, 0xFF	; 255
     256:	d1 e2       	ldi	r29, 0x21	; 33
     258:	de bf       	out	0x3e, r29	; 62
     25a:	cd bf       	out	0x3d, r28	; 61
     25c:	00 e0       	ldi	r16, 0x00	; 0
     25e:	0c bf       	out	0x3c, r16	; 60
     260:	23 e0       	ldi	r18, 0x03	; 3
     262:	a4 e2       	ldi	r26, 0x24	; 36
     264:	b2 e0       	ldi	r27, 0x02	; 2
     266:	01 c0       	rjmp	.+2      	;  0x26a
     268:	1d 92       	st	X+, r1
```

初手アドレス0x250にJMPしてますね。0x250からはメモリ格納命令が続くので変数やら定数やらをまず格納するみたいですが、[前回](https://qiita.com/cactanaka/items/c580e5aa27035d893fc4)のソースコードを見比べるとずいぶん動きが違うのがわかると思います。(そもそもアドレス00000000から始まるのかどうかわかりませんが。。。)