ArduinoのプログラムをCUIで書き込みしまくる

複数のArduinoやAVR系マイコンに対して毎回書き込みするのめんどくさいなーと思ったので調べてみました。
環境は、MAC OS X(Lion)でやっております。


◆pdeがcppされる瞬間を見る
hoge.pdeの時のコード

#include <IRremote.h>

IRsend irsend;

void setup()
{
  Serial.begin(9600);
}

void loop() {
  Serial.println("send");
  irsend.sendSony(0x1, 12); // Sony TV power code
  delay(1000);
  //irsend.sendNEC(0x1, 12); // Sony TV power code
  //delay(1000);
}


hoge.cppになった時のコード

#include <IRremote.h>

#include "WProgram.h"
void setup();
void loop();
IRsend irsend;

void setup()
{
  Serial.begin(9600);
}

void loop() {
  Serial.println("send");
  irsend.sendSony(0x1, 12); // Sony TV power code
  delay(1000);
  //irsend.sendNEC(0x1, 12); // Sony TV power code
  //delay(1000);


というかんじで、関数の宣言(void setup();とか)を自動で追加してくれている模様。
なるほどなるほど。


コンパイルまでの流れ
Arduino IDEでは、シフトキーを押しながらコンパイルすると、
ログが表示されるという機能があります。
実は最近まで知りませんでした><


で、そのログを見てみる。

/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino -I/Users/yuki/Documents/Arduino/libraries/IRremote /Users/yuki/Desktop/hoge/IRsendDemo2.cpp -o/Users/yuki/Desktop/hoge/IRsendDemo2.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino -I/Users/yuki/Documents/Arduino/libraries/IRremote -I/Users/yuki/Documents/Arduino/libraries/IRremote/utility /Users/yuki/Documents/Arduino/libraries/IRremote/IRremote.cpp -o/Users/yuki/Desktop/hoge/IRremote/IRremote.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/pins_arduino.c -o/Users/yuki/Desktop/hoge/pins_arduino.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/WInterrupts.c -o/Users/yuki/Desktop/hoge/WInterrupts.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/wiring.c -o/Users/yuki/Desktop/hoge/wiring.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/wiring_analog.c -o/Users/yuki/Desktop/hoge/wiring_analog.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/wiring_digital.c -o/Users/yuki/Desktop/hoge/wiring_digital.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/wiring_pulse.c -o/Users/yuki/Desktop/hoge/wiring_pulse.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/wiring_shift.c -o/Users/yuki/Desktop/hoge/wiring_shift.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.cpp -o/Users/yuki/Desktop/hoge/HardwareSerial.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/main.cpp -o/Users/yuki/Desktop/hoge/main.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.cpp -o/Users/yuki/Desktop/hoge/Print.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp -o/Users/yuki/Desktop/hoge/Tone.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/WMath.cpp -o/Users/yuki/Desktop/hoge/WMath.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/WString.cpp -o/Users/yuki/Desktop/hoge/WString.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/pins_arduino.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/WInterrupts.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/wiring.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/wiring_analog.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/wiring_digital.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/wiring_pulse.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/wiring_shift.c.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/HardwareSerial.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/main.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/Print.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/Tone.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/WMath.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-ar rcs /Users/yuki/Desktop/hoge/core.a /Users/yuki/Desktop/hoge/WString.cpp.o
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-gcc -Os -Wl,--gc-sections -mmcu=atmega328p -o /Users/yuki/Desktop/hoge/IRsendDemo2.cpp.elf /Users/yuki/Desktop/hoge/IRsendDemo2.cpp.o /Users/yuki/Desktop/hoge/IRremote/IRremote.cpp.o /Users/yuki/Desktop/hoge/core.a -L/Users/yuki/Desktop/hoge -lm
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 /Users/yuki/Desktop/hoge/IRsendDemo2.cpp.elf /Users/yuki/Desktop/hoge/IRsendDemo2.cpp.eep
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-objcopy -O ihex -R .eeprom /Users/yuki/Desktop/hoge/IRsendDemo2.cpp.elf /Users/yuki/Desktop/hoge/IRsendDemo2.cpp.hex
Binary sketch size: 3280 bytes (of a 32256 byte maximum)

※/Users/yuki/Desktop/hogeは、テンポラリのパスが長かったので置換しました.


こんな感じで、実は意外とスマートでした。
じゃあ、これをマイコンに書き込むにはどうすれば良いかというと、、、、


◆ひたすらマイコンに書き込みまくる
・Duemilanoveの場合

/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/etc/avrdude.conf -v -v -v -v -patmega328p -cstk500v1 -P/dev/tty.usbserial-A9009fW1 -b57600 -D -Uflash:w:/Users/yuki/Desktop/hoge/IRSendDemo2.cpp.hex:i

・Unoの場合

/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/etc/avrdude.conf -v -v -v -v -patmega328p -cstk500v1 -P/dev/tty.usbserial-A9009fW1 -b115200 -D -Uflash:w:/Users/yuki/Desktop/hoge/IRSendDemo2.cpp.hex:i

でいけるます。


◆PCにささっているマイコンにたいして書き込みまくる
さて、ここで本題。
どうやるかというと、手を抜いて僕はこんな感じでやってみました。

perl -e '$cmd="/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/etc/avrdude.conf -v -v -v -v -patmega328p -cstk500v1 -Pusb_port -b115200 -D -Uflash:w:/Users/yuki/Desktop/hoge/IRSendDemo2.cpp.hex:i";$m="/tmp/list.tmp";@lst=();`ls -l /dev/tty.usb* > $m`;open $D,$m;while($l=<$D>){@s=split(/[\s]+/,$l);push(@lst,$s[-1]);}close $D;foreach(@lst){$k=$cmd;$k=~s/usb_port/$_/g;print`$k`;};`rm -rf $m`'

わー、きたなーい。