Optibootブートローダーを使用してArduino Unoに新しいスケッチをアップロードすると、どうなりますか?
- Arduinoには何が送られますか?
- どのように応答しますか?
- 「同期していない」とはどういう意味ですか?
- とにかく「同期」とは何ですか?
注:これは「参照質問」として意図されています。
Optibootブートローダーを使用してArduino Unoに新しいスケッチをアップロードすると、どうなりますか?
注:これは「参照質問」として意図されています。
回答:
Optibootローダーを実行しているUnoをリセットすると、ブートローダーは最初にピン13を3回点滅させます。
一番上の行(灰色)はArduinoに送信され、中間の行(オレンジ)はArduino から送信されます。
その間avrdude
、コンピューターで実行されているプログラムはデバイスにクエリを送信しています。
STK_GET_SYNC / CRC_EOP (0x30/0x20)
Arduinoはピン13の点滅でビジー状態であるため、最初の「同期の取得」に気付かない
STK_INSYNC / STK_OK (0x14/0x10)
avrdudeが「get sync」クエリで再試行するため、少しイライラしてタイムアウトになったようです。今回はOptibootがすぐに応答します。
アップロードの残りの部分は、次の画像で説明されています。例では、ストック「Blink」プログラムのアップロードを作成しました。
(拡大版については上の画像をクリックしてください)
手順は次のとおりです。
デバイスパラメータを設定します。次のデバイスパラメータがチップに送信されます。
0x42 // STK_SET_DEVICE
0x86 // device code
0x00 // revision
0x00 // progtype: “0” – Both Parallel/High-voltage and Serial mode
0x01 // parmode: “1” – Full parallel interface
0x01 // polling: “1” – Polling may be used
0x01 // selftimed: “1” – Self timed
0x01 // lockbytes: Number of Lock bytes.
0x03 // fusebytes: Number of Fuse bytes
0xFF // flashpollval1
0xFF // flashpollval2
0xFF // eeprompollval1
0xFF // eeprompollval2
0x00 // pagesizehigh
0x80 // pagesizelow
0x04 // eepromsizehigh
0x00 // eepromsizelow
0x00 // flashsize4
0x00 // flashsize3
0x80 // flashsize2
0x00 // flashsize1
0x20 // Sync_CRC_EOP
Optiboot はこれらすべてを無視し、In Sync / OKで応答します。:)
拡張デバイスパラメータを設定します。
0x45 // STK_SET_DEVICE_EXT
0x05 // commandsize: how many bytes follow
0x04 // eeprompagesize: EEPROM page size in bytes.
0xD7 // signalpagel:
0xC2 // signalbs2:
0x00 // ResetDisable: Defines whether a part has RSTDSBL Fuse
0x20 // Sync_CRC_EOP
Optiboot はこれらもすべて無視し、In Sync / OKで応答します。
プログラムモードに入ります。返信:同期/ OK。
署名を読み取ります。Optibootは0x1E 0x95 0x0F
、実際に署名を読み取らずに応答します。
ヒューズを書き込みます(4回)。Optiboot はヒューズを書き込みません In Sync / OKで応答します。
ロードアドレス(最初は0x0000)。アドレスはワード単位です(つまり、ワードは2バイトです)。これにより、データの次のページが書き込まれるアドレスが設定されます。
プログラムページ(最大128バイトが送信されます)。Optibootはすぐに「In Sync」と応答します。その後、実際にページをプログラムしている間、約4ミリ秒の休止があります。その後、「OK」と応答します。
ロードアドレス(現在は0x0040)。これは、10進数のアドレス64です。プログラムメモリの先頭から128バイト。
別のページが作成されます。このシーケンスは、すべてのページが書き込まれるまで続きます。
アドレスをロードします(0x0000に戻ります)。これは、書き込みを検証するためのものです。
読み取りページ(最大128バイトが読み取られます)。これは検証用です。検証が失敗した場合でも、不良データはすでにチップに書き込まれていることに注意してください。
プログラミングモードを終了します。
上記からわかるように、Arduinoはプログラミングシーケンスのすべてのステップで「In Sync」(0x14)で応答し、場合によってはデータの後に「OK」(0x10)が続きます。
「同期していない」場合、avrdudeは「同期」応答を取得していません。考えられる理由は次のとおりです。
前述のように、「同期」という応答は、Arduino(ブートローダー)がアップロードプログラムと同期していることを意味します。
プロトコルは、Atmelによって文書化されているSTK500プロトコルです。以下の参考文献を参照してください。
注:STK500バージョン2はOptibootでは使用されませんが、Mega2560などのボードを使用している場合の情報用に含まれています。
/* STK500 constants list, from AVRDUDE */
#define STK_OK 0x10
#define STK_FAILED 0x11 // Not used
#define STK_UNKNOWN 0x12 // Not used
#define STK_NODEVICE 0x13 // Not used
#define STK_INSYNC 0x14 // ' '
#define STK_NOSYNC 0x15 // Not used
#define ADC_CHANNEL_ERROR 0x16 // Not used
#define ADC_MEASURE_OK 0x17 // Not used
#define PWM_CHANNEL_ERROR 0x18 // Not used
#define PWM_ADJUST_OK 0x19 // Not used
#define CRC_EOP 0x20 // 'SPACE'
#define STK_GET_SYNC 0x30 // '0'
#define STK_GET_SIGN_ON 0x31 // '1'
#define STK_SET_PARAMETER 0x40 // '@'
#define STK_GET_PARAMETER 0x41 // 'A'
#define STK_SET_DEVICE 0x42 // 'B'
#define STK_SET_DEVICE_EXT 0x45 // 'E'
#define STK_ENTER_PROGMODE 0x50 // 'P'
#define STK_LEAVE_PROGMODE 0x51 // 'Q'
#define STK_CHIP_ERASE 0x52 // 'R'
#define STK_CHECK_AUTOINC 0x53 // 'S'
#define STK_LOAD_ADDRESS 0x55 // 'U'
#define STK_UNIVERSAL 0x56 // 'V'
#define STK_PROG_FLASH 0x60 // '`'
#define STK_PROG_DATA 0x61 // 'a'
#define STK_PROG_FUSE 0x62 // 'b'
#define STK_PROG_LOCK 0x63 // 'c'
#define STK_PROG_PAGE 0x64 // 'd'
#define STK_PROG_FUSE_EXT 0x65 // 'e'
#define STK_READ_FLASH 0x70 // 'p'
#define STK_READ_DATA 0x71 // 'q'
#define STK_READ_FUSE 0x72 // 'r'
#define STK_READ_LOCK 0x73 // 's'
#define STK_READ_PAGE 0x74 // 't'
#define STK_READ_SIGN 0x75 // 'u'
#define STK_READ_OSCCAL 0x76 // 'v'
#define STK_READ_FUSE_EXT 0x77 // 'w'
#define STK_READ_OSCCAL_EXT 0x78 // 'x'
avrdude
のデフォルトの検証動作をサポートするブートローダーは、フラッシュコンテンツの読み取りをサポートするブートローダーです。