docs(真值): 勘查 13 条文档/代码不一致全部处置(10 改 3 核实)+ 补 3 处

证据源 = 主树 ci-artifacts/archify/architecture-dtu-overview-20261030-095132/
evidence.md §11。该目录不入库,故把每条的判据与实测源抄进正文,别让证据只活在
一台机器上。处置口径:能改的改成与代码同源,核实后确认文档没问题的明确写「不改」。

判停点与就绪屏障(条 1、条 3)
- AGENTS 原写 `protect_task.c:98` 直接停走判据:`:98` 是 `s_prev_cal_lock` 变量,
  判停点是 `App/task/protect_task.c:268 if (adc_cal_prot_blocked() != 0u)`,
  判定本体在标定层 `adc_cal_prot_blocked()`、protectTask 只是消费者 → 改引用,
  同步 `ui_task.c:240` 页面注释与 `docs/任务规划/数据可信.md` 的同一处行号。
- `SYS_EVT_FTP_READY` 有生产者(`Src/freertos.c:490`,注释自陈预留)无消费者;
  `SYS_EVT_TIMESYNC_READY` 全仓无生产者也无消费者(只有定义与测试桩)。
  AGENTS、`sys_events.h` 位注释、屏障配图(生成器 + 产物)三处从「四个就绪位
  并列」改成「bit0/bit1 在用 + bit2/bit3 预留」,并指向
  `docs/架构设计/项目启动顺序管理.md` §3.2 的逐位对照表。ftpTask 实际等的是
  `NET|STORAGE`(`Src/freertos.c:477-479`,WaitAll|NoClear,100 ms 分片喂狗)。

/log 不是「三本」(条 5)
- `App/log/sys_log_mcu.c` 的 `s_paths[]` = run / selftest / accid / alarm /
  start / oper / yk 七本 64B 定长文本 + `soe.log`(64B 定长二进制)+ `wdev.log`
  (变长取证行,`App/fs/vol_lock` 侧投,不走定长格式)。
  → AGENTS 两处、总览 §2.1 与 §4 的「三本」改成「七本 + SOE(+ wdev 取证行)」。

主机单测 44 套 → 47 套(条 2,两把机器尺互证)
- `scripts/check_test_coverage.py --list` 打印 47 行;`ls -d test/host/*/` = 48 个
  一级目录,唯一没有 `run_unit_test.py` 的是 `common/` ⇒ 47 套。
- 差额三名 = 屏板链路套件:`sb_proto`、`sb_link`(2026-10-29 入库)、
  `sb_led_map`(2026-10-30 入库)。专属钩子仍是 22 根 ⇒ 无专属钩子的从 22 套变 25 套。
- 同步面:AGENTS、`docs/门禁说明/README.md`、`host-unit-tests.md` §6 台账(名单补
  三名)、`docs/代码规范/pre-commit使用说明.md`、`主机单测覆盖率口径.md`(含耗时句)、
  `scripts/README.md`、总览目录树、`.pre-commit-config.yaml` 三处注释、
  `test/host/sys_log_mcu/sys_log_mcu_test.c` 一处注释。
- 带日期戳的历史测量值按纪律冻结不动:28 套、41 套 ~105 s、40 套/18 套那三处。

本仓 LVGL 版本(条 6)
- vendored 版本 = `Lib/lvgl/lv_version.h:9-11` 的 9.3.0;总览两处「LVGL v9.2」与
  `gen_arch_svg.py` 图内文字改 v9.3 并重跑产物(脚本与产物同一笔,`generated-fresh`
  逐字节核)。
- **刻意不动**:`docs/内存管理/RAM使用分析与优化方案.md` 两处「LVGL v9.2 文档」+
  GitHub `release/v9.2` 分支 URL ——那是对外游某分支文档的引用,不是本仓版本声明。

触发口径与栈值(条 4、7、9、10)
- ADC 映射 §1「ADC1 为软件触发」是旧口径:`Src/adc.c:53` 实为
  `ADC_EXTERNALTRIGCONV_T3_TRGO` → 改成 TIM3 TRGO,并补一句「TIM3 与 TPAFE 的
  CONVST 之间没有硬件耦合,仍不构成共同采样触发」,缺陷结论本身不变。
- 同文档 adcTask 栈 512 → 640 words(`Src/freertos.c:159 .stack_size = 640 * 4`)。
- `docs/UI设计/UI_设计架构.md` 的 uiTask 栈「16384 words」是单位错:
  实为 4096 words = 16384 B(`Src/freertos.c:218`),顺手补上行号。
- `App/app/app_main.c:197` 注释「DE = PD0」陈旧:`:198` 实传 `ST_DIR4_*`
  (V0.1 实板 PA15,V0.0 才是 PD0)→ 注释改指 V0.1 网表报告的引脚迁移表。
- 两处已退役编号 `N-18`(ADC 映射、V0.1 网表报告)换成登记簿条目名
  「双转换器无共同采样触发」。

核实后确认「文档没问题」的三条(条 8、12、13)
- 黄金参考「菜单 8 状态 + 内容页 66 张」:`simulator/tests/ref/` 实测 66 个
  `shot_*.bin`,与 `ui-golden` 钩子显示名一致 → 不改。
- `App/task/rs485_task.c` 存在但 `Src/freertos.c` 不创建它(grep 无 rs485):
  AGENTS 与总览都已写明「尚未接线 / 暂缓」,图侧画成「实现待接线」→ 不改。
- 104 端口 `:2404` 是工厂默认、可经 `/config.ini` `[comm]` 改 → 总览索引表补
  「默认」二字;「uiTask 10 ms 节拍」核实 = `ui_tokens.h:65 UI_TASK_TICK_MS 10` ✓。

并行勘查会话的同族发现(它扫「文档声明数 vs 真值」,逐处独立复验后采纳 3 处)
- `App/protocol/iec104/iec104_link.h` 头注释写「端口:TCP 2404(§1.5 B0 定义)」,
  同文件下方已写「服务端口真源已迁 [comm] 段」= 自相矛盾 → 补「工厂默认」并指回
  [comm] 与「下次重 bind 即生效」。
- `scripts/gen_task_table.py` 的 iec104Task 描述「:2404 监听」→「工厂默认 :2404
  监听」,`--write` 重生成 README 任务表(AGENTS 表无描述列,实测未被改写)。
- `App/log/README.md` 五行写入点行号全漂:事故 181→188、告警 184→191、启动
  176→183(`App/task/protect_task.c`);操作 `iec104_pts.c` 574/602→582/610、
  `default_task.c` 242→266、`sys_log_mcu.c` 646→682;遥控 573/576/582/586/596/
  598/609 → 581/584/590/594/604/606/617(宿主 `sim_syslog.c:245` 原值正确、未动)。
