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

4.8 KiB
Raw Blame History

协议板 Boot:UPK 打包规则

1. 适用范围

本文用于实现协议板 App 固件的 .upk 打包和解析工具,适配 apps/boot 当前 Boot。传输层 YMODEM 规则见协议板Boot_YMODEM上位机实现规则.md。

2. 1K 文件布局

当前 Boot 收到第一个文件数据帧时,只取其中前 96 字节作为 UPK 头,会忽略该帧其余数据。因此打包文件必须使用固定 1024 字节首数据块:

输出 .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 字节:

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 字节逻辑头字段

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