http://electronics.stackexchange.com/questions/2603/i-dont-get-the-arduino-concept
ブートローダはあらかじめ書き込まれているファームウェア。
ArduinoではISP経由ではなく、シリアル(UART)経由でHEXを受け取り
AVRのSelf programming機能を使ってブートローダが受け取ったコードを
Flashに書き込んでいる。
※1. 送信しているHEX自体はbootloaderを使わずに単体でも動作するコード)
※2. ということはArduino IDEを使って開発したコードは(シリアルではなくSPI経由で)
AVR ISP mkIIでも転送できるということになる
転送プロトコルはSTK500を使っている。
http://forum.arduino.cc/index.php?topic=125226.0
STK500プロトコルの詳細
http://www.atmel.com/Images/doc2525.pdf
動作はoptiboot.cを読むとわかると書いてある。
optiboot
https://code.google.com/p/optiboot/
のぞいてみるとSTK500プロトコルを使っていることがわかる。
optiboot.c
宣言されている関数プロトタイプ
int main(void) __attribute__ ((OS_main)) __attribute__ ((section (".init9"))); void putch(char); uint8_t getch(void); static inline void getNch(uint8_t); /* "static inline" is a compiler hint to reduce code size */ void verifySpace(); static inline void flash_led(uint8_t); uint8_t getLen(); static inline void watchdogReset(); void watchdogConfig(uint8_t x); #ifdef SOFT_UART void uartDelay() __attribute__ ((naked)); #endif void appStart(uint8_t rstFlags) __attribute__ ((naked));
メイン関数
int main(void) { uint8_t ch; register uint16_t address = 0; register uint8_t length; asm volatile ("clr __zero_reg__"); #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) SP=RAMEND; // This is done by hardware reset #endif ch = MCUSR; MCUSR = 0; if (!(ch & _BV(EXTRF))) appStart(ch); //External Reset Flagがたったら再起動? ..........(中略) /* Forever loop */ for (;;) { /* get character from UART */ ch = getch(); //Arduino IDEからシリアルデータを受信 受信コマンドによって処理を分ける if(ch == STK_GET_PARAMETER) { unsigned char which = getch(); verifySpace(); if (which == 0x82) { /* * Send optiboot version as "minor SW version" */ putch(OPTIBOOT_MINVER); } else if (which == 0x81) { putch(OPTIBOOT_MAJVER); } else { /* * GET PARAMETER returns a generic 0x03 reply for * other parameters - enough to keep Avrdude happy */ putch(0x03); } } (以下略)