เมื่อคุณรีเซ็ต Uno ที่เรียกใช้ตัวโหลด Optiboot ตัวบูตจะกระพริบที่ 13 ครั้งสามครั้ง
สายบน (สีเทา) ถูกส่งไปยัง Arduino สายกลาง (สีส้ม) จะถูกส่งจาก Arduino
ในขณะที่เกิดขึ้นโปรแกรมที่avrdude
ทำงานบนคอมพิวเตอร์ของคุณกำลังส่งแบบสอบถามไปยังอุปกรณ์:
STK_GET_SYNC / CRC_EOP (0x30/0x20)
Arduino ไม่ได้แจ้งให้ทราบเป็นครั้งแรก "รับการซิงค์" เพราะมันยุ่งขากระพริบที่ 13 เมื่อเสร็จแล้วมันจะสังเกตเห็น "รับการซิงค์" (มันจะถูกบัฟเฟอร์โดยฮาร์ดแวร์อนุกรม) และการตอบกลับ:
STK_INSYNC / STK_OK (0x14/0x10)
ดูเหมือนว่า avrdude จะมีความอดทนเล็กน้อยและหมดเวลาเพราะลองอีกครั้งด้วยข้อความค้นหา "get sync" เวลานี้ Optiboot ตอบสนองทันที
การอัปโหลดที่เหลือจะอธิบายไว้ในภาพถัดไป ตัวอย่างที่ผลิตอัพโหลดโปรแกรม "Blink" หุ้น
(คลิกที่ภาพด้านบนสำหรับรุ่นที่ใหญ่กว่า)
ขั้นตอนคือ:
- คำถาม: รับการซิงค์หรือไม่ ตอบ: อยู่ในซิงค์
- การค้นหา: รับพารามิเตอร์หรือไม่ (รุ่นหลัก) ตอบกลับ: รุ่น 4
- การค้นหา: รับพารามิเตอร์หรือไม่ (รุ่นรอง) ตอบ: รุ่น 4
ตั้งค่าพารามิเตอร์ของอุปกรณ์ พารามิเตอร์อุปกรณ์ต่อไปนี้จะถูกส่งไปยังชิป:
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
เข้าสู่โหมดโปรแกรม ตอบ: อยู่ใน Sync / OK
อ่านลายเซ็น Optiboot ตอบกลับ0x1E 0x95 0x0F
โดยไม่อ่านลายเซ็นจริง
เขียนฟิวส์ (สี่ครั้ง) Optiboot ไม่ได้เขียนฟิวส์แต่เพียงแค่ตอบกลับใน Sync / OK
ที่อยู่โหลด (เริ่มแรก 0x0000) ที่อยู่เป็นคำ (เช่น. คำคือสองไบต์) ชุดนี้จะกำหนดที่อยู่สำหรับการเขียนหน้าข้อมูลถัดไป
หน้าโปรแกรม (ส่งถึง 128 ไบต์) Optiboot ตอบกลับ "In Sync" ทันที จากนั้นจะมีการหยุดประมาณ 4 ms ในขณะที่มันเขียนโปรแกรมหน้าจริง จากนั้นจะตอบกลับว่า "ตกลง"
ที่อยู่โหลด (ตอนนี้ 0x0040) นี่คือที่อยู่ 64 ในทศนิยมเช่น 128 ไบต์จากจุดเริ่มต้นของหน่วยความจำโปรแกรม
หน้าอื่นถูกเขียน ลำดับนี้จะดำเนินต่อไปจนกว่าจะเขียนหน้าทั้งหมด
โหลดที่อยู่ (กลับไปที่ 0x0000) นี่คือการตรวจสอบการเขียน
อ่านหน้า (อ่านได้สูงสุด 128 ไบต์) นี่คือการตรวจสอบ โปรดทราบว่าแม้ว่าการตรวจสอบล้มเหลวข้อมูลที่ไม่ดีได้ถูกเขียนไปยังชิปแล้ว
ออกจากโหมดโปรแกรม
"ไม่ซิงค์กัน" หมายความว่าอย่างไร
ดังที่คุณเห็นจากข้างต้นทุกขั้นตอนผ่านลำดับการเขียนโปรแกรม Arduino คาดว่าจะตอบกลับด้วย "In Sync" (0x14) ตามด้วยข้อมูลบางส่วนตามด้วย "OK" (0x10)
หากเป็น "ไม่ซิงค์" หมายความว่า avrdude ไม่ได้รับการตอบสนอง "ในการซิงค์" สาเหตุที่เป็นไปได้อาจเป็น:
- อัตราการรับส่งข้อมูลผิดที่ใช้
- เลือกพอร์ตอนุกรมผิดใน IDE
- เลือกประเภทบอร์ดผิดใน IDE
- ไม่ได้ติดตั้ง bootloader
- ติดตั้ง bootloader ไม่ถูกต้อง
- บอร์ดไม่ได้กำหนดค่าให้ใช้ bootloader (ในฟิวส์)
- อุปกรณ์บางตัวเสียบเข้ากับพิน D0 และ D1 บน Arduino ซึ่งรบกวนการสื่อสารแบบอนุกรม
- ชิปอินเตอร์เฟส USB (ATmega16U2) ทำงานไม่ถูกต้อง
- ผิดนาฬิกาสำหรับบอร์ด
- การตั้งค่าฟิวส์ผิดบน Atmega328P (เช่น "หารด้วย 8")
- บอร์ด / ชิปเสียหาย
- สาย USB ผิดพลาด (สาย USB บางสายให้พลังงานเท่านั้นและไม่ได้มีไว้สำหรับข้อมูลเช่นสายเคเบิลราคาถูกสำหรับพัดลม USB)
"กำลังซิงค์" คืออะไร
ดังที่ได้กล่าวไว้ข้างต้นการตอบสนอง "In sync" หมายความว่า Arduino (bootloader) ซิงค์กับโปรแกรมอัพโหลด
มีการใช้โปรโตคอลใด
โปรโตคอลนี้เป็นโปรโตคอล STK500 ตามที่จัดทำโดย Atmel ดูการอ้างอิงด้านล่าง
อ้างอิง
หมายเหตุ : STK500 เวอร์ชัน 2 ไม่ได้ใช้ใน Optiboot แต่จะรวมอยู่ในข้อมูลในกรณีที่คุณใช้บอร์ดเช่น Mega2560
ค่าคงที่ STK500
/* 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'