UART 是底层串行传输协议,YMODEM 是建立在 UART 之上的文件传输应用层协议(常用于嵌入式 Bootloader/IAP 固件升级)。下面分两部分详解。


第一部分:UART 协议解析

一、UART 基本概念

UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是一种异步、全双工、串行通信协议。

特性说明
同步方式异步(无独立时钟线,靠约定波特率)
通信方式全双工
线数最少 2 根:TX(发送)+ RX(接收),共地
数据方向TX↔RX 交叉连接

Apply

设备A              设备B
 TX ───────────────► RX
 RX ◄─────────────── TX
 GND ────────────── GND

二、UART 帧格式(核心)

UART 没有时钟线,收发双方必须事先约定相同的波特率,并按固定帧格式收发。

空闲(高) │起始位│ D0 D1 D2 D3 D4 D5 D6 D7 │校验位│停止位│ 空闲(高)
  ─────┐ ┌──────────────────────────────────────┐ ┌────
       └─┘  LSB                            MSB    └─┘
       起始   ←──────── 数据位 ────────→  奇偶  停止
       (低)        (低位先发,LSB first)    校验  (高)

1. 各字段说明

字段位宽说明
空闲态高电平(逻辑 1)
起始位1 bit固定为 低电平 0,标志一帧开始
数据位5~9 bit(常用 8)LSB 先发(低位在前)
校验位0 或 1 bit奇校验/偶校验/无校验
停止位1 / 1.5 / 2 bit固定为高电平 1,标志一帧结束

2. 常见配置表示法

如 "115200 8N1" 表示:

  • 波特率 115200 bps
  • 8 个数据位
  • N = No parity(无校验)
  • 1 个停止位

三、波特率与采样

1. 波特率(Baud Rate)

每秒传输的位数(bps)。常见值:9600、19200、38400、57600、115200

每一位的时间: tbit=1波特率tbit​=波特率1​

例:115200 bps → 每位约 8.68 µs

2. 接收采样机制

接收方通常以 16 倍波特率过采样

  • 检测到起始位下降沿后,延迟半个位时间
  • 在每个数据位的中点采样(最稳定)

起始位下降沿检测 → 等待 0.5 bit → 在每 bit 中央采样
              ↓
SDA  ─┐    ┌─x─┐    ┌─x─┐
      └─x─┘    └─x─┘
       ↑采样点在每位中心

四、UART 数据解析示例

假设接收到一帧,约定 8N1,要传输字符 'A'(ASCII = 0x41 = 二进制 0100_0001):

时序电平含义
空闲1总线空闲
起始位0帧开始
D01bit0(LSB)
D10bit1
D20bit2
D30bit3
D40bit4
D50bit5
D61bit6
D70bit7(MSB)
停止位1帧结束

还原:LSB first,读出顺序 D0→D7 = 1000_0010倒序得 0100_0001 = 0x41 = 'A' ✓

关键:UART 是 LSB 先发,解析时要把采样位序反过来组成字节。


五、UART 常见信号线(含流控)

信号全称作用
TXTransmit发送数据
RXReceive接收数据
RTSRequest To Send请求发送(流控)
CTSClear To Send允许发送(流控)
GNDGround共地(必须)

多数嵌入式应用只用 TX/RX/GND 三线。


六、UART 常见错误

错误原因
帧错误(Framing Error)停止位不是高电平(波特率不匹配)
奇偶校验错误校验位不符
溢出错误(Overrun)接收缓冲未及时读取,新数据覆盖
乱码波特率设置错误是最常见原因


第二部分:YMODEM 协议解析

一、YMODEM 概述

YMODEM 是基于串口(UART)的文件传输协议,是 XMODEM 的增强版,广泛用于嵌入式设备固件升级(Bootloader/IAP)

