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 帧开始
D0 1 bit0(LSB)
D1 0 bit1
D2 0 bit2
D3 0 bit3
D4 0 bit4
D5 0 bit5
D6 1 bit6
D7 0 bit7(MSB)
停止位 1 帧结束

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

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


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

信号 全称 作用
TX Transmit 发送数据
RX Receive 接收数据
RTS Request To Send 请求发送(流控)
CTS Clear To Send 允许发送(流控)
GND Ground 共地(必须)

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


六、UART 常见错误

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


第二部分:YMODEM 协议解析

一、YMODEM 概述

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

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

二、YMODEM 关键控制字符

字符 值(Hex) 含义
SOH 0x01 数据块开始(128 字节数据块)
STX 0x02 数据块开始(1024 字节数据块)
EOT 0x04 传输结束(End of Transmission)
ACK 0x06 应答(正确接收)
NAK 0x15 非应答(错误,要求重传)
CAN 0x18 取消传输
C 0x43 接收方请求开始('C' 表示用 CRC 校验)

三、YMODEM 数据包格式

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

偏移 字节 解析
0 0x01 SOH,128 字节包
1 0x00 包序号 = 0(起始帧)
2 0xFF 序号反码(0xFF = ~0x00)✓
3~9 61 70 70 2E 62 69 6E "app.bin"
10 0x00 文件名结束符
11~14 31 30 32 34 "1024"(文件大小 ASCII)
15 0x00 分隔符
16~130 00...00 填充
131~132 xx xx CRC-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 对比总结

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

十、总结

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

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

Logo

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

更多推荐