现状口径:/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 全过;字节卫生零漂移。
启动日志(boot_log)存档
本目录保存 /serial-boot-test(.dsh/skills/serial-boot-test/scripts/run_boot_test.py)产出的开机串口日志快照,
用于跨构建的栈 / 堆水位对照(解析其中的 [STACK] 行)。
1. 为什么需要存档
/serial-boot-test默认把 boot_log 写到临时目录%TEMP%\serial-boot-test\boot_log_<时间戳>.txt——会被系统清理;- 台架长跑的 20MB 串口日志截头会丢掉早期
[STACK]水位行(开机首次约 5s 后才报告); - 两者叠加导致无法事后回溯"改代码前后"的栈水位变化。
因此凡涉及栈 / 堆预算的改动或基线重采,必须把该轮的 boot_log 快照固化到本目录。
2. 约定
| 项 | 规则 |
|---|---|
| 来源 | & '.venv\Scripts\python.exe' .dsh/skills/serial-boot-test/scripts/run_boot_test.py(默认 --out-dir %TEMP%\serial-boot-test,产出 boot_log_<stamp>.txt + selftest_log_<stamp>.log) |
| 命名 | <日期>_<构建标识>_boot_log.txt,例:20261005_prod_none_boot_log.txt |
| 构建标识 | 建议含:产品 / 测试套件(prod_none / suite_ch395f …)+ 负载(idle / v5_30min / ftp_stress) |
| 随文件登记 | 在下方 §3 清单登记日期、构建、负载、关键 [STACK] 水位(如 defaultTask 峰值) |
| 入库门槛 | 只存有对照价值的快照——常规 /serial-boot-test 通过日志不必入库 |
| 故障注入日志 | 含刻意产生的 [ERR] 行(如兜底门闭锁)的日志用自定义标记集采集:--required 加闭锁/复归两行、--forbidden 去掉 [ERR] 保留 FAIL;ERROR;HardFault。此类日志的 PASS 只代表注入行为符合预期,不代表标记集等价于日常门禁 |
| 证据可达性 | 台账只准引用已入库的文件。被忽略规则挡住的产物(如全局 *.bin)要么显式 force-add 入库,要么把行内引用改写成「本机产物(不入库)」——两者都不做 = 让台账行指着仓库里不存在的证据,按图索骥的人只能拿到 File Not Found |
2.1 一处已知断链的处置记录(2026-10-26 核查)
清单里 2026-10-12 B9 那一行引用的 20261012_B9_soe_pre.bin 与 20261012_B9_soe_after_post.bin
从未入库:.gitignore 第 115 行的全局 *.bin 规则挡的,git ls-files 查无此文件,但文件确实在本机台架目录里。
核查过全目录 37 个被引用的证据名,只有这两个是真断链——其余查不到的名字要么是模板占位(如
boot_log_<stamp>.txt),要么是设备侧路径(/log/soe.log、/prot_set.bin),本就不是仓库文件。
选定处置:入库(对这两个具名文件 force-add),不改成「可再生成的派生物」。 理由是后者在这里前提不成立:
- 这两个
.bin是当次 FTP 下载的/log/soe.log原始 64 B 记录帧,而该文件是 512 条环形累计历史—— 当时那 56 条早被后续台架长跑覆盖,不可复现、不可重生成。把它写成「可由脚本重新生成」= 新造一条无法 核实的断言,比现在这条断链更糟(这正是本卡要修的毛病,不能拿一个新毛病换一个旧毛病)。 - 体积可忽略:两个文件合计 6,528 B(2,944 + 3,584,64 B/条的裸记录),比同目录已入库的两份解码
文本
20261012_B9_soe_decode_pre.txt/20261012_B9_soe_decode_post.txt(7,861 + 9,521 B)还小;对登记簿 「仓库体积膨胀观察」那条(.git 约 233 MB)没有可测影响。 - 不放宽任何规则:全局
*.bin与simulator/tests/ref/*.bin的显式反选(.gitignore第 130 行)都不动, 只对这两个具名文件各git add -f一次。入库理由要与黄金参考区分开:那边入库是因为它是判据本体 (不入库则新克隆上这条门禁直接不存在),这边入库是因为它是不可复现的原始证据——理由不同, 但都落在「被引用的文件必须在库里」这一条上,不构成把全局规则打开的口实。
落库动作由提交车道执行(本卡不碰 git):
git add -f docs/测试说明/测试数据/boot_log_data/20261012_B9_soe_pre.bin
git add -f docs/测试说明/测试数据/boot_log_data/20261012_B9_soe_after_post.bin
⚠ 同目录另有 3 个同状态的本机
.bin目前没有被任何台账行引用,故本卡不代其决定,只登记防复发:20261026_prod_77779d49_ui_set_badge_uncal.bin、20261026_task24_boardnav_standby_unknown.bin、20261026_task24_boardnav_view_set.bin(各 3200 B = 160×160 单色帧)。谁先把它们写进台账,谁就得先按 §2「证据可达性」二选一处置掉——否则本节这条断链会以同样形态重长一遍。
3. 清单
| 日期 | 构建 / 负载 | 关键 [STACK] 水位 |
文件 |
|---|---|---|---|
| 2026-10-10 | prod_adc_tim6 / 开机 + 30 s 空载 |
adc 528/2048(74%);default 2164/4096(47%);heap free=15088 min_ever=7152 |
20261010_prod_adc_tim6_boot_log.txt |
| 2026-10-10 | prod_adc_l1 / 开机 + 30 s 空载 |
adc 584/2048(71%)(+56 B,语义取数与有效性层 adc_input_poll/raw 上链);default 2164/4096(47%);heap free=15088 min_ever=7152 |
20261010_prod_adc_l1_boot_log.txt |
| 2026-10-11 | prod_phasor / 开机 + 30 s 空载(全周傅氏相量台架闭环) |
adc 928/2048(54%)(+344 B,压环 + phasor_run + log_phasors 上链);default 2152/4096(47%);heap free=15088 min_ever=7152 |
20261011_prod_phasor_boot_log.txt |
| 2026-10-11 | prod_adc_health / 开机 + 30 s 空载(L1-6 + 抬栈 640 words) |
adc 952/2560(62%)(静态最坏链 1080 B,adc_health_report→syslog_post 回显尾);default 2152/4096(47%);heap free=14576 min_ever=6640(抬栈 -512 B,符合预算) |
20261011_prod_adc_health_boot_log.txt |
| 2026-10-12 | prod(HEAD d3107f3,B4/B5 验收窗口 B6)/ 开机 + 30 s 空载 |
首采:iec104 424/2560(83%);protect 828/2048(59%,free_min 1220);新 56 KB 堆 heap free=17936 min_ever=10000(>3072 告警线,无 [HEAP] 告警);⚠ @test FAIL(缺陷证据快照):protect task start 锚点行字节级交错损坏(st[art: cycle=220ms elm=70,两次开机同形复现)= protectTask 违反控制台写者注册前门控纪律(控制台单写者日志设计说明.md §3.4),其余 8 Required / 零 [ERR] / 锚点×1 / 回读一致全过;缺陷已修(启动行改 writer-ready 首拍补打),修复后 PASS 见下行 |
20261012_B6_prod_boot_log_PROTECT_MISS.txt |
| 2026-10-12 | prod(B7 1fe163b + B6 门控修复)/ 开机 + 30 s 空载(B6 复测 PASS) |
protect 828/2048(59%,free_min 1220);iec104 424/2560(83%);heap free=17936 min_ever=10000(N-33 抬栈 min_ever 背书就绪);锚点行完好 cycle=20ms elm=7(+577 ms,写者 attach 后首拍);零 [ERR]、采样闭锁不误报 |
20261012_B6_prod_boot_log.txt |
| 2026-10-12 | 同 MISS 固件(d3107f3)/ PC 主站 2404 往返(test/host/iec104_master.py) |
STARTDT/总召四组+actterm/C_SE 两段写触发 YX15·16 变位(COT=3)/恢复复归/YK11 两段正答/C_RD 读回 10.000 → 18/18 PASS(104 链与锚点缺陷无关,验收窗口固件本身上先行闭环) | 20261012_B6_iec104_roundtrip_pre-fix_log.txt |
| 2026-10-12 | 同 PASS 固件(B7+fix)/ PC 主站 2404 往返(复测) | 同上全链 18/18 PASS——B7 set_sealed+持久化写路径下 C_SE→YX 联动仍成立(B5 遗留"104 YX 联动"腿闭环) |
20261012_B6_iec104_roundtrip_log.txt |
| 2026-10-12 | 同 PASS 固件 / B7 定值持久化 + 软压板 YK12 台架腿(test/host/iec104_master.py --b7-pre/--b7-post/--b7-mark/--b7-check,中间 ST-LINK 复位) |
pre 21/21:C_SE 写 7.5+C_RD 回读、YK12 两段 OFF → 0.05 A 低定值不动作(保护退出)、YK12 ON → YX15/16 立即动作(COT=3)、收尾留压板退出;post 13/13:压板退出态跨复位保持(开机日志 global plate OUT -> protection disabled + 低定值仍不动作)、重启后 YK12 ON 即动作(联动在位);mark/check 4/4+4/4:非默认定值 7.5 跨复位保持(C_RD=7.500,与出厂默认可区分);开机日志两次 [CFG] prot set loaded (/prot_set.bin) |
20261012_B7_iec104_persist_log.txt / 20261012_B7_persist_boot_log.txt |
| 2026-10-12 | prod(B9 1d96fc9 sync 追平 B8/N33 后重跑,merge 6cbf400 覆盖代码)/ B9 SOE 动作记录 + 时标台架腿 |
@test PASS:锚点 protection init: OK (set=40 elm=9)、freq layer init: OK、freq(hb): f=0 valid=0(浮空不发散)、prot set blob version change (ver=1 cnt=32), defaults in use(B8 换代 INFO ≠ CORRUPT 实证)、零 [ERR]、protect 828/2048(59%,与静态 872 相符);主站回归 --b7-pre 21/21 + --b7-post 13/13 不回归,自发 YX = M_SP_TB_1 带 CP56 时标(动作/复归/重启后联动三段,iv=0);FTP 下载 /log/soe.log 56 条 test/host/soe/decode_soe.py --max-elm 16 PASS(boot 段内 seq 严格 +1、ELM_ASSERT 26、CP56↔epoch UTC 交叉一致);.bin 为原始 64 B 记录可复解码 |
20261012_B9_prod_boot_log.txt / 20261012_B9_iec104_soe_pre_log.txt / 20261012_B9_iec104_soe_post_log.txt / 20261012_B9_soe_pre.bin + 20261012_B9_soe_after_post.bin / 20261012_B9_soe_decode_pre.txt + 20261012_B9_soe_decode_post.txt |
| 2026-10-25 | prod(最终主干 1a624b1:看门狗 v1.5 按位分账 + F3 推流心跳边界)/ f3rounds 轮① :7003 relisten_stress 单独 30 min(11×200=2200 个 connect/close 周期,零拒绝) |
v1.1 判据 PASS:task stall=0;MISS 758 条中 NET 缺席=0(旧 12 条 NET 参与组合消失达成);推流段在途峰值 103 ms / 完成段 183 ms(UI 周期最坏 254 ms)——F2 复合零误报 + F3 阻塞型治愈的定案样本;gz 前置 6 行 ASCII 来源/判据头 |
f3rounds_r1_7003_churn_30min.log.gz |
| 2026-10-25 | 同固件 / f3rounds 轮② e02_probe 单独 30 min(50 个探针掉线窗) | v1.1 判据 FAIL(如实申报,零放水):stall=8 = 3 事件(20:06:05/20:16:54/20:20:30,miss=998-1000/1187-1189/1249-1250),mask=0x1E7 纯 UI 单串×7 + 0x167 UI+I104×1,h= 环全部 ≥8 连窗真申报;饿死型(每样本点 uisn=0、mg=217/262、拖点不在推流段而在 feed/port 墙钟)=「reconcile 突发饿死 uiTask」登记行与 E-27/E-28 批 3 的直接立项证据;全窗无 IWDG 复位 | f3rounds_r2_probe_30min.log.gz |
| 2026-10-21 | prod + 兜底新鲜度门停 TIM3 注入探针(task/adc-health-design-doc,探针已撤)/ 开机 + 45 s |
protect 620/2048(69%)、adc 与 heap 水位同前;[ERR][PROT] … blocked (hf=0x00000100) +5462ms、recovered +5757ms、health: 0 次、reset cause: ×1 |
20261021_probe_stale_gate_boot_log.txt |
| 2026-10-26 | prod(像来自仓外只读 detached worktree _wt/bench-21-77779d49 @ 77779d49;主树当时另有在飞文档改动,这份像不含主树未提交内容——别拿本行结论去对主树源码)/ 开机 + 30 s 空载,@test PASS |
protect 492/2048(75%)、iec104 540/2560(78%)、adc 1000/2560(60%)、ui 4088/16384(75%)、default 2160/5120(57%)、heap free=15624 min_ever=8464;protection init: OK (set=40 elm=9)、锚点 reset cause: ×1、[ERR]=0 / Fault=0、net init: OK +762 ms、身份戳 Oct 26 2026 16:27:01 suite=NONE dstr=off 从 hex 抠出并与线上相符、-CmpFile 回读 No difference found(排在采日志之后);⚠ 启动日志行内字节交错缺陷:protectTask [PROT] 与 [NAND_FTL] 两个写者并发,3 次启动命中 2 次,hexdump 实证「某行内多出的字节恰等于下一行被吃掉的行首」(串口 framing 错不可能让行变长)→ 已立项派 App/log 属主 |
20261026_prod_77779d49_boot_log.txt / 20261026_prod_77779d49_boot_log_reset_only.txt / 20261026_prod_console_interleave_evidence.txt |
| 2026-10-26 | 同镜像 / 整定页两条实机判据(主站 test/host/iec104_master.py 以库形式复用,驱动脚本留在仓外 _wt/scratch/bench21_104.py(原写 _wt/.state/,但那是 task-worktree 的台账目录,放脚手架会把 list 撞崩,已挪出),未改仓库;复位只用 -Rst -Run,全程不重烧) |
C_RD 27/27 可寻址项全中出厂值(清单取自 git show 77779d49:App/algo/prot_set.[ch] 而非工作树;13 个 comm_addr=0 本地项结构性不可寻址 → 明确不参与本判据,另以 0x8854/0x8855/0x8862 三个未映射地址实证「不应答」);⚠ 未标定闭锁态下 C_SE 仍允许写(闭锁 ≠ 禁写):0x8858=7.5 / 0x885D=1234 / 0x8820=11000 三项 sel+exe 均 actcon 且 C_RD 同值 → 仅复位后仍为 7.5/1234/11000,启动日志 [CFG] prot set loaded (/prot_set.bin)、CORRUPT=0、version change=0、YX31=OFF(校验和通过);越界写 0x8858=500(>100)、0x8821=0.5(<1) 均回 actcon+PN 且原值一字未变;还原默认值 → 再复位 → 27/27 回默认(双向持久化,台架留在出厂态)。屏检:整定页(123 修改密码)标题右侧**「未标定」徽标在位**(Glyph 精确命中 x=105/117/129;同页用查看密码进去无徽标 = 设计如此),LOCK 未见且可证未闭锁(ENTER 被消费进入数值编辑,而闭锁时 ENTER 一律不消费),全程零提交;强制真 LOCK 需篡改 /prot_set.bin,台架禁做 |
20261026_prod_77779d49_iec104_setpoint_leg.txt / 20261026_prod_77779d49_ui_set_badge_uncal.png(同名 .bin = 原始 3200 B 帧、可 board_ui_nav.py --classify 复判,但被 .gitignore 的 *.bin 全局规则挡住,入库需 git add -f;顺带一条既存事实:本目录上方 B9 那两行引用的 20261012_B9_soe*.bin 同样从未入库,git ls-files 查不到)/ 20261026_prod_77779d49_ui_set_view_readonly.png / 20261026_prod_77779d49_ui_set_edit_enter_accepted.png / 20261026_prod_77779d49_ui_nav_trace.json |
| 2026-10-26 | prod(像 = 1d4b6a17 控制台整行独占修复;仓外只读 detached worktree _wt/bench-23-1d4b6a17 出像,主树同 HEAD 但压着 UI 道 task-6 未提交半成品 → 像不含它)/ task-23 收口复验:1 次烧录启动 + 连续 4 次「仅复位不重烧」 |
5/5 启动 [ERR]=0、CONSOLE dropped=0(让路没被计成 [ERR],与设计一致);两条旧受害行逐字节完整:[PROT] 未标定行恒 91 px、[NAND_FTL] Initializing… 恒 56 px 且行首 [ts] 齐(旧缺陷正是吃它行首);锚点 reset cause: ×1、无 Fault、comm init: OK (ca=1 port=2404) 每次都在、prot set loaded ×1 且 CORRUPT ×0;heap free=15624 min_ever=8464 与上一轮逐字节相同、protect 492/2048 相同;ui 峰值 4116~4188/16384 —— 同一份像自己就摆 72 B,故相对上一轮 4088 的 +100 B 不可归因于本修复(顺带记账:[STACK] 峰值有 ±100 B 噪声,拿它当门禁得先定容差);行序一处变化:[NAND_FTL] 现排在 [PROT] 前一行 = 抢不到独占者整行入环延后发,与修法吻合;反证非空跑:同一校验器打旧缺陷那份 → rc=1 FAIL、nand_head_ok=false(那行真读作 26-10-26 …);-CmpFile 排在全批日志之后、No difference found |
20261026_bench23_flash_boot_log.txt / 20261026_bench23_reset_only_boots_r1_r4.txt(4 次仅复位原始字节,按 gen 264~267 分块)/ 20261026_bench23_recheck_verdicts.txt(逐启动判据 + 反证 + 栈口径 + 最终回读) |
| 2026-10-27 | prod(身份戳为准、SHA 只当坐标:fw build: Oct 26 2026 22:52:09 suite=NONE dstr=off;坐标 HEAD b24b2b5f;像 = 主树现成 MDK-ARM/STM32F407-Demo/STM32F407-Demo.hex,出像前机械核验「b623a406 之后无任何提交碰过 *.c/*.h、工作树 *.c/.h 全干净、唯一比 .hex 新的源文件是 test/host/console_log/console_log_test.c(主机侧单测,不在 uvprojx)」→ 无需重建,UI 道三页与维护链已含在像内)/ task-42 台架窗口:UI 落地后同判据复跑 + 执行类页面真机硬闸 |
烧录启动 1 次(00:25,不计入仅复位序列):@test PASS,9 条 required 全中(含身份戳)、Forbidden 零命中、锚点 reset cause: ×1、boot→net init: OK 777 ms、回读 No difference found。仅复位 4 次(01:46–01:52,逐圈 clear 使 serial gen 273→276 单调递增自证窗口不重叠;stlink_flash.py reset = -c SWD -Rst -Run,零重烧):4/4 PASS —— [ERR] / CONSOLE dropped / 任一 Fault 令牌 / ERROR / assert 全部零命中;两条旧受害行逐字节完整:[PROT] … protection blocked (UA/UN/IA VALID not all set) 恒 91 px、[NAND_FTL] Initializing NAND FTL 恒 56 px(行首 [ 齐全、loose_neighbours=0、head_bad=0),锚定用仓内 verify_log.py --exact(b1280e3c 并入的能力,本轮首次自用);[APP] comm init: OK (ca=1 port=2404) 恒 57 px;prot set loaded (/prot_set.bin) ×4、CORRUPT ×0;boot→net init 733–786 ms。反证非空跑:同一把尺指向修复前归档 20261026_prod_77779d49_boot_log_reset_only.txt → rc=1 FAIL、缺行首邻居原样打回 26-10-26 08:37:07][NAND_FTL] …。执行类页面硬闸真机实证:board_ui_nav --to clear / --to reset 在下钻前即拒绝(连轨迹文件都没生成、非零退出),理由文本点名「第二次 ENTER 即真执行」——正是 00:17 我报的那条三段叠险的收口;--to clock 正常到达(9 步,每次 ENTER 都落在菜单上下文),页面渲染无缺字白框(年/月/日/时/分/秒 + 第 1 页,共 1 页 全显),帧见 PNG。栈/堆:heap free=15624 min_ever=8464 与 task-30 逐字节相同,protect 492/2048、ui 4188/16384 四轮内部零摆动(本轮 max=4188,与上轮 max 4188 持平 → 无回退);仍按 task-32 未定稿口径只报数不做单次比较。收尾:-CmpFile 排在全部日志采集之后(它复位目标),No difference found;bench 锁 task-42 释放并复验 build/bench 双空闲。两次如实申报:① 01:34 头一圈采到 0 字节——根因不是板子,是常驻 daemon(pid 18020,uptime 156589 s)已死,而 serial_tool.py status 会自动拉起新 daemon、于是 status 一直"正常"地报 port.ready=false / rx_lines=0 / 日志 58 B;事后证明板子那次复位后正常启动(uptime 计数对得上、PROF 成流)→ 立口径:每圈复位前 open + 断言 ready + 观察 rx_lines 增长,别假设 @test 留下的端口状态能过夜;② 我加的 Forbidden 令牌 Fault 是假红:它子串命中 de*fault*(打到 [FTP] using factory default password 与 [STACK] default peak_used),已换成显式故障令牌——四个 Fault 本来都以 [ERR] 开头,裸 Fault 只是噪声。另记一条观察(不下结论、不属本卡职责):装置墙钟显示 2026-10-26 18:00:35,而主机记录为 2026-10-27 01:5x +08:00(固件日志时标与 daemon 时标也恒差 8 h)→ 时区/RTC 语义请 lead 定道处理 |
20261027_bench42_reset_only_boots_r1_r4.txt、20261027_bench42_verdicts.txt、20261027_bench42_ui_clock_page.png |
f3rounds 两只是判读证据存档(非
[STACK]水位快照):源为 serial-assistant live 日志的 字节偏移切片(不 clear、行边界对齐),gz 前置 ASCII 头行携带偏移窗、负载定义与 v1.1 判据 结论;判据口径 =../../板级测试/实机测试实施指南.md§7.2(v1.1),工具 =scripts/v5_log_gap_report.py。
4. 关联
- 沉淀约定:
../../流程与规范/测试开发标准流程.md§7.3 - 栈水位探针与基线:
../../../内存管理/RAM使用分析与优化方案.md§4.0.2 / §4.0.6 - 当前诊断基线:
../../../内存管理/RAM预算台账.md - 本流程立项:原
../../../任务规划/README.md的「启动日志固化流程」条目(2026-09-22 提出;2026-10-05 固化为本节流程后销项)