feat(UI/采集/104): 通讯设置页 + 开机账本 + adc_cal 可诊断化——三车道同树一次构建入库

三条道在同一棵树上交付,故合并成**一次权威构建**(@build 0 错 0 警,Code=235236 RO=26308 RW=1572
ZI=136924)后同笔入库;台账已按该构建回填(`ram_baseline.py --update` + `--write`、`chec
k_mem_numbers.py
 --write`),凭证与实际 .map 同源。归属如下:

· **通讯设置页**(道G task-9):新增 `Drivers/BSP/UI/ui_page_comm.{c,h}`(通道六注入,与死
区页同骨架同纪
  律),`#page=comm` 绑定使 bound **21 → 22**、内容页黄金 **47 → 53**(旧 47 页字节零变化,
新增六态含
  WAIT/OK 两张);`iec104_comm` 脏位 + store_save(**无事件位**)挂 defaultTask 同点位
轮询;`port_104` 由
  宏改走 getter、`IEC104_SERV_PORT` 删除;字体 +听/监(185 字全覆)。**实机链已闭环**:FTP 外改
[comm]
  的 ca/port → 复位 → 串口出现 `section 'comm' (2 keys)` 与 `i104: listening o
n 9004` → 还原 2404,全程无
  FAIL ⇒「重启即生效 + 端口真值」不是推断是实测。上限核对 6/8 段、2/16 键,超限现象由 TC-CONFIG-056/057
  钉死(注册 -1 + `comm init: FAIL` 锚 + getter 回 ROM),**不抬宏**。
· **开机账本**(道F task-12):新增 `App/util/boot_stats.{c,h}`——上电次数落 SD2506 用户
 SRAM(magic +
  小端计数 + 版本 + 异或校验),一次上电 = 1 读 + ≤1 写,**零 NAND、零卷锁、零配置段**;四态互斥
  UNKNOWN / FRESH / CONTINUED / RESTARTED(BLF=1 才算电池域掉过电),**读失败绝不回写**;
文案口径「自 RTC
  电池周期起」,**禁写终身次数**。复位原因优先级链从 `app_main.c` 的 if-else 收进一份真源(串口与屏幕同
  源);104 四个只增不清计数 + `iec104_serv_get_stats()` 留在 serv、未塞进 link(会被 open
/close 洗掉)。
  运行时长按用户裁定 = **只报本次开机以来**,零新增代码。新套件 `test/host/boot_stats` 21/21,五处注入
  **全部有牙**(含「漂一字节被校验和挡下而不是报 256 倍错账」)。
· **adc_cal 可诊断化**(道E task-43):三个 volatile 计数 + `adc_cal_get_stats()`
/ `adc_cal_note_persisted()`
  (水位**盖写非自增**,因为一次 save 覆盖整档,数 save 会留假未落盘);「差额 × 脏位」三态语义唯一落在
  `adc_cal.h`,其中「差额 > 0 且脏位恒 0」= 绕过语义 setter 的静默丢失;TC-ADCCAL-019~023。

三条**必须留档的自纠**(都是执行道自己报的,我不替他们润色):
① stdint 那条断链是**宿主套件抓到、通讯道先修**,采集道承认自己是重复添加者并删掉自己那份;
② 「exit 2 不是证据,断言变红才是」——采集道第一版反证注入了未声明标识符导致编译错,差点当成功;
③ 套件汇总行原写 `s_total/s_total`,失败时会打印「21/21 PASSED (failed=1)」这种自相矛盾的行,已改。

另修:`check_registration.py` 的 `SIM_EXEMPT` 加一行豁免 `App/util/boot_stats.c
`(依赖 I2C 与 RCC 位掩码,
MCU 专属;核过 `sys_clock.c`/`sha256.c` 同形态先例),注册反向校验 exit 1 → 0。发号 TC-IEC1
04-034、
TC-UIDATA-029 已实抬游标(`TC-IEC104-033→034`、`TC-UIDATA-026→029`)。

