Files
STM32F4-Base/docs/门禁说明/registration-check.md
T
wandering1 511fd30cc6 docs: 清理全仓变更记录流水(43 篇整节删 / 23 篇留一行 / 5 篇保留)
用户裁定:文档只写现状,历史流水一律删掉,过程查 git log。

- 43 篇「变更记录 / 修订记录」整节删除:继电保护规划 12.6 KB、产品
  需求 11.8 KB、项目部署环境 5.5 KB、BSD Socket 指南 5.3 KB、架构
  总览 5.0 KB、实机测试实施指南 3.8 KB 等
- 23 篇别处仍有指向:只留节名 + 一行「本文件不再记流水账,过程查
  git log」,节号与锚点不位移(doc-links 不因此断链)
- 5 篇整表保留(被当唯一证据 / 活台账引用):看门狗设计说明、配置
  文件设计说明、RAM预算台账、内容页架构、本地工具路径环境变量方案
- 规范同步:文档规范 §5.1 改新裁定;测试文档模板规范删示例节与
  登记句;测试开发标准流程 / UI 两篇 / 实机测试实施指南 / 四篇单测
  说明 / 并行任务工作树方案 / 编号规范 的「登记变更记录」改「写进
  正文」
- 技能同步:stale-doc-count-sweep / ui-verify / id-family 三个 SKILL
  正文不再要求追加流水行(顺带消掉 SKILL.md:121「产品需求 §12」
  失效引用)
- 修 5 处悬空指针:采样有效性校验目录锚点、BSD 指南「文末变更
  记录」、docs/README 过期描述、网络自愈架构两处指向面

72 篇文档净减 600 余行;check_doc_links --all --sections-strict 可判
定比例 61% → 78%、失效引用 0;静态门禁 passed=50 failed=0;gitlint
10 条历史提交信息 0 failed。

未提交他人在飞改动:.dsh/skills/keil-build/*(%SystemDrive% 守卫)。
2026-10-28 22:00:34 +08:00

4.9 KiB
Raw Blame History

registration-check — 双端注册反向校验(源文件有没有真的参与编译)

一句话:本仓两处注册表都是显式文件列表,忘了登记的文件能编过、能提交,但从不参与编译 ——这一门专抓"写了却从不生效"的死代码,包括第四种更隐蔽的:页面描述符没接线。

  • 配置:entry: python scripts/check_registration.py --strict、pass_filenames: false。
  • 背景:登记簿条目「rs485_task 白名单缺口」;UI 页面那类是「UI 字符集与像素回归门禁」补强(2026-10-15)。

1. 它在查什么(四类缺口)

扫描 App/、Drivers/BSP/、Src/ 下全部 .c(排除第三方),对照 MDK-ARM/STM32F407-Demo.uvprojx 的 <FilePath> 与 simulator/CMakeLists.txt 的源列表:

类 情形 后果
① 文件存在但未进 uvprojx 固件端不编译(死代码或漏注册)
② 文件存在但未进 CMakeLists 模拟器端不编译——MCU-only 文件不进模拟器是正确的,脚本按豁免判定
③ 注册了但文件不存在(反向) 幽灵注册(改名/删除后残留条目)
④ Drivers/BSP/UI/ui_page_*.c 定义了 ui_page_<name>_desc,但该符号在 UI 目录内除自身 .c/.h 外无人引用 页面没接进 ui_content_page.c 的 s_defs[] 描述符表:两端编译链接全过(无人引用的 desc 被链接器整段剥离),菜单永远打不开这一页
  • UI 页面的"注册"有两层,第 ④ 类只管第二层:第一层是构建注册(uvprojx + CMakeLists, 即 ①② 类);第二层是框架注册(ui_content_page.h 的枚举 + ui_content_page.c 的 s_defs[] 描述符表)。只做第一层 → 编译链接全过,但菜单里就是没有这一页。

2. 为什么要它

  • 真事故:App/task/rs485_task.c、Drivers/BSP/NET/lftpd/lftpd_log.c 历史上两处都没注册, 等于代码从不参与任何一端编译,而读者以为功能已生效。
  • 第 ④ 类尤其值:2026-10-15 实测,前三类对"页面写了但没接线"完全照不出(编译链接都过), 所以才有"新增 UI 页面必须过本门"的机械口径。

3. 触发面

files: 覆盖 \.c$|\.uvprojx$|CMakeLists\.txt$|^scripts/check_registration\.py$; pass_filenames: false → 每次全量对照两份注册表。

4. 报错怎么读

双端注册反向校验 (uvprojx + CMakeLists).......Failed
  [示例] [GAP-1] App/x/y.c 未出现在 MDK-ARM/STM32F407-Demo.uvprojx
  • 单独跑:& '.venv\Scripts\python.exe' scripts/check_registration.py --strict。
  • 修法是补注册(新 .c 走 new-source-file skill 的两处登记),不是把文件删掉凑绿。
  • 新目录还要把目录加进 uvprojx 的 <IncludePath>,否则报错会落在消费者编译单元上 (cannot open source input file),容易被误判成别人的问题。

5. 好处

  • 把"显式列表 = 必须登记两次"这条极易忘的约定机械化;
  • 反向校验(③)让改名/删文件不留幽灵条目,配合 scripts/rename_ref.py 才敢说"改名安全"。

6. 限制与盲区

  1. 只管"在不在列表里",不管"注册得对不对":把 a.c 的 <FilePath> 指向 b.c,只要路径 存在就过。
  2. MCU-only / 模拟器专用的判定靠豁免清单(脚本内 KNOWN_GAPS 一类,存量 + 逐条理由)。 新增一个正确的 MCU-only 文件需要同时改豁免清单,否则②会误报——反过来也成立:进了豁免 清单的文件就永久不再被检查。
  3. 第 ④ 类只覆盖 ui_page_*.c + ui_page_<name>_desc 这一种接线形态;其它"注册了但运行期 无人调用"的入口(命令表、事件回调)不在内。
  4. 头文件不校验:只漏 .h 不会报(漏的是 include 路径,不是注册表)。
  5. 它不看条件编译:文件在列表里但整个文件被 #ifdef 关掉,仍然算"已注册"。

7. 豁免与基线

  • 无"只减不增"的基线,而是逐条带理由的已知缺口清单(KNOWN_GAPS 形态):新增条目必须写 理由,性质上比基线更容易被滥用,改动时要看得到理由文本。

  • 豁免用显式清单 + 每行理由(命名模式 *_mcu.c 加个别点名),不整目录一刀切——一刀切等于 把该目录所有漏注册都免了。

  • 存量缺口走白名单只打 [WARN] 不拦:KNOWN_GAPS 里登记着 App/task/rs485_task.c、 Drivers/BSP/NET/lftpd/lftpd_log.c(Lead 处置中)。

8. 改这个门禁本身

  • 加新的注册面(例如新增一套第三方构建脚本)要同步"正向 + 反向"两向检查,只查单向会漏幽灵注册;
  • 放宽第 ② 类(更多豁免)前,先确认该文件真的不需要在 PC 上跑——模拟器不编译意味着该文件的 逻辑永远没有主机侧单测(见 host-unit-tests)。