- **撤销一条**:我早先记的「`docs/算法/继电保护功能复现规划.md:225` 声称记录本已
  有消费者」与原文不符——:225 实为规划表里「动作/SOE 记录 | 复用 `sys_log`」一行,
  属能力复用口径、不是当前态断言 → 不改。教训:**改引用前逐处读现文,别照自己
  上一轮的笔记盲替**(这条比改中的每一处都值钱)。
- 同一批勘查还报了约 12 处「`2404` 缺『工厂默认』限定词」(AGENTS、`App/protocol/
  README.md`、`Src/freertos.c` 注释、5 篇 docs、`test/host` 工具,含一张配图生成器
  要连产物同批重跑)与 `测试开发标准流程.md`「像素层 60 内容页」、
  `.pre-commit-config.yaml` uinav 注释「快检档 18 张黄金参考」(后者写时为真、
  描述的却是钩子现有行为):**本笔刻意不做**,另开任务空间处理——那批要同时动
  AGENTS.md 与 `.pre-commit-config.yaml` 两处单写者面,与并行会话撞车的代价更高。
- 端口生效语义(用户裁定 2026-10-30):产品基线写「公共地址与端口可配…改后需重启
  生效」,代码 `App/task/iec104_serv.c` 是「ca 改后要重启;port 下次重 bind 才生效」
  ——裁定**按代码语义要改**处理(改了端口应立刻重 bind),属固件行为变更,另开任务
  且需真机验证;`.serialtest/config.json` 写死 `i104: listening on 2404` 必检锚点
  是同题(现场改端口会让串口回归假失败),一并留给那条任务。

自查(任务树内)
- `check_doc_links.py --sections-strict`:12 个改动 .md 逐个 rc=0;
  `check_mermaid.py` 改动 .md 全 rc=0;`check_generated_fresh.py` PASS
  (25 个生成器 / 21 一致 / 4 存量基线);`check_nested_comment.py --all` PASS
  (449 文件,新发 0、存量 2);`check_bom_drift.py --all` 99 个名单文件无漂移。
- 编译:`.dsh/skills/keil-build` 退出码 0(0 错误 0 警告),
  Program Size Code=246720 RO=29836 RW=2052 ZI=149708 —— 与本树凭证同码,
  证明这批改的确实只有注释与文档。
- 字节体检:23 个文件无 CR / U+FFFD / 行尾空格 / 缺末行换行;`ui_task.c` 被编辑后
  丢的 3 字节 BOM 已补回(bom-guard 复验通过);5 处「三连空行」逐文件与
  HEAD 比对确认是存量(Python 生成器的 PEP8 双空行与个别 C 文件原有空行)。
- 一次性工具 `ci-artifacts/fix_docs2.py`:断言式规则表,按文件读一次、在演化文本上
  逐条替换、一次写盘。第一版写成「每条规则各自从启动时快照起算」,同一文件后一条
  把前一条整体覆盖,只有每文件最后一条活下来——靠「改完再全仓复扫旧形态」当场抓到,
  这条判据本身已值得写进流程。
- 待办:`git add` 后需重跑 `ram_baseline.py --update`(体积凭证按 git 索引内容生成,
  未 staged 的文件不在凭证里,`check_size_gate.py --local` 现在因此报红)。
- 未 commit、未 push(AGENTS.md 边界:提交属 Ask first)。
This commit is contained in:
2026-10-30 14:16:16 +08:00
parent 8d8ecd9c56
commit e4d70f9fcb
24 changed files with 61 additions and 55 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ MCU **无物理屏幕**:LVGL 做 160×160 **1bpp 单色离屏渲染**,帧缓
| 刷新周期 | 10 ms(`ui_port_step(10)` + `osDelay(10)`) | `ui_task.c` |
| 推流端口 | 7003(TCP,与 DTU-RemoteLCD 客户端对齐) | `ui_net_sink.h` |
| 默认字体 | `ui_font_cn_12`(12px 1bpp,224 汉字/符号 + ASCII 0x20–0x7E,共 319 字形) | `Lib/lv_conf.h` |
| uiTask 栈 | 16384 words(BelowNormal) | `Src/freertos.c` |
| uiTask 栈 | 4096 words = 16384 B(BelowNormal) | `Src/freertos.c:218`(`.stack_size = 4096 * 4`) |
### 1.4 硬约束(改 UI 必须遵守)
+1 -1
View File
@@ -33,7 +33,7 @@
<rect x="428" y="557" width="30" height="30" rx="7" fill="#94a3b8"/>
<text x="443" y="577" font-size="14" font-weight="700" fill="#ffffff" text-anchor="middle">3</text>
<text x="470" y="566" font-size="14" font-weight="700" fill="#94a3b8">bit3 · TIMESYNC_READY</text>
<text x="470" y="588" font-size="12" fill="#64748b">预留(尚未接入调度)</text>
<text x="470" y="588" font-size="12" fill="#64748b">预留(无生产者置位)</text>
<rect x="40" y="200" width="290" height="84" rx="10" fill="#eff6ff" stroke="#2563eb" stroke-opacity="0.5"/>
<text x="56" y="234" font-size="15" font-weight="700" fill="#0f172a">defaultTask</text>
<text x="56" y="258" font-size="12" fill="#64748b">卷挂载 + net_cfg_load(f_mount)</text>

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

+1 -1
View File
@@ -67,7 +67,7 @@
<rect x="887" y="580" width="186" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="980" y="603" font-size="13" fill="#1e293b" text-anchor="middle">nand_ftl(dhara FTL)</text>
<rect x="1083" y="580" width="164" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="1165" y="603" font-size="13" fill="#1e293b" text-anchor="middle">LVGL v9.2(图形库)</text>
<text x="1165" y="603" font-size="13" fill="#1e293b" text-anchor="middle">LVGL v9.3(图形库)</text>
<rect x="1258" y="580" width="177" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="1347" y="603" font-size="13" fill="#1e293b" text-anchor="middle">sys_clock(墙钟基准)</text>
<rect x="44" y="628" width="219" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

