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)
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标志。
快速开始
# 全产物: 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):
{
"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"
}
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 |
回归测试
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
下载
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。
legacy 单槽模式(过渡兼容)
旧单槽方案(LDC1612 等,布局:BL 8K + APP 54K + 校准页 1K + 标志页 1K),
-f/-m 触发:
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。v5 格式临时脚本 make_v5_update.py
已于 v2 落地后删除(能力并入 fw_pack.py)。
烧录
# 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