现状口径:/keil-build 与 /serial-boot-test 是 DSH 会话的技能调用名, 不是 shell 命令;「名 + 命令行参数」的命令形态改为可执行体 run_boot_test.py 的真实调用。 - AGENTS.md:别名说明重写为「技能调用名不是 shell 命令」,两条目改 「编译(/keil-build)」「串口回归(/serial-boot-test)」 - keil-build / serial-boot-test 两 skill 调用名与示例同步;task-worktree 方案文档去掉 @build/@test 惯例从句;@task 保留(不在点名范围) - 123 文件现状陈述全改;台架捕获、变更记录/时间线、rename 映射输入 等 41 行历史证据保留旧名 - gen_memory_svg.py 6 处措辞随改,3 张 SVG 产物同批重跑 - 顺手补并行方案同行漏网计数 51→52 钩子 验证:提交期快钩子对 123 文件实跑全 Passed;check_doc_links --all rc=0(3038 处、无法判定 0);check_mermaid --all rc=0;YAML 解析 52 钩子不变;skill-size rc=0;py_compile 全过;字节卫生零漂移。
8.3 KiB
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/锚点计数/顺序/耗时),可单独用。--exact 做整行 ^…$ 锚定(子串口径照不出"行还在但行首被吃掉/行内被插字节"那一类损坏)、--pair 做跨复位配对、--allow-residual/--head-char 服务崩溃注入腿、--selftest 跑内置判别用例(证明这套判据不是空跑)。四个行级开关(--exact / --pair / --allow-residual / --head-char)同时接进了 run_boot_test.py,/serial-boot-test 闭环直接可用 |
/serial-boot-test是 DSH 会话的技能调用名、不是 shell 命令(同/keil-build,见 AGENTS「构建与验证」总口径):可执行形态 = 上表run_boot_test.py命令行(仓库根跑);项目配置与判据见本仓docs/测试说明/流程与规范/自动化测试流程.md。
判据取向(重要,会复发):
--exact默认只锚文本、不钉长度——字节长度属于某一份构建,钉死它会在无辜改动上假红(@@LEN=<n>是显式逃生口,不是默认)。子串--required不能用于"可能丢行首/被插字节"的行。来龙去脉与固定动作见本仓docs/测试说明/专项验证/启动日志原子性复验流程.md。
交互式串口操作(open/send/log/wait-idle/status 等)不属于本 skill——
用 serial-assistant skill。
前置条件
- 解释器需装有 pyserial(闭环经采集层脚本用串口)。优先用项目自己的 venv;
否则按
serial-assistantskill 的"前置条件"建专用 venv。 下文$PY= 选定的解释器,$SKILL=.dsh\skills\serial-boot-test(项目根下相对路径)。 - 所有命令都在项目根目录下运行(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 |
顺序校验 / 复位原因白名单 / 套件汇总行 | 空 = 关闭 |
selftest_scope |
自检台账判定口径:this-run(烧录前取基线,只判新增)/ all(累计,任一记录即 FAIL) |
this-run |
ftp_user / ftp_pass |
抓 /log/selftest.log 用的 FTP 账号(设备无匿名通道) |
admin / admin |
require_selftest_pass + device_ip |
设备侧自检台账联合判定(FTP 抓取;默认只判本次启动新增,抓取失败/无数据源一律 FAIL) | 关闭 |
先跑项目的构建(本仓库 = 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 容忍)。