3. 通信协议基础

Bootloader 的通信协议并不是“把数据从 A 发到 B”这么简单。它要在有限的硬件资源、不可靠的物理链路和严格的升级时序之间建立一套可预测的规则。理解协议分层、串行通信原理、帧结构、同步/异步方式以及差错控制,是设计可靠 Bootloader 通信协议的五块基石。

一、协议分层模型:把复杂问题切成可管理的层

Bootloader 通信协议通常借鉴 OSI 的分层思想,但会大幅简化。典型的分层如下:

  • 物理层:定义电气特性,如 UART 的 TTL/RS-232/RS-485 电平、CAN 的差分信号、SPI 的时钟极性。
  • 数据链路层:负责帧定界、字节填充、校验和重传,保证相邻节点之间无差错地传输帧。
  • 传输/会话层:管理命令-响应配对、超时重试、序号与确认,保证升级数据按序到达。
  • 应用层:定义具体命令,如擦除 Flash、写入数据、校验固件、跳转执行。

分层的价值在于:更换物理介质(UART 换 CAN)时,只需替换物理层和部分链路层,上层命令语义保持不变。Bootloader 协议设计中最常见的错误是把所有逻辑塞进一个“大函数”,导致换一个波特率或加一个校验就要重写全部代码。

分层原则:下层为上层提供服务,上层不关心下层的实现细节。Bootloader 中,应用层只调用“发送一帧并等待 ACK”,而不直接操作 UART 寄存器。

二、串行通信原理:一位一位地传

串行通信把并行数据按时间顺序逐位发送。以 UART 为例,发送端把 8 位数据加上起始位、校验位、停止位组成一个字符帧,接收端通过检测起始位下降沿来同步采样。关键参数包括波特率、数据位、停止位和校验位,双方必须完全一致。

波特率误差是常见故障源。若发送端与接收端时钟偏差超过约 2%~3%,采样点会逐渐偏移,导致误码。Bootloader 中常用 115200、460800 甚至 921600 bps,高波特率对时钟精度要求更高。CAN 则采用位填充和差分信号,抗干扰能力更强,适合车载 Bootloader。

三、帧结构:协议的“集装箱”

帧是链路层传输的基本单位。一个典型的 Bootloader 帧包含:帧头、长度、命令/地址、数据、校验和帧尾。帧头用于接收端快速定位帧起点,长度字段决定后续读取多少字节,校验字段用于检错。

帧格式示例(UART Bootloader):
+--------+--------+--------+--------+----------+--------+
| 帧头   | 长度   | 命令   | 序号   | 数据     | CRC16  |
| 0xAA55 | 1 Byte | 1 Byte | 1 Byte | N Bytes  | 2 Byte |
+--------+--------+--------+--------+----------+--------+

帧设计要避免“帧头出现在数据中”造成误同步。常用方法有:字节填充(转义)、固定长度、或使用带长度字段的 TLV 结构。Bootloader 升级数据量大,帧长通常取 128~1024 字节,兼顾效率和 RAM 占用。

四、同步与异步通信:时钟从哪来

同步通信中,收发双方共享时钟信号(如 SPI、I2C),数据位与时钟边沿对齐,传输效率高,适合板内 Bootloader 与外部 Flash 通信。异步通信没有共享时钟,依靠起始位和约定的波特率采样(如 UART),硬件简单但效率略低。

Bootloader 场景中,UART 异步通信最常用,因为 PC 端工具链成熟;SPI 同步通信多用于 MCU 与外部存储之间的固件搬运;CAN 则介于两者之间,通过位同步机制实现多节点通信。

五、差错控制基础:让错误可发现、可恢复

差错控制包括检错和纠错。Bootloader 中最常用的是检错加重传:

  • 奇偶校验:每字节加 1 位,只能发现奇数个位错误,能力弱。
  • 校验和:累加求和,实现简单,但无法发现字节顺序错误。
  • CRC16/CRC32:检错能力强,是 Bootloader 帧校验和整包校验的首选。
  • 序号与 ACK:接收端确认正确帧,发送端超时重传,解决丢帧问题。

整包校验通常在固件全部传输完成后进行,例如对整段 Flash 计算 CRC32,与协议中携带的期望值比对,一致才跳转执行。这能防止“帧都正确但整体被篡改或写入错误”的情况。

六、案例:一次 UART Bootloader 升级的完整数据流

下面用一张信号链/数据流图展示从 PC 到 MCU 的升级过程,涵盖握手、擦除、传输、校验和跳转五个阶段。

UART Bootloader 升级数据流 PC 上位机 升级工具 固件 .bin CRC32 计算 帧封装 超时重传 UART 115200 8N1 MCU Bootloader 帧解析 / CRC 校验 命令分发 Flash 擦除 数据写入 整包 CRC 比对 跳转 App 片内 Flash Bootloader 区 App 区 参数/标志区 CRC 存储区 ACK / NAK 响应 ① 握手 ② 擦除 ③ 传输 ④ 校验 ⑤ 跳转

该数据流中,PC 端负责封装帧并维护重传队列,MCU 端负责解析、校验和写入 Flash。ACK/NAK 构成闭环,确保每一帧都被确认。整包 CRC 比对通过后,Bootloader 修改启动标志并复位跳转到 App。

七、常见误区与复盘

误区 后果 改进措施
只用校验和,不用 CRC 突发错误漏检率高 帧校验用 CRC16,整包用 CRC32
没有序号和重传 丢帧后固件不完整 加入帧序号、ACK 和超时重传
帧头与数据冲突 接收端误同步 使用长度字段或字节填充
波特率误差过大 高波特率下误码率上升 校准时钟,误差控制在 2% 以内
擦除与写入无超时 Flash 忙时阻塞通信 加入超时和忙等待状态机
复盘建议:在协议设计阶段先用示波器或逻辑分析仪抓取实际波形,确认起始位、停止位和采样点位置;再用脚本模拟丢帧、错帧和超时,验证 Bootloader 的重传与恢复逻辑。
注意:Bootloader 通信协议一旦发布,升级工具和固件端必须严格版本匹配。帧格式、命令码和 CRC 算法任何一处变更,都要同步更新双方,否则会出现“能握手但无法升级”的隐蔽故障。