Files
gd32e230f8_firmware_merge_tool/README.md
T

178 lines
7.9 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_v51`,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 └──────────────────┘
```
### 计算规则(与 BL dev_fact v5.1 逐字一致)
- **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, B 包 → *_B.bin, 整片 → *_FULL.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
# 仅 B 底包(产线备用,不拼 FULL)
python gd32e230_firmware_tool.py app_b.bin
```
输入 bin 从**向量表自动识别** A/B 包(初始 SP 须在 SRAM `[0x20000000,0x20002000]`、
复位向量 Thumb 且落在对应槽区间);也可 `--a`/`--b` 显式指定,与向量表判定冲突时报错。
写盘后回读复核(重算 trailer/记录/锚点一致才报成功),并输出布局摘要 + 19 项字节校验。
### 产物
| 产物 | 用途 |
|---|---|
| `*_UPDATE.bin` | A 包(补页+trailer),Ymodem/OTA 推送 |
| `*_B.bin` | B 底包(满槽+记录),产线单独烧 B 槽备用 |
| `*_FULL.bin` | 整片镜像,`@0x08000000` 整片烧录(底包) |
| `*.md5.txt` | 全部产物 MD5 清单 + 布局摘要 |
FULL 镜像自动命名 `<项目>_FULL_A-V<版本>_B-V<版本>[_日期].bin`(从输入文件名推导)。
### 布局 profile(可复用到任意工程)
内置 `ceramixnano_mb_v51`(默认)与 `f8_single_slot`(无保底槽)。其他工程写一份
JSON 即可(保底槽 8K/28K、无保底槽、BL 更大等都支持),工具做完整性校验
(分区不重叠、页对齐、总和=flash_size):
```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"
}
```
```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_v51` | 内置名或 profile JSON 路径 |
| `-o, --output` | 输入所在目录 | **输出目录**(产物自动命名) |
| `--no-full` | — | 只出 UPDATE/B 包,不拼 FULL |
### 回归测试
```bash
python test_fw_pack.py # 49 项: 规格基准 + 边界 + 篡改检测 + 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)。v5 格式临时脚本 `make_v5_update.py`
已于 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