Ymodem协议
0. 文件传输协议概述
在进行文件传输时,为使文件能被正确识别和传送,需要在两台计算机之间建立统一的传输协议,协议需要包括了文件的识别、传送的起止时间、错误的判断与纠正等内容。常用的文件传输协议有:
- ASCII:传输速度快最快,但只能传送文本文件。
- Xmodem:协议古老悠久,传输速度较慢,采用了CRC校验算法,传输的准确率可高达99.6%;每次传输信息块为128字节。
- Ymodem:Ymodem是Xmodem的改进版,每次传输信息块最大1024字节,速度比Xmodem快;同时还支持传输多个文件。
- Zmodem:Zmodem采用了串流式(streaming)传输方式,传输速度较快,而且还具有自动改变区段大小和断点续传、快速错误侦测等功能。Zmodem目前最流行的文件传输协议。
Ymodem协议用于计算机间传输文件,同样适用于嵌入式领域,如MCU升级固件时,可以使用Ymodem协议传输固件文件,传输总线不限于USB、UART、CAN等。
1. 数据帧类型
名称 | 帧头 | 包号 | 包号反码 | 信息块 | 校验(高位) | 校验(低位) |
---|---|---|---|---|---|---|
简写 | SOH/STX | PN | XPN | DATA | CRC-H | CRC-L |
字节数 | 1 | 1 | 1 | 1024/128 | 1 | 1 |
帧头 | SOH(0x01) | STX(0x02) |
---|---|---|
信息块长度 | 128字节 | 1024字节 |
若不允许回绕Ymodem协议支持最大255KB大小的文件传输
1.1 SOH
以SOH(0x01)开始的数据包,信息块是128字节,该类型帧总长度为128+5(133)字节。
1.2 STX
以STX(0x02)开始的数据包,信息块是1024字节,该类型帧总长度为1024+5(1029)字节
1.3 包号与包反码
-
包头和包反码都是 uint8_t 类型,范围0x00 ~ 0xFF(0~255),每发送一个数据包递增 1,超过 255 后回绕到
-
包反码的计算: 包反码 = 0xFF - 包号。由此可得出包序号校验为 包号 + 包反码 = 0XFF
-
当包号出现错误时,发送NAK要求重传
-
当包号出现非预期值时(期望0x02,但出现0x01),可能出现丢包或乱序,要求重传
1.4 CRC校验
多项式公式: x^16 + x^12 + x^5 + 1 (0x1021)
Ymodem协议的校验码为16位,占两个字节,即CRC16,传输时CRC高八位在前,低八位在后;CRC计算数据为信息块数据,不包含帧头、包号、包号反码。
2. Ymodem起始帧(size == 133byte)
名称 | 帧头 | 包号 | 包号反码 | 文件名 | 文件大小 | 填充区 | 校验(高位) | 校验(低位) |
---|---|---|---|---|---|---|---|---|
简写 | SOH | 0x00 | 0xFF | Filename +0x00 | Filename +0x00 | NULL(0x00) | CRC-H | CRC-L |
其中包号为固定为0;Filename为文件名称,文件名称后必须加0x00作为结束;Filesize为文件大小值,文件大小值后必须加0x00作为结束;余下未满128字节数据区域,则以0x00填充。
例如:
SOH 00 FF "data.bin" NUL "2048" NUL "1630454400" NUL [NUL填充...] CRC16
3. Ymodem数据帧(size == 133byte 1028byte)
名称 | 帧头 | 包号 | 包号反码 | 数据域 | 填充区(文件内容小于帧长度时) | 校验(高位) | 校验(低位) |
---|---|---|---|---|---|---|---|
简写 | SOH/STX | 0x01~0xFF | 0xFF - 包号 | 文件内容 | 0x1A 填充 |
CRC-H | CRC-L |
长度 | 1 | 1 | 1 | 128 or 1024 | 剩余部分 | 1 | 1 |
- 传输有效数据时主要考虑的是最后一包数据的是处理,SOH帧和STX帧有不同的处理。
-
对于SOH帧,若余下数据小于128字节,则以0x1A填充,该帧长度仍为133字节。
-
对于STX帧需考虑几种情况:
- 余下数据 == 1024 字节,以1029长度帧发送;
- 余下数据 < 1024 字节,但 > 128字节,以1029字节帧长度发送,无效数据以0x1A填充。
- 余下数据 == 128 字节,以133字节帧长度发送。
- 余下数据 < 128 字节,以133字节帧长度发送,无效数据以0x1A填充。
4. Ymodem结束帧(size == 133byte)
帧头 | 包号 | 包号反码 | 数据区 | 校验高位 | 校验低位 |
---|---|---|---|---|---|
SOH | 0x00 | 0xFF | 0x00 | 0x00 | 0x00 |
- Ymodem的结束帧采用SOH 133字节长度帧传输,该帧不携带数据(空包),即数据区、校验都以0x00填充。
5. Yomdem握手信号
Ymodem 握手分为三个阶段:
- 接收方 发起 传输请求(YMODEM_C)
- **发送方 **发送 文件头包(起始帧)
- **接收方 **确认 文件头包(ACK/NAK)
示例:
接收方 -> 发送方: 'C'
发送方 -> 接收方: SOH头包(CRC错误)
接收方 -> 发送方: NAK(0x15) // 要求重传
发送方 -> 发送方: 重传SOH头包 接收方 -> 发送方: ACK // 确认成功
Ymodem协议命令表
命令名称 | 命令码(Hex) | 说明 | 备注 |
---|---|---|---|
YMODEM_SOH | 0x01 | 128 字节数据块头 | 数据包总长度 133 字节(SOH + 包号 + 反码 + 128 数据 + 2 字节 CRC) |
YMODEM_STX | 0x02 | 1024 字节数据块头 | 数据包总长度 1029 字节(STX + 包号 + 反码 + 1024 数据 + 2 字节 CRC) |
YMODEM_EOT | 0x04 | 文件传输结束标志 | 发送方发送此字符表示当前文件传输完成,接收方需回复ACK 确认。 |
YMODEM_ACK | 0x06 | 确认响应 | 接收方校验数据包成功后发送,要求发送方继续传输下一包。 |
YMODEM_NAK | 0x15 | 否定确认 / 重传请求 | 接收方检测到数据包错误时发送,要求发送方重传当前包。 |
YMODEM_CAN | 0x18 | 取消传输 | 任意一方发送两次CAN (如0x18 0x18 )终止传输。 |
YMODEM_C | 0x43 | CRC 模式初始化请求 | 接收方发送'C' (ASCII 字符)启动传输,要求使用 CRC-16 校验和 1024 字节块。 |
YMODEM_NUL | 0x00 | 填充字符 / 分隔符 | 用于文件头包中的文件名、大小字段分隔及填充剩余空间。 |
YMODEM_CTRLZ | 0x1A | 数据填充字符 | 数据包不足块大小时,用此字符填充剩余空间(仅限数据帧)。 |
参考链接
Ymodem协议要点 - Acuity - 博客园
Ymodem协议解析-CSDN博客