Author SHA1 Message Date
hulk 9492a8dcce release(v2.6.1): GUI 2.6.1 安装包发布,板卡 BL bin 改随本仓库 Release 分发
- app_gui.py APP_VERSION 2.6.0→2.6.1;重建 onedir + 组 zip(23.1 MB,MD5 ae9aa6590bf46b8e46472dc2d1f1ebc7)并上传 DAPLinkFlash-v2.6.1 Release
- 本版 GUI 首次随包分发 fw_pack 2.2(含 CeramixNano_EDDY_Dual_FW profile,CLI 与「打包 v2」弹窗均可用)
- Release 同时附 MB/EDDY 两板 BL bin + bootloader_bins.md5.txt(BL bin 分发渠道自此为本仓库 Release)
- 入库发布脚本 publish_bl_release.py(建 Release + 传 BL 附件);bootloader_disasm*.txt 分析副产物加入 .gitignore(维持不入库)
- AGENTS.md 补 v2.6.1 发布进度(含 zip MD5,供复现核对)
2026-10-25 00:49:48 +08:00
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
hulk 5a85f68c5d chore(version): fw_pack 2.1→2.2——新增内置 profile CeramixNano_EDDY_Dual_FW 2026-10-24 21:46:24 +08:00
hulk 5b302d13d1 docs(profile): EDDY profile 注释改为专属 BL 分支 bin(撤销复用表述) 2026-10-24 21:34:07 +08:00
hulk b8de2dce3c feat(profile): 新增内置 CeramixNano_EDDY_Dual_FW——EDDY 板双固件布局(与 MB 逐字节相同,BL 复用同一 bin) 2026-10-24 21:15:16 +08:00
hulk 5c46441b29 docs(agents): v2.6.0 发布完成 — exe 冻结态新 profile 名验证通过, zip 已传 Gitea Release 2026-10-22 08:31:49 +08:00
9 changed files with 156 additions and 20 deletions
+2
View File
@@ -26,4 +26,6 @@ FlashTool/flash_gui_settings.json
FlashTool/release/ FlashTool/release/
FlashTool/src/build/ FlashTool/src/build/
FlashTool/toolchain/ FlashTool/toolchain/
# BL 反汇编分析副产物(不入库, 见 AGENTS 2026-10-22 留档)
bootloader_disasm*.txt
+24 -4
View File
@@ -17,7 +17,7 @@ GD32E230 系列固件处理与烧录工具仓库。本文件为项目标杆文
MD5 清单),`test_fw_pack.py` 回归测试套件(55 项,含 CeramixNano 实测基准); MD5 清单),`test_fw_pack.py` 回归测试套件(55 项,含 CeramixNano 实测基准);
`merge_bin.py`/`fill_bin.py` 旧版脚本保留兼容, `merge_bin.py`/`fill_bin.py` 旧版脚本保留兼容,
`gd32e230f8_bootloader_hulk.bin` 出厂 bootloader; `gd32e230f8_bootloader_hulk.bin` 出厂 bootloader;
- `FlashTool/`:DAPLink Flash GUI v2.6.0(烧录 + 打包 v2 + 补齐 Pad + 拼接 - `FlashTool/`:DAPLink Flash GUI v2.6.1(烧录 + 打包 v2 + 补齐 Pad + 拼接
Merge),源码在 `src/`(`flash_gui.py` 入口与 CLI、`app_gui.py` 界面、 Merge),源码在 `src/`(`flash_gui.py` 入口与 CLI、`app_gui.py` 界面、
`openocd_runner.py` 命令构建、`fw_image.py` 旧补齐/拼接、`config.py` 设置、 `openocd_runner.py` 命令构建、`fw_image.py` 旧补齐/拼接、`config.py` 设置、
`build_exe.py`/`package_release.py`/`publish_gitea.py` 发布流水线); `build_exe.py`/`package_release.py`/`publish_gitea.py` 发布流水线);
@@ -34,7 +34,7 @@ GD32E230 系列固件处理与烧录工具仓库。本文件为项目标杆文
FACTORY=BL+B 满槽+flag **无 A**(A 槽整体擦除态,上电判定链落 B 跳出厂固件), FACTORY=BL+B 满槽+flag **无 A**(A 槽整体擦除态,上电判定链落 B 跳出厂固件),
12 项字节校验;不再单独落盘 B 包文件(B 内容已含于 FULL/FACTORY)。 12 项字节校验;不再单独落盘 B 包文件(B 内容已含于 FULL/FACTORY)。
默认 profile 名为 `CeramixNano_MB_Dual_FW`(旧名 `ceramixnano_mb_v51` 已 默认 profile 名为 `CeramixNano_MB_Dual_FW`(旧名 `ceramixnano_mb_v51` 已
废弃不留别名,GUI 旧配置自动迁移)。 废弃不留别名;迁移映射已删,配置残留旧名会在加载时报错提示重选)。
回归基准(CeramixNano 实测):1.0.17→20 页 trailer=0xD30F0014;1.0.18→ 回归基准(CeramixNano 实测):1.0.17→20 页 trailer=0xD30F0014;1.0.18→
0x6F380014;V1.0.12 B→记录 `DE C0 13 00 6F 18 FF FF`;FULL 镜像 MD5 0x6F380014;V1.0.12 B→记录 `DE C0 13 00 6F 18 FF FF`;FULL 镜像 MD5
`f704b837...` 逐字节复现。**改 `fw_pack.py` 后必须 `f704b837...` 逐字节复现。**改 `fw_pack.py` 后必须
@@ -88,11 +88,31 @@ GD32E230 系列固件处理与烧录工具仓库。本文件为项目标杆文
- 参数拼接审计:`flash_gui --pack -o` 加目录护栏(拒绝 .bin 路径,对齐根工具), - 参数拼接审计:`flash_gui --pack -o` 加目录护栏(拒绝 .bin 路径,对齐根工具),
全链路冒烟(GUI 弹窗/CLI/命名拼接)通过;`bootloader_disasm*.txt` 为分析 全链路冒烟(GUI 弹窗/CLI/命名拼接)通过;`bootloader_disasm*.txt` 为分析
副产物留在工作区未入库。 副产物留在工作区未入库。
- 2026-10-22 **v2.6.0 发布**(tag `DAPLinkFlash-v2.6.0`):重建 onedir exe
(冻结新 fw_pack,`--pack` 默认 profile 显示 `CeramixNano_MB_Dual_FW`、
旧名拒绝、UPDATE/FULL/FACTORY 产物冻结态验证通过),组 zip 23.1 MB
(内置 OpenOCD 0.11 工具链 + cfgs),已传 Gitea Release。
- 2026-10-22 **内部迭代号出清**(用户定规:v4/v4.1/v5/v5.1、dev_fact 等
会话自管理标签只许存在于 AGENTS/SKILL 等文档,不得出现在任何代码):
清理 `fw_pack.py`/`gd32e230_firmware_tool.py`/`test_fw_pack.py`/`README.md`
注释中的标签表述(改"双固件 bootloader");**删除 config.py 的
`_RENAMED_PROFILE` 旧名迁移映射**(`ceramixnano_mb_v51` 仅存在数小时,
残留配置会在加载 profile 时报错提示重选);同步 skill 缓存
(fw_pack.py / gd32e230_firmware_tool.py 重新逐字节一致);参考产物
`*_UPDATE_V5.bin` 更名 `*_UPDATE.bin`(含验收包内 1.0.18),测试引用同步;
55 项回归全过。注:BL 侧 `bootloader.c` 同日清理 3 处注释标签(注释不影响
代码生成,已烧 BL bin 仍有效)。
- 2026-10-25 **v2.6.1 发布**(tag `DAPLinkFlash-v2.6.1`,Release id 47):GUI
升版 2.6.1 重建 onedir 并组 zip 23.1 MB(24,177,112B,MD5
`ae9aa6590bf46b8e46472dc2d1f1ebc7`)上传 Release——fw_pack 2.2
(`CeramixNano_EDDY_Dual_FW`)首次随 GUI 安装包分发,CLI 与「打包 v2」弹窗
均可用;同 Release 附 MB/EDDY 两板 BL bin + `bootloader_bins.md5.txt`,
**BL bin 分发渠道自此为本仓库 Release**(不再从 BL 仓库 Build 目录取);
发布脚本 `publish_bl_release.py` 入库(建 Release + 传 BL 附件)。zip 由
本次提交树构建(tag `5a85f68` 之后叠加出清与升版),复现核对以 MD5 为准。
### 计划 / TODO ### 计划 / TODO
- GUI v2.6.0 打包发布(build_exe → package_release → publish_gitea,需新 tag
`DAPLinkFlash-v2.6.0`;exe 已验证可打包 v2,zip 尚未组);
- (待用户物理排查)当前目标板对 SWD 完全无应答(`cannot read IDR`,复位下 - (待用户物理排查)当前目标板对 SWD 完全无应答(`cannot read IDR`,复位下
100k~4000k 全失败,同探针同工具链曾可连):需确认目标板供电、DAPLink RST → 100k~4000k 全失败,同探针同工具链曾可连):需确认目标板供电、DAPLink RST →
GD32 NRST 连线、必要时拔插 DAPLink USB / 目标板断电重上电;恢复后用 GD32 NRST 连线、必要时拔插 DAPLink USB / 目标板断电重上电;恢复后用
+1 -1
View File
@@ -41,7 +41,7 @@ BOLD = ('Microsoft YaHei UI', 13, 'bold')
TITLE_FONT = ('Microsoft YaHei UI', 18, 'bold') TITLE_FONT = ('Microsoft YaHei UI', 18, 'bold')
APP_NAME = 'DAPLink Flash' APP_NAME = 'DAPLink Flash'
APP_VERSION = '2.6.0' APP_VERSION = '2.6.1'
REPO_URL = 'https://gitea.hulk.wang/hulk/gd32e230f8_firmware_merge_tool' REPO_URL = 'https://gitea.hulk.wang/hulk/gd32e230f8_firmware_merge_tool'
OK_BLUE = '#3B8ED0' OK_BLUE = '#3B8ED0'
+1 -4
View File
@@ -80,8 +80,7 @@ def _legacy_settings():
return path return path
# 旧内置 profile 名 → 现名 (改名前保存的配置一次性迁移, 旧名不再受支持) # 旧内置 profile 名已废弃: 配置里若残留旧名, 会在加载 profile 时报错提示重选
_RENAMED_PROFILE = {"ceramixnano_mb_v51": "CeramixNano_MB_Dual_FW"}
def load_settings(): def load_settings():
@@ -101,8 +100,6 @@ def load_settings():
for key in DEFAULTS: for key in DEFAULTS:
if key in stored: if key in stored:
data[key] = stored[key] data[key] = stored[key]
if data.get("pack_profile") in _RENAMED_PROFILE:
data["pack_profile"] = _RENAMED_PROFILE[data["pack_profile"]]
return data return data
+3 -3
View File
@@ -27,7 +27,7 @@
0x08010000 └──────────────────┘ 0x08010000 └──────────────────┘
``` ```
### 计算规则(与 BL dev_fact v5.1 逐字一致) ### 计算规则(与双固件 bootloader 逐字一致)
- **CRC-16/XMODEM**(poly 0x1021、init 0x0000、不反转、无 xorout), - **CRC-16/XMODEM**(poly 0x1021、init 0x0000、不反转、无 xorout),
启动自检向量 `"123456789" → 0x31C3`; 启动自检向量 `"123456789" → 0x31C3`;
@@ -162,8 +162,8 @@ python gd32e230_firmware_tool.py -m app.bin -a 0x0800B000 -b bl.bin # FW_B 槽
### 旧版脚本 ### 旧版脚本
`merge_bin.py` / `fill_bin.py` 为旧版命令行脚本,功能已合并进 `gd32e230_firmware_tool.py`, `merge_bin.py` / `fill_bin.py` 为旧版命令行脚本,功能已合并进 `gd32e230_firmware_tool.py`,
历史说明见 [README_old.md](README_old.md)。v5 格式临时脚本 `make_v5_update.py` 历史说明见 [README_old.md](README_old.md)。带 trailer 的临时打包脚本
已于 v2 落地后删除(能力并入 `fw_pack.py`)。 已在 v2 落地后删除(能力并入 `fw_pack.py`)。
### 烧录 ### 烧录
+22 -4
View File
@@ -10,7 +10,7 @@ fw_pack — GD32E230 双固件打包公共库 (CLI 与 FlashTool GUI 共用)
锚点擦除态 → A 向量非法 → 落 B 记录校验 → 跳出厂固件) 锚点擦除态 → A 向量非法 → 落 B 记录校验 → 跳出厂固件)
*.md5.txt 产物 MD5 清单 + 布局摘要 *.md5.txt 产物 MD5 清单 + 布局摘要
规则与 BL dev_fact 侧 (v5.1) 逐字一致: 规则与双固件 bootloader 侧逐字一致:
- CRC-16/XMODEM (poly 0x1021, init 0x0000, 不反转, 无 xorout), - CRC-16/XMODEM (poly 0x1021, init 0x0000, 不反转, 无 xorout),
自检向量 b"123456789" -> 0x31C3; 自检向量 b"123456789" -> 0x31C3;
- A 包: 补 0xFF 至整 N 页; body 恰整页或 余量 < 记录长 R -> 向后扩 1 页; - A 包: 补 0xFF 至整 N 页; body 恰整页或 余量 < 记录长 R -> 向后扩 1 页;
@@ -38,7 +38,7 @@ __all__ = [
'pack_all', 'suggest_full_name', 'suggest_factory_name', 'pack_all', 'suggest_full_name', 'suggest_factory_name',
] ]
TOOL_VERSION = '2.1' TOOL_VERSION = '2.2' # 2.2: 新增内置 profile CeramixNano_EDDY_Dual_FW
# GD32E230 家族 SRAM: F8 最大 8K, SP 必须落在其中 (F4/F6 的 4K 也在范围内) # GD32E230 家族 SRAM: F8 最大 8K, SP 必须落在其中 (F4/F6 的 4K 也在范围内)
SRAM_LO, SRAM_HI = 0x20000000, 0x20002000 SRAM_LO, SRAM_HI = 0x20000000, 0x20002000
@@ -197,7 +197,7 @@ class SlotSpec:
# ═══════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════
BUILTIN_PROFILES = { BUILTIN_PROFILES = {
# CeramixNano-MB v5.1 双固件 BL 的布局 (BL dev_fact@512bf7a) # CeramixNano-MB 双固件 bootloader 的布局
'CeramixNano_MB_Dual_FW': { 'CeramixNano_MB_Dual_FW': {
'profile': 'CeramixNano_MB_Dual_FW', 'profile': 'CeramixNano_MB_Dual_FW',
'chip': 'GD32E230F8', 'chip': 'GD32E230F8',
@@ -214,6 +214,24 @@ BUILTIN_PROFILES = {
'flag': {'page': 'last', 'addr': '0x0800FFFC', 'value': '0xEEEE'}, 'flag': {'page': 'last', 'addr': '0x0800FFFC', 'value': '0xEEEE'},
'crc': 'xmodem', 'crc': 'xmodem',
}, },
# CeramixNano EDDY (LDC1612) 双固件布局——Flash 分配与 MB 完全相同;
# BL 用专属分支 bootloader_CeramixNano_EDDY 的 bin(LED=PB1,与 MB 分支并列、独立编号)
'CeramixNano_EDDY_Dual_FW': {
'profile': 'CeramixNano_EDDY_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',
},
# 无保底槽的单槽布局 (旧 BL 升级过渡 / 无 B 槽工程) # 无保底槽的单槽布局 (旧 BL 升级过渡 / 无 B 槽工程)
'f8_single_slot': { 'f8_single_slot': {
'profile': 'f8_single_slot', 'profile': 'f8_single_slot',
@@ -555,7 +573,7 @@ def build_full(profile, bl_data, a_pack, b_pack=None):
def build_factory(profile, bl_data, b_pack): def build_factory(profile, bl_data, b_pack):
"""工厂烧录镜像: BL + B 满槽(含记录) + flag, **无 A 包、无锚点**。 """工厂烧录镜像: BL + B 满槽(含记录) + flag, **无 A 包、无锚点**。
上电判定链(v5.1 BL): A 锚点为擦除态(0xFFFF...) → legacy flag + A 向量校验 上电判定链(双固件 BL): A 锚点为擦除态(0xFFFF...) → legacy flag + A 向量校验
(A 槽全 0xFF → 向量非法) → 落 B 记录 {magic|pages|crc} 校验 → 跳出厂固件; (A 槽全 0xFF → 向量非法) → 落 B 记录 {magic|pages|crc} 校验 → 跳出厂固件;
后续 OTA 写入 A 槽后即切运行固件。 后续 OTA 写入 A 槽后即切运行固件。
""" """
+1 -1
View File
@@ -8,7 +8,7 @@ v2 模式(默认): 输入编译好的 APP bin, 自动识别 A/B 槽, 产出
*_FULL.bin 整片镜像 (BL + A 包 + 槽尾锚点 + B 满槽 + 0xEEEE 标志) *_FULL.bin 整片镜像 (BL + A 包 + 槽尾锚点 + B 满槽 + 0xEEEE 标志)
*_FACTORY.bin 工厂烧录镜像 (BL + B 满槽 + flag, 无 A 内容; 上电跳 B) *_FACTORY.bin 工厂烧录镜像 (BL + B 满槽 + flag, 无 A 内容; 上电跳 B)
*.md5.txt 产物 MD5 清单 + 布局摘要 (随主镜像生成) *.md5.txt 产物 MD5 清单 + 布局摘要 (随主镜像生成)
打包规则与 BL (dev_fact v5.1) 逐字一致, 写盘后回读复核。计算与校验在 打包规则与双固件 bootloader 逐字一致, 写盘后回读复核。计算与校验在
fw_pack.py 公共库 (FlashTool GUI 共用)。 fw_pack.py 公共库 (FlashTool GUI 共用)。
legacy 模式(过渡期兼容, -f/-m 二选一时启用): 旧单槽方案 legacy 模式(过渡期兼容, -f/-m 二选一时启用): 旧单槽方案
+99
View File
@@ -0,0 +1,99 @@
#!/usr/bin/env python3
"""发布 DAPLinkFlash-v2.6.1:fw_pack 2.2(EDDY profile)+ 随 Release 附板卡 BL bin"""
import hashlib
import json
import os
import ssl
import time
import urllib.request
from pathlib import Path
BASE = "https://gitea.hulk.wang/api/v1"
REPO = "hulk/gd32e230f8_firmware_merge_tool"
TOKEN = os.environ["GITEA_TOKEN"]
CTX = ssl._create_unverified_context()
BL_DIR = Path(r"E:\Hulk-Coding\gd32e230_bootloader\Build\Release")
BLS = [
BL_DIR / "gd32e23x_V0.1.0_bootloader_CeramixNano_MB_2026-10-22.bin",
BL_DIR / "gd32e23x_V0.1.0_bootloader_CeramixNano_EDDY_2026-10-24.bin",
]
MANIFEST = BL_DIR / "bootloader_bins.md5.txt"
BODY = """## 本版变更
- **fw_pack 2.1 → 2.2**:新增内置布局 profile `CeramixNano_EDDY_Dual_FW`(CeramixNano EDDY 板 / LDC1612 电涡流传感器单板;Flash 分配与 MB 逐字节相同,BL 用各自的板卡分支 bin)。
- **DAPLinkFlash GUI 无改动**——需要 GUI 请继续用 [v2.6.0](https://gitea.hulk.wang/hulk/gd32e230f8_firmware_merge_tool/releases/tag/DAPLinkFlash-v2.6.0) 的安装包。
- **新增:随 Release 分发各板卡双固件 BL bin**(拼 FULL/FACTORY 时 `-b` 传入):
| 附件 | 板卡 | 大小 | MD5 | 来源 |
|---|---|---|---|---|
| `gd32e23x_V0.1.0_bootloader_CeramixNano_MB_2026-10-22.bin` | CeramixNano-MB(LED=PA14) | 4,044B | f7b447cf800e062cdf15abd8d7edc723 | BL 仓库 `bootloader_CeramixNano_MB` 分支,tag `v0.1.0` |
| `gd32e23x_V0.1.0_bootloader_CeramixNano_EDDY_2026-10-24.bin` | CeramixNano-EDDY(LED=PB1,升级会话期间 SWD 可用) | 4,040B | 1dcc17bf530930a9686afa4dd04d30db | BL 仓库 `bootloader_CeramixNano_EDDY` 分支,V0.1.0 |
| `bootloader_bins.md5.txt` | 清单 | — | — | 上述两文件的 MD5 |
## 用法
```bash
# MB 双固件打包(在 APP bin 所在目录)
python gd32e230_firmware_tool.py app_a.bin app_b.bin -b gd32e23x_V0.1.0_bootloader_CeramixNano_MB_2026-10-22.bin
# EDDY 双固件打包
python gd32e230_firmware_tool.py app_a.bin app_b.bin \
-b gd32e23x_V0.1.0_bootloader_CeramixNano_EDDY_2026-10-24.bin \
--profile CeramixNano_EDDY_Dual_FW
```
两块板 Flash 布局完全一致(BL 8K + FW_A 36K + FW_B 19K + 末页标志),仅 LED 引脚不同;
**BL 版本号按板卡分支独立编号,勿跨板混烧**(MB 版 LED=PA14 会占 SWCLK)。
"""
def api(method, path, data=None, ctype="application/json", tries=6):
for i in range(tries):
try:
r = urllib.request.Request(BASE + path, method=method)
r.add_header("Authorization", "token " + TOKEN)
body = None
if data is not None:
body = json.dumps(data).encode() if ctype == "application/json" else data
r.add_header("Content-Type", ctype)
with urllib.request.urlopen(r, body, context=CTX) as resp:
txt = resp.read()
return resp.status, (json.loads(txt) if txt else {})
except Exception as e:
print(f" retry {i + 1} {method} {path.split('?')[0]}: {e!r}")
time.sleep(8)
raise SystemExit(f"API 多次重试失败: {method} {path}")
# 0) 生成 BL 清单
lines = ["# 双固件板卡 BL bin 清单(来源:gd32e230_bootloader 仓库对应板卡分支)"]
for p in BLS:
md5 = hashlib.md5(p.read_bytes()).hexdigest()
lines.append(f"{md5} {p.stat().st_size:>6}B {p.name}")
MANIFEST.write_text("\n".join(lines) + "\n", encoding="utf-8")
print(MANIFEST.read_text(encoding="utf-8"))
# 1) 创建 Release(tag 打在 main 顶端)
st, rel = api("POST", f"/repos/{REPO}/releases", {
"tag_name": "DAPLinkFlash-v2.6.1",
"target_commitish": "main",
"name": "DAPLinkFlash v2.6.1 — fw_pack 2.2(EDDY profile)+ 板卡 BL 分发",
"body": BODY,
})
print("release:", st, rel.get("id"), rel.get("html_url"))
rid = rel["id"]
# 2) 附件
boundary = "----zcodebl"
for p in BLS + [MANIFEST]:
blob = p.read_bytes()
parts = (
f"--{boundary}\r\n"
f'Content-Disposition: form-data; name="attachment"; filename="{p.name}"\r\n'
f"Content-Type: application/octet-stream\r\n\r\n"
).encode() + blob + f"\r\n--{boundary}--\r\n".encode()
st, res = api("POST", f"/repos/{REPO}/releases/{rid}/assets?name={p.name}", parts,
ctype=f"multipart/form-data; boundary={boundary}")
print("asset:", st, p.name)
+3 -3
View File
@@ -43,8 +43,8 @@ CAP = r'E:\Hulk-Coding\capsule_mb_camke_vscode\Build'
A17 = os.path.join(CAP, 'Release', 'CeramixNano-MB_V1.0.17_APP_2026-10-21.bin') A17 = os.path.join(CAP, 'Release', 'CeramixNano-MB_V1.0.17_APP_2026-10-21.bin')
A18 = os.path.join(CAP, 'Release', 'CeramixNano-MB_V1.0.18_APP_2026-10-21.bin') A18 = os.path.join(CAP, 'Release', 'CeramixNano-MB_V1.0.18_APP_2026-10-21.bin')
B12 = os.path.join(CAP, 'Release', 'CeramixNano-MB_V1.0.12_APP_2026-10-20.bin') B12 = os.path.join(CAP, 'Release', 'CeramixNano-MB_V1.0.12_APP_2026-10-20.bin')
U17_REF = os.path.join(CAP, 'test', 'CeramixNano-MB_V1.0.17_APP_2026-10-21_UPDATE_V5.bin') U17_REF = os.path.join(CAP, 'test', 'CeramixNano-MB_V1.0.17_APP_2026-10-21_UPDATE.bin')
U18_REF = os.path.join(CAP, 'test', 'CeramixNano-MB_V1.0.18_APP_2026-10-21_UPDATE_V5.bin') U18_REF = os.path.join(CAP, 'test', 'CeramixNano-MB_V1.0.18_APP_2026-10-21_UPDATE.bin')
FULL_REF = os.path.join(CAP, 'test', 'acceptance_2026-10-22', FULL_REF = os.path.join(CAP, 'test', 'acceptance_2026-10-22',
'CeramixNano-MB_FULL_A-V1.0.17_B-V1.0.12_2026-10-21.bin') 'CeramixNano-MB_FULL_A-V1.0.17_B-V1.0.12_2026-10-21.bin')
HAVE_REAL = all(os.path.isfile(p) for p in (A17, A18, B12, U17_REF, FULL_REF)) HAVE_REAL = all(os.path.isfile(p) for p in (A17, A18, B12, U17_REF, FULL_REF))
@@ -495,7 +495,7 @@ class TestFactory(unittest.TestCase):
# ═══════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════
# 8. 真机回归: CeramixNano v5.1 (字节级复现验收包) # 8. 真机回归: CeramixNano 双固件 (字节级复现验收包)
# ═══════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════
@unittest.skipUnless(HAVE_REAL, '需要 CeramixNano 固件(见 test_fw_pack.py 头部路径)') @unittest.skipUnless(HAVE_REAL, '需要 CeramixNano 固件(见 test_fw_pack.py 头部路径)')