Files
chrg/docs/协议板Boot_YMODEM上位机实现规则.md
wrh 05309dfb41 一:增加了纹波滤波,当纹波板有电阻时打开辅助继电器应该为3帧过冲,使用五次过滤可以消除异常纹波
二、修改了负载启动的顺序,先开启辅助继电器使地相通,再开启D+D-继电器

feat: 发布V1.1.23版本,优化负载初始化继电器时序

- 更新所有头文件版本号至V1.1.21~V1.1.23,协议板固件版本更新为0x0127
- 新增纹波滤波相关宏定义与函数,实现继电器闭合后纹波过滤
- 调整负载初始化流程:先下发辅助继电器,等待回码后延迟30ms再打开北向继电器
- 优化D+/D-寄存器上位机显示单位,适配0.001V解析格式
- 补充YMODEM升级文档说明,完善传输校验与重发规则
- 清理冗余调试打印与Allegro工程日志文件
2026-09-14 15:13:20 +08:00

214 lines
9.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 协议板 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 配置。