+1 -1
View File
@@ -32,7 +32,7 @@ git commit
└─ manual(pre-commit --hook-stage manual;不随 git commit 跑)
├─ cppcheck 全量 C 静态分析(自有代码)
├─ test-cppcheck test/ 侧静态分析
└─ test-coverage 主机单测覆盖率总闸(44 套 + 回退台账)
└─ test-coverage 主机单测覆盖率总闸(47 套 + 回退台账)
```
**阶段**:`pre-commit` 阶段拦截代码问题、`commit-msg` 阶段拦截格式问题,任一失败 → commit 中止;另有 `manual` 阶段(`stages: [manual]` 的慢钩子)**不随 `git commit` 跑**,由远端 CI 与 `scripts/ci_local.py` 的 manual 段承担(见下)。一次 `git commit` 实跑 **48** 根 = `pre-commit` 阶段 47 根 + `gitlint` 1 根。
+1 -1
View File
@@ -237,7 +237,7 @@ M4 的六条退出判据(逐条对齐现状,别整格打勾):
保护判据拿"ADC 引脚电压"跟"二次值定值"比必然误动作,所以 `protect_task` 多一个闭锁源:
**UA / UN / IA 的 `VALID` 未全置位 → 判据停走**(实现已搬进 `App/algo/adc_cal.c` 的
`adc_cal_prot_blocked()`,`App/task/protect_task.c:245` 消费并打 INFO + 记 SOE)。
`adc_cal_prot_blocked()`,`App/task/protect_task.c:268-273` 消费并打 INFO + 记 SOE)。
- 与"自检失败 / 采样故障闭锁"同构(`PROT_HF_LOCK_MASK` 那一套),**不新增机制**。
- 现有台架 `/serial-boot-test` 的期望会因此变化——**这是有意的**,任务卡里同步更新判据。
+8 -7
View File
@@ -24,7 +24,7 @@
| ① 业务层 | `Drivers/BSP/NETCFG/` | 顶层共享配置(被 UI 与基础服务共用) | `net_cfg`(`/config.ini` `[network]` 段) |
| ② UI 层 | `Drivers/BSP/UI/` | LVGL 160×160 单色界面(与 PC 模拟器、屏板、远程显示**共用同一份显存**) | `ui_port` `ui_menu` `ui_menu_view` `ui_menu_tab`(生成物) `ui_content_page` `ui_page_registry`(生成物) `ui_page_*`(20+ 页插件) `ui_data`(数据供给发布 API) `ui_net_sink` `ui_standby` `ui_font_cn_12` `ui_deco` |
| ③ 基础服务层 | `App/`、`Drivers/BSP/NET/lftpd/` | 应用侧服务与编排 | `app_main` `sys_events` `ui_data_feed` `task/*`(9 任务) `algo/*`(语义取数与有效性~保护判据 + 遥测快照 + 录波数据面 + 屏板灯位映射) `protocol/iec104` `sys_log`·`soe_*`·`console_log` `cfg_file`·`prot_set_store` `vol_lock` `time_sync` `lftpd` |
| ④ 中间件层 | `Drivers/BSP/NET/`、`Lib/`、`App/util/` | 通用库 / 协议栈 | `net_socket` `net_select` `net_events` `net_listener` `net_pending` `FatFs` `nand_ftl(dhara)` `LVGL v9.2` `sys_clock` `task_watchdog` |
| ④ 中间件层 | `Drivers/BSP/NET/`、`Lib/`、`App/util/` | 通用库 / 协议栈 | `net_socket` `net_select` `net_events` `net_listener` `net_pending` `FatFs` `nand_ftl(dhara)` `LVGL v9.3` `sys_clock` `task_watchdog` |
| ⑤ 驱动层 | `Drivers/BSP/{CH395F,GD5F2GQ5UE,TPAFE5160,SD2506,RS485,ScreenLink}/` | 芯片寄存器 / 时序 / 中断 | `ch395f` `gd5f2gq5ue` `tpafe5160` `sd2506` `rs485` `sb_link`·`sb_proto` |
| ⑥ 内核 / HAL | `Middlewares/`、`Drivers/STM32F4xx_HAL_Driver/`、`Drivers/CMSIS/` | 任务调度、外设 HAL、启动 | FreeRTOS V10.3.1 · STM32 HAL · CMSIS |
| ⑦ 硬件 | — | STM32F407ZGTx @168MHz | SPI1 / SPI2 / I2C1 / UART4 / UART5 / USART1 / ADC1 / TIM3 / DMA / GPIO |
@@ -59,7 +59,7 @@
| 任务 | 栈 (字节) | 优先级 | 职责 | 入口 |
|---|---|---|---|---|
| `defaultTask` | 5120 | Normal | FatFS 挂载(无卷 `f_mkfs`)→ 卷健康探针/自愈 → `net_cfg_load`(配置引擎属主)→ 置 `STORAGE_READY`(= 存储+配置就绪)→ **`/log` 唯一写者**(`syslog_drain` 尾部统一排空 syslog / SOE 两条队列 → run/selftest/soe 三本日志 + 控制台排空)+ **录波落盘道**(已封存段游标分次搬 `/wave`,轮转号启动扫盘重建)+ 配置保存执行/2s poll + LED 闪烁 + **栈水位观测**(`stack_probe_poll`) | `StartDefaultTask` |
| `defaultTask` | 5120 | Normal | FatFS 挂载(无卷 `f_mkfs`)→ 卷健康探针/自愈 → `net_cfg_load`(配置引擎属主)→ 置 `STORAGE_READY`(= 存储+配置就绪)→ **`/log` 唯一写者**(`syslog_drain` 尾部统一排空 syslog / SOE 两条队列 → syslog 七本 + `soe.log` + 控制台排空)+ **录波落盘道**(已封存段游标分次搬 `/wave`,轮转号启动扫盘重建)+ 配置保存执行/2s poll + LED 闪烁 + **栈水位观测**(`stack_probe_poll`) | `StartDefaultTask` |
| `netTask` | 3840 | Normal | 等存储(配置已由 defaultTask 就绪,本任务只读 RAM 副本)→ `net_stack_bring_up()`(不触碰配置文件引擎)→ 置 `NET_READY` → 循环 `net_poll` + `net_process_messages`;消费 `SYS_EVT_NET_RECONFIG` → 按网络代次号重建监听(CH395F 硬件层测试模式下入口自挂起) | `StartNetTask` |
| `ftpTask` | 4096 | Normal | 等网络**且**存储(`WaitAll`)→ `lftpd_start("/", 21)` → 单客户端会话循环(断开后经 `net_listener` 重建监听);录波段文件的取回通道 | `StartFtpTask` |
| `testTask` | 8192 | BelowNormal | 测试套件入口(`test/board/test_config.h` 选择)。**产品构建不创建**:CubeMX 生成区无条件建后,`MX_FREERTOS_Init()` 在未选套件时(`!TEST_SUITE_SELECTED`)立即 `vTaskDelete` 回收其 8KB CCM 栈(2026-10-04) | `start_test_task` |
@@ -189,7 +189,7 @@ flowchart LR
```
- **配置文件**:通用 `/config.ini`(cfg_file 引擎,静态态单任务收敛于 defaultTask,外部变更 4s 沉降后自动重载),**多段注册制**:`[network]`(net_cfg)/ `[ftp]`(鉴权)/ `[adc_cal]`(标定系数与零点)/ `[run_par]`(运行参数 + 104 地址映射真源)/ `[comm]`(104 ca/端口);新模块加段=注册 `cfg_file` 段处理器,唯一落盘者不变。旧版 NCFG 二进制(`/cfg/netcfg.bin`)已不再读取(2026-10-10 删迁移),存在则忽略。→ `docs/子系统设计/配置文件设计说明.md`
- **记录三本**:`sys_log` 引擎写定长 64B 文本记录到 `/log/run.log` 与 `/log/selftest.log`;`soe_store` 同先例落 `/log/soe.log`(64B 定长二进制,容量满删除重建)。defaultTask 是 `/log` 唯一写者(两条队列在 `syslog_drain` 尾部统一排空),FTP 可直下。→ `docs/子系统设计/运行与自检记录设计说明.md`
- **记录九件**:`sys_log` 引擎按 `App/log/sys_log_mcu.c` 的 `s_paths[]` 写**七本**定长 64B 文本记录——`/log/run.log`、`selftest.log`、`accid.log`、`alarm.log`、`start.log`、`oper.log`、`yk.log`;`soe_store` 同先例落 `/log/soe.log`(64B 定长二进制,容量满删除重建);`/log/wdev.log` 是**变长取证行**(掉电不丢,`App/fs/vol_lock` 侧投,不走 64B 定长格式)。defaultTask 是 `/log` 唯一写者(两条队列在 `syslog_drain` 尾部统一排空),FTP 可直下。→ `docs/子系统设计/运行与自检记录设计说明.md`
- **录波段文件**:`/wave`(首 boot `mkdir`,8.3 短名 WAVE 前缀轮转、启动扫盘重建下标),段头 + 通道表 + 两处 CRC-16/MODBUS + 整段自检;defaultTask 游标**分次搬运**(每次 64B 批)不独占 FatFs,落盘成功回执才解冻录波环。→ `docs/子系统设计/故障录波设计说明.md`
- **实时调试流** = 控制台单写者日志(**UART5**/RS232#1,4KB 环形缓冲 + defaultTask 唯一发送;2026-10-29 因屏板占用 USART1 自 UART5 定态),详见 `docs/子系统设计/控制台单写者日志设计说明.md`。
- NAND 坏块表(BBT)持久化在保留块池,不交给 dhara 管理。
@@ -327,14 +327,15 @@ STM32F4-Base/
│ ├── UI/ LVGL UI(与模拟器共用):ui_port / ui_menu* / ui_content_page / ui_page_*(20+ 页)/
│ │ ui_page_registry(生成)/ ui_data / ui_net_sink / ui_standby / ui_font_cn_12 / ui_pwd_def.h
│ └── dbg_log.h/dbg_cfg.h/app_assert.h/bsp_err.h 分级日志与 BSP 契约
├── Lib/ 第三方:LVGL v9.2、FatFs、dhara + lv_conf.h(MCU 端)
├── Lib/ 第三方:LVGL v9.3、FatFs、dhara + lv_conf.h(MCU 端)
├── Middlewares/ FreeRTOS V10.3.1(ST 官方中间件)
├── Drivers/STM32F4xx_HAL_Driver/ + Drivers/CMSIS/ ST HAL / CMSIS(裁剪版)
├── MDK-ARM/ Keil 工程(uvprojx + scatter + build/download 脚本)
├── simulator/ PC 模拟器(CMake + SDL2,共用 UI 源码 + tests/ref 像素黄金参考回归)
├── test/ 测试套件(test_config.h 互斥选择,产品构建空转)
│ ├── board/ 板端套件(.c/.h:CH395F / 存储 / RTC / ADC / RS485 / UI)
│ └── host/ 主机侧单测与脚本(44 套带 run_unit_test.py,覆盖率总闸全量真跑)
│ ├── board/ 板端套件:CH395F(硬件层 + NET 层 Phase 6~11 + 链路时延探针)/ GD5F /
│ │ 存储性能 / SD2506 RTC(逐文件清单 = `test/board/README.md`;无 ADC / RS485 / UI 板端套件)
│ └── host/ 主机侧单测与脚本(47 套带 run_unit_test.py,覆盖率总闸全量真跑)
├── ui_menu_tree.txt 菜单树声明源(生成器输入,仓根)
├── ui_cn_chars.txt 中文字库输入(生成器输入,仓根)
├── tools/ font_gen / menu_gen / arch_diagram(文档配图生成器)/ refgraph(引用图)/
@@ -383,7 +384,7 @@ flowchart LR
| ADC 通道映射(网名/板级/通道号 13 路置换) | `docs/硬件平台/ADC通道映射说明.md` |
| 故障录波(数据面/段格式/回放契约) | `docs/子系统设计/故障录波设计说明.md` |
| 屏板链路(USART1 主出口 / 帧 A 帧 B / 实测证据) | `docs/子系统设计/屏板链路设计说明.md` |
| IEC 60870-5-104 上行(:2404) | `docs/子系统设计/IEC104上行设计说明.md` |
| IEC 60870-5-104 上行(默认 :2404,可经 `[comm]` 改) | `docs/子系统设计/IEC104上行设计说明.md` |
| 配置文件引擎(/config.ini 多段注册制) | `docs/子系统设计/配置文件设计说明.md` |
| 运行与自检记录(64B 记录 + SOE) | `docs/子系统设计/运行与自检记录设计说明.md` |
| 墙钟时间维护 | `docs/子系统设计/系统墙钟时间维护说明.md` |
@@ -56,7 +56,7 @@
## 3. 怎么跑
```powershell
# 全量:44 套单测逐套"编译(带 PDB)→ 插桩运行 → 解析 Cobertura",最后并集 + 比基线
# 全量:47 套单测逐套"编译(带 PDB)→ 插桩运行 → 解析 Cobertura",最后并集 + 比基线
& '.venv\Scripts\python.exe' scripts/check_test_coverage.py
# 只跑一套(调试用;子集会跳过"在测文件消失"类回退判定,见 §5)
@@ -78,7 +78,7 @@
编译失败、XML 缺失)/ `3` 用法错误。全量实测约 **67 s**(33 套 × 编译 + 插桩运行;
2026-10-25 实测;16 套时约 25 s、28 套时约 45 s,套件数涨了耗时就涨,别拿旧数当预算)。最新一次实测:
2026-10-28 = 41 套 **~105 s**(该钩子同日移入 `stages: [manual]`,由远端 CI 与 `ci_local.py` 的 manual 段强制);
套件数现值 **44 套**(2026-10-29 实测,台账见 `docs/门禁说明/host-unit-tests.md` §6 第 4 条),**44 套这一轮的总闸耗时未重测**,
套件数现值 **47 套**(2026-10-30 实测,台账见 `docs/门禁说明/host-unit-tests.md` §6 第 4 条),**47 套这一轮的总闸耗时未重测**,
上面那三个耗时都是当时值,别当现值预算。
套件数的现值与逐个来历见 `docs/门禁说明/host-unit-tests.md` §6 第 4 条。
@@ -156,7 +156,7 @@
宁可红,也不给可疑的数字。
6. **只覆盖跑到的进程树。** 一次 `collect` 只看一次运行;没跑到的套件不进分母
(全量跑时以"模块未跑到"判 REGRESS),子集运行明确降级(§5)。
7. **头文件里的代码归 `.h`。** 统计面含 `.h`(静态内联与被展开的行落在头文件上);当前 44 套
7. **头文件里的代码归 `.h`。** 统计面含 `.h`(静态内联与被展开的行落在头文件上);当前 47 套
几乎没触及 `.h`,表里看不到它们——不要以为头文件"天生 100%"。
8. **依赖 `Microsoft.CodeCoverage.Console.exe`。** 探测顺序:`DTU_MS_COVERAGE`(设了就必须
有效、**不静默回退**)→ 各 VS 安装根的 `Common7\IDE\Extensions\Microsoft\CodeCoverage.Console` →
+4 -4
View File
@@ -21,11 +21,11 @@
| **温度** | V_ZL2 | 温度 | 温度检测模拟采样 |
| 备用 | AIN5 / AIN6 / AIN7 / AIN12 / AIN13 / AIN14 / AIN15 / V_ZL1 | — | **未使用**(悬空或不用),软件侧一律标 `RESERVED`,不参与采集与上报 |
**设计口径(重要,2026-10-10 更正)**:本产品的**电能计量在子板(计量模块)完成**,主板 ADC 只做**监视 / 辅助测量**。但**"8 路电气量被分到两片转换器上"(UA/UN/IA 走 TPAFE5160,UB/UC/IB/IC/IN 走 STM32 12 位 ADC)是 V0.1 的硬件缺陷**——建档时(2026-10-09)写的"有意分配、不要按'8 路电气量应全部走 TPAFE'去修正"**说法作废**:该分配**就是需要修正的对象**,已列入下一版硬件(V0.2)改版项(登记簿 **N-18**)。
**设计口径(重要,2026-10-10 更正)**:本产品的**电能计量在子板(计量模块)完成**,主板 ADC 只做**监视 / 辅助测量**。但**"8 路电气量被分到两片转换器上"(UA/UN/IA 走 TPAFE5160,UB/UC/IB/IC/IN 走 STM32 12 位 ADC)是 V0.1 的硬件缺陷**——建档时(2026-10-09)写的"有意分配、不要按'8 路电气量应全部走 TPAFE'去修正"**说法作废**:该分配**就是需要修正的对象**,已列入下一版硬件(V0.2)改版项(登记簿条目「双转换器无共同采样触发」)。
**缺陷实质(为什么必须改)**:
1. **跨转换器通道没有同一时刻性**:TPAFE5160 是 8 通道**同步**采样,STM32 ADC 是**顺序**扫描(9 通道一轮 ≈ 67 µs),且两片转换器**没有共同采样触发**(CONVST 只打 TPAFE,ADC1 为软件触发)。于是 UA↔UB、IA↔IB 这类同族量之间**相位关系不确定**,主板侧任何功率 / 功率因数 / 相角 / 对称分量类运算都不成立。
1. **跨转换器通道没有同一时刻性**:TPAFE5160 是 8 通道**同步**采样,STM32 ADC 是**顺序**扫描(9 通道一轮 ≈ 67 µs),且两片转换器**没有共同采样触发**(CONVST 只打 TPAFE;ADC1 由 TIM3 TRGO 触发——见 §7 与 `Src/adc.c:53`,但 TIM3 与 TPAFE 的 CONVST 之间没有硬件耦合,仍不构成「共同采样触发」)。于是 UA↔UB、IA↔IB 这类同族量之间**相位关系不确定**,主板侧任何功率 / 功率因数 / 相角 / 对称分量类运算都不成立。
2. **精度与量程不一致**:TPAFE 16 位 ±5 V **双极性**(LSB ≈ 152.6 µV,满量程 = 10 V 跨度,口径见 §7.1)vs STM32 12 位 0~3.3 V **单极性**(前端无中点偏置,交流量负半周削顶;LSB ≈ 806 µV)。同为相电压,UA 与 UB/UC 满量程码值差 16 倍、可用象限也不同——同一套算法无法统一处理 8 路电气量。
3. **语义与硬件归属交叉**:UA 在 TPAFE、UB 在 STM32,固件映射表 / UI 通道序 / 自检注入都必须逐通道查表绕开这个交叉(本文件 §4、§5 两张表的存在本身就是代价)。
@@ -128,11 +128,11 @@ STM32(U17)为 LQFP144 脚号。
| 项 | 现状 | 影响 |
|---|---|---|
| **通道归属(硬件缺陷)** | 8 路电气量分属两片转换器:UA/UN/IA → TPAFE,UB/UC/IB/IC/IN → STM32 ADC | **V0.1 硬件缺陷**(非有意分配,理由见 §1)→ V0.1 上禁止跨转换器做相位/功率/功率因数/矢量类运算;**V0.2 改版要求 8 路电气量全部走 TPAFE**(登记簿 N-18) |
| **通道归属(硬件缺陷)** | 8 路电气量分属两片转换器:UA/UN/IA → TPAFE,UB/UC/IB/IC/IN → STM32 ADC | **V0.1 硬件缺陷**(非有意分配,理由见 §1)→ V0.1 上禁止跨转换器做相位/功率/功率因数/矢量类运算;**V0.2 改版要求 8 路电气量全部走 TPAFE**(登记簿条目「双转换器无共同采样触发」) |
| STM32 ADC 外设 | **已生成(2026-10-09,CubeMX 6.17 + FW_F4)**:`Src/adc.c`/`Inc/adc.h` 已入库并挂进 `MDK-ARM/*.uvprojx`;`Inc/stm32f4xx_hal_conf.h` 的 `HAL_ADC_MODULE_ENABLED` 已生效;HAL `stm32f4xx_hal_adc.c/_ex.c` + `stm32f4xx_ll_adc.h` 已补入仓库(HAL 原本是裁剪子集);`Src/main.c` 里 `MX_ADC1_Init()` 排在 `MX_IWDG_Init()` 之后。生成配置核对无误:9 通道 / Rank 1~9 / 全部 144 cycles / `ScanConvMode=ENABLE` / `ContinuousConvMode=DISABLE` / `ExternalTrigConv=ADC_SOFTWARE_START` + `EDGE_NONE` / `EOCSelection=ADC_EOC_SINGLE_CONV` / `DataAlign=RIGHT` / 12 位;`HAL_ADC_MspInit()` 已把 PA0~PA7+PC4 配成 `GPIO_MODE_ANALOG` | 硬件通路已打通(`hadc1` 可用);**消费者已落地**——`App/algo/adc_input.c` 的 `stm32_take()`(「STM32 ADC1 启动与扫描」,v2.0,2026-10-10):ADC1 由 **TIM3 TRGO 硬件触发**一轮 9 通道 + **DMA2_Stream4 循环搬运**进乒乓双缓冲,任务侧只消费刚完成的半区(零忙等),9 通道一轮 ≈ 67 µs |
| ADC1 上电自校准 | **已补(2026-10-10)**:`Src/adc.c` 的 `USER CODE BEGIN ADC1_Init 2` 调用 `adc1_calibrate()`(实现同文件 `USER CODE BEGIN 1`,按 RM0090 §13.3.6:清 ADON→等生效→置 ADON→置 CAL→等 CAL 由硬件清零)。⚠ **CubeMX 不生成这一步**,且本仓库裁剪版 HAL **没有** `HAL_ADCEx_Calibration_Start`、裁剪版 CMSIS 头**没有** `ADC_CR2_CAL`(bit3,代码里按 RM 自建 `ADC1_CAL_BIT`)→ 属 USER CODE 区手工定制,审计项 `adc1-calibration-call` / `adc1-calibration-impl` 兜底 | 实测有效:校准前后同一拍 STM32 侧 6 路**同向**变化 `UB 898→961`、`UC 978→1038`、`IB 906→922`、`IC 1061→1071`、`IN 1017→1055`、`T 790→846`(+10~+63 LSB ≈ 0.2~1.5 % FS);TPAFE 侧 `UA/UN/IA` 一字不变 → 变化确来自 ADC1 校准。缺这一步不报错,只是**读数带失调** |
| ADC 时钟 | CubeMX 的 F4 ADC 面板**有** Clock Prescaler 一项(此前"面板没有该项、固定 DIV2"的判断有误),已选 **PCLK2/4 → ADCCLK = 21 MHz** ✓。面板里 **DIV2 是灰的、选不到**:DB 里 `FadcConstraint Max=36000000`,APB2 = 84 MHz → DIV2 = 42 MHz 超限,该候选值被 `Action="DISABLE"` 禁掉,超规值进不来 | **不设额外防护(2026-10-09 决定)**:约束已由 CubeMX 把关;`.ioc` 虽不保存 `ADC1.ClockPrescaler` 键,重生成也只会回落到约束允许的值。按 144+12 cycles 算 ≈ 7.4 µs/通道、9 通道一轮 ≈ 67 µs |
| `adc_task` | **已实现(B1,2026-10-10;语义取数与有效性层 v2.3;P1-5 事件驱动消费,2026-10-10)**:`App/task/adc_task.c` 每拍调 `adc_input_poll()`(`App/algo/adc_input.c`)= TPAFE `tpafe5160_snapshot()` 原子快照(8 通道)+ 消费一帧 STM32 ADC1 DMA 乒乓缓冲,**经 `adc_input_raw()` 按语义取数**(不再直接索引驱动缓冲);**消费唤醒由 TIM3 ISR 置位 `ADC_WAKE_FLAG`**(不再 1 ms 轮询);任务在 `Src/freertos.c` 的 `USER CODE` 区创建为 `adcTask`(512 words / **AboveNormal**) | 数据路径已通(台架 `/serial-boot-test`:`frames` 严格 1000 Hz 递增、**`idle=0`**、`adc1_rc=0` / `adc1_err=0`) |
| `adc_task` | **已实现(B1,2026-10-10;语义取数与有效性层 v2.3;P1-5 事件驱动消费,2026-10-10)**:`App/task/adc_task.c` 每拍调 `adc_input_poll()`(`App/algo/adc_input.c`)= TPAFE `tpafe5160_snapshot()` 原子快照(8 通道)+ 消费一帧 STM32 ADC1 DMA 乒乓缓冲,**经 `adc_input_raw()` 按语义取数**(不再直接索引驱动缓冲);**消费唤醒由 TIM3 ISR 置位 `ADC_WAKE_FLAG`**(不再 1 ms 轮询);任务在 `Src/freertos.c` 的 `USER CODE` 区创建为 `adcTask`(640 words / **AboveNormal**,`Src/freertos.c:159 .stack_size = 640 * 4`) | 数据路径已通(台架 `/serial-boot-test`:`frames` 严格 1000 Hz 递增、**`idle=0`**、`adc1_rc=0` / `adc1_err=0`) |
| TPAFE 采样触发 | **周期 CONVST 已实现(2026-10-10)**:`Src/main.c` 的 `HAL_TIM_PeriodElapsedCallback` 在 **TIM3 更新事件(1 kHz)** 内调 `tpafe5160_start_conv_irq()`;`app_main_init()` 用 `HAL_TIM_Base_Start_IT(&htim3)` 启动节拍(在 `tpafe5160_init()` 之后)。同一 TIM3 更新事件还经 **TRGO** 硬件触发 ADC1 一轮 9 通道(DMA 搬运),并调 `adc_tick_irq_notify()` **唤醒消费者**(P1-5 方案 a,2026-10-10;内含"消费者就绪"门)→ 两片转换器由同一硬件事件同源对齐 | 连续波形(1 kHz);详见 `docs/子系统设计/ADC采样节拍设计说明.md` §4(DMA 乒乓搬运)与 §6(事件驱动唤醒) |
| 前端偏置 | 每路 1k 串联 + 滤波 C 跨接差分输入;差分负端(`*_GND` 网)经 1k 拴 AGND。**不是对地分压**(2026-10-27 网表追线定死,拓扑图见 §7.1),**无中点偏置** | TPAFE 输入阻抗 **1 MΩ 恒定**(`../芯片手册/TPAFE5160.md` "Analog Input Impedance" 节),故端子对 AGND 的直流通路 = 1k + 1 MΩ + 1k ≈ **1.002 MΩ**,不是 1 kΩ。两侧各 1 kΩ 是手册要求的**源阻抗匹配**(AIN_nP / AIN_nGND 外接源阻抗相等以抵消失调),**不是分压**。STM32 侧只能测 **0~3.3 V 单极性**,交流量负半周被削顶;主板侧只做监视可接受,若要算 RMS/功率需硬件补偏置或明确算法口径 |
| TPAFE 量程(**2026-10-25 量程口径冻结定死**) | 板上 RANGE 接 GND → **±5 V 双极性量程**(芯片手册输入量程表:RANGE = 0 → −5 ~ +5 V),16 位二进制补码,**±5 V 满量程 = 10 V 跨度**,LSB = 10 V / 65536 ≈ **152.59 µV/码(@ 转换器引脚)**。“±10 V” 是芯片的另一可选档(RANGE = HIGH,跨度 20 V、LSB ≈ 305.18 µV),**本板未用**——历史版本曾把本板误标为“±10 V 双极性”,与 §7 本行矛盾、且会让 TPAFE 侧系数差一倍,更正记录见 §9 | 用 `tpafe5160_to_voltage()` 换算;端到端口径见 §7.1 |
@@ -63,7 +63,7 @@
| V7 | **VCAP1/VCAP2(U17.71/106)旁路电容 C94/C79 值未标注**:数据手册要求 VCAP1/VCAP2 各接 1~4.7µF 低 ESR 陶瓷电容至 VSS(内部 1.2V LDO 稳定裕量) | 实测 C94/C79 容值(若为 100nF 则低于手册建议,168MHz 满负荷下 1.2V 轨纹量/稳定性需留意);值补录 BOM |
| V8 | **V15/J3/F3 子板 LED 3 线落在 PC13/PC14/PC15**(脚 7/8/9):备份域电源开关供电,手册 Note 3 限**灌流 ≤3mA、≤2MHz、不可作电流源** | 核子板 LED 驱动电流需求;超 3mA 则 V0.2 移足驱力脚或子板加三极管扩展 |
| V9 | **V0.1 主板 SDIO 固定引脚组全被占用**:PC6/PC7/PC8/PC9/PA8(TPAFE 控制)+ PA9(USART1)+ PC10/PC11/PC12/PD2(UART4/UART5)= SDIO 全部 10 脚(F407 SDIO 无重映射) | 架构约束备案:V0.1 主板**无 SDIO 能力**;当前设计不受影响(代码未启用 SDIO,FatFs 卷在 SPI NAND 上) |
| **V10** | **8 路电气量分属两片转换器(V0.1 硬件缺陷,V0.2 改版项)**:UA/UN/IA 走 TPAFE5160(16 位、同步、±5 V 双极性),UB/UC/IB/IC/IN 走 STM32 ADC(12 位、顺序扫描、0~3.3 V 单极性)→ 跨转换器通道**无同一时刻性**(相位关系不确定)、精度与量程不一致。详见 §6-3 与 [`ADC通道映射说明.md`](ADC通道映射说明.md) §1(2026-10-10 定性更正,登记簿 **N-18**) | **V0.2 改版**:8 路电气量 UA/UB/UC/UN/IA/IB/IC/IN **全部接 TPAFE5160**,与 TPAFE 上 5 路备用路(AIN5/13/7/15/12)对调串联电阻在转换器一侧的目的地——元件数量与料号不变,属走线级改动。V0.1 现板:主板侧只做逐通道监视,**不做**跨转换器的相位/功率/功率因数/矢量运算 |
| **V10** | **8 路电气量分属两片转换器(V0.1 硬件缺陷,V0.2 改版项)**:UA/UN/IA 走 TPAFE5160(16 位、同步、±5 V 双极性),UB/UC/IB/IC/IN 走 STM32 ADC(12 位、顺序扫描、0~3.3 V 单极性)→ 跨转换器通道**无同一时刻性**(相位关系不确定)、精度与量程不一致。详见 §6-3 与 [`ADC通道映射说明.md`](ADC通道映射说明.md) §1(2026-10-10 定性更正,登记簿条目「双转换器无共同采样触发」) | **V0.2 改版**:8 路电气量 UA/UB/UC/UN/IA/IB/IC/IN **全部接 TPAFE5160**,与 TPAFE 上 5 路备用路(AIN5/13/7/15/12)对调串联电阻在转换器一侧的目的地——元件数量与料号不变,属走线级改动。V0.1 现板:主板侧只做逐通道监视,**不做**跨转换器的相位/功率/功率因数/矢量运算 |
## 2. 元件级变化
@@ -214,7 +214,7 @@ V0.0 §2.2/§4.7 的 6 路 MCU 控制 LED(实板位号 LED5~LED10,阴极经
1. **TPAFE 8 路 ↔ STM32 ADC 9 路的"归属"也变了**:V0.1 中 TPAFE(U3)采 U5 的 B6/A6/B5/A5/B4/A4/A3/B3,STM32 ADC 采 C13/C9/C10/C14/C12/C11/A8/B7——两族通道数(8+9)不变,成员重分。
2. 网名 AINn 与 ADCn 编号**不再一一对应**(如 AIN1→ADC7),任何按"AINn=ADCn"假设的代码/文档/测试都会静默采错通道——这正是 V0.0 §1.6 警示的"静默死亡"型风险,务必以本表建立映射。
3. 置换疑似按 U5 连接器物理位置重排走线(TPAFE 8 路恰为 B6→B3 降序)。**2026-10-10 更正**:置换本身(AINn↔ADCn 编号打乱)可视为走线安排,但**"8 路电气量分到 TPAFE 与 STM32 两侧"属 V0.1 硬件缺陷**——2026-10-09 曾按"计量在子板、主板只做监视"把它确认为"有意设计",该定性**作废**。缺陷实质:TPAFE 8 通道同步采样、STM32 ADC 顺序扫描且两者无共同采样触发 → 跨转换器通道**无同一时刻性 / 相位关系不确定**;16 位 ±5 V 双极性 vs 12 位 0~3.3 V 单极性 → 同族量精度与量程不一致。**下一版硬件(V0.2)需把 8 路电气量 UA/UB/UC/UN/IA/IB/IC/IN 全部改接 TPAFE5160**(与 TPAFE 上 5 路备用路对调串联电阻目的地,BOM 不变),登记簿 **N-18**。语义分配(UA/UB/UC/UN、IA/IB/IC/IN、V_ZL2=温度检测,其余 8 路备用)与 17 路端到端映射已固化为 [`docs/硬件平台/ADC通道映射说明.md`](ADC通道映射说明.md)(缺陷实质与改版要求见其 §1);固件通道映射表、UI 通道显示、自检逐通道注入验证(V0.0 §5.1-6)按该表执行。
3. 置换疑似按 U5 连接器物理位置重排走线(TPAFE 8 路恰为 B6→B3 降序)。**2026-10-10 更正**:置换本身(AINn↔ADCn 编号打乱)可视为走线安排,但**"8 路电气量分到 TPAFE 与 STM32 两侧"属 V0.1 硬件缺陷**——2026-10-09 曾按"计量在子板、主板只做监视"把它确认为"有意设计",该定性**作废**。缺陷实质:TPAFE 8 通道同步采样、STM32 ADC 顺序扫描且两者无共同采样触发 → 跨转换器通道**无同一时刻性 / 相位关系不确定**;16 位 ±5 V 双极性 vs 12 位 0~3.3 V 单极性 → 同族量精度与量程不一致。**下一版硬件(V0.2)需把 8 路电气量 UA/UB/UC/UN/IA/IB/IC/IN 全部改接 TPAFE5160**(与 TPAFE 上 5 路备用路对调串联电阻目的地,BOM 不变),登记簿条目「双转换器无共同采样触发」。语义分配(UA/UB/UC/UN、IA/IB/IC/IN、V_ZL2=温度检测,其余 8 路备用)与 17 路端到端映射已固化为 [`docs/硬件平台/ADC通道映射说明.md`](ADC通道映射说明.md)(缺陷实质与改版要求见其 §1);固件通道映射表、UI 通道显示、自检逐通道注入验证(V0.0 §5.1-6)按该表执行。
## 7. 电源/地网络成员变化(拓扑不变)
+1 -1
View File
@@ -85,7 +85,7 @@
| [`setview-check.md`](setview-check.md) | `setview-check` | 定值查看行表与 `prot_set` 枚举序 / `g_prot_set_meta` 上下限是否同一份口径 | `tools/setview_check/**`、`ui_w_setview.*` | 已写 |
| (专篇待补,档位与限度正文在 [`../UI设计/UI_自动化测试流程.md`](../UI设计/UI_自动化测试流程.md) §7.3) | `uinav-selftest` | 板端 UI 导航器认屏快检(黄金参考帧分类;完整闭环档=合入前/上板前手工跑,快检不互替) | `scripts/board_ui_nav.py`、`simulator/tests/ref/*.bin` | 指针 |
| [`host-unit-tests.md`](host-unit-tests.md) | 22 个 `*-unit-test` | 主机侧单测(同一机制 22 个实例):逻辑层在无硬件的 PC 上编译并跑断言 | 各自被测模块与其测试目录 | 已写 |
| 详解在 [`../测试说明/单元测试/主机单测覆盖率口径.md`](../测试说明/单元测试/主机单测覆盖率口径.md)(口径 / 分母 / 基线 / 盲区都在那篇,本目录不重复) | `test-coverage` | **覆盖率总闸**:跑全部 44 套主机单测 + 已覆盖行只增不减的回退台账 | `App/`、`Drivers/BSP/`、`test/host/`、脚本与基线 | 已写(在 `docs/测试说明/`;`stages: [manual]`) |
| 详解在 [`../测试说明/单元测试/主机单测覆盖率口径.md`](../测试说明/单元测试/主机单测覆盖率口径.md)(口径 / 分母 / 基线 / 盲区都在那篇,本目录不重复) | `test-coverage` | **覆盖率总闸**:跑全部 47 套主机单测 + 已覆盖行只增不减的回退台账 | `App/`、`Drivers/BSP/`、`test/host/`、脚本与基线 | 已写(在 `docs/测试说明/`;`stages: [manual]`) |
| [`trailing-whitespace.md`](trailing-whitespace.md) | `trailing-whitespace` | 行尾空白(改写型;CubeMX/Keil 生成文件豁免) | 全部 | 已写 |
| [`end-of-file-fixer.md`](end-of-file-fixer.md) | `end-of-file-fixer` | 文件末尾必须恰好一个换行(改写型;同豁免) | 全部 | 已写 |
| [`check-added-large-files.md`](check-added-large-files.md) | `check-added-large-files` | 别把大文件(日志/镜像/二进制)误提进仓库 | 全部 | 已写 |
+7 -7
View File
@@ -91,19 +91,19 @@
清点(2026-10-28 复点、2026-10-29 录波三套入库后再复点:下列数字已按复点值更新;上一版写「16 个模块有专属钩子、另有 12 套、总闸跑 28 套」——三个数都随 2026-10-25 的
六根新钩子与后续新增套件过期了,正是本目录反复在防的"文档与机器面不同码"):
- **22** 根专属钩子 = 有独立 `files:` 触发面、需要**秒级归因**的那个子集;
- `test/host/` 下带 `run_unit_test.py` 的套件实测 **44** 套(46 个目录,除 `common` 与
`__pycache__`;两个数分别来自 `check_test_coverage.py --list` 与 `ls -d test/host/*/`,2026-10-29 实测)
⇒ **没有专属钩子的是 22 套**:`boot_stats`、`cfg_file_store_mcu`、`console_log`、
- `test/host/` 下带 `run_unit_test.py` 的套件实测 **47** 套(48 个目录,除 `common` 与
`__pycache__`;两个数分别来自 `check_test_coverage.py --list`(47 行)与 `ls -d test/host/*/`(48 个目录),2026-10-30 复点)
⇒ **没有专属钩子的是 25 套**:`boot_stats`、`cfg_file_store_mcu`、`console_log`、
`ftp_cfg`、`iec104_serv`、`lftpd`、`lftpd_inet`、`lftpd_io`、`net_cfg`、`net_events`、
`net_listener`、`net_pending`、`net_select`、`net_socket`、`prot_set_store`、`soe_store`、
`net_listener`、`net_pending`、`net_select`、`net_socket`、`prot_set_store`、`sb_led_map`、`sb_link`、`sb_proto`、`soe_store`、
`sys_log_mcu`、`task_prof`、`ui_sink`、`wave_ring`、`wave_store`、`wave_trig`(末三套 2026-10-29 随
故障录波入库,按同一条 Lead 裁定不补专属钩子;22 = 44 套 − 22 根专属钩子,逐点数与两处机器源互证);
故障录波入库,屏板三套(`sb_proto`/`sb_link` 2026-10-29、`sb_led_map` 2026-10-30)随屏板链路入库,同一条 Lead 裁定不补专属钩子;25 = 47 套 − 22 根专属钩子,逐点数与两处机器源互证);
- 这 22 套每次 CI 与 `scripts/ci_local.py` 都由 `test-coverage` **总闸**真跑(该钩子带 `stages: [manual]`:
`git commit` 阶段不跑它,这一根与 `cppcheck` / `test-cppcheck` 同属 CI 与 `ci_local.py` 的 manual 段);
发现规则是
`HOST_TEST_DIR.rglob("run_unit_test.py")`(与 `scripts/ci_local.py` 的主机侧纯逻辑单测同一口径),
退出码语义写死「0 = 全部单测通过且覆盖率相对基线没回退 / 1 = 有单测失败或覆盖率回退」⇒
**失败照样拦(CI 与 `ci_local.py` 的 manual 段)**。差的只是归因粒度(要在总闸输出里认出是哪套)与耗时(44 套全量比单根慢得多);
**失败照样拦(CI 与 `ci_local.py` 的 manual 段)**。差的只是归因粒度(要在总闸输出里认出是哪套)与耗时(47 套全量比单根慢得多);
- 要不要给某套补第 23 根,判据现成:pre-commit 4.x 没有 `always: true`,**该模块有没有自己的
`files:` 触发面**决定补了会不会真跑;只为凑数加一根,等于把「快归因面」和「全量把关」两件事混成
一件,还要让钩子计数再改一次;
@@ -113,7 +113,7 @@
实跑数」三处同源同步的计数点——本仓 2026-10-26 到 27 一天之内就为 40 / 50 / 51 这三个数不同源
返工过两轮。**要读「这套跑没跑」,读总闸输出,不要来数钩子。** 两个方向的空头账一起堵住:
① 别把没接线的套件算进钩子账(原写「23 个 / 含 ui-sink」正是这么错的;2026-10-27 复核的准数是
22 根 / 40 套 / 18 套无专属钩子(三个数都是当时值)——第 41 套 `boot_stats` 当日 11:29 才入库,此后两数当时是 41 / 19,现值 44 / 22 以本条上面的实测行为准);② 也别把总闸的绿读成「每套都被单独归因过」——它只保证
22 根 / 40 套 / 18 套无专属钩子(三个数都是当时值)——第 41 套 `boot_stats` 当日 11:29 才入库,此后两数当时是 41 / 19,现值 47 / 25 以本条上面的实测行为准);② 也别把总闸的绿读成「每套都被单独归因过」——它只保证
「全跑过 + 覆盖率没回退」。将来确实要给某套补专属钩子,先过上一条判据,并在**同一笔**里改
AGENTS 与门禁索引的计数(口径 = YAML 解析条目数,见 `docs/门禁说明/README.md` §2 首条)。
- 总闸的触发面是 `App/`、`Drivers/BSP/`、`test/host/`、覆盖率脚本与基线,**外加门禁自身**