特性说明
传输介质UART 串口
数据块大小128 字节 或 1024 字节(1K-YMODEM)
校验方式CRC-16
流程控制接收方主动发起(发 'C' 请求)
增强点支持文件名、文件大小传输;支持批量文件

二、YMODEM 关键控制字符

字符值(Hex)含义
SOH0x01数据块开始(128 字节数据块)
STX0x02数据块开始(1024 字节数据块)
EOT0x04传输结束(End of Transmission)
ACK0x06应答(正确接收)
NAK0x15非应答(错误,要求重传)
CAN0x18取消传输
C0x43接收方请求开始('C' 表示用 CRC 校验)

三、YMODEM 数据包格式

┌─────┬──────┬──────────┬──────────────┬─────────┐
│ 包头 │ 包序号│ 包序号反码 │   数据区      │ CRC-16  │
│ 1字节│ 1字节 │  1字节    │ 128/1024字节  │  2字节  │
└─────┴──────┴──────────┴──────────────┴─────────┘
 SOH/STX  SEQ   ~SEQ        Data           CRC
字段字节说明
包头1SOH(0x01)=128字节包 / STX(0x02)=1024字节包
包序号1从 0 开始递增(0,1,2,...,回绕到0)
序号反码1包序号取反(= 255 - SEQ),用于校验
数据区128/1024实际数据,不足填充(常用 0x1A 或 0x00)
CRC-162对数据区做 CRC16-CCITT 校验,高字节在前

四、YMODEM 传输完整流程

YMODEM 分三个阶段:起始帧(文件信息)→ 数据帧 → 结束帧

整体流程图

接收方(R)                          发送方(S)
   │                                  │
   │──────────  'C' ─────────────────►│  请求开始(CRC模式)
   │                                  │
   │◄────── 第0包(文件名+大小) ────────│  起始帧
   │─────────── ACK ─────────────────►│
   │─────────── 'C' ─────────────────►│  请求数据
   │                                  │
   │◄────── 第1包(数据) ──────────────│  数据帧
   │─────────── ACK ─────────────────►│
   │◄────── 第2包(数据) ──────────────│
   │─────────── ACK ─────────────────►│
   │            ......                 │
   │◄────────── EOT ──────────────────│  发送结束
   │─────────── NAK ─────────────────►│  (第一次回NAK)
   │◄────────── EOT ──────────────────│
   │─────────── ACK ─────────────────►│
   │─────────── 'C' ─────────────────►│  请求下一个文件
   │                                  │
   │◄────── 第0包(全0,空文件名) ───────│  结束帧(批次结束)
   │─────────── ACK ─────────────────►│  传输完成

1. 起始帧(第 0 包)—— 文件信息

YMODEM 相比 XMODEM 最大的改进:第 0 包传输文件名和大小

SOH 0x00 0xFF │ 文件名\0 文件大小(ASCII)\0 填充... │ CRC16

数据区内容示例:

"firmware.bin" 0x00 "102400" 0x00 0x00 0x00 ...(填充至128字节)
   文件名      分隔   文件大小   分隔    填充
字段说明
文件名ASCII 字符串,以 \0 结尾
文件大小十进制 ASCII 字符串,以 \0 结尾(如 "102400")
填充剩余字节填 0

接收方据此预先知道文件名和总大小,可分配空间、显示进度。


2. 数据帧(第 1~N 包)

SOH/STX │ SEQ │ ~SEQ │ 数据(128/1024) │ CRC16
  • 包序号从 1 开始递增
  • 每收到一包,接收方校验 CRC 和序号:
    • 正确 → 回 ACK,请求下一包
    • 错误 → 回 NAK,要求重传
  • 最后一包数据不足时,用 0x1A(CTRL-Z) 填充

3. 结束帧

(1) 单个文件结束:EOT

发送方 → EOT(0x04)
接收方 → NAK         (第一次故意回 NAK)
发送方 → EOT(0x04)   (再发一次)
接收方 → ACK         (确认)

