Files
STM32F4-Base/.dsh/skills/serial-boot-test/SKILL.md
T
wandering1 5009a844a9
CI / L0 静态门禁 (pre-commit) (push) Has been cancelled
CI / L0.5 主机侧单测 (MSVC) (push) Has been cancelled
收敛 reset.bat 到 stlink-flash skill 并删除该批处理
stlink_flash.py 新增 hard 子命令(-c SWD RM=Hrst -HardRst PULSE=100),
RM= 被 CLI 拒绝时自动降级为系统复位并打印 RESET_NOTE;至此 reset.bat 的
全部子命令(复位/hard/halt/run/list/flash/cmp)均已由 skill 覆盖。

删除 MDK-ARM/reset.bat(git rm)。@build/@download 两条旧批处理入口至此
全部收敛到 .dsh/skills/ 下的 skill,一个能力一个实现。

同步更新引用:AGENTS.md、README、MDK-ARM/README、7 篇 docs、4 个 skill
(stlink-flash/serial-boot-test/new-machine-setup 及 config.example.json)。

真机验证:hard 子命令 RM= 被拒 → RESET_NOTE → 回退系统复位 → STLINK_RC=0。
2026-10-10 16:41:46 +08:00

6.8 KiB
Raw Blame History

name, description, whenToUse
name description whenToUse
serial-boot-test 嵌入式目标"烧录/复位 → 抓串口开机日志 → 标记校验"一键闭环。构建在 serial-assistant skill(串口采集层)之上,自带烧录测试编排器与日志标记校验器;项目差异全部收在 <项目根>/.serialtest/config.json,任何带调试串口的项目都能用。 需要向目标板烧录或复位后,用串口日志自动判定运行是否正常(开机回归、固件身份校验、HardFault/FAIL 标记扫描、开机耗时测量),或需要交互式串口收发与日志回放时。

serial-boot-test — 串口自动验证(判定层,构建在 serial-assistant 之上)

分层:采集层 = 兄弟 skill serial-assistant(常驻 daemon 串口助手), 本 skill 只负责闭环编排 + 判定。换项目时把 serial-boot-test 和 serial-assistant 两个文件夹一起拷进目标项目的 .dsh/skills/ (或 .agents/skills/),脚本不含任何仓库路径。

脚本 作用
.dsh/skills/serial-boot-test/scripts/run_boot_test.py 一键闭环:open+clear → 烧录 → wait-idle → 提取 boot log → 烧录回读校验 → 标记校验。串口助手按 $DSH_SERIAL_TOOL > 同目录 > ../serial-assistant/scripts/serial_tool.py 解析
.dsh/skills/serial-boot-test/scripts/verify_log.py 对任意日志文件做标记校验(Required/Forbidden/锚点计数/顺序/耗时),可单独用

交互式串口操作(open/send/log/wait-idle/status 等)不属于本 skill—— 用 serial-assistant skill。

前置条件

  1. 解释器需装有 pyserial(闭环经采集层脚本用串口)。优先用项目自己的 venv; 否则按 serial-assistant skill 的"前置条件"建专用 venv。 下文 $PY = 选定的解释器,$SKILL = .dsh\skills\serial-boot-test(项目根下相对路径)。
  2. 所有命令都在项目根目录下运行(cwd 决定配置源解析)。

第一步:项目档案(每个项目一次)

配置解析顺序:$DSH_SERIAL_CONFIG > <cwd>/.serialtest/config.json > <cwd>/.opencode/serial_config.json(旧位置,仅串口字段)。

若项目没有 .serialtest/config.json:先从项目文档(AGENTS.md/README/测试文档)推断各字段,推断不了的问用户,然后按 config.example.json 写一份。字段含义:

