Files
gd32e230f8_firmware_merge_tool/README.md
T
hulk 8af9264ae4 chore: 内部迭代号出清收尾——CLI/测试/README 注释标签改中性表述,删除旧 profile 名迁移映射
- gd32e230_firmware_tool.py / test_fw_pack.py / README.md:v5/dev_fact 等会话自管理标签改为"双固件 bootloader"中性表述;参考产物 *_UPDATE_V5.bin 更名 *_UPDATE.bin(含验收包内 1.0.18),测试引用同步
- config.py:删除 _RENAMED_PROFILE 旧名迁移映射(ceramixnano_mb_v51 仅存在数小时;残留旧名加载 profile 时报错提示重选)
- AGENTS.md:留档出清进度,并修正"GUI 旧配置自动迁移"的过时表述(迁移映射已删)
- 55 项回归全绿;fw_pack.py 侧标签清理已随 5a85f68 入库
2026-10-25 00:43:53 +08:00

182 lines
8.4 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.
# GD32E230 固件工具
本仓库提供 GD32E230 系列固件的打包与烧录工具:
- **v2 双固件打包(默认)**:`gd32e230_firmware_tool.py` + `fw_pack.py` 公共库——
布局 profile 化,输入编译好的 bin 自动识别 A/B 槽,产出 OTA 包 / B 底包 /
整片镜像 + MD5 清单,写盘后回读复核;
- **DAPLink Flash GUI(推荐)**:图形界面烧录工具(含 v2 打包弹窗),位于 `FlashTool/`;
- **legacy 单槽模式(过渡兼容)**:`-f` 纯 0xFF 补页 / `-m` 拼 BL+APP+flag;
- **旧版脚本**:`merge_bin.py`、`fill_bin.py`(保留兼容)。
## v2 双固件打包
### 布局(默认 profile `CeramixNano_MB_Dual_FW`,GD32E230F8/64K)
```text
0x08000000 ┌──────────────────┐
│ Bootloader │ 8K 页 0~7
0x08002000 ├──────────────────┤
│ FW_A 运行槽 │ 36K 页 8~43 OTA/Ymodem 唯一接收区
0x0800AFFC │ [槽尾锚点]──────│ ← 与 trailer 同值 {页数16|CRC16}
0x0800B000 ├──────────────────┤
│ FW_B 出厂保底槽 │ 19K 页 44~62 固定满槽,产线冻结
0x0800FBF8 │ [B 记录 8B]─────│ ← magic|页数|CRC|2B 保留
0x0800FC00 ├──────────────────┤
│ 0xEEEE 标志 │ 1K 页 63 @0x0800FFFC
0x08010000 └──────────────────┘
```
### 计算规则(与双固件 bootloader 逐字一致)
- **CRC-16/XMODEM**(poly 0x1021、init 0x0000、不反转、无 xorout),
启动自检向量 `"123456789" → 0x31C3`;
- **A 包**:补 `0xFF` 至整 N 页,末 4B 写 trailer `{页数N(低16)|CRC(高16)}`;
CRC 范围 = N 页内容去掉末 4B(含 0xFF 填充)。**整页扩展**:body 恰为整页
倍数、或余量 < 4B → 向后扩 1 页;扩展后须 ≤ 槽容量,否则报错;
- **B 包**:补 `0xFF` 恰好填满槽(19,456B),槽末 8B 写记录
`{magic16=0xC0DE, 页数16, CRC16, 2B 0xFF}`;CRC 范围 = 槽内容去掉末 8B;
**固件 > 槽-8B 直接报错**(固定槽不可扩展);
- **FULL**:BL + A 包 + 槽尾锚点 + 空隙 0xFF + B 满槽 + `0xEEEE` 标志。
### 快速开始
```bash
# 全产物: A 包 → *_UPDATE.bin, 整片 → *_FULL.bin, 工厂镜像 → *_FACTORY.bin (+*.md5.txt)
python gd32e230_firmware_tool.py app_a.bin app_b.bin -b bootloader.bin
# 只打 A 包(OTA 升级包)
python gd32e230_firmware_tool.py app_a.bin --no-full --no-factory
# 只打工厂烧录镜像(BL + B 满槽 + flag, 上电跳 B, 后续 OTA 写 A)
python gd32e230_firmware_tool.py app_b.bin -b bootloader.bin
```
输入 bin 从**向量表自动识别** A/B 包(初始 SP 须在 SRAM `[0x20000000,0x20002000]`、
复位向量 Thumb 且落在对应槽区间);也可 `--a`/`--b` 显式指定,与向量表判定冲突时报错。
写盘后回读复核(重算 trailer/记录/锚点一致才报成功),并输出布局摘要与逐项字节校验
(FULL 19 项 / FACTORY 12 项)。
### 产物
| 产物 | 用途 |
|---|---|
| `*_UPDATE.bin` | A 包(补页+trailer),Ymodem/OTA 推送 |
| `*_FULL.bin` | 整片镜像(BL + A + B + flag),`@0x08000000` 烧录后直接运行 A(开发/验收底包) |
| `*_FACTORY.bin` | **工厂烧录镜像**(BL + B 满槽 + flag,**无 A 内容、锚点擦除态**),上电判定链落 B 跳出厂固件,之后 OTA 写 A |
| `*.md5.txt` | 全部产物 MD5 清单 + 布局摘要(挂在 FULL,无 FULL 挂 FACTORY) |
命名从输入文件名推导:FULL 为 `<项目>_FULL_A-V<版本>_B-V<版本>[_日期].bin`,
FACTORY 为 `<项目>_FACTORY_B-V<版本>[_日期].bin`。不再单独输出 B 包文件
(B 内容已包含在 FULL/FACTORY 中)。
### 布局 profile(可复用到任意工程)
内置 `CeramixNano_MB_Dual_FW`(默认)与 `f8_single_slot`(无保底槽)。其他工程写一份
JSON 即可(保底槽 8K/28K、无保底槽、BL 更大等都支持),工具做完整性校验
(分区不重叠、页对齐、总和=flash_size):
```json
{
"profile": "CeramixNano_MB_Dual_FW",
"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"
}
```
```bash
python gd32e230_firmware_tool.py app.bin --profile my_layout.json # 自定义布局
python gd32e230_firmware_tool.py app.bin --profile f8_single_slot # 无保底槽
```
### v2 参数
| 参数 | 默认值 | 说明 |
|------|--------|------|
| `bins...` | (可选) | 输入 bin,A/B 包按向量表自动识别 |
| `--a BIN` / `--b BIN` | — | 显式指定 A/B 包(与自动识别冲突时报错) |
| `-b, --bootloader` | — | BL bin(参与 FULL 拼接;缺省仅警告) |
| `--profile` | `CeramixNano_MB_Dual_FW` | 内置名或 profile JSON 路径 |
| `-o, --output` | 输入所在目录 | **输出目录**(产物自动命名) |
| `--no-full` | — | 不拼 FULL 整片镜像 |
| `--no-factory` | — | 不出 FACTORY 工厂镜像 |
### 回归测试
```bash
python test_fw_pack.py # 55 项: 规格基准 + 边界 + 篡改检测 + CLI 冒烟
```
覆盖 UPGRADE_PLAN_v2.md 第五节全部基准(CeramixNano 1.0.17/1.0.18/V1.0.12
实测值逐字节复现、恰整页/余量<4 扩页等);真机固件不在本仓库时相关用例自动跳过。
## DAPLink Flash GUI(推荐)
日常烧录优先使用图形界面工具,不需要打开 VSCode,也不需要记忆 OpenOCD 命令。
v2.6.0 起顶栏新增**"打包 (v2)"**弹窗(profile 选择 + BL/A/B 输入 + 输出目录),
与命令行共用 `fw_pack.py`,结果与逐项校验流进主日志。
- **免安装版**:到 [Gitea Releases](https://gitea.hulk.wang/hulk/gd32e230f8_firmware_merge_tool/releases)
下载 `DAPLinkFlash-vX.Y.Z-win64.zip`,解压后进入 `DAPLinkFlash` 文件夹
双击 `DAPLinkFlash.exe` 即可,**包内自带 OpenOCD 工具链**
(`toolchain/openocd/`),目标机器无需任何环境。
- **源码运行**:`python FlashTool/src/flash_gui.py` 或双击 `FlashTool\start_flash_gui.bat`
(需 Python 3.10+ 与 `pip install customtkinter`;OpenOCD 默认找 `D:/toolchain`)。
- **命令行打包**:`python FlashTool/src/flash_gui.py --pack a.bin b.bin --pack-bl bl.bin -o outdir`
详细说明见 [FlashTool/README.md](FlashTool/README.md)。
## legacy 单槽模式(过渡兼容)
旧单槽方案(LDC1612 等,布局:BL 8K + APP 54K + 校准页 1K + 标志页 1K),
`-f`/`-m` 触发:
```bash
python gd32e230_firmware_tool.py -f app.bin # 纯 0xFF 补页, 无 trailer → *_UPDATE.bin
python gd32e230_firmware_tool.py -m app.bin # BL+APP+0xEEEE → *_BL.bin
python gd32e230_firmware_tool.py -m app.bin -s F6 # F6 芯片
python gd32e230_firmware_tool.py -m app.bin -a 0x0800B000 -b bl.bin # FW_B 槽落位
```
| 参数 | 默认值 | 说明 |
|------|--------|------|
| `-m, --merge` | — | 合成完整 Flash 镜像(不补齐) |
| `-f, --fill` | — | 补齐到整页边界(纯 0xFF) |
| `-s, --flash-size` | `F8` | 芯片型号:`F4`(16K) `F6`(32K) `F8`(64K) |
| `-b, --bootloader` | 内置 `gd32e230f8_bootloader_hulk.bin` | Bootloader .bin 路径 |
| `-o, --output` | 自动生成 | **输出文件**路径 |
| `-a, --app-addr` | `0x08002000` | APP 落位地址(1K 页对齐) |
> `-m` 与 `-f` 互斥;新工程请用 v2 模式(不带 `-f/-m`)。
### 旧版脚本
`merge_bin.py` / `fill_bin.py` 为旧版命令行脚本,功能已合并进 `gd32e230_firmware_tool.py`,
历史说明见 [README_old.md](README_old.md)。带 trailer 的临时打包脚本
已在 v2 落地后删除(能力并入 `fw_pack.py`)。
### 烧录
```bash
# OpenOCD
openocd -f interface/cmsis-dap.cfg -f target/gd32e23x.cfg \
-c "init; reset halt; flash write_image erase FULL.bin 0x08000000; reset; exit"
# J-Link
JFlash -openprj project.jflash -open FULL.bin,0x08000000 -auto -exit
```
## License
MIT