二、修改了负载启动的顺序,先开启辅助继电器使地相通,再开启D+D-继电器 feat: 发布V1.1.23版本,优化负载初始化继电器时序 - 更新所有头文件版本号至V1.1.21~V1.1.23,协议板固件版本更新为0x0127 - 新增纹波滤波相关宏定义与函数,实现继电器闭合后纹波过滤 - 调整负载初始化流程:先下发辅助继电器,等待回码后延迟30ms再打开北向继电器 - 优化D+/D-寄存器上位机显示单位,适配0.001V解析格式 - 补充YMODEM升级文档说明,完善传输校验与重发规则 - 清理冗余调试打印与Allegro工程日志文件
214 lines
9.4 KiB
Markdown
214 lines
9.4 KiB
Markdown
# 协议板 Boot:YMODEM 上位机实现规则
|
||
|
||
## 1. 适用范围
|
||
|
||
本文适用于 **PC 上位机通过 USART1 直连协议板 Boot**,传输协议为 YMODEM + CRC16。
|
||
|
||
不适用于“协议板 App 通过南向 Modbus `0x20` 转发功率板 Boot”的链路;该链路的报文封装、应答和状态机需要独立实现。
|
||
|
||
## 2. 基本要求
|
||
|
||
| 项目 | 规则 |
|
||
| --- | --- |
|
||
| 串口 | USART1,115200 bps,8N1,无校验、无流控 |
|
||
| 升级文件 | 必须发送已由现有打包工具生成的完整 `.upk` 文件 |
|
||
| 不支持的文件 | 裸 `.bin`,以及自行封装/加密但不符合工程 UPK 格式的文件 |
|
||
| 启动依据 | 等待 Boot 发出 ASCII `C`(`0x43`)后再开始传输 |
|
||
| Boot 上电等待 | 首次等待主机开始约 5 秒;超时后可能跳转 App |
|
||
| 传输中的帧间等待 | Boot 约 10 秒;上位机不得使相邻有效帧间隔达到 10 秒 |
|
||
| 单帧发送方式 | 一个完整 YMODEM 帧必须连续写入串口;不得把同一帧拆开并在中间产生明显空闲间隔 |
|
||
|
||
Boot 每约 1 秒发送一次 `C`。若没有收到 `C`,上位机不可直接发送 YMODEM 首帧;应提示设备未进入 Boot,或重新复位/触发其进入 Boot。Boot 的接收层按 UART 收帧处理,不会为上位机重组被空闲间隔拆断的 YMODEM 包。
|
||
|
||
## 3. YMODEM 常量与帧格式
|
||
|
||
| 名称 | 值 | 含义 |
|
||
| --- | --- | --- |
|
||
| SOH | `0x01` | 128 字节数据包 |
|
||
| STX | `0x02` | 1024 字节数据包 |
|
||
| EOT | `0x04` | 数据结束 |
|
||
| ACK | `0x06` | 接收成功 |
|
||
| NAK | `0x15` | 接收失败/请求重发 |
|
||
| CAN | `0x18` | 取消传输 |
|
||
| C | `0x43` | 请求以 CRC16 模式发送 |
|
||
|
||
数据包格式:
|
||
|
||
```text
|
||
Header + PacketNo + (~PacketNo) + Data + CRC16_H + CRC16_L
|
||
```
|
||
|
||
| 包类型 | Data 长度 | 总长度 |
|
||
| --- | ---: | ---: |
|
||
| SOH | 128 | 133 |
|
||
| STX | 1024 | 1029 |
|
||
|
||
CRC 算法必须为 **CRC-16/XMODEM**:
|
||
|
||
```text
|
||
poly=0x1021, init=0x0000, RefIn=false, RefOut=false, XorOut=0x0000
|
||
```
|
||
|
||
CRC 覆盖 `Data` 的全部固定长度字节(128 或 1024),并按 **高字节、低字节** 放在帧尾。
|
||
|
||
## 4. 包序号与数据填充
|
||
|
||
1. 元数据包必须使用 `SOH`,`PacketNo=0x00`,反码为 `0xFF`。
|
||
2. 首个文件数据包使用 `PacketNo=0x01`;每得到 ACK 后序号加 1,按 8 位自然回绕。
|
||
3. 本 Boot 的 `.upk` 使用 1K 首数据块布局,因此文件数据包必须使用 `STX`(1024 字节);最后一包不足 1024 字节时仍应补齐到 1024 字节,建议补 `0x1A`。
|
||
4. Boot 校验包号、包号反码、帧长度与 CRC。任一校验失败会立即回复 NAK;当前 Boot 随后会重置 YMODEM 包号和流程。
|
||
5. 对于业务层处理失败产生的 NAK,可以重发**原完整帧**,包号不得递增。对于 CRC、包号或帧长度错误产生的 NAK,不能只重发当前帧,必须重新进入 Boot 并从元数据包开始完整传输。
|
||
|
||
## 5. 元数据包规则
|
||
|
||
第一个包固定是包号 0 的 SOH 包,128 字节 Data 的内容为:
|
||
|
||
```text
|
||
ASCII 文件名 + 0x00 + ASCII 十进制文件大小 + 0x00 + 其余补 0x00
|
||
```
|
||
|
||
示例(文件名仅用于协议描述,实际可使用真实 `.upk` 文件名):
|
||
|
||
```text
|
||
protocol_v1.2.upk\0 123456\0 [其余填 0]
|
||
```
|
||
|
||
文件大小必须是待传输 `.upk` 的实际字节数。传输结束包也是 SOH/包号 0,但其 128 字节 Data 必须全部为 `0x00`。
|
||
|
||
## 6. `.upk` 文件要求
|
||
|
||
Boot 在接收数据后按 UPK 格式处理,而不是把它当作裸固件。
|
||
|
||
- 头部标识必须为 `UPK_IDENTIFIER=0x006B7075`(`"upk"`)。
|
||
- UPK 逻辑头为 1 字节对齐、总计 96 字节,包含版本、目标分区、原始/包体大小、CRC 等字段。
|
||
- 工程启用了 AES-256-CBC 解密组件,但不强制加密;`config[1]=0` 的未加密包和 `config[1]=1` 的 AES-256-CBC 包均可被当前 Boot 处理。
|
||
- Boot 根据 UPK 头确定下载与安装流程;当前配置会先写 download 分区,再更新 app 分区。
|
||
|
||
打包输出的 `.upk` 必须符合[协议板Boot_UPK打包规则.md](协议板Boot_UPK打包规则.md),特别是 1024 字节首数据块布局。YMODEM 元数据中的文件大小使用该 `.upk` 的实际字节数。
|
||
|
||
## 7. 完整正常时序
|
||
|
||
```text
|
||
Boot -> PC : C (每秒一次,等待开始)
|
||
PC -> Boot: SOH, 00, FF, 元数据, CRC
|
||
Boot -> PC : ACK
|
||
Boot -> PC : C (必须等待此 C)
|
||
|
||
PC -> Boot: STX, 01, FE, 数据块, CRC
|
||
Boot -> PC : ACK
|
||
PC -> Boot: STX, 02, FD, 数据块, CRC
|
||
Boot -> PC : ACK
|
||
... (直至全部 .upk 数据发送完成)
|
||
|
||
PC -> Boot: EOT
|
||
Boot -> PC : NAK
|
||
PC -> Boot: EOT
|
||
Boot -> PC : ACK
|
||
Boot -> PC : C
|
||
PC -> Boot: SOH, 00, FF, 128 字节全 0, CRC
|
||
Boot -> PC : ACK
|
||
|
||
Boot : 校验 UPK、写 Flash、安装 App、校验 App,并可能跳转 App
|
||
```
|
||
|
||
关键点:
|
||
|
||
- 元数据 ACK 后,必须等 Boot 的第二个 `C` 才能发送数据包。
|
||
- 第一个 EOT 后,必须等 NAK;第二个 EOT 后,必须等 ACK。
|
||
- 第二个 EOT 的 ACK 后,必须等 `C`,再发送结束空包。
|
||
- Boot 处理擦除和 Flash 写入期间,ACK 可能延迟;PC 的单帧 ACK 等待建议设为 3~10 秒。
|
||
|
||
## 8. 上位机状态机(可直接实现)
|
||
|
||
```text
|
||
WAIT_C_START
|
||
收到 C -> SEND_META
|
||
|
||
SEND_META
|
||
发送包号 0 元数据 -> WAIT_META_ACK
|
||
|
||
WAIT_META_ACK
|
||
ACK -> WAIT_C_DATA
|
||
NAK/超时 -> 重发元数据
|
||
|
||
WAIT_C_DATA
|
||
C -> SEND_DATA(包号=1)
|
||
|
||
SEND_DATA
|
||
发送当前数据包 -> WAIT_DATA_ACK
|
||
|
||
WAIT_DATA_ACK
|
||
ACK -> 若还有数据:包号+1,SEND_DATA;否则 SEND_EOT_1
|
||
NAK/超时 -> 重发当前数据包
|
||
|
||
SEND_EOT_1
|
||
发送 EOT -> WAIT_EOT_NAK
|
||
|
||
WAIT_EOT_NAK
|
||
NAK -> SEND_EOT_2
|
||
超时 -> 重发 EOT(保持本状态)
|
||
|
||
SEND_EOT_2
|
||
发送 EOT -> WAIT_EOT_ACK
|
||
|
||
WAIT_EOT_ACK
|
||
ACK -> WAIT_C_END
|
||
NAK/超时 -> 重发 EOT
|
||
|
||
WAIT_C_END
|
||
C -> SEND_END_PACKET
|
||
|
||
SEND_END_PACKET
|
||
发送包号 0 的全 0 SOH 包 -> WAIT_END_ACK
|
||
|
||
WAIT_END_ACK
|
||
ACK -> TRANSFER_FINISHED
|
||
NAK/超时 -> 重发结束空包
|
||
```
|
||
|
||
## 9. 超时、重发、取消与结果判定
|
||
|
||
| 事件 | 上位机处理 |
|
||
| --- | --- |
|
||
| 收到 ACK | 仅推进到下一协议状态;数据包 ACK 后才递增包号 |
|
||
| 收到明确 NAK | 业务层 NAK 可重发当前完整帧;协议校验 NAK 应重新进入 Boot,从元数据包开始传输 |
|
||
| 等待 ACK 超时 | 标记“传输结果不确定”,停止本次会话;重新进入 Boot 后从元数据包开始完整传输 |
|
||
| 明确 NAK 重发耗尽 | 发送 CAN 两次,标记升级传输失败 |
|
||
| 收到 CAN | 立即停止,标记 Boot 取消升级 |
|
||
| 用户取消 | 发送 CAN 两次,停止发送后续字节 |
|
||
| 无 C | 不开始发送,提示设备未进入 Boot 或串口参数/连线错误 |
|
||
|
||
Boot 对单个 CAN 会进入取消流程并回 ACK;上位机仍建议按标准发送两个 CAN,并接受可能出现的 ACK。
|
||
|
||
> **当前 Boot 的可靠性限制:** 成功接收一个数据包后,Boot 已把期望包号加一;若该包的 ACK 在串口上丢失,上位机重发同一包会被 Boot 判为“重复包”并回复 NAK,同时触发 YMODEM 重置。因此“ACK 超时后无条件重发当前包”不能可靠恢复,必须重新进入 Boot 并从元数据包开始传输。若要支持当前会话内的可靠自动重发,需要修改 Boot,使其保留期望包号,并对 CRC 正确的重复帧直接回复 ACK、不再次写入数据。
|
||
|
||
`WAIT_*_ACK` 的建议超时为 3~10 秒,元数据后的 `WAIT_C_DATA`、结束阶段的 `WAIT_C_END` 建议为 10 秒。上位机可将串口接收设计为持续缓存并按字节解析,忽略调试文本或仅识别 `C/ACK/NAK/CAN` 控制字符,避免因分段到达造成误判。
|
||
|
||
## 10. 成功判定与日志
|
||
|
||
结束空包得到 ACK 仅表示 **YMODEM 文件传输完成**,不是最终“固件安装成功”的结构化回码。随后 Boot 仍需校验 `.upk`、写下载区、安装 App、校验 App。
|
||
|
||
上位机应分两级显示结果:
|
||
|
||
1. `传输完成`:收到结束空包 ACK。
|
||
2. `升级确认成功`:设备重启并进入 App 后,通过应用通信读取新固件版本(推荐)或观察 Boot/App 启动日志确认。
|
||
|
||
建议记录:开始时间、文件名/大小、每个包号、重试次数、控制字符、异常原因、传输完成时间和最终版本读取结果。
|
||
|
||
## 11. 与功率板 Boot 转发升级的边界
|
||
|
||
若上位机目标是功率板,而物理串口只连接协议板 App,则不能直接把本 YMODEM 原始字节流写到串口。需要按协议板 App 已实现/约定的 Modbus 扩展功能码 `0x20` 封装,再由 App 南向转发给功率板 Boot,并处理 App 的转发 ACK、`C`、NAK、超时和重发。
|
||
|
||
本文件可作为功率板转发方案中“YMODEM 内层状态机”的依据;外层 Modbus `0x20` 帧格式和升级进入/退出控制需以 `apps/chrg/applications/thread/chrg_comm.c`、`chrg_comm.h` 的实际实现为准,不能与协议板 Boot 直连流程混用。
|
||
|
||
## 12. 代码依据
|
||
|
||
- `apps/boot/application/main.c`:USART1/USART2 初始化及 Boot 启动。
|
||
- `apps/boot/application/func/transfer.c`:USART1 接收传输层。
|
||
- `apps/boot/application/include/ymodem.h`:YMODEM 常量、包定义。
|
||
- `apps/boot/application/func/ymodem.c`:YMODEM 状态机、C/ACK/NAK/EOT 时序和超时。
|
||
- `apps/boot/application/func/app.c`:UPK 接收、校验、写入和安装流程。
|
||
- `apps/boot/application/include/firmware.h`:UPK 头和分区相关定义。
|
||
- `apps/boot/application/func/utils.c`:CRC-16/XMODEM 实现。
|
||
- `apps/boot/application/include/app_config.h`:超时、分区和 AES 配置。
|