键 含义 缺省行为
portName / baudRate 串口 无 portName 直接 exit 3
flash_cmd 烧录命令(必须含复位运行,如 -Rst -Run;可带参数) 空 = 不烧录,脚本提示人工复位板子
hex 刚构建的镜像(Intel HEX),供身份戳 + 回读比对 空 = 两项都跳过(WARN)
fw_marker 固件身份戳前缀(固件里打印 "<前缀>" __DATE__ " " __TIME__) 默认 fw build: ;hex 里无此串只 WARN 不假判
readback_cmd 回读校验命令模板,{hex} = 镜像路径(引号自动加) 空 = 跳过
readback_ok 回读成功判据(按行首匹配,大小写不敏感) no difference found
required 必须出现的标记(; 分隔,大小写敏感) 空 = exit 3(必须给)
forbidden 禁止出现的模式(; 分隔,大小写不敏感) FAIL;ERROR;HardFault
boot_marker 一轮启动的锚点子串(如 reset cause:) 空 = 锚点计数关闭
max_boot_count 锚点出现 0 次或 >N 次 = FAIL 1(仅 boot_marker 非空时生效)
done_marker + max_boot_ms 开机耗时口径与上限 空/0 = 只报告不判
settle_ms / max_wait_ms / first_wait_ms RX 静默判据 / 总超时 / 首字节超时 8000 / 30000 / 12000
require_order / expect_reset_cause / require_suite_summary 顺序校验 / 复位原因白名单 / 套件汇总行 空 = 关闭
require_selftest_pass + device_ip 设备侧自检台账联合判定(FTP 抓取) 关闭

先跑项目的构建(本仓库 = keil-build skill,其它 Keil 项目照该 skill 套; 非 Keil 项目用项目自己的构建入口),确认 0 错误 0 警告后再进闭环。 档案里的 flash_cmd/readback_cmd 就是烧录层的入口命令 (本仓库 = stlink-flash skill 的 stlink_flash.py flash / cmp {hex})。

第二步:跑闭环

# cwd = 项目根目录
& $PY "$SKILL\scripts\run_boot_test.py"
# 临时覆盖:--port COM7 --required "..." --forbidden "..." --flash-cmd "..."

退出码:0=PASS / 1=FAIL(标记缺失或命中)/ 2=采集或烧录错误(含回读不一致,本次运行作废)/ 3=用法/预检错误。

产物:boot log(每行带 [+Nms] 相对时基)写到 %TEMP%\serial-boot-test\boot_log_<时间戳>.txt(--out-dir 改,保留最近 20 份)。

第三步:判读与迭代

  • PASS → 报告命中的标记与开机耗时。
  • FAIL → [MISS]/[HIT] 行(Forbidden 命中带行号+内容)+ 日志尾部已给出;需要更多上下文直接 Read/Grep boot log 文件或 status 里 log.path 指向的 serial.log。修代码 → 重新构建 → 重跑闭环。
  • exit 2 no_data → 板子全程零字节:查端口在位(ports)、板电、烧录命令是否真的复位了目标。

交互式串口调试(不跑闭环时)

用 serial-assistant skill(ports/open/send/log/clear/wait-idle/status 全套命令、 抓开机日志铁律、daemon 陷阱都在那边)。本 skill 不重复采集层用法。

陷阱(都是实测教训)

  • daemon 一台机只有一个(HTTP 口 18765 独占绑定,由采集层 serial-assistant 管理)。改配置后必须 restart(daemon 启动时缓存配置)。若机器上还有旧 daemon,先 status 看 daemon.version(serial-assistant 版 = 1.1.0-skill)确认归属,必要时 stop 后重开。
  • 回读校验排在日志采集之后:部分烧录工具(如 ST-LINK -CmpFile)连接时会复位目标,提前跑会截断开机日志。脚本已按此顺序,勿手工调换。
  • 烧录命令必须让目标复位运行(裸 -P 类写入在目标核死循环时不落地);写完镜像后 fw build 身份戳校验会揭穿"芯片还是旧镜像"。
  • settle_ms 必须大于固件的自然静默间隙(常见 3~4s),默认 8000;日志被截断先调大它。
  • Required 标记宁少勿多:先用启动锚点 + 少数里程碑标记;按用例临时覆盖 --forbidden(预期出现的 [ERR] 负路径用例)。
  • 烧录与串口采集不冲突:SWD 下载走探针、调试日志走 USB-serial(CH340 类),互不占用;烧录期间串口侧静默几秒属正常,不算 no_data(首字节门会兜住)。
  • 中文/编码:脚本全程字节级处理,不受控制台代码页影响;配置文件存 UTF-8(BOM 容忍)。