#はじめに
なんとなく歩いていたら、「Arduinoに書き込んだバイナリを抽出することはできるんかなぁ」と思い立ったので調べてみました。この記事は後に投稿する記事と繋がりがありますので、合わせて見て頂けると嬉しいです。
(できるだけ早く投稿します!)
「書き込み済みのArduinoはあるけど元のプログラムは無くした!でも別のArduinoにも書き込みたい!」(バイナリファイル別のArduinoに書き込む方法は次回以降)
とか、
「プログラム書いたけどなぜか遅い!アセンブリコードを覗いてみたい!」(バイナリファイルからアセンブリコードを取得する方法は次回以降)といった場合の前段階として役立てて頂ければと思います。
また、本記事ではMacOSでの手順を示します。(需要があればwindowsでの手順も書こうと思います。)
#その前に下準備
まず使用するツールを用意します。以下の2種類の方法があるので好きな方でやってください。
###1、ArduinoIDEに付属するツールを使用する方法
この記事を見る方の中にはいないとは思いますが、まだインストールしていない方はARDUINO SOFTWAREから落としてください。
インストールしただけの段階ではパスが通っていませんので、初めにパスを通す作業を行います。
使用するツールはArduino.app内の以下の階層にあります。
Arduino.app/Contents/Java/hardware/tools/avr/bin/
.bash_profileファイルを開き、以下の行を追加します。自分はArduino.appが/Applicationsにありましたので以下のように記述していますが、ここは環境に合わせて適宜変更してください。
export PATH="/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin:$PATH"
.bash_profileを追記できましたら、sourceコマンドを利用するかターミナルを再起動するなどして変更を反映させてください。
###2,Homebrewを使用する方法
以下をターミナルで実行してください。
brew install avrdude --with-usb
#手順
##1,対象のArduinoをMacに接続する
ArduinoをMacに接続し、ポート名を確認をします。Arduino.appを立ち上げて、ツール→シリアルポートを選択するとポート名の一覧が出てくるのでそこから確認する方法が簡単だと思います。
Macであれば、/dev/cu.usbmodem(数字)となっていると思います。
##2,対象のArduinoに載ったマイコンの種類を調べる。
Arduinoのマイコン表面に書かれた名前を調べます。ATmega****となっていると思います。
自分はArduino Unoを使用していますので、ATmega328Pでした。
##3,コマンドの実行
ArduinoIDEに付属するツールの一つ、avedudeを使用します。コマンドが見つからない場合は、下準備のパスの設定がうまくいっていないと思われます。
####-pオプション
手順2で調べたマイコンの種類を指定します。ここから対応表を見ることができます。
Arduino UnoはATmega328Pなのでm328pでした。
####-Pオプション
手順1で調べたポート名を指定します。
####-bオプション
ここではボーレートを指定します。
Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.confに記載されているボーレートがデフォルトとなるので指定する必要はないと思います。ボーレートが原因でうまくいかないことがあるので、失敗したらここも疑って見るポイントです。
####(取得したい書式の指定)
出力するファイル名は-Dオプションで指定するが、ファイル名の後に出力フォーマットを指定することができる。
書式 | 指定形式 |
---|---|
intel Hex | i |
raw binary | r |
自動検出 | a |
Arduino Unoで試した自分の例です。
以下の例ではタイトルの通りバイナリでの出力です。
avrdude -C../etc/avrdude.conf -F -v -pm328p -carduino -P/dev/cu.usbmodem1463201 -b115200 -D -Uflash:r:出力されるファイル名.bin:r
こんな感じに出力されればOKです
出力例
avrdude: Version 6.3-20190619
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 "/Users/mac/.avrduderc"
User configuration file does not exist or is not a regular file, skipping
Using Port : /dev/cu.usbmodem14601
Using Programmer : stk500v1
Overriding Baud Rate : 115200
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 : STK500
Description : Atmel STK500 Version 1.x firmware
Hardware Version: 3
Firmware Version: 4.4
Vtarget : 0.3 V
Varef : 0.3 V
Oscillator : 28.800 kHz
SCK period : 3.3 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x000000 (retrying)
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x000000 (retrying)
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x000000
avrdude: Yikes! Invalid device signature.
avrdude: Expected signature for ATmega328P is 1E 95 0F
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: reading flash memory:
Reading | ################################################## | 100% 4.19s
avrdude: writing output file "program.bin"
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: safemode: Fuses OK (E:00, H:00, L:00)
avrdude done. Thank you.
#最後に
以上Arduinoに書き込み済みのバイナリを抽出する方法でした。
次回とその次くらいまではこの抽出したバイナリを用いて別のArduinoに書き込んだり、アセンブリコードを取得してみたりする予定です。
ありがとうございました。
[参考]
https://www.nongnu.org/avrdude/user-manual/avrdude_4.html#Option-Descriptions
https://reverseengineering.stackexchange.com/questions/125/how-do-i-figure-out-what-is-burned-on-an-arduino-rom
↓これを読めば完璧
https://www.cs.ou.edu/~fagg/classes/general/atmel/avrdude.pdf