Ymodem 协议固件升级(上)
扫描二维码
随时随地手机看文章
Ymodem 协议作为 Xmodem 协议家族的增强版,是嵌入式设备通过串口(UART/RS232/RS485)实现固件升级的经典方案,其核心定位是 “低成本、高可靠的串行数据传输协议”,尤其适用于无网络模块(如 ENC28J60)、资源极度受限(如 8 位 MCU、KB 级 RAM)或工业场景中依赖串口通信的设备 —— 例如老旧工业 PLC、STM32F103 嵌入式开发板、智能仪表等,这些设备往往无法支持 HTTP OTA 的网络传输,却可通过 Ymodem 利用现有串口链路完成固件更新。相较于 Xmodem 的单包 128 字节传输与简单校验,Ymodem 在保留 “帧结构清晰、实现轻量化” 优势的基础上,新增了文件信息预传输、1024 字节大数据包支持、双向握手重传机制及文件完整性校验,既能提升大固件(如 512KB~2MB)的传输效率,又能通过多重校验避免固件传输错误导致的设备 “变砖”,成为嵌入式领域串口升级的 “标配协议”。
Ymodem 协议的帧结构是其实现可靠传输的基础,采用 “固定帧头 + 可变数据 + 强校验” 的设计,确保每帧数据在串口噪声干扰下仍能被正确解析。完整的 Ymodem 帧分为两种核心类型:用于数据传输的 “数据帧” 与用于控制交互的 “控制帧”。数据帧的结构固定为 “起始符(1 字节)+ 帧序号(1 字节)+ 帧序号反码(1 字节)+ 数据段(128/1024 字节)+ 校验字段(2 字节 CRC16 或 4 字节 CRC32)”:起始符(SOH=0x01)对应 128 字节数据段,起始符(STX=0x02)对应 1024 字节数据段,后者在大固件升级中可将传输帧数减少 75%,大幅提升效率;帧序号从 0x00 开始递增,帧序号反码为 0xFF 与帧序号的异或值(如帧序号 0x01 的反码为 0xFE),用于接收端验证帧的连续性,避免帧丢失或乱序;校验字段默认采用 CRC16-CCITT(多项式 0x1021),工业高干扰场景可升级为 CRC32,进一步降低误码率。控制帧则用于升级流程中的交互,包括 “文件信息帧(C 帧,0x43)”—— 用于传输固件文件名、大小等元数据;“结束帧(EOT,0x04)”—— 标识固件数据传输完成;“确认帧(ACK,0x06)” 与 “否定帧(NACK,0x15)”—— 接收端对每帧数据的校验结果反馈,构成双向握手的基础。
Ymodem 固件升级的完整流程需设备端 Bootloader 与上位机(如 PC 端串口助手、工业控制软件)协同,遵循 “初始化 - 协商 - 数据传输 - 校验 - 重启” 的闭环逻辑,每个环节均设计容错机制以应对串口传输风险。首先是 “升级初始化” 阶段:设备上电后,Bootloader 先检测升级触发条件(如特定引脚电平拉低、串口收到 “进入升级模式” 指令 0x11),若满足则进入 Ymodem 接收模式,初始化串口参数(波特率通常为 9600~115200bps,需与上位机一致,数据位 8、停止位 1、无校验),并向上位机发送 “等待文件信息” 信号(通常是连续的 NACK 帧,提示上位机开始传输);上位机收到信号后,准备固件文件(需预先转换为二进制格式,避免文本编码干扰),并构建 Ymodem 文件信息帧(C 帧),包含固件名(如 “firmware_v1.2.bin”)、文件大小(如 “524288”,单位字节)及 CRC 校验值,通过串口发送至设备端。
进入 “文件信息协商” 阶段后,设备端 Bootloader 接收 C 帧并解析固件元数据,验证文件大小是否匹配 Flash 预留的应用分区(如 STM32F103 的应用分区大小为 512KB,需确保固件大小≤512KB),若匹配则发送 ACK 帧确认,上位机收到 ACK 后开始准备数据分块传输;若不匹配(如固件过大),则发送 NACK 帧并重启协商流程,避免 Flash 写入溢出。随后进入核心的 “数据分块传输” 阶段:上位机将固件按 1024 字节(或 128 字节)分块,为每块构建 Ymodem 数据帧(STX 帧),帧序号从 0x00 开始递增,每发送一帧后等待设备端反馈;设备端 Bootloader 接收数据帧后,先验证帧序号连续性(如当前应接收 0x01 帧,若收到 0x03 帧则判定帧丢失),再计算数据段的 CRC 值与帧尾校验字段比对,双重验证通过后,将数据块写入 Flash 应用分区(通过 STM32 的 HAL_FLASH_Program 接口实现),并发送 ACK 帧请求下一块;若校验失败或帧序号异常,设备端发送 NACK 帧,上位机收到后立即重传该帧,重传次数通常设为 3 次,若 3 次均失败则终止升级,避免无限重试导致的资源浪费。





