启动引导¶
如何烧写固件¶
支持以下方式烧写固件:
- 启动的时候,通过UART + YMODEM协议,在线写到app分区
- 启动的时候,将文件系统(U盘/SD卡)中固件程序写到app分区
- 启动的时候,从download分区搬到app分区
基本原理¶
Bootloader基于RTT-Thread开发,使用到以下组件:
- qboot,必须,bootlaoder的核心主程序
- fal,必须,FAL分区管理组件
- ota_downloader,非必须,固件下载组件
- tinycrypt,非必须,固件解密组件
- quicklz,非必须,固件解压组件
- quick_led,非必须,LED指示组件
YMODEM协议¶
Xmodem、Ymodem和Zmodem协议是最常用的三种通信协议。Xmodem协议是最早的,传输128字节信息块。YModem协议是由XModem协议演变而来的,每包数据可以达到1024字节,是一个非常高效的文件传输协议,同时还支持传输多个文件。
平常所说的Ymodem协议是指的Ymodem-1K,除此还有Ymodem-g(没有CRC校验,不常用)。YModem-1K用1024字节信息块传输取代标准的128字节传输,数据的发送回使用CRC校验,保证数据传输的正确性。它每传输一个信息块数据时,就会等待接收端回应ACK信号,接收到回应后,才会继续传输下一个信息块,保证数据已经全部接收。
帧协议¶
Ymodem帧包含,帧头、包号、包反码、数据块和校验,一共133或1029字节。其中SOH表示数据块长度是128字节,STX表示数据块长度1024字节。
SOH/STX SEQ SEQ_NOT DATA[128/1024] CRCH CRCL
序号 | 符号 | 字节 | 取值 | 说明 |
---|---|---|---|---|
1 | SOH/STX | 1 | 0x00/0x01 | 帧头,SOH表示数据块128字节,STX表示数据块1024字节 |
2 | SEQ | 1 | 0x00 | 帧序号,初始是0,依次向下递增 |
3 | SEQ_NOT | 1 | 0xFF | 帧序号的反码,比如帧序号是0x00,则反码为0xFF |
4 | DATA | 128/1024 | 数据块,不够的或者不足的补充0x00 | |
5 | CRCH | 1 | 校验高位,DATA部分CRC16校验码的高8位 | |
6 | CRCL | 1 | 校验低位,DATA部分CRC16校验码的低8位 |
起始帧(128字节)¶
YModem的起始帧并不直接传输文件的数据,而是传输文件名、文件大小、文件修改日期等信息,其中文件名和文件大小信息是必须的,它的帧长=3字节数据首部+128字节数据+2字节CRC16校验码=133字节
,如果数据不足128字节,剩余部分用空字符(0x00)填充
。它的数据结构如下:
SOH 00 FF FILENAME 0x00 FILESIZE 0x00 NUL[N] CRCH CRCL
假设文件名是fw_v1.0.bin,则对应的编码为(注意最后补0x00):
0x66 0x77 0x5f 0x76 0x31 0x2e 0x30 0x2e 0x62 0x69 0x6e
假设文件大小为12568字节,转为十六进制是0x3118,则3188对应ASCII码为(注意最后补0x00):
0x33 0x31 0x31 0x38
文件名fw_v1.0.bin占用11+1个字节,文件大小0x3118占用4+1个字节,因此剩余填充128-(11+1)-(4+1)=111个字节。
数据帧(128或1024字节)¶
YModem的数据帧的数据块大小可以是128字节或者1024字节。
// 128字节的数据块
SOH 01 FE data[128] CRCH CRCL
// 1024字节的数据块
STX 01 FE data[1024] CRCH CRCL
一般会使用1024字节的数据块进行传输,这样可以加快传输速度,但是
- 如果最后剩余的数据在128~1024之前,则还是使用STX的1024字节传输,但是剩余空间全部用0x1A填充;
- 如果最后剩余的数据小于128字节,则YModem会选择SOH数据帧用128字节来传输数据,如果数据不满128字节,剩余的数据用0x1A填充。
结束帧(128字节)¶
当文件传输结束时,除了发送EOT传输结束指令外,还需要发送一个结束帧。YModem的结束帧与起始帧的数据格式相同,数据块大小为128字节,但是结束帧的数据块要全用空字符填充。
SOH 3A C5 NUL[128] CRCH CRCL
传输过程¶
Ymodem传输是由接收端发起的,整个过程如下:
序号 | 发送端 | 方向 | 接收端 | 说明 |
---|---|---|---|---|
1 | <--- | STR_C | 第1次C,请求起始帧 | |
2 | 起始帧 | ---> | ||
3 | <--- | ACK | 应答 | |
4 | <--- | STR_C | 第2次C,请求数据帧 | |
5 | 数据帧1 | ---> | ||
6 | <--- | ACK | 应答 | |
7 | 数据帧2 | ---> | ||
8 | <--- | ACK | 应答 | |
9 | 数据帧N | ---> | 最后一帧数据 | |
10 | <--- | ACK | 应答 | |
11 | EOT | ---> | 发送结束了,不要再发送应答了 | |
13 | <--- | NACK | 好我知道了,不再发送应答了 | |
11 | EOT | ---> | 那你还发个锤子 | |
14 | <--- | STR_C | 第3次C,请求结束帧 | |
15 | 结束帧 | ---> | ||
16 | <--- | ACK | 传输结束,合作愉快 |
传输过程中涉及的符号,取值和含义如下:
符号 | 数值 | 含义 |
---|---|---|
SOH | 0x01 | START OF HEADER,128字节帧头 |
STX | 0x02 | 1024字节帧头 |
EOT | 0x04 | END OF TRANSFER,发送端发送,表示数据块发送完了 |
ACK | 0x06 | ACKNOWLEDGE,接收端发送,每次收到数据都回复ACK |
NAK | 0x15 | 非应答,发送端发送, |
CAN | 0x18 | CANCEL,发送端发送,终止传输 |
STR_C | 0x43 | 字符C,接收端发送,一共3次,第1次请求起始帧,第2次请求数据帧,第3次请求结束帧 |
参考链接¶
YMODEM协议手册:https://github.com/EdgeAI-Lab/JAVA_YMODEM_FOR_STM32_IAP/blob/master/doc/xymodem.pdf