双重 EOT 握手是为了可靠确认传输结束。

(2) 批次结束帧(空包)

所有文件传完后,发送方再发一个第 0 包,但文件名为空(全 0)

SOH 0x00 0xFF │ 0x00 0x00 ... 0x00(全0)│ CRC16

接收方回 ACK,整个传输会话结束


五、CRC-16 校验算法

YMODEM 使用 CRC-16/CCITT(多项式 0x1021,初值 0x0000):

uint16_t crc16_ccitt(uint8_t *data, uint16_t len)
{
    uint16_t crc = 0x0000;
    for (uint16_t i = 0; i < len; i++) {
        crc ^= (uint16_t)data[i] << 8;
        for (uint8_t j = 0; j < 8; j++) {
            if (crc & 0x8000)
                crc = (crc << 1) ^ 0x1021;
            else
                crc = crc << 1;
        }
    }
    return crc;
}

CRC 存放在数据包末尾 2 字节,高字节在前(大端)


六、YMODEM 数据包解析示例

假设抓到一个起始帧(传输 app.bin,大小 1024 字节):

偏移字节解析
00x01SOH,128 字节包
10x00包序号 = 0(起始帧)
20xFF序号反码(0xFF = ~0x00)✓
3~961 70 70 2E 62 69 6E"app.bin"
100x00文件名结束符
11~1431 30 32 34"1024"(文件大小 ASCII)
150x00分隔符
16~13000...00填充
131~132xx xxCRC-16

接收方解析后得知:文件名 app.bin,大小 1024 字节,回 ACK + 'C' 开始接收数据。


七、UART 与 YMODEM 的层次关系

┌─────────────────────────────────────┐
│  应用层:YMODEM 文件传输协议           │
│  (数据包、序号、CRC、ACK/NAK、文件名)   │
├─────────────────────────────────────┤
│  物理/链路层:UART                     │
│  (起始位、数据位、校验位、停止位、波特率) │
├─────────────────────────────────────┤
│  硬件:TX / RX / GND 线               │
└─────────────────────────────────────┘

YMODEM 的每个字节(SOH、SEQ、数据、CRC...)都是通过 UART 一帧一帧(8N1)发送出去的。UART 负责"怎么传一个字节",YMODEM 负责"怎么把字节组织成可靠的文件传输"。


八、典型应用:Bootloader 固件升级

嵌入式 IAP 升级流程:

1. 设备上电进入 Bootloader
2. Bootloader 通过 UART 不断发送 'C'
3. PC 端(如 SecureCRT/Xshell)选择 YMODEM 发送固件
4. 设备按 YMODEM 协议接收数据包
5. 每收到一包,CRC 校验通过后写入 Flash
6. 接收完成(结束帧),校验整体,跳转到 App 运行

SecureCRT、Xshell、Tera Term、sb/rb(Linux lrzsz 工具)都支持 YMODEM 发送/接收。


九、UART vs YMODEM 对比总结

维度UARTYMODEM
层次物理/链路层应用层
传输单位1 字节(1 帧)1 数据包(128/1024字节)
可靠性仅奇偶校验CRC-16 + 序号 + ACK/NAK 重传
文件信息支持文件名、大小
流控硬件 RTS/CTSACK/NAK 软件握手
用途通用字节传输文件/固件传输

十、总结

协议一句话总结
UART异步串行,约定波特率,起始位(0)+数据位(LSB先发)+校验位+停止位(1) 构成一帧,负责"可靠地传一个字节"
YMODEM建立在 UART 之上的文件传输协议,起始帧传文件名/大小 → 数据帧(带序号+CRC) → ACK/NAK 重传 → EOT/空帧结束,负责"可靠地传整个文件"

核心关系:YMODEM 是"内容组织者",UART 是"字节搬运工"。固件升级时,YMODEM 把固件切成带校验的数据包,再由 UART 逐字节搬运过去。

Logo

免费领 150 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