Skip to content

Releases: TaoCosmo-Dev/STM32_AutoDebug_Universal_Kit

v2.4.5 — AGENTS.md / SKILL.md 精简:只写工具用法与事实,不再规定做法

Choose a tag to compare

@TaoCosmo-Dev TaoCosmo-Dev released this 30 Sep 12:28

纯文档版本,代码无改动。

参考 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 一键启用

Choose a tag to compare

@TaoCosmo-Dev TaoCosmo-Dev released this 30 Sep 11:58

本版的问题全部来自第一份真实硬件上的使用报告(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

Choose a tag to compare

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 模板

Choose a tag to compare

@TaoCosmo-Dev TaoCosmo-Dev released this 27 Sep 11:56

修复: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 模板

STM32F103C8 HAL 模板工程 v1.0

  • 由 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 秒

Choose a tag to compare

@TaoCosmo-Dev TaoCosmo-Dev released this 27 Sep 11:23

变化

以前的固件契约检查(有没有打印通过令牌、有没有调用 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 模板工程

Choose a tag to compare

@TaoCosmo-Dev TaoCosmo-Dev released this 27 Sep 11:11

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 全部随包:

STM32F103C8 标准库模板工程 v1.0

SKILL.md 与 AGENTS.md §3.0 已同步更新:遇到 F103C8 且还没有工程时,代理会直接下载模板,不再手写。

其他

  • 离线测试:114 → 128 项
  • 升级方式:git pull 后重跑 python install_skill.py,刷新各编辑器目录里的 skill 副本

STM32F103C8 标准库模板工程 v1.0

Choose a tag to compare

@TaoCosmo-Dev TaoCosmo-Dev released this 27 Sep 11:09

给手头还没有 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

Choose a tag to compare

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 — 补上「进入闭环之前」的短板

Choose a tag to compare

@TaoCosmo-Dev TaoCosmo-Dev released this 24 Sep 03:24

来自首位外部用户在另一台电脑上的实战复盘:从零点亮 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 撕裂中文行

Choose a tag to compare

@TaoCosmo-Dev TaoCosmo-Dev released this 19 Sep 04:30

两个问题出在同一处入口,第二个是在修第一个时撞出来的。

🔍 安装脚本此前不校验 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