4. 通信接口选型与协议设计
Bootloader 的升级能力,首先取决于它“从哪条路收数据”。STM32 常见的六种接口在升级场景下的差异,不只是速率高低,更体现在拓扑、寻址方式、是否需要外部收发器、是否支持多节点、以及协议栈复杂度上。选型时先问三个问题:升级通道是点对点还是总线?设备是否已经引出该接口?现场是否允许拆机接线?回答清楚后,接口基本就确定了。
UART 是最常用的兜底通道。它异步、点对点、无需时钟线,只要 TX/RX/GND 三根线即可工作,配合 RS-485 收发器还能变成半双工总线。缺点是速率受波特率和线缆长度制约,且没有硬件寻址,多设备需要靠软件地址区分。I2C 是两线同步总线,SCL/SDA 加上拉电阻即可挂多个从机,适合板内升级,但总线电容限制线长,且从机不能主动发起传输,必须由主机轮询。SPI 是四线全双工同步接口,速率可达数十 Mbps,适合板内高速传输,但每增加一个从机就多一根片选线,且没有应答机制,可靠性依赖协议层保证。CAN 是差分总线,抗干扰强、支持多主和多节点仲裁,天然适合车载与工业现场,但需要收发器,且单帧有效载荷只有 8 字节(CAN FD 可到 64 字节),大文件必须分帧。USB 速率高、可热插拔,STM32 常用 DFU 或 CDC 类,但主机端需要驱动或 DFU 工具,且协议栈较重。Ethernet 适合带 MAC 的高端型号,可走 TFTP、HTTP 或自定义 UDP,吞吐最高,但需要 PHY、网络参数配置和较完整的 TCP/IP 栈。
接口确定后,真正决定升级成败的是协议帧格式。一个健壮的自定义升级协议帧通常由五段组成:帧头、命令字、长度、数据域、校验。帧头用于接收端从字节流中定位帧起点,常用两个固定字节,例如 0xAA 0x55;命令字区分握手、擦除、写数据、校验、跳转等操作;长度字段说明数据域字节数,接收端据此判断何时收完;数据域承载实际载荷,如地址、固件数据块;校验字段用于验证整帧完整性。下面给出一个可直接参考的帧结构示例,采用小端序,长度字段为 2 字节,校验采用 CRC16-CCITT。
帧格式(共 8+N 字节):
偏移 字段 长度 说明
0 帧头1 1B 0xAA
1 帧头2 1B 0x55
2 命令字 1B 0x01握手 0x02擦除 0x03写数据 0x04校验 0x05跳转
3 长度L 2B 数据域字节数 N(小端)
5 数据域 N B 命令相关载荷
5+N 校验H 1B CRC16 高字节
6+N 校验L 1B CRC16 低字节
示例:写数据命令,地址 0x08008000,数据 4 字节 DE AD BE EF
AA 55 03 07 00 00 80 08 00 DE AD BE EF [CRC_H] [CRC_L]
其中长度=7(4字节地址+3字节数据?此处按实际载荷调整),
实际工程中建议数据域固定为“4字节地址 + 最多256字节数据”,
长度字段 = 4 + 实际数据字节数。
校验与重传是升级可靠性的两道防线。校验分两级:帧内 CRC 用于发现单帧传输错误,整包校验(如固件全部字节的 CRC32 或 SHA-256)用于确认整个镜像完整。接收端每收到一帧先算 CRC16,与帧尾比对,不一致则丢弃并请求重传;全部数据写完后,再对 Flash 中读回的内容计算整包校验,与发送端提供的期望值比对,一致才允许跳转。重传机制通常采用“发送—等待确认”的停等协议:发送方发出数据帧后启动超时定时器,接收方校验通过则回 ACK,校验失败或超时则回 NAK 或直接不响应,发送方重发该帧。超时时间要大于“帧传输时间 + 接收处理时间 + 应答传输时间”,例如 115200 bps 下传 260 字节约需 23 ms,加上处理与应答,超时可设 100~200 ms。重传次数建议限制在 3~5 次,超过则终止升级并上报错误码,避免在链路已断的情况下无限等待。
把接口、帧格式、校验重传三者串起来看:UART 适合作为默认升级通道,协议简单、现场易接入;SPI 适合板内高速搬运;CAN 适合多节点远程维护;USB 和 Ethernet 适合有主机或网络条件的场景。无论选哪种,帧格式都应保持“帧头可定位、长度可界定、校验可验证、命令可扩展”这四条底线,重传策略则根据链路质量在停等与滑动窗口之间取舍。这样设计出的 Bootloader 升级协议,才能在换接口、换速率、换现场条件时仍然稳定工作。