当我使用Optiboot引导加载程序将新草图上传到Arduino Uno时,真正发生了什么?
- 什么被发送到Arduino?
- 它如何反应?
- “不同步”是什么意思?
- 什么是“同步”?
注意:这旨在作为“参考问题”。
当我使用Optiboot引导加载程序将新草图上传到Arduino Uno时,真正发生了什么?
注意:这旨在作为“参考问题”。
Answers:
当您重置运行Optiboot加载程序的Uno时,引导加载程序首先将13针闪烁3次。
顶线(灰色)发送到 Arduino,中线(橙色)发送到 Arduino。
发生这种情况时,avrdude
计算机上运行的程序正在向设备发送查询:
STK_GET_SYNC / CRC_EOP (0x30/0x20)
Arduino没有注意到第一个“获取同步”,因为它正在忙于闪烁引脚13。完成后,它会注意到“获取同步”(它将由串行硬件缓冲)并回复:
STK_INSYNC / STK_OK (0x14/0x10)
似乎avrdude有点急躁,并已超时,因为它再次尝试使用“获取同步”查询。这次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将忽略所有这些内容,并通过“同步中/确定”进行答复。:)
设置扩展设备参数:
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也将忽略所有这些内容,并通过“同步中/确定”进行答复。
进入程序模式。回复:在同步/确定中。
阅读签名。Optiboot答复时0x1E 0x95 0x0F
并未实际读取签名。
写保险丝(四次)。Optiboot 不写保险丝,而只是在同步/正常情况下回复。
加载地址(最初为0x0000)。地址以字为单位(即,一个字是两个字节)。这设置了下一页数据将写入的地址。
程序页(最多发送128个字节)。Optiboot立即回复“同步中”。然后在实际编程页面时会有大约4 ms的暂停。然后它回答“确定”。
加载地址(现在为0x0040)。这是十进制的地址64,即。从程序存储器的开始起128个字节。
写入另一页。此顺序一直持续到写入所有页面为止。
加载地址(返回0x0000)。这是为了验证写入。
读取页(最多读取128个字节)。这是用于验证。请注意,即使验证失败,不良数据也已经被写入芯片。
退出编程模式。
从上面可以看到,在编程过程的每一步中,Arduino都将以“同步中”(0x14)进行响应,可能还会跟一些数据,然后是“ OK”(0x10)。
如果不是“同步”,则表示avrdude没有得到“同步”响应。可能的原因可能是:
如上所述,响应“同步”表示Arduino(引导加载程序)与上传程序同步。
该协议是Atmel记录的STK500协议。请参阅下面的参考。
注意:Optiboot中未使用STK500第2版,但如果您使用的是Mega2560之类的板卡,则包含在STK500版本2中以供参考。
/* 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
的默认验证行为的引导程序都是支持读取闪存内容的引导程序。