From 8dcbfa9f9915d0a0080493363cb27cdfd6e34313 Mon Sep 17 00:00:00 2001 From: hulk Date: Sat, 24 Oct 2026 21:15:11 +0800 Subject: [PATCH] =?UTF-8?q?build(golden):=20=E5=87=BA=E5=8E=82=E4=BF=9D?= =?UTF-8?q?=E5=BA=95=E7=BA=BF=E5=AE=9A=E7=89=88=E2=80=94=E2=80=94CeramixNa?= =?UTF-8?q?no-EDDY=20=E5=91=BD=E5=90=8D/=E6=9D=BF=E5=8D=A1=E7=A0=81=2026/?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=86=BB=E7=BB=93=20V1.0.2/variant=3Dgolden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 136 +++++++++++++++++++++++++------------ CMakeLists.txt | 5 +- README.md | 24 ++++--- cmake/project_config.cmake | 8 ++- 4 files changed, 115 insertions(+), 58 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 4223771..f122407 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,30 +1,38 @@ -# AGENTS.md — ldc1612_cmake_vscode 项目约定与进度 +# AGENTS.md — CeramixNano EDDY(ldc1612_cmake_vscode)项目约定与进度 ## 项目概述 -GD32E230 电涡流传感器节点固件:LDC1612(电涡流/电感数字转换器)+ TMP112(板载温度), -通过 RS485 串口命令协议(`D5 03 LEN [cmd] CRC`)与上位机通信,支持温度补偿与标定。 +CeramixNano EDDY 电涡流传感器单板固件(工程目录名沿用 ldc1612_cmake_vscode): +LDC1612(电涡流/电感数字转换器)+ TMP112(板载温度),RS485 串口命令协议 +(`D5 03 LEN [cmd] CRC`,板卡类型 0x03),支持温度补偿与标定。 - 协议文档:`CommunicationProtocol.md`;寄存器速查:`LDC1612_REG_LIST.md` -- 版本策略:`Inc/version.h`(BOARD_TYPE_CODE.主.次.修订,当前 23.1.0.1) +- 命名/版本规则(2026-10-24 起):产物名 `CeramixNano-EDDY_*`,板卡码 **26** + (M999 应答 `v26.主.次.修订`,与 MB 的 25 同源规则);版本维护在 + `cmake/project_config.cmake`(编译时生成 version.h,`Inc/version.h` 说法已过时) ## 工具链与构建 -- 语言/环境:C99,GD32E23x 标准库(`SDK/`) -- 编译器:`arm-none-eabi-gcc`(D:\toolchain\xpack-arm-none-eabi-gcc-15.2.1-1.1) -- 构建:CMake + Ninja,preset `Debug` / `Release`,输出 `Build//Application/Application.elf` - - 命令行构建:`cmake --build Build\Debug`(需 arm-none-eabi-gcc/cmake/ninja 在 PATH) +- 语言/环境:C99,GD32E23x 标准库(`SDK/`),MCU GD32E230F8(64K Flash/8K RAM) +- 编译器:xpack-arm-none-eabi-gcc 15.2.1(`GD32_GCC_BIN` 环境变量解析) +- 构建:CMake + Ninja,preset `Debug` / `Release`,输出 `Build//Application/` + 及 `Build//CeramixNano-EDDY_<版本>__<日期>.bin/.hex` 等 + (variant:dev 线 `APP`,golden 线 `golden`) - 烧录/调试(.vscode/tasks.json、launch.json): - - OpenOCD:`GD32_OPENOCD_BIN` 指向定制构建(含 gd32e23x flash 驱动,CMSIS-DAP HID 后端) + - OpenOCD:`GD32_OPENOCD_BIN` 指向定制构建(含 gd32e23x flash 驱动,CMSIS-DAP 后端) - `Flash MCU (DAPLink)` 任务 + `.vscode/openocd_daplink_gd32e23x.cfg`: - 适配 DAPLink 探针(无 connect_assert_srst,当前共享 cfg 的 connect_assert_srst - 会导致 Cortex-M23 识别失败);烧录命令 `program Application.elf verify reset exit` + 适配 DAPLink 探针(无 connect_assert_srst;该选项在此 DAPLink 上会导致 + examination 失败,但 SRST 线是接通的,见下文排障) - J-Link 任务需 SEGGER 探针 + PATH 中 JLink.exe(当前接的是 DAPLink,不适用) - 调试器探针历史问题(2026-10-02 已解决):DAPLink 的 CMSIS-DAP v1 接口曾被 Zadig 装上 libwdi WinUSB 驱动(oem244.inf),导致 OpenOCD 枚举不到探针;删除该驱动包后 恢复 HID。若复发:管理员运行 `pnputil /delete-driver /uninstall`。 - 串口验证:RS485 转 USB(FTDI,COM15),115200-8N1,**需同时置位 RTS+DTR** (转换器方向控制),否则命令发不出去;DAPLink 虚拟串口为 COM8。 +- 本地测试工具(git 不跟踪,在 `Toolchain/eddy_test/`):`eddy_cmd.py`(D5 帧命令行)、 + `soc_ota.py`(PC 模拟 SOC 完整 OTA/Ymodem,支持 `--abort-after`/`--no-ca` 中止模式)、 + `swd.py`(OpenOCD 封装:probe/image/boot/erasepage/read/dump)、`verify_pack.py`、 + `verify_dump.py`(独立 CRC 复算与读回比对)。 ## 硬件/板级约定(Inc/board_config.h) @@ -35,46 +43,86 @@ GD32E230 电涡流传感器节点固件:LDC1612(电涡流/电感数字转换 - 传感器:LDC1612 @0x2B(40MHz 外部时钟),TMP112 @0x49(ADD0=GND) - 调试宏(均默认关闭):DEBUG_VERBOSE / COM_DEBUG / LDC_DEBUG / EDDY_DRIVE_CURRENT_DETECTION -## 内存布局(仓库默认 = 正式发布布局) +## 双固件布局(2026-10-24 移植完成,与 CeramixNano-MB 完全相同的 Flash 分配) -- **APP 链接在 0x08002000(54K),VECT_TAB_OFFSET=0x2000(Src/system_gd32e23x.c), - 前置 8KB Bootloader**;OTA/Ymodem 打包(_UPDATE.bin/_BL.bin)基于此布局, - 详见 hulk-mcu-firmware skill -- 调试阶段如需脱离 Bootloader 裸机运行(直接烧 0x08000000):临时把 - `LD/gd32e23x_flash.ld` 的 ORIGIN 改为 0x08000000、VECT_TAB_OFFSET 改为 0x00, - **仅限本地临时修改,不要提交推送**(否则烧 _BL 镜像时 Bootloader 会覆盖 APP 头部) -- 修改布局需同时改 `LD/gd32e23x_flash.ld` 的 ORIGIN 与 VECT_TAB_OFFSET +``` +0x08000000 ┌─────────────────┐ + │ Bootloader │ 8K 页 0~7 复用 MB 板 BL bin(V0.1.0,4,044B,MD5 f7b447cf…) +0x08002000 ├─────────────────┤ + │ FW_A 运行槽 │ 36K 页 8~43 OTA/Ymodem 接收区;锚点 A 记录@0x0800AFFC +0x0800B000 ├─────────────────┤ + │ FW_B 出厂保底槽│ 19K 页 44~62 golden 线构建;B 记录@0x0800FBF8 +0x0800FC00 ├─────────────────┤ + │ 末页标志页 │ 1K 页 63 legacy 0xEEEE@0x0800FFFC +0x08010000 └─────────────────┘ +``` + +- **BL 复用**:直接使用 `gd32e230_bootloader` 仓库 `bootloader_CeramixNano_MB` 分支 + V0.1.0 bin(RS485 引脚/波特率/DE 方案与 EDDY 完全一致;唯一差异 LED 引脚 + MB=PA14 / EDDY=PB1——BL 的 LED 仅 Ymodem 收包闪烁,纯装饰,EDDY 板不亮无碍)。 +- **A 线 = dev/main**:链接 0x08002000 / **LENGTH 36K**(LD 上限防溢出 B 槽), + VTOR 0x2000;版本从 V1.0.3 起(首个双固件 A 版本,码 26)。 +- **B 线 = release/golden**:链接 0x0800B000 / LENGTH 0x4BF8(19K−8B,B 记录由打包 + 工具写入,链接区不含尾 8B——与 MB 的 .fw_tail 方案等价),VTOR 0xB000; + **版本冻结 V1.0.2**(保底判定值 = M999 返回 `v26.1.0.2` ⇔ 在跑 FW_B,该版本号 + 永不再用于 OTA 升级包)。此分支改动不得合回 dev/main。 +- 打包:`hulk-mcu-firmware` skill / merge tool profile **`CeramixNano_EDDY_Dual_FW`** + (布局与 `CeramixNano_MB_Dual_FW` 逐字节相同),产出 `_UPDATE/_FULL/_FACTORY + MD5`。 +- 升级链路:上位机(原 SOC 职责)—RS485—> BL(Ymodem);APP 用 `M9999` 软复位进 + 升级模式(SWRSTF=1 ⇒ BL 直留升级模式)。握手:BL 发 `ok` → `0x30` → BL `ok` → + `0x31` → 预擦 A+末页 → `'C'` 周期 → Ymodem(文件头 ACK 后 **ACK+'C' 连发**, + 发送器须一次等齐)→ EOT → ACK×2 → 跳新固件。 +- 完全体方案文档:`E:\Hulk-Coding\capsule_mb_camke_vscode\doc\双固件方案_完全体说明.md`。 ## 开发进度 ### 已完成 -- [x] LDC1612 驱动(初始化/单通道配置/原始值读取/状态检查) -- [x] TMP112 驱动(初始化/温度读取/阈值/单次转换) -- [x] RS485 命令体系:M1/M2(周期上报开关)、M3(涡流原始值)、M4(温度×10000)、 +- LDC1612 驱动(初始化/单通道配置/原始值读取/状态检查) +- TMP112 驱动(初始化/温度读取/阈值/单次转换) +- RS485 命令体系:M1/M2(周期上报开关)、M3(涡流原始值)、M4(温度×10000)、 M5(温度补偿涡流值)、M6(标定数据:涡流+温度)、M999(版本)、M9999(复位) -- [x] v1.0.1:涡流传感器温度标定方法与标定命令(M6) -- [x] 2026-10-02:从模板 gd32e23x_template_cmake_vscode 导入 IIC 驱动改进: - 错误路径改为 i2c_bus_reset() 总线恢复+重试、_i2c_wait_flag_timeout 系列带超时 - 辅助函数、i2c_scan 增加 AERR 处理、新增 i2c_read_raw(无子地址读取)、 - i2c_write/i2c_read 改为 16 位寄存器地址(DLPC 风格,本项目传感器仍走 - i2c_write_16bits/i2c_read_16bits 8 位寄存器路径);移除未使用的 - i2c_read/write_8bits、_32bits、i2c_read_display_params 显示面板便捷函数; - tmp112.c 读取改回 i2c_read_16bits -- [x] 2026-10-02:硬件验证通过——全部命令实测:M3 涡流原始值 ~0x01ADBADC - (室温)/0x01B094BA(板子被手捂热后,随温度同步上移,无错误位)、 - M4 温度 27.25→30.45→29.95°C(跟踪板温变化合理)、M5 补偿值(系数为 0 时≈M3)、 - M1 周期上报(~10ms/帧)开启、M2 停止("ok" 确认)、M6 组合数据、 - M999 版本 v23.1.0.1、M9999 复位(复位后 M999 恢复应答); - 所有响应 CRC 抽查校验正确;Release 预设编译通过(text 11.4KB) -- [x] 2026-10-02:解决 DAPLink 烧录器识别问题(Zadig WinUSB 驱动冲突); - 新增 DAPLink 专用烧录 cfg 与任务 -- [x] 2026-10-02:发布 V1.0.2(Gitea Release + tag,基于 0x08002000 Bootloader - 布局打包 _UPDATE.bin/_BL.bin;dev 顶端另提交调试布局 0x08000000 供日常烧录) +- v1.0.1:涡流传感器温度标定方法与标定命令(M6) +- 2026-10-02:IIC 驱动改进导入(总线恢复重试/超时辅助/read_raw/scan AERR 处理); + 硬件全命令实测通过;DAPLink 烧录问题解决;发布 V1.0.2(Gitea Release + tag) +- **2026-10-24:双固件(出厂救援)方案移植完成并全链路实测通过**(详见下节) + - BL 复用 MB V0.1.0 bin(未改动 BL 代码,仅文档说明) + - dev:LD 54K→36K、命名 CeramixNano-EDDY、板卡码 26、V1.0.3; + golden:V1.0.2 冻结命名 + variant=golden + - 两线 CMake 补齐 `--gap-fill=0xFF` 与 `LD LINK_DEPENDS` + - fw_pack 新增 `CeramixNano_EDDY_Dual_FW` profile(55 项回归过,skill 缓存已同步) + - 产物(`Build/test/dualfw_2026-10-24/`):UPDATE(12 页,trailer 0x5C09000C)、 + FULL(A=V1.0.3/B=V1.0.2,19 项校验过)、FACTORY(12 项校验过)+ MD5 清单; + 独立 python XMODEM 复算全部命中 + - **硬件实测矩阵(SWD 探针 PC 采样 + 485 命令双重手段,全部 PASS)**: + FACTORY→跳B(v26.1.0.2) / FULL→记录路径跳A(v26.1.0.3) / PC 模拟 SOC 完整 OTA + 44s 成功+读回整片逐字节与包一致(B 区在真实 OTA 中毫发无损)/ + 擦锚点页→legacy 跳A / 锚点在位毁A体→CRC 拦截直落B(防降级)/ + 再毁B体→拒跳坏固件停留 BL(PC=0x080001B6) / OTA 第4包 CA 中止→落B / + 非整页裸 bin 包→头部预检 CA×2 拒收→落B / M3/M4/M6 功能全通 ### 计划 / TODO -- [ ] 正式发布前切回 Bootloader 布局(0x08002000/54K)并适配 OTA/Ymodem 打包流程 -- [ ] M5 温度补偿系数目前为 0(TEMP_COMP_COEFF_*),待标定后填入实际温漂系数 -- [ ] 模板侧(gd32e23x_template_cmake_vscode)的 SEGGER RTT / CFG_ENABLE 宏体系 - 尚未同步到本项目(board_config.h 仍是 define/undef 风格),如需对齐另起任务 +- dev → main 合并待发布节奏(V1.0.3 为首个双固件 A 版本,main 仍是 54K 单槽布局) +- M5 温度补偿系数目前为 0(TEMP_COMP_COEFF_*),待标定后填入实际温漂系数 +- 上位机/SOC 侧需预存保底判定值 `v26.1.0.2`(跑 B ⇒ 升级未生效重推) +- (可选)模板侧 SEGGER RTT / CFG_ENABLE 宏体系同步 + +### 教训(避免复发) + +- **SWRSTF 残留**:M9999/调试器软复位置位的 SWRSTF **不随 NRST/SRST 清除**(仅 POR + 或 RSTFC 清),此后任何复位 BL 都直进升级模式、不跳 APP——表现为"设备沉默, + M999 无响应,但 0x30 能回 ok"。排障/测试时须 SWD `mww 0x40021024 0x01000000` + 清标志后再放跑(`swd.py boot` 已内置)。 +- **BL 收到 0x30 后 SWD 必死**:复用的 MB BL 在 0x30 应答后调用 gpio_init 把 + PA14(EDDY 板=SWCLK)切为 LED 输出。因此:探针类 SWD 操作前**不要**发 0x30; + OTA/升级会话结束后 SWD 失联属预期,恢复 = `M9999` 复位(PA14 回默认)后再连。 + 若 APP 也没在跑(BL 卡收包),用 connect_assert_srst 变体 cfg + (`Toolchain/eddy_test/daplink_srst.cfg`)脉冲 SRST 复位恢复——SRST 线已验证接通, + 但该 DAPLink 下 examination 必失败属正常,复位本身生效。 +- **Ymodem 文件头 ACK 后是 ACK+'C' 连发**:发送器若分两次等会永远等不到第二个 'C' + (首次 OTA 调试即栽在此,BL 无超时会卡死;随后发 5×CA 可解)。 +- OpenOCD `program`/`dump_image` 的文件路径必须转正斜杠,否则 Tcl 吃掉 `\l` `\t`。 +- legacy 路径(锚点擦除态+flag 在)**没有 CRC 安全网**:实测毁 A 体后仍会跳进坏 A + 导致 HardFault(xPSR=0x41000003)——这正是 v5 记录机制存在的意义,量产镜像必须 + 带锚点(FULL/OTA 正常路径均带)。 diff --git a/CMakeLists.txt b/CMakeLists.txt index 7da1dd5..78348c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,9 @@ target_link_options(${PROJECT_NAME} PRIVATE -T${CMAKE_SOURCE_DIR}/LD/gd32e23x_flash.ld -Xlinker -L${CMAKE_SOURCE_DIR}/LD ) +# LD 变更时触发重链接(改布局不重编也要重新生成 bin) +set_target_properties(${PROJECT_NAME} PROPERTIES LINK_DEPENDS + ${CMAKE_SOURCE_DIR}/LD/gd32e23x_flash.ld) # 生成 map 文件等 target_link_options(${PROJECT_NAME} PRIVATE @@ -80,7 +83,7 @@ add_custom_command(TARGET ${PROJECT_NAME} COMMAND echo -- Running Post Build Commands COMMAND ${CMAKE_OBJCOPY} -O ihex $ ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_PREFIX}.hex COMMAND ${CMAKE_OBJCOPY} -O ihex $ $/Application.hex - COMMAND ${CMAKE_OBJCOPY} -O binary $ ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_PREFIX}.bin + COMMAND ${CMAKE_OBJCOPY} -O binary --gap-fill=0xFF $ ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_PREFIX}.bin COMMAND ${CMAKE_SIZE} $ COMMAND ${CMAKE_OBJDUMP} -h -S $ > ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_PREFIX}.list COMMAND ${CMAKE_SIZE} --format=berkeley $ > ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_PREFIX}.bsz diff --git a/README.md b/README.md index 71f0bc3..e590814 100644 --- a/README.md +++ b/README.md @@ -41,23 +41,27 @@ cmake --build Build/local-check/Debug --- -## 固件布局与 Bootloader +## 固件布局与 Bootloader(双固件,2026-10-24 起) -GD32E230F8(64KB Flash)按 Bootloader + APP 方式分区: +GD32E230F8(64KB Flash)采用与 CeramixNano-MB 相同的双固件(出厂救援)布局: | 区域 | 地址范围 | 说明 | |---|---|---| -| Bootloader | `0x08000000` - `0x08001FFF`(8KB) | 随板提供,独立固件(`gd32e230f8_bootloader_hulk.bin`),负责 RS485 Ymodem OTA 与跳转 | -| APP(本仓库) | `0x08002000` - `0x0800F7FF`(54KB) | 链接区 `FLASH ORIGIN=0x08002000, LENGTH=54K` | -| 温度标定页(预留) | `0x0800F800` - `0x0800FBFF` | 预留存放标定数据;当前 APP 不访问,仅靠 54KB 链接上限保证不越界覆盖 | -| 有效标志 | `0x0800FFFC` | Bootloader OTA 完成后自写 `0x0000EEEE`,跳转前校验 | +| Bootloader | `0x08000000` - `0x08001FFF`(8KB,页 0~7) | **复用 CeramixNano-MB 板 BL**(V0.1.0,4,044B)——RS485 引脚/波特率/DE 方案完全一致;启动判定链 + RS485 Ymodem OTA | +| FW_A 运行槽(本仓库 dev/main) | `0x08002000` - `0x0800AFFF`(36KB,页 8~43) | 唯一 OTA/Ymodem 接收区;链接 `ORIGIN=0x08002000, LENGTH=36K`(上限防溢出 B 槽);槽尾锚点 A 记录 @`0x0800AFFC` | +| FW_B 出厂保底槽(release/golden 分支) | `0x0800B000` - `0x0800FBFF`(19KB,页 44~62) | 出厂救援固件(版本冻结 V1.0.2),OTA 永不擦写;B 记录 @`0x0800FBF8` | +| 末页标志页 | `0x0800FC00` - `0x0800FFFF`(1KB,页 63) | legacy 标志 `0xEEEE` @`0x0800FFFC` | -工程侧的两个适配点(缺一不可): +启动判定:A 记录在位 ⇒ trailer 比对 + 固件体 CRC 复算 + 向量校验 ⇒ 跳 A(不过直落 B,防降级);锚点擦除态 ⇒ legacy flag ⇒ 跳 A;B 记录 CRC 复算通过 ⇒ 跳 B;否则留 BL 等 Ymodem。OTA 中途断电/中止 ⇒ 重启落 B 跑出厂固件,**设备不变砖**。 -- `LD/gd32e23x_flash.ld`:FLASH `ORIGIN = 0x08002000, LENGTH = 54K`; -- `Src/system_gd32e23x.c`:`VECT_TAB_OFFSET = 0x2000`——Bootloader 不写 VTOR,APP 必须自己把向量表指到 `0x08002000`,否则中断会落回 Bootloader 向量表(现象:收到第一个 RS485 字节即死机)。 +工程侧的适配点: -⚠️ 与旧版布局(APP 链接在 `0x08000000` 的独立镜像)不兼容:从旧版升级需整片烧录一次。RS485 协议、命令集(M1-M6/M999/M9999)与回包格式无任何变化。布局依据与 Bootloader 反汇编分析见 `doc/LDC1612_工程审查与实验方案_2026-09-26.md`。 +- `LD/gd32e23x_flash.ld`:FLASH `ORIGIN = 0x08002000, LENGTH = 36K`; +- `Src/system_gd32e23x.c`:`VECT_TAB_OFFSET = 0x2000`——Bootloader 不写 VTOR,APP 必须自己把向量表指到 `0x08002000`,否则中断会落回 Bootloader 向量表(现象:收到第一个 RS485 字节即死机); +- 出厂保底固件在 `release/golden` 分支构建(`ORIGIN=0x0800B000 / LENGTH=0x4BF8`、`VECT_TAB_OFFSET=0xB000`,版本冻结 V1.0.2,判定值 `v26.1.0.2`); +- 打包(`_UPDATE/_FULL/_FACTORY` + MD5)用 merge tool / `hulk-mcu-firmware` skill,profile `CeramixNano_EDDY_Dual_FW`;产物命名 `CeramixNano-EDDY_*`(板卡码 26)。 + +⚠️ 与旧版 54K 单槽布局不兼容:需整片烧录一次(FACTORY/FULL 镜像)。RS485 协议、命令集(M1-M6/M999/M9999)与回包格式无任何变化。方案完全体文档见 MB 仓库 `doc/双固件方案_完全体说明.md`;开发约定与实测记录见本项目 `AGENTS.md`。 --- diff --git a/cmake/project_config.cmake b/cmake/project_config.cmake index f9e4f31..66426af 100644 --- a/cmake/project_config.cmake +++ b/cmake/project_config.cmake @@ -1,6 +1,8 @@ # Project basic info -set(PROJECT_NAME "LDC1612") -set(BOARD_TYPE_CODE 23) +# golden 出厂保底线:版本号冻结 V1.0.2(保底判定值 v26.1.0.2,永不再用于 OTA 升级包) +# 此分支改动不得合回 dev/main(链接基址 0x0800B000 为 B 槽专属) +set(PROJECT_NAME "CeramixNano-EDDY") +set(BOARD_TYPE_CODE 26) set(VERSION_MAJOR 1) set(VERSION_MINOR 0) set(VERSION_PATCH 2) @@ -11,7 +13,7 @@ string(TIMESTAMP BUILD_DATE "%Y-%m-%d") # Example: HW-IIC_APP / HW-IIC_Bootloader # set(BUILD_VARIANT "AutoDetectDriveCurrent") # set(BUILD_VARIANT "HW-IIC") -set(BUILD_VARIANT "APP") +set(BUILD_VARIANT "golden") # 其它自定义宏 add_definitions(-DBUILD_VARIANT=${BUILD_VARIANT})