Files
STM32F4-Base/docs/门禁说明/mem-numbers.md
T
wandering1 4a4ad6bc5f chore(全仓): @build/@test 旧文档别名清退为技能调用名
现状口径:/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 全过;字节卫生零漂移。
2026-10-30 13:03:12 +08:00

4.6 KiB
Raw Blame History

mem-numbers — 文档里的内存 / Flash 数字是否与 .map 一致

一句话:它让**"照文档推算内存余量"这件事仍然成立**。事实源是 Keil 的 .map,不是文档作者的记忆。 属于"文档数字一致性"三档里的体积档(三档口径见 docs/文档规范.md)。

  • 配置:entry: python scripts/check_mem_numbers.py --scan、pass_filenames: false、 files: 覆盖 docs/内存管理/*.md 与相关脚本/文档改动面。

1. 它在查什么

  1. 解析 .map,取 RW_IRAM1、RW_CCM、ER_IROM1、Code/RO/RW/ZI 等用量与占比;
  2. 重新渲染文档里的受管生成区并比对是否一致: <!-- MEM_SNAPSHOT:BEGIN generated by scripts/check_mem_numbers.py --> … <!-- MEM_SNAPSHOT:END -->;
  3. --scan 额外扫描行文中的散句数字(不在受管区里的手抄数字)并报不一致项;
  4. 受管区外的内容一律不改写,只提示。

2. 为什么要它(这是本目录里"真事故"最硬的一篇)

  • 实测记录:2026-09-26 复核时,文档写 RW_IRAM1 82,048 B / 62.6%,而 .map 实际已是 87,040 B / 66.4%;Flash 文档写 249,432 B / 23.8%,实际 261,932 B / 25.0%。 读者照文档推算余量会得出错误结论——这类错误不会报错,只会让人做出错误的容量决策。
  • 做法与 task-table 同构:能生成的就别手抄,手抄的必须有门禁核对。

3. 触发面与"看不见"的地方

  • 事实源必须是最新一次 /keil-build 产出的 .map;.map 不存在(这台机器没做 Keil 构建) → 自适应跳过(与 ram_baseline.py --gate 同口径)。CI 明确不跑构建,这一门在远端曾长期 是盲区——2026-10-25 已由同码凭证关闭为强制路径(scripts/check_size_gate.py,口径正文见其 docstring;CI 复核同码性 + 按凭证数字复跑红线,不重算绝对值)。
  • 只覆盖脚本配置里登记的文档与字段;没进受管区、也没被 --scan 认出的数字 = 无人核对。

4. 报错怎么读

内存/Flash 数字一致性(体积档).......Failed
  docs/内存管理/xxx.md:46  受管区与 .map 不一致:RW_IRAM1 期望 75,264 B (57.4%),文档写 82,048 B (62.6%)
  • 同步受管区:& '.venv\Scripts\python.exe' scripts/check_mem_numbers.py --write(只改受管区)。
  • 只想看期望值:--diff;改 .map 路径:--map <路径>。
  • 行文散句数字要手改(--scan 只报不改),改完再跑一次确认。

5. 好处

  • 文档里的体积数字从"某次构建的快照"变成"每次核对的活数";
  • 数字与 .map 一起进 diff,评审时一眼看出这次改动吃了多少 RAM/Flash。

6. 限制与盲区

  1. 只核对数字对不对,不核对结论对不对。受管区旁边那句"余量充足,可以再开一个任务" 与数字是否矛盾,它不知道。
  2. 散句只报不改,且 --scan 靠正则认数字——写成"约 75 KB""七万五千字节"或换单位的句子 不在核对范围内(假阴性)。
  3. .map 缺失即跳过 → 在没有 Keil 构建的机器上它是绿的(自适应跳过 = 无信息,不是通过)。
  4. 依赖最新构建:/keil-build 之后没跑 --write 与文档同步,就会红;反过来,先 --write 再改代码 会写出与将要提交的代码不一致的漂亮数字。
  5. 只覆盖已登记的文档:新开一篇写满体积数字的文档,不在名单里就没人管。
  6. 同码凭证(2026-10-25)不重算绝对数字,只复核"代码 == 测量时的代码"与红线复算;编译器选项 (.uvprojx)不在指纹范围内——换优化等级不改指纹,靠本地 /keil-build 纪律兜。
  7. 数字口径 = .map 的静态视图,不含运行时水位(栈峰值、堆低水位、碎片)——那些要另跑 scripts/stack_report.py 与串口 [STACK] 读数。

7. 豁免与基线

  • 无基线概念:要么与 .map 一致,要么失败。
  • 并行开发时的口径(Lead 裁决 2026-10-12):分支不跑 --write(多分支同改受管表会冲突), 台账由主干在合并后统一回填;分支若只因本门与 mem-budget 失败,须先跑全量门禁确认只有这两条 失败、把摘要写进提交说明,再考虑绕过(见 docs/环境与部署/并行任务工作树方案.md 的合并流程)。

8. 改这个门禁本身

  • 新增要核对的文档/字段:改脚本里的文档清单与解析器,先确保 .map 解析不出错再挂进提交;
  • 别把 --write 接进钩子——"自动改数字"等于允许文档自己证明自己是对的。