门禁:id-check --strict 与 plain 均 rc=0、doc-links --all rc=0、注册校验 0、cppche
ck / coding-standard /
bom-drift 0;iec104 179/179、ui_data 295/295、boot_stats 21/21、adc_cal 11
7/117、run_par 67/67;菜单 8 状态
池 5368 不变、内容页 53/53。**已知遗留**:内容页数 47 → 53 的全仓文本同步尚未做(另卡跟踪),本笔只保
证代码与黄金一致;面板注键真机那一腿缺 CLI,交台架道补。
This commit is contained in:
2026-10-27 11:29:23 +08:00
parent 0ae9c10f24
commit 728d60675f
47 changed files with 2364 additions and 123 deletions
@@ -47,10 +47,10 @@ dhara 失败类 +84;RO 另 +208,全是该失败类名表)→ `ER_IROM1`
<!-- MEM_SNAPSHOT:BEGIN generated by scripts/check_mem_numbers.py -->
| 区域 | 用量 | 容量 | 占比 |
|---|---|---|---|
| ER_IROM1 | 260,004 B (253.91 KB) | 1,048,576 B (1024 KB) | 24.8% |
| RW_IRAM1 | 80,920 B (79.02 KB) | 131,072 B (128 KB) | 61.7% |
| ER_IROM1 | 261,544 B (255.41 KB) | 1,048,576 B (1024 KB) | 24.9% |
| RW_IRAM1 | 81,072 B (79.17 KB) | 131,072 B (128 KB) | 61.9% |
| RW_CCM | 57,376 B (56.03 KB) | 65,280 B (64 KB) | 87.9% |
| **Flash (ROM 合计)** | **261,540 B (255.4 KB)** | 1,048,576 B (1024 KB) | **24.9%** |
| **Flash (ROM 合计)** | **263,116 B (256.9 KB)** | 1,048,576 B (1024 KB) | **25.1%** |
<!-- MEM_SNAPSHOT:END -->
各区的容量与常量来源:
@@ -512,9 +512,17 @@ vApplicationAssertFailed` 共 103 行),而 `vApplicationAssertFailed` 钩子
记账 208 = D360)与 `[ERR]→NVIC_SystemReset` 这类终点路径,真实运行不会把环走满;它
也不算 ISR 上下文保存(约 100 B)与间接调用(§4.0.6 盲区条同源)。所以静态链适合当
**硬线**(可复现、无噪声、机器可判:margin ≥ max(1024 B, cfg×30%)),不适合当实际余量;
实际余量看 §4.0.2 的串口 `[STACK]` 水位。台架判据「栈水位不劣于上一轮」必须加容差或
改拿本节的静态硬线(「栈水位判据加容差或改静态最坏链当硬线」卡 = task-32,与本节和
§4.0.2 互指)。
实际余量看 §4.0.2 的串口 `[STACK]` 水位。**台架栈判据已定稿(task-32,2026-10-27)——三档分权**:
静态 margin 是**唯一拦提交项**(提交时由 `scripts/stack_report.py` 守,见 §4.0.6);运行时水位只做
**趋势告警**:同镜像 ≥3 圈取最大值与基线轮最大值互比,容差 **tol = 160 B**(来源 = 实测同镜像最大摆动
80 B × 2,再向上取整到 16 B 格;登记与改数规则见 `scripts/stack_tolerance.tsv`——**只有台架重测后才能
回填,被这把尺考核的人不得当场决定尺子的松紧**);运行时唯一能升级成 FAIL 的条件是绝对底线
`free_min < 25% cfg`;**采集健康门不过 = VOID(exit 2)**,不红不绿也不进台账——按码聚合的人不会把
「端口没开」记成「又崩了一次栈」。判据与门都可执行:`scripts/stack_gate.py`(`--selftest` 14 条),它是
**台架侧门禁**(每轮台架跑完必跑;Lead 裁定 2026-10-27:不接 pre-commit——提交时既无设备也无当轮日志,
挂上去只会得到「永远 SKIP」或「拿上一轮日志判这一轮的码」,后者正是体积门禁那条假凭证的同族)。
口径正文:`docs/测试说明/启动日志原子性复验流程.md` §5(三档表与门的细节都在那节)。
本节口径与本文的运行时水位小节、静态硬线小节互指(同文件内引用,不再另标编号,避免跨文档串号)。
**取证纪律(本节方法的可复用模板)**:凡跨树/跨构建引用数字,必须同时钉**产物路径 +
Linker run 时刻**——commit hash 不是稳定身份(重写正文即换 hash),tree hash + 父提交