Releases: TaoCosmo-Dev/STM32_AutoDebug_Universal_Kit
Release list
v2.4.5 — AGENTS.md / SKILL.md 精简:只写工具用法与事实,不再规定做法
纯文档版本,代码无改动。
参考 OpenAI《Rethinking skills and prompts for GPT-6 Astra》,对给代理看的两份文件做了最小化修改。文章的核心观点是:为了推动旧模型而写的强硬指令,会让能力更强的模型过度执行——在用户其实希望它继续的地方停下来。
改动
| 文章建议 | 之前 | 现在 |
|---|---|---|
| 技能描述要短、触发要窄 | 列了 8 种触发情况,包括「改动任何 STM32 源码」 | 只在需要编译、烧录、上板验证、定位崩溃或新建 F103C8 工程时触发 |
| 根文档当路由,不要一刀切的前置要求 | SKILL「第一步(必做):读完规范,按它执行」 | 改成「什么情况查 AGENTS.md 的哪一节」;删掉 SKILL 里重复抄写的规则 |
| 事先定义完成标准,安全的操作明确授权 | 「严禁直接结束对话,必须跑完闭环」 | 「完成标准是退出码 0;闭环只作用于接好的开发板,可以直接反复运行、修复后重跑,不用每步请示」 |
| 去掉强硬的「先问再做」 | 「严禁盲目动手,新外设必须先追问 5 大分支,用户确认后才编码」 | 只在参数缺失且影响正确性时才问;清单保留在 templates/ 里按需查阅 |
| 保持更新 | 「第一次跑闭环前先自检,全部满足后再进闭环」 | 闭环从 v2.4.2 起每轮都会自动自检,文档改为如实描述 |
| 过细的指导会妨碍强模型 | 7 条通用嵌入式准则、「第一性原理 / YAGNI / 修脚本」一节 | 删除。只保留模型自己不可能知道的内容:退出码、报告字段、工程命令、AC5 中文字符串陷阱、测时间的方法,以及大电流负载要在软件里限幅这一条安全提醒 |
AGENTS.md 中的「严禁」从 11 处减到 0 处;剩下的「必须」都是附带原因的技术事实,例如「新建的 .c 必须注册进工程,否则链接报 L6218E」。
升级
git pull 后运行 python install_skill.py,刷新各编辑器里的 skill 副本。
v2.4.4 — 不再把环境问题当成代码问题;新增时基自检与 HAL 一键启用
本版的问题全部来自第一份真实硬件上的使用报告(STM32F103C8T6 + 板载 ST-Link V2-1,Keil AC5 5.06u3)。报告里的问题大多有一个共同点:环境出了问题(没接线、没装包),套件却把它报成了固件问题,于是 AI 去改了本来正确的代码。
不再误导 AI 改正确的代码
| 问题 | 以前 | 现在 |
|---|---|---|
| 源码一行没改,重跑后失败相同 | 判为「卡住了,上次修改没生效,请换思路」(退出码 5) | 标记 source_unchanged,不计入卡住判定;报告明确说「根因不在代码,先查接线、探针、串口链路、芯片支持包」 |
| 串口一个字节都没收到 | 4 条建议全部指向固件 | 签名改为 TIMEOUT|no bytes,建议先查物理链路;识别出是 ST-Link 虚拟串口(VID 0483)时,直接提醒「很多板子没把它接到 MCU」 |
源码是否改动,按文件内容判断,并在编译之后计算。Keil 每次编译都会用相同内容重写生成的头文件,这不会被误判为改动。
新增:时基自检
通过令牌只能说明测试跑完了,不能说明时间是对的。报告里的真实案例:FreeRTOSConfig.h 里多写了一行 configSYSTICK_CLOCK_HZ,SysTick 被切到 HCLK/8,所有延时慢 8 倍,而闭环照样判定通过。
现在收到通过令牌后,套件会通过 SWD 读两次 uwTick(HAL)与 xTickCount(FreeRTOS),与电脑时钟对比:
- 偏差超过 5%,判
TIMEBASE_SKEW(退出码 3)。报告附上SYST_CSR/SYST_RVR/SystemCoreClock,以及据此推算出的 SysTick 频率。 - 实测正好差 8 倍时,报告直接点名
configSYSTICK_CLOCK_HZ这个陷阱。 - 读内存不会暂停内核,整个检查约 0.5 秒。计数器完全不动的情况(固件测试完后关了中断)不判失败。
- 可用
loop.timebase_check: false关闭。
新增:--enable-hal
HAL 工程要用新外设(ADC、I2C 等)时,原来会连环报错:模块宏没打开、驱动文件不在、没注册进工程。现在一条命令解决:
python run_autodebug.py --project MDK-ARM/App.uvprojx --enable-hal adc i2c- 驱动文件先从工程里找,找不到再从本机 CubeMX 仓库拷贝,优先使用
.ioc记录的固件版本。 - 任何一个模块有问题,就一个文件都不改;重复执行不会重复修改。
- 编译报
stm32f1xx_hal_adc.h找不到、ADC_HandleTypeDef未定义、HAL_ADC_Init未解析时,诊断报告会直接给出这条命令。
配套的 HAL 模板 v1.1 自带全部 HAL 驱动,没装 CubeMX 的电脑上也能直接用这条命令。
芯片支持包自动安装
以前缺芯片支持包时,只打印一条命令让用户自己去执行。现在闭环开始前会自动安装(需联网),装完后会再确认一次 pyOCD 已经认识这颗芯片,而不是只看安装命令的退出码。
无法联网时,把 .pack 文件的路径写进 debugger.pack_files 即可离线使用,每次调试会话和兜底烧录都会带上它。报告里提到的 populate_targets_from_pack 方法只在当前进程内有效,下次运行就失效了,因此没有采用。
其他修复
--add-include A --add-include B只有 B 生效:参数解析的缺陷,--add-source和--add-define同样受影响。现在同一个参数可以写多次,执行后会回显当前完整的包含路径和宏定义列表。- Git Bash 里
tar -xf解压 zip 失败:文档中的解压命令统一改为python -m zipfile -e template.zip .,任何终端都能用。 - 诊断报告位置写错:文档写的是「工程根目录」,实际在
.uvprojx所在目录(CubeMX 工程中即MDK-ARM/)。文档已改正,失败时也会把两个路径都打印出来。 - pip 在 Windows 上装坏包却不报错:
setup_env装完依赖后会清理~开头的残留目录、逐个检查能否导入,失败的包会自动强制重装。 - FreeRTOS
configASSERT类型冲突:cm_backtrace_lite.h里给出了可以直接照抄的接法。 - AGENTS.md 新增第 9 条:测量时间用板子上的 tick,不要用串口的行间距。
报告中未采纳的建议
| 建议 | 原因 |
|---|---|
| 模板打印令牌前先检查 USART 的 UE 位 | 报告中 UE=0 是读错了位:F1 的 UE 在第 13 位,读回的 0x200C 中 UE=1。而且链路不通时,这条失败信息同样送不到电脑 |
模板加 setvbuf(stdout, NULL, _IONBF, 0) |
MicroLIB 本身不做缓冲,加上后只多 16 字节,基本是空函数。报告里的 0.00 s 间隔来自电脑按收到时间打的时间戳 |
升级
git pull 后重新运行一次 setup_env.bat,也可以只运行 python install_skill.py。离线测试:133 → 168 项。
STM32F103C8 HAL 模板工程 v1.1
v1.0 的后续版本,配合套件 v2.4.4 使用。
相比 v1.0 的变化
| 变化 | 说明 |
|---|---|
| 带全部 HAL 驱动 | Drivers/STM32F1xx_HAL_Driver 包含 FW_F1 V1.8.7 的全部 61 个驱动源文件,但工程只编译用到的 12 个,编译时间不变 |
配合 --enable-hal |
要用 ADC、I2C、TIM 等新外设时,run_autodebug.py --enable-hal adc i2c 一步完成「开模块宏 + 补驱动 + 注册进工程」。没装 CubeMX 的电脑上也能直接使用模板自带的驱动 |
| 上板实测结果写入 README | 见下表 |
| 串口接线说明 | 补充了只插一根线、使用板载 ST-Link 虚拟串口时的注意事项 |
| 崩溃追踪器头文件 | 更新到套件 v2.4.4 版本(附 FreeRTOS configASSERT 的接法) |
用 CubeMX 重新生成代码时,CubeMX 会清理没用到的驱动文件。之后再用 --enable-hal,会从本机 CubeMX 仓库补齐。能重新生成,就说明本机已经装了 CubeMX 仓库。
验证情况
| 项 | 结果 |
|---|---|
| 上板(v1.0,STM32F103C8T6 + ST-Link V2-1,Keil AC5 5.06u3) | 烧录后芯片 Flash 与镜像逐字节一致;烧录后内核停在复位入口;LED 正常翻转;uwTick 正常走动;增量编译 0.9 s |
| 串口输出 | 取决于接线。上板那次板载 ST-Link 的虚拟串口没有连到 PA9/PA10,接通链路后输出正常 |
| Keil MDK 5.24a + AC5 5.06u5 | 0 Error / 0 Warning |
| 从压缩包解压后自检 + 编译 | 通过;首次 19 个文件,第二次 0 个 |
本机无 CubeMX 时 --enable-hal adc tim |
使用模板自带驱动,编译 0 Error / 0 Warning |
使用
curl.exe -L -o template.zip https://github.com/TaoCosmo-Dev/STM32_AutoDebug_Universal_Kit/releases/download/template-f103c8-hal-v1.1/STM32F103C8_HAL_Template.zip
python -m zipfile -e template.zip .
python <套件目录>/run_autodebug.py --project STM32F103C8_HAL_Template/MDK-ARM/Template.uvprojx解压用 python -m zipfile,任何终端都能用;Git Bash 里的 tar 不认 zip。
许可证
| 部分 | 许可证 |
|---|---|
Drivers/STM32F1xx_HAL_Driver/ |
BSD-3-Clause |
Drivers/CMSIS/ |
Apache-2.0 |
Core/、MDK-ARM/ |
由 STM32CubeMX 生成,按原样(AS-IS)提供;模板加入的代码使用 MIT |
mcu_support/ |
MIT |
v2.4.3 — CubeMX 工程的增量编译修复,新增 HAL 模板
修复:CubeMX 生成的工程每次仍全量重编
v2.4.1 加入了编译器记录同步(<pCCUsed>),用来避免 Keil 批处理编译时每次都重编所有文件。但 STM32CubeMX 生成的工程里既没有 <pCCUsed> 也没有 <uAC6>,而同步逻辑只会把记录插在 <uAC6> 前面,于是在 CubeMX 工程上完全没有生效。偏偏这正是 HAL 用户最常见的起点。
现在找不到 <uAC6> 时,会改为插在 <ToolsetName> 之后(µVision 自己保存时也放在这里)。<uAC6> 依然不会被添加,编译器选择保持工程原样。
在 CubeMX 生成的 F103 工程上实测:
| 修复前 | 修复后 | |
|---|---|---|
| 源码无改动时再编译 | 19 个文件 | 0 个文件 |
只改 main.c |
19 个文件 | 1 个文件 |
新增:STM32F103C8 HAL 模板
- 由 STM32CubeMX 6.16.1 + FW_F1 V1.8.7 生成,附带
Template.ioc,可用 CubeMX 打开修改引脚和外设 - 四个故障中断取消了「Generate IRQ handler」,重新生成代码时不会与崩溃追踪器冲突
- 实测:加一个外设后重新生成,崩溃追踪器、工程设置、
USER CODE区块内的代码全部保留
代理遇到 F103C8 且还没有工程时,现在默认下载 HAL 版;用户明确说用标准库时才用标准库版。AGENTS.md 与 SKILL.md 同时要求:在 HAL 工程里写的代码必须放在 USER CODE 区块内,否则会被 CubeMX 覆盖。
其他
- 离线测试:132 → 133 项
- 升级:
git pull后重跑python install_skill.py,刷新各编辑器里的 skill 副本
v2.4.2 — 烧录前检查固件契约,缺令牌时不再白等 15 秒
变化
以前的固件契约检查(有没有打印通过令牌、有没有调用 cm_backtrace_init()、有没有串口输出函数)只在超时之后才运行。固件忘了打印通过令牌时,每次都要先烧录,再干等满 15 秒,报告才说出原因。
现在编译通过后、烧录之前就检查一次,结果写在日志开头:
| 情况 | 以前 | 现在 |
|---|---|---|
| 源码里找不到通过令牌 | 烧录 → 等满 15 秒 → 超时报告 | 烧录 → 只等 3 秒(用来抓崩溃)→ 超时报告,并注明原因 |
| 固件契约已满足 | — | 多一次源码扫描,毫秒级 |
不拦截任何步骤:编译、烧录、串口捕获、SWD 读故障寄存器照常执行,退出码不变。令牌如果放在工程目录之外,设 test.precheck_firmware: false 即可恢复原来的行为。
新增配置项(test 节):
precheck_firmware: true
no_token_wait_seconds: 3评估后决定不做:编译前检查 RTE 芯片包
原计划在编译前检查 RTE 引用的芯片包是否已安装,以防 Keil 弹窗卡住,最坏要等满 600 秒的编译超时。在 MDK 5.24a 上实测了两种情况:
| 情况 | 结果 |
|---|---|
| RTE 引用的 CMSIS 版本本机没有 | 自动改用已安装的版本,正常编译,约 3.5 秒 |
| 整个芯片支持包(DFP)都没装 | 按工程里保存的设置照常编译,约 3.8 秒 |
两种情况都不弹窗、不卡住,这个检查省不下任何时间,所以没有加。
其他
- 离线测试:128 → 132 项
firmware_precheck()扫描一次源码,同时返回问题清单和「是否找到通过令牌」;check_firmware_contract()的签名保持不变
v2.4.1 — 命令行入口修复,增量编译恢复,F103C8 模板工程
Important
v2.3.0 至 v2.4.0 的命令行入口无法运行,请升级到本版本。 这些版本里,run_autodebug.py 的任何命令都会在启动时直接报 UnboundLocalError 退出。
本版的问题全部是在用真实 Keil 工程端到端编译时发现的,而不是读代码读出来的。它们都通过了原有测试,因为测试用的夹具比 µVision 实际生成的文件简单。
修复
| 问题 | 影响 | 修复 |
|---|---|---|
--project 参数从未赋值给 proj_path |
v2.3.0 起,任何命令都在启动时崩溃 | 补上赋值,新增真正调用命令行入口的测试 |
--add-include / --install-tracer 把包含路径写进了 <TargetCommonOption><IncludePath> |
那是 Folder Setup 用的路径,编译器看不到;命令却提示「已加入」,随后编译报 #5: cannot open source input file |
改为写入 C 编译器的 <Cads> 节;--add-define 同样处理 |
µVision 日志中的 AC5 错误格式 main.c(17): error: #5: ... 没有被解析 |
编译失败时报告里没有任何错误条目,只有「未生成镜像」,AI 无从下手 | 新增该格式的解析;原先断言「应忽略这一行」的测试已更正 |
性能:增量编译恢复
工程里的 <pCCUsed>(上次使用的编译器版本)缺失或与本机不符时,UV4 -b 每次都会重编所有文件:µVision 在内存中更正了版本,但批处理模式从不保存。从别的电脑拷来的工程、手写的工程都会触发这个问题。
现在每次编译后,套件会把 UV4 实际使用的编译器写回工程(auto_sync_compiler,默认开启)。在 F103C8 模板上实测:
| 修复前 | 修复后 | |
|---|---|---|
| 源码无改动时再编译 | 29 个文件 | 0 个文件 |
只改 main.c |
29 个文件 | 1 个文件 |
如果工程里记录的版本与本机一致、只是目录写法不同,套件不会改动,因为那可能是对方机器上的正确写法。
新增:STM32F103C8 模板工程
首次实战复盘里,接入耗时的约一半花在从零手写 .uvprojx 上。现在提供一个开箱即可编译的模板,已接好崩溃追踪器和通过令牌,标准库与 CMSIS 全部随包:
SKILL.md 与 AGENTS.md §3.0 已同步更新:遇到 F103C8 且还没有工程时,代理会直接下载模板,不再手写。
其他
- 离线测试:114 → 128 项
- 升级方式:
git pull后重跑python install_skill.py,刷新各编辑器目录里的 skill 副本
STM32F103C8 标准库模板工程 v1.0
给手头还没有 Keil 工程的用户:解压即可进入 AutoDebug 闭环,不用手写 .uvprojx,也不用找 CMSIS 头文件或安装 RTE 组件。
首次实战复盘中,接入耗时的约一半花在从零手写工程上,这个模板就是为了省掉这一步。
内容
| 项 | 内容 |
|---|---|
| 芯片 | STM32F103C8T6(Blue Pill / 最小系统板),8 MHz HSE 倍频至 72 MHz |
| 库 | 标准外设库 V3.6.2 与 CMSIS Core 5.0.1,全部随工程提供,不依赖 RTE 组件或外部 pack |
| 已接入 | 崩溃追踪器(USART1)、通过令牌 [ALL TESTS PASSED]、printf 重定向(MicroLIB) |
| 接线 | SWD 四线;PA9(TX) / PA10(RX) 接 USB-TTL,115200 8N1;PC13 为板载 LED |
验证情况
| 项 | 结果 |
|---|---|
| Keil MDK 5.24a + AC5 5.06u5 | 0 Error / 0 Warning,Code=3604 B |
| Keil MDK 5.24a + AC6 6.7 | 0 Error(ST 标准库在 All Warnings 档位下有 27 条提示) |
--check-firmware |
固件侧契约已满足 |
| 增量编译 | 无改动时 0 个文件,只改 main.c 时 1 个文件(需要套件 v2.4.1 及以上) |
| 从压缩包解压到新目录后自检 + 编译 | 通过 |
| 上板烧录与串口输出 | 尚未实测 |
使用
curl.exe -L -o template.zip https://github.com/TaoCosmo-Dev/STM32_AutoDebug_Universal_Kit/releases/download/template-f103c8-v1.0/STM32F103C8_StdPeriph_Template.zip
python -m zipfile -e template.zip .
python <套件目录>/run_autodebug.py --project STM32F103C8_StdPeriph_Template/MDK-ARM/Template.uvprojx解压用 python -m zipfile,任何终端都能用;Git Bash 里的 tar 是 GNU tar,不认 zip。详细说明见压缩包内的 README.md。
许可证
| 部分 | 许可证 |
|---|---|
User/、MDK-ARM/、mcu_support/ |
MIT |
StdPeriph/、Device/、Startup/ |
STMicroelectronics SLA0044,只能用于 ST 的芯片 |
CMSIS/Include/ |
Apache-2.0 |
模板单独以 Release 附件发布,没有放进仓库代码,因为 ST 标准库不能并入 MIT 许可范围。
STM32F103C8 HAL 模板工程 v1.0
Note
已有新版 v1.1:带全部 HAL 驱动,配合套件 v2.4.4 的 --enable-hal 使用,并补充了上板实测结果。新项目请用 v1.1。
给平时用 STM32CubeMX + HAL 库的开发者:解压即可进入 AutoDebug 闭环,也可以直接用 CubeMX 打开 Template.ioc 修改引脚和外设。
使用标准外设库的,请用 标准库版模板。
内容
| 项 | 内容 |
|---|---|
| 芯片 | STM32F103C8T6(Blue Pill / 最小系统板),8 MHz HSE 倍频至 72 MHz |
| 生成方式 | STM32CubeMX 6.16.1 + STM32Cube FW_F1 V1.8.7,只复制用到的库文件 |
| 已接入 | 崩溃追踪器(USART1)、通过令牌 [ALL TESTS PASSED]、printf 重定向(MicroLIB) |
| 接线 | SWD 四线;PA9(TX) / PA10(RX) 接 USB-TTL,115200 8N1;PC13 为板载 LED |
| 编译器 | 工程不指定具体版本,使用本机 Keil 的默认编译器,AC5 / AC6 都能编译 |
所有新增代码都在 USER CODE 区块内。Error_Handler 也改成了先通过串口报告位置再停机,不再无声地卡死。
用 CubeMX 重新生成不会丢东西
NVIC 配置中取消了四个故障中断(Hard fault / Memory management / Bus fault / Usage fault)的「Generate IRQ handler」。这四个处理函数由崩溃追踪器提供,CubeMX 不会再生成空的版本与之冲突。
实测:在 Template.ioc 中新增 USART2 后重新生成,main.c 被改写(加入了 USART2 初始化),而以下内容全部保留,编译结果为 0 Error / 0 Warning:
USER CODE区块内的代码(printf重定向、崩溃追踪初始化、通过令牌、Error_Handler报告)stm32f1xx_it.c中仍然没有空的故障处理函数- Keil 工程中的
AutoDebug分组、mcu_support包含路径、MicroLIB 设置
验证情况
| 项 | 结果 |
|---|---|
| Keil MDK 5.24a + AC5 5.06u5 | 0 Error / 0 Warning,Code=5268 B |
| Keil MDK 5.24a + AC6 6.7 | 0 Error(HAL 库和 CubeMX 生成代码在 All Warnings 档位下有 40 条提示) |
--check-firmware |
固件侧契约已满足 |
| 增量编译 | 首次 19 个文件,之后无改动时 0 个,只改 main.c 时 1 个(需要套件 v2.4.3 及以上) |
| 从压缩包解压到新目录后自检 + 编译 | 通过 |
| 上板烧录与串口输出 | 发布时尚未实测;之后已在 STM32F103C8T6 + ST-Link V2-1 上实测通过,详见 v1.1 |
使用
curl.exe -L -o template.zip https://github.com/TaoCosmo-Dev/STM32_AutoDebug_Universal_Kit/releases/download/template-f103c8-hal-v1.0/STM32F103C8_HAL_Template.zip
python -m zipfile -e template.zip .
python <套件目录>/run_autodebug.py --project STM32F103C8_HAL_Template/MDK-ARM/Template.uvprojx解压用 python -m zipfile,任何终端都能用;Git Bash 里的 tar 是 GNU tar,不认 zip。串口分配、换用其他 USART 的方法等详见压缩包内的 README.md。
许可证
| 部分 | 许可证 |
|---|---|
Drivers/STM32F1xx_HAL_Driver/ |
BSD-3-Clause |
Drivers/CMSIS/ |
Apache-2.0 |
Core/、MDK-ARM/ |
由 STM32CubeMX 生成,按原样(AS-IS)提供;模板加入的代码使用 MIT |
mcu_support/ |
MIT |
v2.4.0 — 补上「进入闭环之前」的短板
来自首位外部用户在另一台电脑上的实战复盘:从零点亮 F103C8T6 + OLED 共约 27 分钟,其中 Keil 真正编译约 1 分钟。闭环引擎本身零故障,时间全部消耗在进入闭环之前 —— 而其中多数故障在动手前就能确定,却都指向了错误的方向。
🐛 修复
AC5 源码编码陷阱(约占本次 27% 的时间)
armcc 按本机代码页解析源文件(中文 Windows 上是 GBK),UTF-8 中文字面量会报:
main.c(42): error: #8: missing closing quote
报错指向引号而非编码,会把排查引向语法方向,怎么查都查不出来。
- 写入
AGENTS.md嵌入式黄金准则第 8 条 --check-firmware扫描字符串字面量,点名文件与行号- 注释不检查:注释不参与字面量解析,误报会让这项检查在有中文注释的工程里无法使用
preflight 提前拦截确定性故障
未插调试器、缺 CMSIS 器件包,此前都要等到编译成功之后才以 pyOCD 异常的形式出现。
- 现在提前检查,且仅在调用方声明将访问硬件时执行 ——
--no-flash只编译,不该要求插探针 - 提示直接给出可复制的命令,例如
python -m pyocd pack install stm32f103c8,而非仅描述问题
<Target> 匹配截断导致调试信息开关静默失效
复盘报告称 project_editor.py 已修好、builder.py 是未同步的旧实现。逐行核查发现报告所说的修复函数并不存在 —— 两处都是同一份朴素正则 <Target>.*?</Target>。
uVision 在 <TargetOption><DebugOption> 内还嵌套了一个 <Target> 元素。实测该结构下:
| 旧实现 | 新实现 | |
|---|---|---|
| App 目标块长度 | 232 字节(被截断) | 330 字节 |
含 <CreateExecutable> |
❌ | ✅ |
<CreateExecutable> 正是 ensure_debug_information 插入调试信息开关的锚点。锚点落在块外 → 修改静默失效 → 编译产物不含 DWARF → 崩溃无法定位到源码行。
改为按深度计数的单一实现 iter_target_spans(),两处共用,不会再漂移。
其它
install_skill.py补.workbuddy—— 此前 WorkBuddy 用户安装显示成功,但 skill 从未被加载- 构建管道补
encoding="utf-8", errors="replace"——text=True单独使用时按本机 ANSI 代码页解码,UV4 输出一个非 GBK 字节即抛UnicodeDecodeError中断构建 CM_BACKTRACE_PROVIDE_HANDLER补注释 ——== 1表示由本文件定义HardFault_Handler,与字面理解相反
🧪 测试
新增 tests/test_onboarding_fixes.py(18 项),离线自测 96 → 114。
⏳ 未完成:模板工程
复盘报告将「提供最小可编译模板工程」列为第一优先,这一判断成立。但它需要真实的 CMSIS Core 与标准外设库文件才有意义 —— 凭空构造一个,正是 v2.3.0 移除 --create-project 的原因:看起来正确、实际编译不过的脚手架。留待取得可用工程文件后单独处理。
Full Changelog: v2.3.3...v2.4.0
v2.3.3 — Python 版本校验,修复 cmd 撕裂中文行
两个问题出在同一处入口,第二个是在修第一个时撞出来的。
🔍 安装脚本此前不校验 Python 版本
只要 PATH 里有 python 就直接采用。装的是 3.8 时,第 1 步不报错,拖到装依赖时才以 pip 的报错形式暴露 —— 而那时的错误信息指向依赖解析,而非真正的版本问题。
更隐蔽的是:pip 未必报错。旧解释器下它会静默装上一个还支持该版本的老版 pyelftools,其 DWARF 5 支持较弱,崩溃定位随之失准,而全程没有任何提示。
现在第 1 步显式验版:
- PATH 里版本过低时,改从已知安装位置查找合格版本
- 均不可用时,明确告知检测到的版本、来源路径、3.10 的原因,以及 PATH 中旧版排序靠前时的处理办法
requirements.txt 中记录了版本下限的唯一来源是 pyelftools(0.33 起要求 3.10)—— 本套件自身的代码没有用到任何 3.10 专属语法。
不做自动升级是有意为之:静默改动用户的 Python 环境可能破坏其它项目,且需要管理员权限。
🐛 cmd.exe 会把批处理里的中文行拦腰截断
编写上述中文提示时暴露:cmd 按固定块读取批处理文件,跨块边界的多字节字符被撕裂后,行尾残余会被当成命令执行。
期望: 该库 0.33 版起要求 Python 3.10。这是唯一的版本下限来源。
实际: '这是本套件唯一的版本下限来源。' is not recognized as an internal or external command
断在哪一行完全由字节偏移决定 —— 增加一个字节的填充,断点就换位置。因此文件任何位置的编辑都可能让另一行出问题,现有文件"能跑"只是字节布局碰巧合适。
实测 11 种偏移:
| 编码 | 出错次数 |
|---|---|
| UTF-8 无 BOM | 1 / 11 |
| UTF-8 有 BOM | 0 / 11 |
| GBK 无 chcp | 0 / 11 |
三个发布脚本(setup_env.bat、setup_env.ps1、inject_to_project.bat)统一加 UTF-8 BOM。选 BOM 而非 GBK,是因为 GBK 仅在中文 Windows 上正确。此改动同时解决 PowerShell 5.1 将 .ps1 按 ANSI 读取的问题。
🔧 另修两处批处理陷阱
::注释仍会被扫描重定向符。注释中的>=会将该行截断,其后内容被当作命令执行。- 延迟扩展与字面量
!冲突。启用enabledelayedexpansion后,同一行中的字面量[!]与!VAR!会让 cmd 把两个!之间的文本当作变量名展开为空:[!] PATH 里的 Python 是 !PY_BAD!输出为[PY_BAD,...。
🧪 测试
新增 tests/test_setup_scripts.py,覆盖上述四项。离线自测 91 → 96 项。
执行型测试有一处设计要点:逐字节复制发布文件,并通过 PATH 上的 stub python 拦截副作用。截断文件会改变字节偏移,测到的是永远不会发布的布局 —— 该测试的第一版正是这样写的,报出了一个发布版中并不存在的错误。
完成后移除 BOM 复验,测试如期失败,守卫有效。
Full Changelog: v2.3.2...v2.3.3