Files
gd32e230f8_firmware_merge_tool/UPGRADE_PLAN_v2.md
T

109 lines
7.0 KiB
Markdown
Raw 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.
# gd32e230f8_firmware_merge_tool v2 升级计划(需求规格 / 提示词)
> 本文可直接作为 AI 辅助重构的提示词使用;也是本次彻底升级的需求基线。
> 背景仓库:本仓库(main 分支);配套 skill:hulk-mcu-firmware(SKILL.md + tool/ 缓存)。
> 首个目标工程:CeramixNano-MB(GD32E230F8/64K,双固件 v5.1 布局,BL 侧 dev_fact@512bf7a)。
---
## 一、背景与目标
现有 `gd32e230_firmware_tool.py` 是单槽时代的工具:布局硬编码(APP@0x08002000、标志页、校准页),只有两种模式(`-f` 纯 0xFF 补页、`-m` 拼 BL+APP+flag)。现已演进为**双固件方案**(BL + FW_A 运行槽 + FW_B 出厂保底槽 + 记录/CRC),临时脚本(`make_v5_update.py`、拼 FULL 的临时逻辑)散落各处,需要彻底整合升级。
**目标**:一个布局可配置、可复用到任意 GD32E230 工程(不同 Flash 型号、不同槽大小、可有/可无保底槽)的固件打包工具:输入编译好的 bin,自动识别槽位、补页、计算长度与 CRC、写记录/trailer/标志,产出完整可烧录镜像与 OTA 包。
## 二、现状与痛点
1. 布局硬编码(0x08002000/末页标志/校准页),换工程即失效;
2. 无 A/B 双槽概念,无 trailer/记录/CRC 计算;
3. 新增的 `-a/--app-addr` 只是补丁,无法描述 B 记录、锚点等;
4. GUI(FlashTool)拼接逻辑同样固定 0x08002000;
5. 临时脚本(make_v5_update.py 等)逻辑未固化,存在两套真相。
## 三、核心设计:布局 Profile
用 JSON 配置文件描述一个工程的 Flash 布局(CLI 也可覆盖单项)。示例(CeramixNano-MB v5.1):
```json
{
"profile": "ceramixnano_mb_v51",
"chip": "GD32E230F8",
"flash_base": "0x08000000",
"flash_size": "64K",
"page_size": 1024,
"bl": { "addr": "0x08000000", "size": "8K" },
"slot_a": { "addr": "0x08002000", "size": "36K",
"anchor": "slot_end-4", "record": "{pages16@+0, crc16@+2}" },
"slot_b": { "addr": "0x0800B000", "size": "19K", "fixed_slot": true,
"record": "{magic16@+0=0xC0DE, pages16@+2, crc16@+4}",
"record_addr": "slot_end-8" },
"flag": { "page": "last", "addr": "0x0800FFFC", "value": "0xEEEE" },
"crc": "xmodem"
}
```
**可复用性要求**:其他工程仅换 profile——例如保底槽 8K 或 28K、无保底槽(`slot_b: null`)、BL 更大等;所有地址/大小支持 `0x` 十六进制与 `K` 后缀;工具对 profile 做完整性校验(分区不重叠、页对齐、总和=flash_size)。
## 四、功能规格
### 4.1 输入与自动识别
- 输入为**编译好的 bin**:底包(LD/向量配置在 B 槽基址,如 0x0800B000)与升级包(配置在 A 槽基址,如 0x08002000)。
- 工具从**向量表自动识别**:初始 SP ∈ SRAM、复位向量落在哪个槽区间 → 判定该 bin 属于 A 包还是 B 包;与显式参数冲突时报错。
- BL bin(可选)、底包 bin(可选)作为输入项;BL 需校验 ≤ `bl.size`。
### 4.2 计算规则(与 BL dev_fact 侧逐字一致,不得偏离)
- **CRC-16/XMODEM**(poly 0x1021、init 0x0000、不反转、无 xorout;测试向量 `"123456789"` → `0x31C3`——工具启动自检)。
- **A 包(OTA/升级包)**:补 0xFF 至整 N 页,末 4B 写 trailer `{页数N(低16), CRC(高16)}`,CRC 范围 = **N 页内容去掉末 4B**(含 0xFF 填充)。
- **槽尾锚点**(FULL 镜像用):A 槽末 4B(`slot_a` 末)写与 trailer 同值——BL 收包后会独立算出同值交叉验证。
- **B 包(底包,固定槽)**:补 0xFF 至**恰好填满槽**(如 19,456B),槽末 8B 写记录 `{magic16, pages16, crc16, 2B 0xFF}`,CRC 范围 = 槽内容去掉末 8B。**若 B 固件 > 槽−8B → 报错拒绝**(固定槽不可向后扩展,这是与 A 包的本质区别)。
- **flag**:`0xEEEE` 写 `flag.addr`(FULL 镜像)。
### 4.3 整页扩展规则(重点)
对动态补页的 A 包:设记录长度 R(A=4B trailer),
- `余量 = N_pages*1024 − body_len`;
- 若 `body_len` 恰为整页倍数,或 `余量 < R` → **向后扩展一页**(N_pages+1,全 0xFF 补齐后写记录);
- 扩展后仍须 ≤ `slot_a.size`,否则报错。
(B 包为固定槽,不适用扩展,见 4.2;若未来某工程 B 也动态化,须在 profile 中用 `fixed_slot:false` 显式声明并用同一规则。)
### 4.4 产物
1. `*_FULL.bin`:整片镜像 = BL + FW_A(补页+trailer+锚点) + 空隙0xFF + FW_B(满槽+记录) + flag;输出布局摘要与 MD5 清单(`*.md5.txt`)。
2. `*_UPDATE.bin`:A 包(补页+trailer),供 Ymodem/OTA。
3. `*_B.bin`(可选):满槽 B 包单独输出(产线备用)。
4. 兼容模式:`--legacy` 产出旧格式(纯 0xFF 补页、无 trailer),过渡期用。
### 4.5 校验(打包前硬门槛)
- 向量表:SP ∈ [0x20000000, 0x20002000];复位向量 Thumb 且落在声明槽内;
- 尺寸:A 包 ≤ 槽;B 包 = 槽(含记录);BL ≤ `bl.size`;
- 写盘后**回读复核**(重算 CRC/trailer 一致才报成功);
- 输出布局摘要表(各分区起止/大小/页号/记录值)供人工核对。
## 五、回归基准(本项目实测值,重构后必须逐项复现)
| 用例 | 期望 |
|---|---|
| 1.0.17 原始 bin 19,580B | A 包 20 页/20,480B,trailer=锚点=`0xD30F0014` |
| 1.0.18 原始 bin 19,580B | A 包 20 页,trailer=`0x6F380014`(CRC 0x6F38) |
| V1.0.12 B bin 19,456B(尾部已含 magic) | B 记录 = `DE C0 13 00 6F 18 FF FF`(pages=19,CRC=0x186F) |
| FULL 镜像 65,536B | 17 项字节校验全过(分区内容/空隙 0xFF/记录/flag) |
| 恰整页用例(构造 body=20480B) | 扩展为 21 页,trailer pages=21 |
| 余量<4B 用例(body=20477B) | 扩展为 21 页 |
## 六、GUI 与配套同步
- FlashTool(DAPLinkFlash):拼接/补齐弹窗升级为 profile 选择 + 双槽模式,与新 CLI 共用同一打包模块(抽公共库 `fw_pack.py`,CLI 与 GUI 仅为壳);
- 本仓库 README 更新;`AGENTS.md` 进度同步;
- skill `hulk-mcu-firmware`:改开发仓库 → push Gitea → `python scripts/update_tool.py` 同步缓存,SKILL.md 流程描述同步改。
## 七、实施步骤建议
1. 抽公共库 `fw_pack.py`(profile 解析/校验/计算/复核),CLI 改造调用之,先跑通第五节回归基准;
2. 新增 `--profile`(默认内置 ceramixnano_mb_v51),保留 `--legacy`;
3. GUI 接入;
4. 文档/skill 同步、Gitea 发布。
---
## 八、提示词(可直接粘贴给 AI 会话)
"请重构 `gd32e230_firmware_tool.py`:按上文第三~五节实现布局 profile 化的双固件打包工具,抽公共库供 GUI 复用。所有 CRC/记录/补页/整页扩展规则必须与第四节逐字一致,并以第五节回归基准作为验收(构造测试 bin 跑通全部用例)。要求:纯标准库、Windows 兼容、输出布局摘要与 MD5 清单、打包后回读复核;保留 `--legacy` 兼容模式;不要动 `FlashTool/` 之外的无关文件;完成后更新 README 与 AGENTS.md。"