Files
chrg/docs/协议板Boot_UPK打包规则.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

100 lines
4.8 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:UPK 打包规则
## 1. 适用范围
本文用于实现协议板 App 固件的 `.upk` 打包和解析工具,适配 `apps/boot` 当前 Boot。传输层 YMODEM 规则见[协议板Boot_YMODEM上位机实现规则.md](协议板Boot_YMODEM上位机实现规则.md)。
## 2. 1K 文件布局
当前 Boot 收到第一个文件数据帧时,只取其中前 96 字节作为 UPK 头,**会忽略该帧其余数据**。因此打包文件必须使用固定 1024 字节首数据块:
```text
输出 .upk 文件
偏移 0x000 ~ 0x05F : 96 字节 UPK 逻辑头
偏移 0x060 ~ 0x3FF : 928 字节 0x00 填充
偏移 0x400 起 : package body(未加密 BIN 或 AES 加密后的 body)
```
- `.upk` 实际文件大小:`1024 + pkg_size`。
- YMODEM 元数据包的文件大小必须为上述实际文件大小。
- 上位机必须从偏移 0 开始以 `STX/1024` 发送;第一个 STX 是头区,真正 body 从第二个 STX 开始。
- YMODEM 最后一帧的 `0x1A` 补齐仅属于传输层,不能计入文件大小、`raw_size` 或 `pkg_size`。
### YMODEM 1K 帧字节数
`STX/1024` 中的 `1024` 指数据区长度,不是串口线上完整帧长度。每个完整 STX 数据帧固定为 **1029 字节**:
```text
STX 1 字节
PacketNo 1 字节
~PacketNo 1 字节
Data 1024 字节
CRC16 2 字节
总计 1029 字节
```
因此,UPK 首数据块和后续固件数据块的有效数据均为 1024 字节,实际串口发送时均应连续发送 1029 字节。YMODEM 元数据使用 SOH 帧,完整帧为 133 字节(128 字节数据区 + 5 字节控制/校验字段)。
界面中的“表头尺寸 `1024 (ymodem1k)`”应改名为“YMODEM 首数据块/头区尺寸”,并固定为 1024;UPK 逻辑头固定为 96,不能让用户修改。
## 3. 输入、分区与版本
| 项目 | 规则 |
| --- | --- |
| 输入文件 | 仅协议板 App 裸 `bin`,例如 `apps/chrg/build/chrg.bin`;拒绝 `.hex`、`.elf`、已有 `.upk`。 |
| `name[4]` | 固定 ASCII `upk\0`。 |
| `part_name[16]` | 仅允许 `app`、`download`、`factory`,ASCII NUL 结尾;协议板常规升级默认 `app`,Boot 会修正为 `download` 后安装到 `app`。 |
| `fw_old_ver[16]` | 目标设备当前版本,前 4 字节为数值 `major, minor, fix, build`,其余 `0x00`。 |
| `fw_new_ver[16]` | 新固件版本,编码同上。 |
| 版本输入 | 界面应分别提供“当前/旧版本”与“新版本”;不能只保留一个版本号,且不得写 ASCII 版本字符串。 |
| `user_string[16]` | ASCII 水印最多 15 字节,NUL 结尾,其余 `0x00`。 |
| `timestamp` | 当前 Unix 时间戳,`uint32` 小端。 |
| 大小限制 | `raw_size <= 262144` 且 `pkg_size <= 262144`,即 App/download 分区各 256KB。 |
## 4. 加密、大小与 CRC
1. `raw_body` 为原始 `.bin`:`raw_size = len(raw_body)`,`raw_crc = crc32_boot(raw_body)`。
2. 未加密:`package_body = raw_body`,`pkg_size = raw_size`,`pkg_crc = raw_crc`,`config[1]=0x00`。
3. AES:`config[1]=0x01`,使用 AES-256-CBC;Key=`0123456789ABCDEF0123456789ABCDEF`,IV=`0123456789ABCDEF`。加密前 body 必须补齐到 16 字节整数倍;`pkg_size`、`pkg_crc`对应加密后的 body。Key、IV 必须与 Boot 编译配置一致。
4. `config[0]`、`config[2]`、`config[3]` 固定 `0x00`。
5. `head_crc = crc32_boot(逻辑头前 92 字节)`;最后 4 字节按小端写入 `head_crc`。
6. 所有 `uint32` 字段按 STM32 小端序写入。
`crc32_boot()` 必须与 `apps/boot/application/func/utils.c` 的 `crc32_step(0xFFFFFFFF, data, size)` 完全一致;不能直接使用未校验的库默认 CRC32。
## 5. 96 字节逻辑头字段
```text
0x00 name[4]
0x04 config[4]
0x08 fw_old_ver[16]
0x18 fw_new_ver[16]
0x28 user_string[16]
0x38 part_name[16]
0x48 raw_size uint32 little-endian
0x4C pkg_size uint32 little-endian
0x50 timestamp uint32 little-endian
0x54 raw_crc uint32 little-endian
0x58 pkg_crc uint32 little-endian
0x5C head_crc uint32 little-endian
```
## 6. 打包完成前的强制自检
1. 重新解析刚生成的 `.upk`。
2. 校验总长度是否为 `1024 + pkg_size`,并检查 `0x60~0x3FF` 全部为 `0x00`。
3. 校验 `name`、分区名、版本字段、大小限制和 `head_crc`。
4. 校验 `pkg_crc`;未加密时还必须校验 `raw_crc`。加密时使用相同 Key/IV 解密后校验 `raw_crc`。
5. 解析页显示 `raw_size`、`pkg_size`、全部 CRC、加密状态、分区、旧/新版本和时间戳;任一项异常时禁止输出成功文件。
## 7. 当前样本
工程中的 `apps/chrg/chrg.upk` 已验证:实际长度 `155816`,`pkg_size=154792`,两者相差 1024,符合本规则。
## 8. 代码依据
- `apps/boot/application/include/firmware.h`
- `apps/boot/application/func/firmware.c`
- `apps/boot/application/func/app.c`
- `apps/boot/application/func/utils.c`