docs: 删任务规划两份已完成文档,数据可信内容迁入算法层/硬件平台/登记簿

任务规划目录从 5 个文件收敛到 3 个:只留导航(README)、待办(登记簿)、
暂缓专项(暂缓-RS485)。

删除的两个文件都不再有现行读者:
- UI补齐.md 执行清单 2026-10-28 清空、上板判据 2026-11-06 台架轮已复核;
  叶数口径迁 docs/UI设计/菜单页面设计.md §3.9,三条内容页硬规矩迁
  docs/UI设计/内容页架构.md §7.1,两条未闭环待办迁登记簿 §7/§8。
- 数据可信.md 不是完成记录,而是被约 130 处代码头注释引用的设计约束,
  因此按内容分三处落位后删除,不整篇丢弃。

数据可信内容的新归属(旧节号 → 新家):
- §2/§4 设计口径 → docs/算法/采集与算法层设计说明.md 新增 §13(13 小节),
  §7 前置决策表 → §13.12 已定案的前置决策。
- §3 台阶与波次退出判据 → docs/硬件平台/ADC通道映射说明.md 新增 §9。
- §5 任务卡 → docs/任务规划/登记簿.md §7(拆成变比确认 / 两点标定两行)。

引用改写 34 文件 77 处路径引用 + 14 文件 24 处昵称引用 + 双重节号 35 处,
覆盖代码头注释、测试、生成器与文档;归档区历史路径改纯文本提及。
四个 SVG 生成器文案同步并重跑,产物随脚本同批提交。

同批处理两件事:
- 9 个 UTF-16 LE 证据文件转 UTF-8。end-of-file-fixer 按字节判末尾换行,
  UTF-16 的换行是 0A 00、末字节 00,钩子会追加裸 0x0a 使文件变奇数长度,
  8 个已实际损坏。转码后逐文件比对 HEAD 原文验证正文零丢失。
- 修回 App/cfg/cfg_file.c 被剥掉的 UTF-8 BOM(补 3 字节,未整文件重写)。

验证:/keil-build 0 错误 0 警告(Code=255160);check_doc_links --all
--sections-strict 221 篇全通过、无法判定 0;pre-commit 全量全 Passed。
This commit is contained in:
2026-11-09 16:10:55 +08:00
parent 7027718dcd
commit ae09c5737a
87 changed files with 613 additions and 746 deletions
+4 -4
View File
@@ -11,7 +11,7 @@
```
docs/
├── README.md 本索引(阅读顺序 + 全量清单)
├── 任务规划/ 统一待办(README 单一入口 + 6 个职责文件)
├── 任务规划/ 统一待办(README 单一入口 + 2 个职责文件)
├── 产品需求/ 产品需求设计文档(需求基线)+ 参考产品复刻明细(逐项差额)
├── 架构设计/ 全局架构与设计方法论(含 软件架构与运行时规格 / 硬件规格与能力边界:位表与引脚权威)
├── 子系统设计/ 各功能子系统的设计说明
@@ -109,7 +109,7 @@ docs/
| 文档 | 内容 |
|---|---|
| [`傅氏算法详解.md`](算法/傅氏算法详解.md) | 全周波傅氏(单频 DFT)原理与工程实现:正交性、梳状带通、滑动窗、系数表折算有效值;保护/遥测双轨有效值的算法基础 |
| [`采集与算法层设计说明.md`](算法/采集与算法层设计说明.md) | **`App/algo/` 的现状设计说明**:语义取数与有效性判定、全周傅氏相量采样环/相量/测频、保护判据定值模型与元件框架的契约、关键机制(双区原子切换、乒乓半区、自适应测频窗、定值封存-自检-闭锁)、精度判据 J1~J6 与资源足迹 |
| [`采集与算法层设计说明.md`](算法/采集与算法层设计说明.md) | **`App/algo/` 的现状设计说明**:语义取数与有效性判定、全周傅氏相量采样环/相量/测频、保护判据定值模型与元件框架的契约、关键机制(双区原子切换、乒乓半区、自适应测频窗、定值封存-自检-闭锁)、精度判据 J1~J6 与资源足迹;**§13 = 标定折算**(码值→工程量、三态可用性、未标定即闭锁、遥测快照、六轮动态验证判据、已定案的前置决策) |
| [`继电保护功能复现规划.md`](算法/继电保护功能复现规划.md) | **保护功能复现规划**:把参考系统(CLS100)保护链路映射到本项目(STM32F4)的分层功能/性能/参数清单、平台适配(「双转换器无共同采样触发」等)与分阶段路线图 |
| [`采样有效性校验设计说明.md`](算法/采样有效性校验设计说明.md) | **`App/algo/adc_health.c` 单文件深设计**:四类判据(静默 / 丢帧 / 序号倒退 / 错误计数增量)的判据推导与 100 ms 门限依据、电平-锁存-事件三种位语义与位号对齐、闭锁与看门狗兜底的责任划分、观测盲区、主机侧验证分工与现场判读手册(含三张配图生成器) |
@@ -263,8 +263,8 @@ docs/
| 位置 | 内容 |
|---|---|
| [`任务规划/`](任务规划/README.md) | **统一待办入口(5 个文件)**:`README.md` = 现在做什么与全项目顺序;`UI补齐.md` = 当前唯一执行清单;`登记簿.md` = 后续任务、外部窗口与长期观察;(故障录波卡片登记簿已完成代码面收口,判据并入 `docs/子系统设计/故障录波设计说明.md` §10 后已删除 2026-10-30);`数据可信.md` = 采集数据可信度的五级台阶与任务卡(含手边可做的动态波形验证)+ 被代码引用的设计约束;`暂缓-RS485.md` = 暂缓专项(`测试与架构专项.md` 已删除 2026-10-28,未闭环约束并入 `暂缓-RS485.md`;`屏板链路.md` 已完成,转为 `子系统设计/屏板链路设计说明.md` 后删除)。完成即删,重复内容只保留一个归属 |
| `硬件平台/` | 网表详细分析报告与语义图(V0.0 / V0.1);**[`ADC通道映射说明.md`](硬件平台/ADC通道映射说明.md)——V0.1 十七路 ADC 语义/网名/通道号权威映射表(固件取数、UI 显示、自检注入以此为准)** |
| [`任务规划/`](任务规划/README.md) | **统一待办入口(3 个文件)**:`README.md` = 现在做什么与全项目顺序;`登记簿.md` = 全部待办、外部窗口与长期观察(UI 补齐已于 2026-11-06 整体销项,页面口径归 `docs/UI设计/内容页架构.md` §7.1 与 `菜单页面设计.md` §3.9,原执行清单文件已删除;采集数据可信度的设计口径与台阶图归 `docs/硬件平台/ADC通道映射说明.md` §9 与 `docs/算法/采集与算法层设计说明.md` §13);`暂缓-RS485.md` = 暂缓专项(`测试与架构专项.md` 已删除 2026-10-28,未闭环约束并入 `暂缓-RS485.md`;`屏板链路.md` 已完成,转为 `子系统设计/屏板链路设计说明.md` 后删除)。完成即删,重复内容只保留一个归属 |
| `硬件平台/` | 网表详细分析报告与语义图(V0.0 / V0.1);**[`ADC通道映射说明.md`](硬件平台/ADC通道映射说明.md)——V0.1 十七路 ADC 语义/网名/通道号权威映射表(固件取数、UI 显示、自检注入以此为准),含 §7 链路四段口径、§8 注入实测记录与 §9 数据可信五级台阶/波次退出判据** |
| `芯片手册/` | 外部芯片数据手册转录(CH395F / GD5F2GQ5UE / SD2506 / TPAFE5160 / RTL8305NBI 等) |
| `images/` | 文档技术配图(`.svg` 产物,由 `tools/arch_diagram/`、`tools/refgraph/` 生成) |
+3 -3
View File
@@ -179,7 +179,7 @@ typedef struct {
**要点**:
- **`eng` 字段是诚实性的关键**(【2026-10-25 落地注】本条原写"0 = 原始码值(未标定)、`val` 是 ADC 码值(千级)",那是标定落地前的旧口径,已按现场改真值语义):标定层 `adc_cal` 的 ROM 默认系数按**引脚侧 LSB**定死(TPAFE 152.59 µV/码、STM32 805.66 µV/码),采样环折算出来的 `val` 现在是 **ADC 引脚电压 V**——既不是千级码值,也不是端子二次值。承诺边界的依据是 `docs/任务规划/数据可信.md` §2.6:这一波只承诺到"引脚电压","端子二次值"要等变比确认与两点标定。所以页面文案是 `eng=0` → "未标定"、`eng=1` → "二次值",而不是"码值";升档条件写在 `App/app/ui_data_feed.c` 的 `feed_eng()`——**电气 8 路 `adc_cal_flags()` 的 VALID 全置位才升**(整帧共用一个 `eng`,只要还有一路是引脚电压就不能给整帧贴"二次值"标签,宁可整体保守)。TEMP 不参与线性标定 → 该路恒带 `UI_DATA_Q_RAW`,页面据此不挂单位、不与其他路互比。
- **`eng` 字段是诚实性的关键**(【2026-10-25 落地注】本条原写"0 = 原始码值(未标定)、`val` 是 ADC 码值(千级)",那是标定落地前的旧口径,已按现场改真值语义):标定层 `adc_cal` 的 ROM 默认系数按**引脚侧 LSB**定死(TPAFE 152.59 µV/码、STM32 805.66 µV/码),采样环折算出来的 `val` 现在是 **ADC 引脚电压 V**——既不是千级码值,也不是端子二次值。承诺边界的依据是 `docs/算法/采集与算法层设计说明.md §13.5`:这一波只承诺到"引脚电压","端子二次值"要等变比确认与两点标定。所以页面文案是 `eng=0` → "未标定"、`eng=1` → "二次值",而不是"码值";升档条件写在 `App/app/ui_data_feed.c` 的 `feed_eng()`——**电气 8 路 `adc_cal_flags()` 的 VALID 全置位才升**(整帧共用一个 `eng`,只要还有一路是引脚电压就不能给整帧贴"二次值"标签,宁可整体保守)。TEMP 不参与线性标定 → 该路恒带 `UI_DATA_Q_RAW`,页面据此不挂单位、不与其他路互比。
- **字符串只用定长数组**:`clock[20]` 在结构体内,无指针、无生命周期问题(跨层传指针是经典事故源)。
- **`yx_valid` 与 `yx_bits` 分开**:无效点不参与显示、不参与变位判断(沿用 104 点表的既有做法,避免"IV 通道抖动成变位")。
- **`yx_dp`(2026-10-25 批 4 追加)**:单点还是双点是 **104 点表事实**(`iec104_pts.c` 的 `YX_DP_N`
@@ -212,7 +212,7 @@ typedef struct {
**为什么存 Q10 而不是 float**:定值是**整表校验和覆盖的定点值**,快照存浮点会引入"显示值与校验和口径不一致"的二义性。Q10 → 显示值的小数位换算属表现层(§8)。
**`locked` 与 `cal_block` 是两个事实,屏上是两条通道、两个词,不得合并**(判据口径
`docs/任务规划/数据可信.md` §4.3):
`docs/算法/采集与算法层设计说明.md §13.4`):
| 字段 | 真源 | 说的是什么事 | 屏上落点 | 还能改定值吗 |
|---|---|---|---|---|
@@ -400,7 +400,7 @@ ui_data_param_state() / ui_data_param_err_mask()(保存行显词 + 越界行
> ⚠ **提交侧必须只提交 `mask` 内置位的 id,绝不"从显示值回提全表"**:Q10 存不下 0.95 这类
> 返回系数(实际存 972/1024),按显示域往返会把用户没动的项顺手改掉。判据"越界值不落盘"与
> "改哪条只落哪条"都建在这条上(`docs/任务规划/UI补齐.md` §2 第 2 行)。
> "改哪条只落哪条"都建在这条上(判据见 `docs/UI设计/内容页架构.md` §7.1)。
> 换算的往返精度因此也**不需要**逐位可逆:没动的行根本不进换算函数。
**这套结构与 `net_cfg` 的 `net_cfg_save_request` / `net_cfg_save_state` 完全同构**
+8
View File
@@ -450,6 +450,14 @@ extern const content_page_def_t ui_page_device_info_desc; /* 描述符(Flash
| 动态数据页 | `rows=NULL` + `refresh`(逐行取数);行数随数据变再加 `count_cb` |
| 表单/操作页 | `selectable=0`、`rows=NULL`、`draw_cb` 自绘内容 + `key_cb` 自有键(ESC 返回仍由框架保证;首个实例=密码页,见 §4.1) |
### 7.1 三条硬规矩(做执行类页面时先读)
1. **不允许用静态演示数据充数**:页面开工前先有真实写入方或真实计数器,再补页面。历史上记录 5 页与运行报告页就是这么做的。
2. **执行类页面不得做成「点了个按钮但没效果」**:清除记录必须按 `syslog_clear_state()` 出真反馈(按钮按下去 `syslog_count()` 要归零);遥测死区/系数两页的三态用 `run_par_dirty_peek()` 区分「已受理」与「已落盘」,且像素黄金**必须出 WAIT 与 OK 两张**——假件要保留脏位、只由 headless pump 清,否则真机的 WAIT 态永远不会被回归覆盖。
3. **保护闭锁必须可见**:整定页可以改定值,但产品构建下 UA/UN/IA 未标定 → 保护判据闭锁。页面必须显示这个状态,不能让用户以为"改完定值保护就会动作"(口径见 `docs/算法/采集与算法层设计说明.md §13.4`)。
页面涉及保存、重启、主站读回时,台架可用后统一补做实机判据并留证——模拟器测不出 Flash 落盘与跨复位行为。
## 八、验证与回归
- **门禁**(`ui-verify` skill / `UI_自动化测试流程.md`):
+17
View File
@@ -430,6 +430,23 @@ python tools/menu_gen/gen_menu.py
> 逻辑层/显示层**只读**它(§3.4 的 API 都是对它的过滤/查询),从不修改。合计 ≈ **0.7 KB Flash**。
### 3.9 节点数与已绑叶数口径(复核命令)
改菜单树前先能自己数清四个数,别凭印象:**当前 43 节点行 / 34 叶 / 已绑 31 叶 / 未绑 3 叶**(未绑 = 遥信类型、遥信防抖、双点遥信,V0.1 无开入硬件,重开条件见 `docs/任务规划/登记簿.md` §8)。
1. **节点行** = `ui_menu_tree.txt` 里非空、非 `#` 开头的行(含根「主界面」)。
2. **叶** = 其后不再出现更深缩进的后继行(缩进即层级,每级 2 空格);等价于生成物 `ui_menu_tab_has_children(node) == false`。菜单节点 = 有更深缩进后继者。
3. **已绑叶** = 叶行行尾带 ` #page=`;未绑 = 不带。闭合关系 `未绑 = 待做 + 不做`。
4. **别拿 `grep -c '#page='` 当已绑叶数**:它比真值多 1 —— 文件头规则说明里有一行 ` #page=<模块名>` 示例,必须先剔注释/示例行。
复核命令(复用生成器自己的解析器,不另写一套计数逻辑):
```bash
& '.venv\Scripts\python.exe' -c "import io,sys; sys.path.insert(0,'tools/menu_gen'); import gen_menu as g; n,_=g.parse_tree(io.open('ui_menu_tree.txt',encoding='utf-8').read()); leaf=[i for i,x in enumerate(n) if all(y[0]!=i for y in n)]; b=sum(1 for i in leaf if n[i][4]); print('nodes=%d leaves=%d bound=%d unbound=%d' % (len(n),len(leaf),b,len(leaf)-b))"
```
输出四个数与生成物交叉核对:`ui_menu_tab.h` 的 `UI_MENU_TAB_COUNT` = 节点行数、`ui_page_registry.h` 的 `UI_PAGE_MAP_COUNT` = 已绑叶数。
---
## 四、显示规范:横向级联子框模型
+1 -1
View File
@@ -21,7 +21,7 @@
已绑定 6 页:`装置信息`(node 1)、`交流量`(3)、`直流量`(4)、`网口设置`(30)、`自检记录`(39)、`运行记录`(40)。
> ⚠ **本表 = 2026-10-25 立项时快照,按历史冻结不回改。** 2026-10-28 复扫现值:**已绑 28 叶 / 未绑 5 叶**;**2026-10-29 再复扫:已绑 30 叶 / 未绑 4 叶**(手动录波与录波回放两叶已绑)(判据两处互证:`ui_menu_tree.txt` 剔掉文件头注释里的示例行后 `#page=` 实数 = 30,与生成物 `ui_page_registry.h` 的 `UI_PAGE_MAP_COUNT` 一致);未绑 5 叶 = 遥信类型 / 遥信防抖 / 双点遥信 / 手动录波 / SNTP 设置。现状口径见 `docs/任务规划/UI补齐.md` §1 与 `docs/产品需求/产品需求设计文档.md` §8.2 / §8.3。
> ⚠ **本表 = 2026-10-25 立项时快照,按历史冻结不回改。** 2026-10-28 复扫现值:**已绑 28 叶 / 未绑 5 叶**;**2026-10-29 再复扫:已绑 30 叶 / 未绑 4 叶**(手动录波与录波回放两叶已绑)(判据两处互证:`ui_menu_tree.txt` 剔掉文件头注释里的示例行后 `#page=` 实数 = 30,与生成物 `ui_page_registry.h` 的 `UI_PAGE_MAP_COUNT` 一致);未绑 5 叶 = 遥信类型 / 遥信防抖 / 双点遥信 / 手动录波 / SNTP 设置。现状口径见 `docs/UI设计/菜单页面设计.md` §3.9 与 `docs/产品需求/产品需求设计文档.md` §8.2 / §8.3。
### 1.2 27 个空叶子清单(按菜单顺序)
+2 -2
View File
@@ -90,9 +90,9 @@
| 38 | 遥控记录 | 动态列表 | /log/yk.log(SYSLOG_YK,写入点 iec104_pts.c 遥控段) | ✅ 已落地(ui_page_yk.c,2026-10-28) |
| 41 | 运行报告 | 列表页(12 行 / 2 页,四数逐个挂范围标签) | boot_stats(上电次数 + 复位原因)+ 四个 104 观测计数 + uptime_s,经 ui_data info 帧下发 | ✅ 已落地(ui_page_runreport.c,2026-10-28;跨开机累计按裁定不做) |
**统计(2026-10-25 复核)**:本表 27 叶中 **6 叶已落地**(遥信量 / 查看 4 页 / SOE),剩 21 叶 = 数据现成 **8** 项(整定 4 + 时钟 + 复归 + 死区 + 系数)· 需新数据层 **2** 项(清除记录 / 通讯设置)· 数据源不存在 **11** 项(遥信 3 + 手动录波 + SNTP + 记录 5 + 运行报告)。**分批与 DoD 见 `docs/任务规划/UI补齐.md`**——本表只讲逐页形态与数据源,不重复排期。
**统计(2026-10-25 复核)**:本表 27 叶中 **6 叶已落地**(遥信量 / 查看 4 页 / SOE),剩 21 叶 = 数据现成 **8** 项(整定 4 + 时钟 + 复归 + 死区 + 系数)· 需新数据层 **2** 项(清除记录 / 通讯设置)· 数据源不存在 **11** 项(遥信 3 + 手动录波 + SNTP + 记录 5 + 运行报告)。**逐页形态与数据源只看本表,排期不进本文**——当时的执行清单文件已于 2026-11-09 随 UI 补齐整体销项删除,页面口径现归 `docs/UI设计/内容页架构.md` §7.1。
**2026-10-28 复核**:本表 27 叶中 **22 叶已落地**(本批 +6:记录 5 页与运行报告,见 docs/任务规划/UI补齐.md §2 与 docs/任务规划/登记簿.md §7);未落地的 5 叶 = 遥信类型 / 遥信防抖 / 双点遥信(无开入硬件)+ 手动录波(无录波模块)+ SNTP设置(产品口径未定),取舍与重开条件见 docs/任务规划/UI补齐.md §5。口径闭合:本表 22 叶 + 立项前就已绑定、不在本表内的 6 叶(装置信息 / 交流量 / 直流量 / 网口设置 / 自检记录 / 运行记录)= 现值已绑 28 叶(= UI_PAGE_MAP_COUNT);本表未落地 5 叶 = 菜单树未绑 5 叶(33 − 28)。复核方法:按缩进判叶子(有更深缩进后继者即非叶子),再按行内 #page= 数已绑。**2026-10-29 补充**:「手动录波」已随故障录波独立立项(docs/子系统设计/故障录波设计说明.md;原卡片登记簿 2026-10-30 销项并入该文 §10),上面那行数字仍是 2026-10-28 当日复核值,未随立项改动。
**2026-10-28 复核**:本表 27 叶中 **22 叶已落地**(本批 +6:记录 5 页与运行报告,见 `docs/任务规划/登记簿.md` §7);未落地的 5 叶 = 遥信类型 / 遥信防抖 / 双点遥信(无开入硬件)+ 手动录波(无录波模块)+ SNTP设置(产品口径未定),取舍与重开条件见 `docs/任务规划/登记簿.md` §8。口径闭合:本表 22 叶 + 立项前就已绑定、不在本表内的 6 叶(装置信息 / 交流量 / 直流量 / 网口设置 / 自检记录 / 运行记录)= 现值已绑 28 叶(= UI_PAGE_MAP_COUNT);本表未落地 5 叶 = 菜单树未绑 5 叶(33 − 28)。复核方法:按缩进判叶子(有更深缩进后继者即非叶子),再按行内 #page= 数已绑(完整命令见 `docs/UI设计/菜单页面设计.md` §3.9)。**2026-10-29 补充**:「手动录波」已随故障录波独立立项(docs/子系统设计/故障录波设计说明.md;原卡片登记簿 2026-10-30 销项并入该文 §10),上面那行数字仍是 2026-10-28 当日复核值,未随立项改动。
**2026-10-29 二补(录波 UI 道落地)**:本表「手动录波」转已落地(23 叶);菜单树另新增「录波回放」叶(node 43,不在本表立项快照内)——现值 43 节点 / 34 叶 / 已绑 30 / 未绑 4(= 遥信 3 + SNTP 1,UI_PAGE_MAP_COUNT = 30),口径复核方法与上一段相同
**2026-11-04 复核(板端 SNTP 接入立项,#57 调研结论)**:本表「SNTP设置」转已落地(24 叶)——`ui_page_sntp.c` 绑 `#page=sntp`,[sntp] 段经 `net_cfg_load` 注册、SNTP 客户端在 timeSyncTask 轮询(`App/sync/time_sntp.c`);现值 43 节点 / 34 叶 / 已绑 31 / 未绑 3(= 遥信 3,UI_PAGE_MAP_COUNT = 31),口径复核方法与上一段相同
+1 -1
View File
@@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1060" height="566" viewBox="0 0 1060 566" font-family="Microsoft YaHei, Segoe UI, PingFang SC, sans-serif">
<rect x="0" y="0" width="1060" height="566" fill="#ffffff"/>
<text x="46.0" y="42.0" font-size="21" font-weight="700" fill="#0f172a">交流轮为什么连取 10 行、取中位数 —— 机理与操作</text>
<text x="46.0" y="68.0" font-size="12.5" fill="#64748b">meas: 是瞬时基波有效值透传:200 ms 是上送节拍、不是平均窗(数据可信 §4.5)——单行可能恰好抓到波峰或波谷,毛刺行会拖偏算术平均,中位数对两头都钝感</text>
<text x="46.0" y="68.0" font-size="12.5" fill="#64748b">meas: 是瞬时基波有效值透传:200 ms 是上送节拍、不是平均窗(§13.9)——单行可能恰好抓到波峰或波谷,毛刺行会拖偏算术平均,中位数对两头都钝感</text>
<text x="46.0" y="146.0" font-size="13.5" font-weight="700" fill="#0f172a">机理:窗定宽 20 拍,截到的相位逐窗滑动</text>
<polyline points="46.0,276.0 47.7,272.1 49.5,268.3 51.2,264.4 53.0,260.6 54.7,256.8 56.5,253.1 58.2,249.5 60.0,245.9 61.7,242.4 63.5,239.0 65.2,235.7 66.9,232.5 68.7,229.4 70.4,226.5 72.2,223.7 73.9,221.0 75.7,218.5 77.4,216.1 79.2,213.9 80.9,211.9 82.7,210.1 84.4,208.4 86.1,206.9 87.9,205.6 89.6,204.5 91.4,203.6 93.1,202.9 94.9,202.4 96.6,202.1 98.4,202.0 100.1,202.1 101.9,202.4 103.6,202.9 105.3,203.6 107.1,204.5 108.8,205.6 110.6,206.9 112.3,208.4 114.1,210.1 115.8,211.9 117.6,213.9 119.3,216.1 121.1,218.5 122.8,221.0 124.5,223.7 126.3,226.5 128.0,229.4 129.8,232.5 131.5,235.7 133.3,239.0 135.0,242.4 136.8,245.9 138.5,249.5 140.3,253.1 142.0,256.8 143.7,260.6 145.5,264.4 147.2,268.3 149.0,272.1 150.7,276.0 152.5,279.9 154.2,283.7 156.0,287.6 157.7,291.4 159.5,295.2 161.2,298.9 162.9,302.5 164.7,306.1 166.4,309.6 168.2,313.0 169.9,316.3 171.7,319.5 173.4,322.6 175.2,325.5 176.9,328.3 178.7,331.0 180.4,333.5 182.1,335.9 183.9,338.1 185.6,340.1 187.4,341.9 189.1,343.6 190.9,345.1 192.6,346.4 194.4,347.5 196.1,348.4 197.9,349.1 199.6,349.6 201.3,349.9 203.1,350.0 204.8,349.9 206.6,349.6 208.3,349.1 210.1,348.4 211.8,347.5 213.6,346.4 215.3,345.1 217.1,343.6 218.8,341.9 220.5,340.1 222.3,338.1 224.0,335.9 225.8,333.5 227.5,331.0 229.3,328.3 231.0,325.5 232.8,322.6 234.5,319.5 236.3,316.3 238.0,313.0 239.7,309.6 241.5,306.1 243.2,302.5 245.0,298.9 246.7,295.2 248.5,291.4 250.2,287.6 252.0,283.7 253.7,279.9 255.5,276.0 257.2,272.1 258.9,268.3 260.7,264.4 262.4,260.6 264.2,256.8 265.9,253.1 267.7,249.5 269.4,245.9 271.2,242.4 272.9,239.0 274.7,235.7 276.4,232.5 278.1,229.4 279.9,226.5 281.6,223.7 283.4,221.0 285.1,218.5 286.9,216.1 288.6,213.9 290.4,211.9 292.1,210.1 293.9,208.4 295.6,206.9 297.3,205.6 299.1,204.5 300.8,203.6 302.6,202.9 304.3,202.4 306.1,202.1 307.8,202.0 309.6,202.1 311.3,202.4 313.1,202.9 314.8,203.6 316.5,204.5 318.3,205.6 320.0,206.9 321.8,208.4 323.5,210.1 325.3,211.9 327.0,213.9 328.8,216.1 330.5,218.5 332.3,221.0 334.0,223.7 335.7,226.5 337.5,229.4 339.2,232.5 341.0,235.7 342.7,239.0 344.5,242.4 346.2,245.9 348.0,249.5 349.7,253.1 351.5,256.8 353.2,260.6 354.9,264.4 356.7,268.3 358.4,272.1 360.2,276.0 361.9,279.9 363.7,283.7 365.4,287.6 367.2,291.4 368.9,295.2 370.7,298.9 372.4,302.5 374.1,306.1 375.9,309.6 377.6,313.0 379.4,316.3 381.1,319.5 382.9,322.6 384.6,325.5 386.4,328.3 388.1,331.0 389.9,333.5 391.6,335.9 393.3,338.1 395.1,340.1 396.8,341.9 398.6,343.6 400.3,345.1 402.1,346.4 403.8,347.5 405.6,348.4 407.3,349.1 409.1,349.6 410.8,349.9 412.5,350.0 414.3,349.9 416.0,349.6 417.8,349.1 419.5,348.4 421.3,347.5 423.0,346.4 424.8,345.1 426.5,343.6 428.3,341.9 430.0,340.1" fill="none" stroke="#334155" stroke-width="1.8" stroke-linejoin="round"/>
<rect x="46.0" y="186.0" width="174.5" height="180.0" rx="6" fill="none" stroke="#2563eb" stroke-width="1.8"/>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

@@ -328,7 +328,7 @@ flowchart LR
**FR-TIME-3 SNTP 校时** ✅(2026-11-04)
- 需求:设备作 SNTP(RFC 4330)客户端从配置的 IPv4 服务器经 UDP/123 取时写回 RTC;使能、主/备服务器、轮询周期可配(UI「SNTP 设置」页或 `/config.ini` `[sntp]` 段,保存后随下一轮生效)。
- 实现:`timeSyncTask` 200 ms 校时节拍驱动(`time_sync.c` v2.0,:8888 退役后任务即纯宿主;≤50 ms 收片切片,不饿任务狗与 IWDG);48 字节报文由 vendored coreSNTP 序列化器(`Lib/coreSNTP/`)编解码,节奏与判据在本方;防伪 = OriginTimestamp 须逐位等于发出的 T1(含随机小数位),mode / stratum / 闰秒指示 / Kiss-o'-Death 按 RFC 拒绝;主备轮换 + 失败指数退避(5 s 起、60 s 封顶)+ 首轮 1~5 分钟随机;成功时 |offset| < 2 s 只记日志不阶跃,更大偏差阶跃写回 SD2506——钟面 = 本地时间(UTC+8,沿用本地钟面时基口径,取舍见 docs/任务规划/UI补齐.md §4 时基口径注);首个校验通过的同步置 `SYS_EVT_TIMESYNC_READY`。
- 实现:`timeSyncTask` 200 ms 校时节拍驱动(`time_sync.c` v2.0,:8888 退役后任务即纯宿主;≤50 ms 收片切片,不饿任务狗与 IWDG);48 字节报文由 vendored coreSNTP 序列化器(`Lib/coreSNTP/`)编解码,节奏与判据在本方;防伪 = OriginTimestamp 须逐位等于发出的 T1(含随机小数位),mode / stratum / 闰秒指示 / Kiss-o'-Death 按 RFC 拒绝;主备轮换 + 失败指数退避(5 s 起、60 s 封顶)+ 首轮 1~5 分钟随机;成功时 |offset| < 2 s 只记日志不阶跃,更大偏差阶跃写回 SD2506——钟面 = 本地时间(UTC+8,沿用本地钟面时基口径,取舍见 `docs/子系统设计/系统墙钟时间维护说明.md` §1.1);首个校验通过的同步置 `SYS_EVT_TIMESYNC_READY`。
- 判据:主机单测 `test/host/sntp`(报文格式 / 伪造拒收 / KoD 轮换 / 退避与周期 / 阶跃域守卫);真机 = 使能并配置服务器后时钟与时间源一致、`[SNTP] step offset=` 日志在场(台架窗口统一做)。
> **已知限制**:uint32 epoch → **2038 年**上限。
@@ -1552,7 +1552,7 @@ pre-commit run --all-files
**规模**:菜单节点 **9** 个(含根)+ 叶子节点 **34** 个 = **43** 节点;最大深度 **4 级(主界面 / 一级 / 二级 / 三级菜单)**。
**绑定现状**(2026-11-04 复扫):**已绑内容页 31 叶 / 未绑 3 叶**(页面注册表 `UI_PAGE_MAP_COUNT` = 31,
与已绑叶数一致);未绑 3 叶 = 无开入硬件 3(取舍与重开条件见
docs/任务规划/UI补齐.md §5);原「当前执行 6 项」(记录 5 页 + 运行报告)已于 2026-10-28 落地绑页,
`docs/任务规划/登记簿.md` §8「开入开出与遥信配置 3 页」);原「当前执行 6 项」(记录 5 页 + 运行报告)已于 2026-10-28 落地绑页,
「手动录波」与「录波回放」两叶于 2026-10-29 随录波道绑页(判据见 docs/子系统设计/故障录波设计说明.md §4.1 与 §8.1),
「SNTP 设置」叶于 2026-11-04 随 SNTP 客户端立项绑页(判据见 §5.3 FR-TIME-3 与 docs/网络/BSD_Socket_API_使用指南.md §6.1)。
@@ -1672,7 +1672,7 @@ docs/任务规划/UI补齐.md §5);原「当前执行 6 项」(记录 5
| **遥测铺开** | 4、5 | 31 点 + 模型 35 行 | 9 点 | +22 点 + 模型表 |
| **录波子系统** | 10、15 | 3 类型 / 6 段 / 65 通道 / RAM 16 个 / COMTRADE 64·64·16 | **最小闭环代码面已交付**(2026-10-29):1 kHz / 8 路原始码值 / 单段 320 点 / 轮转段文件 / 手动与保护启动 / 单通道回放页;**板级判据一轮未跑** | 仍差 4 kHz 全速与 80 点/周波、多段与 65 通道、COMTRADE、104 文件传输;口径偏离登记见 docs/子系统设计/故障录波设计说明.md §2 |
| **记录体系** | 9、13 | 13 类队列(128/256 条) | 8 类 | +5 类(越限 / 闭锁 / COS / 顺控 / 顺控执行) |
| **UI 记录页** | 9、13 | 参考有完整记录页与运行报告 | 六页已绑并纳入像素黄金回归(2026-10-28) | 只剩真机判据(docs/任务规划/登记簿.md §7) |
| **UI 记录页** | 9、13 | 参考有完整记录页与运行报告 | 六页已绑并纳入像素黄金回归(2026-10-28);台架判据已于 2026-11-06 Issue #53 台架轮复核完成 | 已销项 |
| **多规约栈** | 17 | 12 种 | 1 种(104) | +11 种(101 / 102 / 103 / CDT / ModBus / Whm_GB / 61850 / CAN + 子站侧 3 类) |
| **国密算法** | 18 | `Comm/Ecc/` 全套 | 0 | SM2 / SM3 / ECDSA |
| **软压板铺开** | 11 | 9 面(表容量 32) | 1 面 | +8 面 |
@@ -1694,7 +1694,7 @@ docs/任务规划/UI补齐.md §5);原「当前执行 6 项」(记录 5
| 顺序 | 工作 | 类别 | 当前状态 | 开始条件 |
|---|---|---|---|---|
| 1 | UI 补齐(记录 5 页 → 运行报告) | 规模型 | **清单已清空(2026-10-28)** | 六页已落地;余 4 叶属不做项(手动录波与录波回放两叶已随录波道绑页),重开条件见 docs/任务规划/UI补齐.md §5 |
| 1 | UI 补齐(记录 5 页 → 运行报告) | 规模型 | **✅ 2026-10-28 落地并绑页;2026-11-06 台架判据复核完成,整体销项** | 六页已落地;余 3 叶属不做项(遥信 3,无开入硬件),重开条件见 `docs/任务规划/登记簿.md` §8 |
| 2 | net 层跨上下文收口 | 平台 | **下一顺位(未开工)** | UI 清单已清空,切换条件已满足;**开工待用户点头** |
| 3 | 其余结构与可靠性评估 | 平台 | 排队 | net 收口后 |
| 4 | 端子/子板变比确认 → 两点标定 | 阻塞型 | 等外部资源 | 子板实物/原理图、标准源到位可插入 |
@@ -1818,7 +1818,7 @@ docs/任务规划/UI补齐.md §5);原「当前执行 6 项」(记录 5
| ADC 通道映射与实测 | [`docs/硬件平台/ADC通道映射说明.md`](../../docs/硬件平台/ADC通道映射说明.md) |
| ADC 前端注入验证流程 | [`docs/测试说明/专项验证/ADC前端注入验证流程.md`](../测试说明/专项验证/ADC前端注入验证流程.md) |
| IEC 60870-5-104 上行 | [`docs/子系统设计/IEC104上行设计说明.md`](../../docs/子系统设计/IEC104上行设计说明.md) |
| 数据可信(标定 / 快照 / 运行参数) | [`docs/任务规划/数据可信.md`](../任务规划/数据可信.md) |
| 数据可信(标定 / 快照 / 运行参数) | [`docs/算法/采集与算法层设计说明.md`](../算法/采集与算法层设计说明.md) §13 |
| 页面补齐规划 | [`docs/UI设计/页面补齐规划.md`](../../docs/UI设计/页面补齐规划.md) |
| 条目命名与编号规则 | [`docs/文档规范.md`](../../docs/文档规范.md) §7.1 |
| 部署环境 | [`docs/环境与部署/项目部署环境要求.md`](../../docs/环境与部署/项目部署环境要求.md) |
+23 -27
View File
@@ -1,21 +1,20 @@
# 任务规划
> **UI 补齐执行清单已于 2026-10-28 清空(记录 5 页 + 运行报告页落地)。** 下一顺位 = net 层跨上下文收口,开工待用户点头;顺序权威见 docs/任务规划/README.md §2.0。
> 详细任务与验收见 `UI补齐.md`;UI 完成后的第一项是 net 层跨上下文收口。
> **UI 补齐已于 2026-10-28 清空并整体销项**(记录 5 页 + 运行报告页落地;范围与判据口径已并入
> `docs/UI设计/内容页架构.md` §7.1 与 `docs/UI设计/菜单页面设计.md` §3.9,原执行清单文件已删除)。
> 下一顺位 = net 层跨上下文收口,已闭环。
## 怎么用这份规划
| 你想知道什么 | 只看哪个文件 |
|---|---|
| 现在做什么、接下来做什么 | 本文件 |
| 当前任务怎么做、怎样算完成 | `UI补齐.md` |
| UI 之后还有什么、哪些事在等条件 | `登记簿.md` |
| ADC 标定为什么没做、保护为什么不动作 | `数据可信.md` |
| ADC 标定为什么没做、保护为什么不动作 | `登记簿.md` §7 + `../算法/采集与算法层设计说明.md` §13 |
| RS-485 为什么冻结、重启要满足什么 | `暂缓-RS485.md` |
**一件事只有一个归属。** 本文件只负责导航与顺序,不复制各任务的验收明细;
`登记簿.md` 不再复制当前 UI 任务,`数据可信.md` 的其余章节是被代码引用的设计约束,
不是额外待办。
采集数据可信度的设计口径归 `docs/算法/采集与算法层设计说明.md` §13,待办归 `登记簿.md` §7。
---
@@ -29,24 +28,21 @@
---
## 1. UI 补齐(执行清单已于 2026-10-28 清空)
## 1. UI 补齐(已整体销项)
菜单树共 34 叶(节点行合计 43):按行内 #page= 实测**已绑 31 叶、未绑 3 叶**(2026-11-04 SNTP 设置
叶随 #73 立项转绑 +1,判定规则与重跑命令见 docs/任务规划/UI补齐.md §1「叶数判定与复核」)。未绑的 3 叶
因缺少开入硬件不做(原因与重开条件见 docs/任务规划/UI补齐.md §5)——**手动录波与录波回放两叶
已随录波道绑页**,「不做」清单里的录波那一项已销。
**口径闭合**:未绑 3 = 待做 0(§1 清单已清空)+ 不做 3(遥信 3);**43 是节点行数、不是叶数**(= 9 个菜单节点 + 34 叶)。
已绑叶数以生成物 UI_PAGE_MAP_COUNT 为准:不剔 ui_menu_tree.txt 文件头的注释示例行时,按 #page= 文本计数会得 32(= 31 + 1 行示例)。
菜单树现状:**43 节点行 / 34 叶 / 已绑 31 叶 / 未绑 3 叶**。未绑 3 叶 = 遥信类型、遥信防抖、双点遥信——
V0.1 没有开入硬件,不做;重开条件见 `登记簿.md` §8「开入开出与遥信配置 3 页」。
数法、复核命令与「43 是节点行数不是叶数」的口径 → `docs/UI设计/菜单页面设计.md` §3.9。
**UI 补齐执行清单已于 2026-10-28 清空**:记录 5 页(事故 / 操作 / 保护告警 / 保护启动 / 遥控)与
运行报告页同日落地并绑页,内容页黄金参考 53 → 60 张(runreport 分 2 页,第 2 页单独拍一张;判据 = simulator/tests/ref/ 入库 shot_*.bin 实数,张数 = 页面个数 + 分页多拍的那一张;**该集合 2026-10-29 已扩至 66 张**,多出的是录波回放页 6 态)。
上板判据(真记录翻页、掉电保持、清除后归零、boot_count 自增、RESTARTED、rst_cause=IWDG、conn_up +1)
**已于 2026-11-06 Issue #53 台架轮复核完成并销项**(除「拔 RTC 电池落 RESTARTED」经用户裁定 2026-11-05
台架不可验,销项不挂账);六页文件头「台架待补」段已改「台架复核已完成」,登记簿 §7 对应行已删;
模拟器差距见 docs/测试说明/专项验证/模拟器差距清单.md §2.3「开机账本 boot_stats」一行。
记录 5 页(事故 / 操作 / 保护告警 / 保护启动 / 遥控)与运行报告页已于 2026-10-28 落地并绑页;
上板判据(真记录翻页、掉电保持、清除后归零、`boot_count` 自增、`RESTARTED`、`rst_cause=IWDG`、`conn_up` +1)
已于 2026-11-06 Issue #53 台架轮复核完成(「拔 RTC 电池落 RESTARTED」经用户裁定 2026-11-05 台架不可验)。
模拟器差距见 `docs/测试说明/专项验证/模拟器差距清单.md` §2.3「开机账本 boot_stats」一行。
**执行纪律:单道串行。** 菜单树与页面注册表是生成物,字库也是整文件生成物;
不要同时开多条 UI 页面分支。上板验证可累积成一批,但保存、重启、主站读回等判据不能删除。
页面的统一完成动作、三条硬规矩(不用演示数据 / 不做没效果的按钮 / 保护闭锁必须可见)与回归门禁
→ `docs/UI设计/内容页架构.md` §7、§7.1。
**执行纪律:单道串行。** 菜单树与页面注册表是生成物,字库也是整文件生成物;不要同时开多条 UI 分支。
---
@@ -58,7 +54,7 @@
| 顺序 | 工作 | 当前状态 | 开始或切换条件 |
|---|---|---|---|
| **1** | **UI 补齐** | **清单已清空(2026-10-28)** | 记录 5 页与运行报告页已落地并绑页;余下 5 叶属 §5「当前不做」,重开条件见 docs/任务规划/UI补齐.md §5;上板判据见 docs/任务规划/登记簿.md §7 |
| **1** | **UI 补齐** | **✅ 2026-10-28 清单清空;2026-11-06 台架判据复核完成,整体销项** | 记录 5 页与运行报告页已落地并绑页;余 3 叶属不做项(遥信 3,无开入硬件),重开条件见 `登记簿.md` §8。页面口径见 `docs/UI设计/内容页架构.md` §7.1 |
| **2** | **net 层跨上下文收口** | **✅ 2026-11-06 闭环** | 子项 A(裸指针收口为状态查询 API):审计确认收口已完成(`net_listener` 单一登记入口 `net_listener_request` + 单一执行者 `net_listener_tick`、`s_relisten_req` 0 处模块外直接读写;UI 读侧快照 API `ui_data_info`/唯一填充者 `ui_data_feed`);子项 B(突发分片让路):台架重验确认新负载剖面(SNTP 请求/退避 + FTP + 104 + 7003)下 **uiTask ≥800 ms 饿死签名不复现**(`task stall` 0 条、复位 0、NAND `wdev.log` 当日零新增 STALL、7003 最差 759 ms <800 ms 线)——证据见 `网络自愈架构设计.md` 与 `看门狗设计说明.md` 变更记录 2026-11-06 条目 |
| **3** | 其余结构与可靠性评估 | 排队 | net 收口后;逐项见 `登记簿.md`,观察项不为了“清清单”而强做 |
| **4** | 数据可信(采集数据可信度) | 动态波形验证 **✅ 2026-11-04 闭环(六轮)**;变比确认与两点标定等外部资源 | 信号发生器动态波形验证(不依赖外部资源,✅ 2026-11-04)→ 端子/子板变比确认 → 标准源两点标定;**排序调整(2026-10-29):动态验证让位给故障录波数据面**,段文件落地后判据升级为 PC 独立重算对表(docs/子系统设计/故障录波设计说明.md §11)(已知电压注入已于 2026-10-27 台架闭环并销项);外部资源到位可插入优先处理 |
@@ -72,8 +68,8 @@
- **UI**:写路径、整定 4 页、装置维护 3 页与遥测死区/系数 2 页已收口(含上板判据与真机回读);
菜单树、页面注册表与字库都是生成物,同刻只允许一条道写。
- **送检**:已知电压注入(✅ 2026-10-27 闭环)→ 信号发生器动态波形验证(✅ 2026-11-04 闭环,未闭合
四项标注在 数据可信.md §5 任务卡内)→ 端子/子板变比确认 → 标准源两点标定 → 保护解除闭锁 → 送检。
- **送检**:已知电压注入(✅ 2026-10-27 闭环)→ 信号发生器动态波形验证(✅ 2026-11-04 闭环,
六轮全过;未闭合项已裁定或另登记于 `登记簿.md` §7)→ 端子/子板变比确认 → 标准源两点标定 → 保护解除闭锁 → 送检。
- **保护扩展**:标准源未到位前不新增无法验证的判据;跨转换器相位、功率、对称分量类
功能必须等 V0.2 硬件。
- **结构债**:UI 完成后先做 net 收口;RS-485 白名单、内存优化、仓库体积等观察项不抢占
@@ -85,9 +81,9 @@
1. **完成即删除待办条目**,同时清理其他文档对它的引用;结论和证据写入模块文档,
历史由 `git log` 保留。
2. **当前任务只改 `UI补齐.md`,后续事项只改 `登记簿.md`**;顺序变化才改本文件 §2。
3. `数据可信.md` 的 §2、§4、§7 仍被代码头注释引用为设计依据,不能按“已完成”
删掉;其待办只认 §5 的任务卡表(标识列用语义短语,卡片增减不改本条口径)。
2. **待办只改 `登记簿.md`**(新增、销项、改重启条件都在那一处);顺序变化才改本文件 §2。
3. **设计约束不放在本目录**:采集数据可信度的口径归 `../算法/采集与算法层设计说明.md` §13,
本目录的待办只认 `登记簿.md`(标识列用语义短语,卡片增减不改本条口径)。
4. 专项文档只放**还没闭环的约束**;已落地事项的规格正文归代码头注释或模块文档,
销项即删文件并把引用改指现行出处(先例:`测试与架构专项.md` 已删除 2026-10-28,
唯一未闭环的「采集链路测试可验证性约束」并入 `暂缓-RS485.md`)。
-122
View File
@@ -1,122 +0,0 @@
# 当前任务:UI 补齐
> **执行清单已清空(2026-10-28)**:记录 5 页与运行报告页已落地、绑页并纳入像素黄金回归。
> **2026-10-29 录波 UI 道**:「手动录波」由不做转落地(绑操作页),新增「录波回放」叶(节点 43);
> 叶数口径同步为 43/34/30/4(下方逐项)。
> 本文件保留为 UI 补齐的**范围与判据口径**(§1 叶数、§4 每页统一动作、§5 不做的取舍);
> 下一顺位见 docs/任务规划/README.md §2.0(换主线待用户点头),上板待复核项见 docs/任务规划/登记簿.md §7。
## 1. 目标与范围
菜单树共 **34 叶**(节点行合计 43,缩进即层级):按行内 `#page=` 实测**已绑 31 叶、未绑 3 叶**,
页面映射表 `UI_PAGE_MAP_COUNT` = 31(与已绑叶数一致)。未绑 3 叶 = §5 明确不做的 **遥信 3 叶**,
与下面分类表逐项对得上;2026-10-29 录波 UI 道把「手动录波」从不做转为
落地并新增「录波回放」叶,绑 +2(手动转绑 + 新叶);2026-11-04 SNTP 客户端立项(Issue #57 拍板
选型、#73 拍板节奏),SNTP 设置叶转绑定(+1);2026-10-28 记录 5 页与运行报告页落地后,
原「需补配置或写入方」的 6 叶缺口清零并按销项删行(该行内容见本节末与 §3)。
| 分类 | 数量 | 当前怎么处理 |
|---|---:|---|
| 无开入硬件 | 3 | 不做:遥信类型、遥信防抖、双点遥信 |
(原「缺独立模块或产品定义:SNTP 设置」行已于 2026-11-04 随 SNTP 客户端立项转绑定销项;手动录波更早,2026-10-29 随故障录波 UI 道转绑。)
现有基础:`ui_w_editor` / `ui_w_setlist` / `ui_page_action` 已就绪;`ui_data` 已扩到**四通道**
(rt / par / info + 遥测死区与系数用的第四张注入表);像素黄金用例与字符集门禁已存在,内容页黄金
现有 **74 张**(菜单 8 状态另计;2026-10-29 录波 UI 道 +6 张:手动录波 3 态 + 录波回放 3 态;2026-11-04 SNTP 设置页 +8 张)。**装置维护 3 页、遥测死区/系数 2 页、通讯设置页、SNTP 设置页、记录 5 页与
运行报告页都是把这套基础接上真实消费者做出来的,不另发明一套机制。**
逐页形态见 `docs/UI设计/页面补齐规划.md`;数据契约见
`docs/UI设计/UI_数据供给设计说明.md`。本文件保留范围、完成判据与不做的取舍口径(执行清单已于 2026-10-28 清空)。
### 叶数判定与复核(2026-10-28 复核)
1. **节点行** = `ui_menu_tree.txt` 里非空、非 `#` 开头的行(当前 **43** 行,含根「主界面」)。
2. **缩进即层级**(每级 2 空格;Tab 会被 `gen_menu.py` 直接拒绝):某节点行之后再没有更深缩进的行 = **叶**
(当前 **34** 叶);有更深缩进后继者 = 菜单节点(当前 **9** 个)。等价于生成物口径 `ui_menu_tab_has_children(node) == false`。
3. **绑定**:叶行行尾带 ` #page=` = 已绑(当前 **31** 叶);不带的 = 未绑(当前 **3** 叶)。
4. **闭合**:`未绑 = 待做 + 不做` —— 当前待做 **0**(§2 清单已清空)+ 不做 **3**(遥信 3)= **3**,
与上面的分类表、§5「当前不做」表逐项对得上。
5. **别拿 `grep -c '#page='` 当已绑叶数**:2026-10-28 实测它得 **29**,比真值多 1 —— 文件头第 5 行是规则说明里的
` #page=<模块名>` 示例行(不是节点行),必须先剔注释/示例行;剔完的数才等于生成物 `UI_PAGE_MAP_COUNT`(现 31)。
复核命令(复用生成器自己的解析器 `tools/menu_gen/gen_menu.py` 的 `parse_tree`,不另写一套计数逻辑,免得与生成物脱钩):
```bash
& '.venv\Scripts\python.exe' -c "import io,sys; sys.path.insert(0,'tools/menu_gen'); import gen_menu as g; n,_=g.parse_tree(io.open('ui_menu_tree.txt',encoding='utf-8').read()); leaf=[i for i,x in enumerate(n) if all(y[0]!=i for y in n)]; b=sum(1 for i in leaf if n[i][4]); print('nodes=%d leaves=%d bound=%d unbound=%d' % (len(n),len(leaf),b,len(leaf)-b))"
```
输出 `nodes=43 leaves=34 bound=30 unbound=4`(2026-10-29 录波 UI 道落地后实测);交叉核对生成物:`ui_menu_tab.h` 的 `UI_MENU_TAB_COUNT` = 43(节点行数)、
`ui_page_registry.h` 的 `UI_PAGE_MAP_COUNT` = 30(已绑叶数)——一对 43、一对 30,与上面逐项对得上。
三个已踩过的错算法(每种都同时给**当时**与**2026-10-28 重跑**的产物——错法不会自己失效,只是错数跟着已绑叶数一起漂):
**把 42 个节点行当叶子**(多算 9 个菜单节点:当时已绑 21 叶 → 得「未绑 21」,2026-10-28 同一错法得「未绑 14」= 42 − 28);
**`grep -c '#page='` 当时得 23**(当时已绑 22 叶,多的那 1 正是文件头注释第 5 行的 `#page=<模块名>` 示例字样,必须先剔注释行;
2026-10-28 同一命令得 29 = 当时已绑 28 + 该示例行 1;2026-10-29 当时值 31 = 已绑 30 + 示例行 1;2026-11-04 现值 32 = 已绑 31 + 示例行 1);**按叶子名去重得 29**(`参数`/`定值`/`控制字`/`软压板` 在「整定」「查看」下各一份,
4 对同名不能合并;2026-10-28 重跑仍是 29 = 33 叶 − 4 对同名)。
(21 / 23 两个错数分属 2026-10-27「已绑 21 叶」与「已绑 22 叶」两个时点的实测,只用来说明错法,不代表现值;
去重 29 与上面 grep 现值 29 **只是撞号**:一个是「合并同名叶」、一个是「不剔注释行」,都与真值 30(2026-10-29 现值)无关。)
---
## 2. 执行清单
> 状态只在这里维护。完成一项就删除对应行,并同步调整后续顺序;不要在本文件留完成史。
> 当前无待做项:最后两项(记录 5 页、运行报告)已于 2026-10-28 落地并销项删行。
> 下一批 UI 页面开工时在本节重新起表;完成一项就删除对应行,本文件不留完成史。
### 依赖关系
- 各项虽可独立开发,但当前仍按表序单道执行(菜单树、页面注册表与字库都是生成物)。
- **不允许用静态演示数据充数**:记录 5 页与运行报告页都是先有真实写入方 / 真实计数器(道F task-10、道G task-12),再补页面(2026-10-28 交付口径),下一批沿用。
- 历史教训(已完成的装置维护 3 页留下的口径,后续项沿用):**执行类页面不得做成「点了个按钮但没效果」**——清除记录必须按 `syslog_clear_state()` 出真反馈;遥测死区/系数两页的三态用
`run_par_dirty_peek()` 区分「已受理」与「已落盘」,且黄金必须出 WAIT 与 OK 两张(假件保留脏位、只由
headless pump 清),否则真机的 WAIT 态永远不会被像素回归覆盖。
---
## 3. 数据源对照
| 页面 | 现有数据源 | 还缺什么 |
|---|---|---|
| 通讯设置 | 页面与六态黄金已随 `728d6067` 入库;`[comm]` 段与端口真源在 `App/protocol/iec104/iec104_comm.{c,h}` | 「改后重启即生效」真机判据、配置段数与键数上限核对(台架窗口统一补做并留证) |
| 记录 5 页 | 五类记录 ID / 文件 / 写入点已齐(docs/任务规划/登记簿.md §7 与 App/log/README.md §五类记录);reader 注入两端已映射 7 个记录源 | 页面已交付;只剩真机判据(真记录翻页、掉电保持、清除后归零),见 docs/任务规划/登记簿.md §7 |
| 录波两页 | 手动录波操作页 + 录波回放页已落地绑页(2026-10-29 录波 UI 道);数据源 = `App/algo/wave_ring`/`wave_store` 真实现经 `ui_data_wave_ops_t` 注入,回放读盘走 `vol_lock` try 锁小窗口 | 页面已交付;真机判据归台架(真实触发落盘的段号连续性、削徽标真值、切段切道实测毫秒与卷锁忙「本轮无段」行为,见 `docs/子系统设计/故障录波设计说明.md` §10 台架判据) |
| 运行报告 | boot_stats(SD2506 用户 SRAM 上电次数 + 本次复位原因快照,道G task-12)、iec104_serv 四个只读观测计数、现成 uptime_s | 页面已交付;**跨开机累计不做**(用户裁定只报本次开机)。真机待复核 SRAM 自增与四态判定,见 docs/测试说明/专项验证/模拟器差距清单.md §2.3 |
---
## 4. 每页的统一完成动作
1. 新增 `ui_page_xxx.c/.h`,优先复用现有组件。
2. 在 `ui_menu_tree.txt` 对应叶子增加 ` #page=xxx`。
3. 运行 `& '.venv\Scripts\python.exe' tools/menu_gen/gen_menu.py`,检查生成物差异(该脚本只用标准库,但入口统一走 `.venv`;
新增文案后还要跑字库链,那条**依赖 fontTools** ⇒ 见 `font-regen` skill 与 `docs/环境与部署/本地工具路径环境变量方案.md`)。
4. 新文案先过字符集提取和字库生成,不能显示方块。
5. 加像素黄金用例与必要的主机单测。
6. 涉及保存、重启、主站读回的项目,台架可用后统一补做实机判据并留证。
**单写者约束**:`ui_menu_tree.txt`、页面注册表、字库生成物不得由多个分支同时修改。
`MDK-ARM/*.uvprojx` 的新源文件注册按双端注册规则处理。
**时基口径已裁定,勿顺手改语义**:口径 = 「先本地为准,内部真源是本地钟面」(用户裁定 2026-10-27,
`../子系统设计/系统墙钟时间维护说明.md` §1.1);当时冲突双方「面板时钟页 vs 8888 对时 vs 104 `C_CS` 写 UTC」中的
8888 已于 2026-11-04 退役(写入口现为 SNTP / UI 手工 / 104 `C_CS`,一律先换算成本地钟面再落库)。唯一待决的是
104 **上行** `CP56Time2a` 是否转 UTC(送检前单独定,前引
`../子系统设计/系统墙钟时间维护说明.md` §1.1 末)。裁定前**不要改动 RTC/epoch 语义**,也不要把
时钟设置页的「回读 RTC」判据改成按某一时区补偿——那等于替产品做掉一个未定的决定。
**保护闭锁必须可见**:整定页可以修改定值,但当前产品在 UA/UN/IA 未标定时保护判据闭锁。
页面应显示该状态,不能让用户误以为“修改定值后保护就会动作”。口径见
`docs/任务规划/数据可信.md` §4.3。
---
## 5. 当前不做
| 项目 | 不做原因 | 重开条件 |
|---|---|---|
| 遥信类型 / 防抖 / 双点 3 页 | V0.1 无开入硬件,配置没有消费者 | 开入固件立项后,与开入开出一起做 |
| net 层与其他结构债 | 当前只做 UI,避免两条主线互相拖慢 | UI 当前清单完成后,按 README §2 切换 |
| 104 上行 UTC 换算(原「RTC 时基统一」) | 内部口径已由用户裁定(2026-10-27:本地钟面为真源,各写入口先换算再落库,见 §4 注),「恒差 8 小时」的后写者赢阶段已结束;剩下的只是 104 上行是否按标准转 UTC,动了要改 104 上行语义 | 送检/第三方主站验收方向定下来后,作为跨模块变更单独立项(墙钟说明 §1.1 末) |
| 主站地址白名单 | CH395F 单连接 socket 上「拒绝即 close+重 listen」等于给扫描风暴开门,且该值现在没有任何既有消费点 | 有真实消费场景或多连接后端立项时再评 |
-353
View File
@@ -1,353 +0,0 @@
# 数据可信(等外部资源:子板变比与标准源)
> **这篇是什么**:把"采集出来的数到底能不能信"一次讲完——已经证到哪一步、按构造还证不到什么、
> 下一跳怎么跨、哪些必须等外部资源。
> **它同时是设计约束的归属文件**:§2.1 / §2.3 / §2.6 / §4.1~§4.5 / §7 被**代码与测试头注释**
> 当口径出处引用(`adc_cal.*` / `meas.*` / `cfg_file.*` / `prot_elm` / `protect_task.c` / `ui_data*` /
> `test/host/prot_dim/*`),它们是**现行规范,不是"已完成记录"**。已完成的事项按"完成即销项"只删 §5 表里的行。
> 排序权威只有一处:`docs/任务规划/README.md` §2;后续事项索引在 `docs/任务规划/登记簿.md` §7。
> **最该先知道的一条**:保护判据现在处于**未标定闭锁**态。判据 = `App/algo/adc_cal.c` 的
> `adc_cal_prot_blocked()`——UA / UN / IA 的 `ADC_CAL_F_VALID` **全置位**才放行,`protect_task` 拿它的返回值
> 停走判据(只有 `DTU_BENCH` 构建旁路,**且只旁路这一处**)。
> 用户裁定(2026-10-25):**保持闭锁到标准源到位**,不缩短解锁路径(不用万用表走捷径)。
---
## 1. 三十秒看清全局
图由 `tools/arch_diagram/gen_data_trust_ladder_svg.py` 生成(改图改脚本重跑,勿手改 SVG)。
![数据可信是五级台阶,现在踩在第 3 级](../images/数据可信台阶.svg)
每升一级只多答一个问题,台阶之间的高度差就是"下游能多信多少":
| 台阶 | 多答的问题 | 状态 |
|---|---|---|
| 1 通路活 | 9 路都在转换、没串道、极性没反? | ✅ 2026-10-27 已证 |
| 2 静态引脚电压 | 注 1 V 直流,读数是不是 1 V? | ✅ 2026-10-27 已证(六项判据全 PASS,§2.6) |
| **3 动态引脚波形** | **注 Vpp 2.828 V 正弦(板上读数 ≈1 V),算出来还是不是 1 V?** | **✅ 2026-11-02 / 11-04 已跑两轮、六轮全部闭合**(削顶 2 Hz 档与复位复核经用户裁定 2026-11-04 关闭;谐波 B 行超差已归因板端前端 RC fc≈796 Hz → §4.6.2 谐波轮;实测结论 `docs/硬件平台/ADC通道映射说明.md` §8.2) |
| 4 端子二次值 | 引脚上这 1 V 对应端子侧几 V? | 🟡 等子板原理图或实物 |
| 5 精度等级验收 | 额定工况下整条链误差够几级? | 🟡 等标准源 |
**三条结论**:
1. **第 1、2 级已闭环**,证据与判据的属主是 `docs/硬件平台/ADC通道映射说明.md` §8.1,执行步骤属主是
`docs/测试说明/专项验证/ADC前端注入验证流程.md`——本文不重抄,只写"证到哪、为什么不能再往外推"。
2. **第 3 级已于 2026-11-02 / 11-04 台架闭环,全程没用到任何外部资源**:一台能出 50 Hz 正弦的交流信号发生器,
接在**已经验证过的那个注入点**上就行。它比第 4、5 级安全一个量级——只需 ±2 V 以内的正弦,
而端子级验证要上 100 V / 220 V 二次值。
3. **第 4、5 级在等外部**:④ 子板/端子板变比(仓库里没有原理图)与标准源两点标定,
两者完成前 `eng` 保持 0,本波只承诺"ADC 引脚电压"。
**本文怎么读**:
| 你想做什么 | 直接看 |
|---|---|
| 判断现在这些数能信到什么程度 | §1 这张图 + §2.6(静态证到哪)+ §2.7(动态证到哪) |
| 改采集 / 算法 / 品质位相关代码 | §2.1 §2.2 §2.3(口径)+ §4.1~§4.5(设计依据) |
| 复跑六轮交流验证 | §4.6(判据、数字从哪儿读、坑)+ §5 的「信号发生器动态波形验证」卡 |
| 看还差谁、按什么顺序做 | §5 任务卡 |
| 确认某件事是**故意不做**而不是漏了 | §2.7 的「按下游列一遍」表 + §5 任务卡里的未闭合项 |
---
## 2. 事实基线(2026-10-29 代码级核对;行号是核对时快照)
### 2.1 通道与量纲(锚点:`adc_cal.*` / `meas.*` / `ui_data*`)
**已证的**:9 路语义 ↔ 物理通道 ↔ 转换器这三者一一对应(`k_adc_map` 与 CubeMX 标签逐条对齐 + 开机自检)。
**没证的**:这张表的系数只到**引脚**,不到端子。
| 语义通道 | 转换器 | 码值格式 | LSB(@ 引脚) | 前端 | ROM 默认系数(@ 引脚) | 交流可用性 |
|---|---|---|---|---|---|---|
| UA | TPAFE5160 | 16 位双极性 ±5 V | 152.59 µV | 1k 串 + 滤波 C(③ = 1:1,无分压) | **152.59 µV/码** | ✅ 可用 |
| UN | TPAFE5160 | 同上 | 152.59 µV | 同上 | **152.59 µV/码** | ✅ 可用 |
| IA | TPAFE5160 | 同上 | 152.59 µV | 同上 | **152.59 µV/码** | ✅ 可用(缺 A/V 变比) |
| UB / UC | STM32 ADC1 | 12 位单极性 0~3.3 V | 805.66 µV | 同上 | **805.66 µV/码** | ❌ 削顶(无中点偏置) |
| IB / IC / IN | STM32 ADC1 | 同上 | 805.66 µV | 同上 | **805.66 µV/码** | ❌ 削顶 |
| TEMP | STM32 ADC1 | 同上 | 805.66 µV | 同上 | 热敏非线性 | — 不纳入线性标定 |
- 通道数 `ADC_SEM_COUNT = 9`(8 电气 + 温度),枚举定义 `App/algo/adc_input.h:38-49`(`adc_semantic_t`)。
- 唯一折算点:`App/task/adc_task.c:425` 的 `frame[s] = adc_cal_apply((adc_semantic_t)s, code)`——
**全仓只有这一处**把码值变成工程量,现单位 = **ADC 引脚电压 V**(`eng = 0`)。
- 端到端链路分四段(① 语义↔网名↔通道、② 引脚电压↔码值、③ `AINn` ↔ 引脚、④ 端子 ↔ `AINn`),
属主 `docs/硬件平台/ADC通道映射说明.md` §7.1:①②③ 已定死(③ 变比 1:1),**只有 ④ 是缺口**。
### 2.2 量纲错配与量纲回归(锚点:`test/host/prot_dim/*`;M4 退出判据⑥)
**没有一条判据检查"不该动作时不动作",台架就会一路"通过"**:"码值当工程量"的错配会让 OC
拿 ~11000 码值去比 10 A 定值 → **恒假动作**。这类错不是"测不准",而是**每次都跳**,且三处消费者
(判据、104、UI)一起错、一处都不报错。
固化它的回归 = `test/host/prot_dim/`:从 **ADC 码值**出发、**显式写出码值↔二次值换算**,走真实的
折算 → 采样环 → 全周傅氏 → 元件判据链;任何一环把量纲弄丢(例如折算点被旁路),断言立刻翻转
(TC-PROTDIM-002 就是反错配对照,专门复现那次事故)。它用的是**合成系数 10 mV/码**,
不是板上 152.59 / 805.66 µV/码——**它证的是"链条别丢量纲",不证"变比数值对不对"**(后者归 §2.6 与 §4.6)。
| 量纲档 | 怎么进入这个档 | 现在的处置 |
|---|---|---|
| `eng = 0`(ADC 引脚电压 V) | `VALID` 未置位——**当前产品构建恒此态** | §4.3 闭锁停走整条判据链;UI 第 7 行显示"未标定"徽标 |
| `eng = 1`(二次值 V / A) | ④ 变比到手 **且** 电气 8 路 `adc_cal_flags()` 的 VALID 全置位(`App/app/ui_data_feed.c` 的 `feed_eng()`) | 定值与工程量同域,判据才名副其实 |
| 混档(最坏情况) | 只改折算系数、不改下游常数 | §2.3 那三处必须跟着动,这正是 §2.3 存在的理由 |
### 2.3 三个必须同步重定的下游常数(锚点:`freq.h` / `iec104_pts.*` / `prot_set.c`)
> 这节的意义是**"动一处量纲要同步三处"**,不是待办清单——三行现在两行已落地。
| # | 位置 | 现值与语义 | 状态 |
|---|---|---|---|
| 1 | `App/algo/freq.h:62` | `FREQ_AMP_MIN 50.0f`——测频幅值门,已按**二次值 V 口径**重定(50 V = 0.5×Un,与 `prot_set.c` 头部量纲基准同源) | ✅ 已重定;⚠ **副作用**:`eng=0` 期间帧值 ≤5 V < 50 V → 本门**恒不过** → `freq_valid()` 恒 0(`freq.h:58-60` 自陈)。这条直接决定 §4.6 里测频腿怎么读、为什么测频轮的"过判据"是"如实报不可测" |
| 2 | `App/protocol/iec104/iec104_pts.c:69-80` | `k_yc[].deadband` 已按点重定:电压 0.5 V、电流 0.005 A、频率 0.5 Hz(真源在 `run_par`,UI 可改) | ✅ 已重定;④ 变比到手后需再复核一次量纲 |
| 3 | `App/algo/prot_set.c:25-70` | `g_prot_set_meta[]` 定值 = 二次值 A / V(基准 100 V / 1 A):OC1 10 A、OV 120 V、UV 20 V、3U0 15 V… | 🟡 口径对,但**标定前无法在板上验真**;§7 #1 定了精度目标后连同 `min`/`max` 复核 |
### 2.4 / 2.5 已删除,编号不复用
### 2.6 静态验证:已知电压注入已于 2026-10-27 台架闭环(锚点:`adc_cal.*` / `meas.*` / `ui_data*`)
判据与实测记录的属主 = `docs/硬件平台/ADC通道映射说明.md` §8.1,执行步骤属主 =
`docs/测试说明/专项验证/ADC前端注入验证流程.md`。一块万用表 + 一个电位器 + 串口 `adc:` 心跳行就够,
**不需要**示波器、信号源、标准源;注入点在串联电阻的端子侧 `U5` 排针(不碰 LQFP 引脚)。
| 项 | 实测 | 判据 |
|---|---|---|
| 零点(8 路逐路短接 AGND) | 0~5 码 | TPAFE ≤30 / STM32 ≤5 码 |
| 三点线性(UA 0.3 / 1.0 / 2.0 V) | R² = 0.9999997,截距 −7.2 码 | ≥0.999 |
| 斜率(UA,TPAFE) | **6544.2 码/V**(理论 6553.6,偏差 −0.14 %) | 偏差 ≤2 % |
| 逐通道映射 | 8 路各自塌到**本路** | 注入哪路只动哪路 |
| 极性(TPAFE 三路 −1.0 V) | −6566 / −6568 / −6566,对称性 ≤0.34 % | 落在 −6554 附近且 ≤2 % |
| 节奏 | Δ9998 / 10 s ≈ 1000 Hz,`idle=0`、`adc1_err=0` | 注入期间仍 1000 Hz |
六项全 PASS ⇒ ③ 段(`AINn` ↔ 转换器引脚)**变比 = 1:1**(若存在 2:1 分压,斜率应约 3277)、
`k_adc_map[]` 逐路对应、TPAFE 补码符号位解释正确、§2.1 的 ROM 默认系数被实测支持。
空载浮空读数(TPAFE ~11450 / STM32 ~1000)是**上电瞬态 + 输入悬空**,不是零点,别拿首帧当零点用。
**这一轮证到的是"一条水平线的高度"**:给定直流电压 → 码值 → 折算,斜率、零点、线性度、极性、
通道对位、节拍全在 ±2 % 内。**直流信号在时间轴上没有形状**,所以相位、频率、波形相关性、真实削顶、谐波
这五类**按构造**不在本节证据范围内——逐条列在 §2.7。另有两项**本轮未覆盖**:
串扰(零点步骤时其余七路浮空本身在漂)与"注入进行中"的节奏(只测了注入前后)。
**一个必须记住的区分**:`CLIPPED` 位是**来源派生**(`App/algo/adc_cal.c:291-293`:系数来自 STM32 就置位,
V0.1 恒命中 UB/UC/IB/IC/IN,位图 `0xE6`),它表示"这路不能测交流",**不等于**"这路此刻正在削顶"。真削顶的签名是
`cal:` 行的 `rail=` 位图与 `rail: edge=…` 那行 `[ERR]`——这条路径至今只在直流饱和里起过(§4.6 削顶轮)。
> **M4 承诺边界**:只到 **ADC 引脚电压**(`eng = 0`)。"端子二次值"要等
> §5「端子/子板变比确认」拿到变比、「两点标定与精度验收」用标准源写入 `[adc_cal]` 并置 `VALID`;
> `eng` 升 1 的条件是电气 8 路 VALID **全置位**(`App/app/ui_data_feed.c` 的 `feed_eng()`)。
> **本节编号与承诺边界口径勿删**——`adc_cal.*` / `meas.*` / `ui_data*` / `simulator/main.c` 的头注释都指到这里。
### 2.7 动态验证:已跑两轮(2026-11-02 / 11-04),六轮实测结论在 `docs/硬件平台/ADC通道映射说明.md` §8.2
**一句话**:这一档已台架两轮验证(幅值 / 波形 / 相位 / 测频 / 谐波 / 削顶直流档都过了)。
按下游列一遍"现在能不能信"(数只详述在 `docs/硬件平台/ADC通道映射说明.md` §8.2,此处不抄第二份):
| 下游 | 现在 | 为什么 |
|---|---|---|
| 基波有效值 | ✅ 过(±2 % 内,三档幅值两点复现) | 台架幅值轮 + 波形轮(基波分量口径)实证;**端子二次值仍不归这一档**——从引脚到端子还隔着 ④ 段变比 |
| 相位 | ✅ 同片内过(录波档 ≤2° 判据) | 同段 UA/UN 两路实测(0° 与 90° 两工况);**跨转换器仍禁比**——两片转换器无共同采样触发,是 V0.1 硬件边界(`docs/硬件平台/ADC通道映射说明.md` §7 通道归属行),不是待修缺陷 |
| 频率 | ✅ 「如实报不可测」成立(这就是现状判据) | 含满幅注入段全不可测、UI 恒 `--`;**45~55 Hz 精度仍未验**——要验须降 `FREQ_AMP_MIN` 单跑一轮 → §7 #8 |
| 削顶 / 品质 | ✅ DC −1.00 V 档锁存 + sticky 实证;2.0 Hz 低频档与复位复核经用户裁定 2026-11-04 关闭 | `[ERR] rail: edge=0x2 sticky=0x2` 唯一一条、撤注恒持;执行见 §4.6 削顶轮 |
| 谐波 C04 / C05 | 🟡 选择性轨已证(单注 100/250 Hz 分别只进对应桶、纯基波两桶为 0);**仍无消费者、无处上送** | 250 Hz→`Ia5` 行 −4.4 % **已按板端前端真实衰减关闭(2026-11-04)**:IA 前端差分滤波 C35 = 100 nF + R19/R21 各 1 k 构成一阶低通 fc ≈ 796 Hz,板端读数忠实、工频不受影响;谐波产品化需板改(模型与数据 `docs/硬件平台/ADC通道映射说明.md` §8.2,执行手册谐波记录 B 行);这两根轨归谁用,见 `docs/算法/继电保护功能复现规划.md` 的「遥测谐波轨(可选)」 |
| 保护判据 | 🔒 闭锁中 | §4.3 |
→ 两轮已按 **§4.6** 跑完(从**已验证过的那个注入点**灌正弦);六轮全部闭合(谐波 B 行超差已归因板端前端 RC,削顶 2 Hz 低频档与复位复核经用户裁定 2026-11-04 关闭)。
---
## 3. 目标与里程碑
**波次目标**:把"数"从原始码值推进到**有物理含义、有品质、有死区、能上送**的工程量。
M4 的六条退出判据(逐条对齐现状,别整格打勾):
| 退出判据 | 状态 | 证据 / 缺口 |
|---|---|---|
| ① 至少 1 路电压通道经已知电压注入验证,斜率与理论 LSB 偏差 ≤2 % | ✅ 2026-10-27 | UA 6544.2 vs 6553.6 码/V(−0.14 %),`docs/硬件平台/ADC通道映射说明.md` §8.1 |
| ② `adc_cal` 折算落地,采样环里是**引脚电压 V** 而非码值 | ✅ | `App/task/adc_task.c:425`(全仓唯一折算点) |
| ③ 8 通道系数 / 零点可落盘,加载失败回退 ROM 默认 | ✅ | `[adc_cal]` / `[adc_cal_ofs]`,见 §4.4 |
| ④ 三处下游常数按工程量重定并注明依据 | ✅(有尾巴) | §2.3;#1 在 `eng=0` 恒失效已记因于 `freq.h:58-60` |
| ⑤ "未标定 → 保护闭锁"生效 | 🟡 软件道 ✅;**"解锁"这半程要等 `VALID` 置位**才能上台架验 | `adc_cal_prot_blocked()` + `App/task/protect_task.c:268` |
| ⑥ 量纲回归用例(不该动作时不动作)通过 | ✅ | `test/host/prot_dim/`,见 §2.2 |
**所以 M4 差的是"台架面",它分两半**:动态这半(§4.6)已于 2026-11-02 / 11-04 台架闭环;
端子与精度那半要等子板与标准源(§5 后两张卡)。
**M5 遥测链 / M6 运行参数与点表**:均已达成,口径沉淀在 `App/algo/meas.h`、`App/algo/run_par.h`
头注释与 §4.5;其中"104 上送值与**工程量**一致"仍挂在变比确认与两点标定上(注入验证只证到引脚电压口径)。
---
## 4. 设计要点
### 4.1 折算模型:板级事实进 ROM,现场标定进 cfg
```
工程量[V 或 A] = (code + b) × k_f
k_f = k[µV/码] × 1e-6 (float,init/load 时算一次)
```
| 符号 | 含义 | 存哪 | 定标 |
|---|---|---|---|
| `k` | µV/码(通道灵敏度) | cfg 段,int32 **Q16**(µV/码 × 65536) | 默认 = 板级理论系数(§2.1 表) |
| `b` | 零点偏移(码值) | cfg 段,int32 | 默认 0 |
| `k_f` | V/码(运行时) | RAM,`adc_cal_init/load` 时由 `k` 派生 | 不落盘 |
- **为什么存 µV 而不是 V/码**:`k` 在 V/码 量级是 3×10⁻⁴,Q16 只有 20 个刻度(5 % 分辨率);
换成 µV/码是 305,Q16 有 2000 万个刻度。
- **为什么 Q16 而不是参考项目的 Q10**:TPAFE 通道 Q10 只能表达 312(+0.16 %),Q16 误差 < 0.001 %;
两者都占 4 字节,Q16 把"系数定点舍入"这一项从误差预算里直接抹掉。参考项目用 2^10 是因为定点 DSP
乘法成本,本机有 FPU、运行时本来就是 float。int32 上限可表达 32767 µV/码,远够。
- **运行时不走定点**:`k` 预乘成 `float k_f`,逐点只做一次浮点乘——1 kHz × 9 通道 = 9k 次/秒,可忽略。
- **系数合法带**:`adc_cal_set()` / `adc_cal_two_point()` 只接受落在板级 ROM 系数 ×[0.5, 2.0] 内的 `k`。
实测斜率与理论值偏差大时**先查前端**(分压 / 变比 / 焊接),不许用系数把硬件的错凑回来——
那等于把故障固化成"标定值"。零点越 ±`ADC_CAL_B_MAX` 同样直接拒绝(口径在 `App/algo/adc_cal.h`)。
### 4.2 三态可用性:标定 ≠ 可测
`k` 的默认值是**板级理论系数**,此时工程量单位是"ADC 引脚电压",不是二次值——还缺互感器/子板变比。
所以通道状态必须让消费者区分三档,不能把引脚电压当二次值用:
```c
#define ADC_CAL_F_VALID 0x01u /* 该通道 k 已按变比标定 → 工程量为二次值 */
#define ADC_CAL_F_CLIPPED 0x02u /* 硬件削顶(单极性无偏置)→ 交流量不可信 */
```
| 通道 | `VALID` | `CLIPPED` | 消费者应如何对待 |
|---|---|---|---|
| UA / UN / IA | 标定后置位 | 0 | 可用于保护、计量、上送 |
| UB / UC / IB / IC / IN | 永不置位(V0.2 硬件改版前) | **1,且是来源派生**(不是实测削顶,见 §2.6 表) | 只作码值监视;点表**已绑定**,靠品质位把 104 侧驱动成 IV、值清零 |
| TEMP | 0 | 0 | 不参与线性标定,页面显示 `--` |
`adc_cal_flags(sem)` 是三处(UI / 104 / 保护)唯一的可用性查询入口;`adc_cal_apply()` **不返回**可用性,
所以"只看系数不看 flags"这种用法在接口层就被堵掉(CLIPPED 通道恒报 IV 的单测见 `test/host/prot_dim/`)。
### 4.3 未标定即闭锁(本波唯一的行为变更)
保护判据拿"ADC 引脚电压"跟"二次值定值"比必然误动作,所以 `protect_task` 多一个闭锁源:
**UA / UN / IA 的 `VALID` 未全置位 → 判据停走**(实现已搬进 `App/algo/adc_cal.c` 的
`adc_cal_prot_blocked()`,`App/task/protect_task.c:268` 消费并打 INFO + 记 SOE)。
- 与"自检失败 / 采样故障闭锁"同构(`PROT_HF_LOCK_MASK` 那一套),**不新增机制**。
- 台架 `/serial-boot-test` 的期望与未闭锁构建不同(判据已同步),这是有意为之。
- 台架调试要旁路只能走编译期开关 `DTU_BENCH`,不进 cfg、不进 104。
⚠ **`DTU_BENCH` 只旁路这一处**:它**不**旁路 §2.3 #1 的测频幅值门,也不产生任何新的读数通道。
### 4.4 落盘:拆两段,不碰引擎
`CFG_FILE_MAX_KEYS = 16`,8 通道 ×(k + b)= 16 正好顶格,将来加一个键就爆。故拆两段:
| 段名 | 键 | 字节 | 回调 |
|---|---|---|---|
| `[adc_cal]` | `k_ua` `k_un` `k_ia` `k_ub` `k_uc` `k_ib` `k_ic` `k_in` + `valid`(uint8 位图) | 8×4 + 1 = 33 | 不挂(RAM 副本即生效值) |
| `[adc_cal_ofs]` | `b_ua` … `b_in` | 8×4 = 32 | 不挂 |
段名 7 / 11 字符、键名 4 字符,均在 15 字符上限内;段数总计 5/8(含 `[run_par]` 9 键死区),未逼近上限。
- 系数唯一真源仍是这两段——104 写 k/b 经 `adc_cal_set()` 代理,`run_par` **不存第二份**;
落盘链走 `SYS_EVT_RUN_PAR_SAVE`(iec104Task peek 投递 → defaultTask 整档 save),`p_cb` 依旧未用。
- ⚠ **负零点**:零点偏移是带符号量,引擎只有 `CFG_VAL_UINT`(`strtoul` + 上界校验)时 −5 会落成
`4294967291`。所以 `[adc_cal_ofs]` 走 `CFG_VAL_INT`(定案口径 §7 #3)。
### 4.5 遥测快照:让 104 与 UI 共用一份上游
104 的 `s_src_yc_read()` 自己遍历相量、UI 将来也要一份 → 两处各自决定"什么时候算新值""品质怎么判",
迟早打架。本波引入 `App/algo/meas.c`:每 **200 ms** 从相量使用区取一次,产出
```c
typedef struct {
uint32_t seq; /* 只增;消费者据此判断是否换帧 */
uint32_t tick_ms;
uint8_t valid; /* 整帧有效 */
uint8_t rsv[3];
float yc[9]; /* 工程量(二次值或 ADC 引脚电压,由 flags 决定) */
uint16_t qds[9]; /* 每点品质:IV / NT / OV / CLIPPED */
uint8_t freq_valid;
float freq_hz;
} meas_snap_t; /* 72 B,双区共 ≈144 B;改字段 = 改协议,须同步 104 与 UI */
```
- **发布者 = `adc_task`**,在 `phasor_run()` / `freq_run()` 之后按 200 ms 分频发布;生产者在自己上下文里
发布,消费者不组装、不判断新旧。全仓 `meas_tick()` **调用点数 = 1** 是评审判据。
- **跨任务读沿用 `phasor` 的双区原子交换**(写侧填非使用区、末尾翻单字节索引;读侧先取索引再整体拷),
**不是新机制**、不引入锁。
- 104 与 UI 都读这份快照 → **同一份数据、两个消费者**;104 侧值与品质整体透传,不做本地判断。
- **200 ms 是上送节拍,不是平均窗**:相量本身已是 1 ms 刷新的基波有效值,再平均只会引入滞后。
⚠ 这条在动态验证里有个可读的后果:注入非整 50 Hz 的正弦时,快照轨会呈现拍频式跳动,**属预期**。
### 4.6 动态波形验证:用信号发生器把整条计算链跑一遍
图由 `tools/arch_diagram/gen_data_trust_dc_ac_svg.py` 生成(改图改脚本重跑,勿手改 SVG)。
![上排直流静态标定、下排交流正弦验证:同一个注入点、同一套前端,两种证法](../images/ADC直流标定与交流验证.svg)
#### 4.6.1 范围与幅度上限
| 边界 | 口径 |
|---|---|
| 注入点 | `docs/测试说明/专项验证/ADC前端注入验证流程.md` §3 的注入点清单(串联电阻端子侧 = `U5` 排针);③ 段 1:1 已拿到台架证据(§2.6) |
| 不知道 ④ 变比也能验 | 注入点在 ④ **之前**,发生器给的电压就是引脚电压,这一轮要证的正是"引脚域里算得对不对" |
| 幅度上限 | ±2 V 以内的正弦(TPAFE 侧判据上限);端子二次值验证要上 100 V / 220 V,风险与设备都在那一级 |
| 读数的地方 | 串口心跳,零固件改动(§4.6.3) |
**这一轮证的是功能性**(算得对不对、品质报得实不实、节拍稳不稳),**不是计量**(误差几级)——
发生器不当"标准"的界线见 §7 #9。
#### 4.6.2 判据(六轮:幅值 / 波形 / 相位 / 测频 / 削顶 / 谐波)
> **分工**:本节定"验什么、过判据是多少";**期望值的算术、接法细节与执行步骤**在
> `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8。
>
> **注入幅度一律按峰峰值 Vpp 设定(用户裁定 2026-11-04)**:发生器面板的有效值显示不当设定基准
> (同一个 Vpp 换波形后有效值显示跟着变,切波形瞬间还残留上一波形的值);万用表 AC 档与板上读数
> 天然是有效值刻度,正弦下 有效值 = Vpp ÷ 2.828,换算着比。
| 轮次 | 验什么 | 接法 | 读哪 | 过判据 |
|---|---|---|---|---|
| **幅值轮** | 基波幅值计量 | UA(R31 / `AIN1`)注 Vpp 2.828 V(= 峰值 ±1.414 V)、50.000 Hz 正弦 | `meas:` 的 `ua_mv` | 读数 = 万用表 AC 档读数,偏差 ≤2 %(与静态同档)。⚠ 别用 `phasor(hb)` 行比幅值——那是 ×0.1 定点,注 1 V 只剩 10 格(§4.6.3) |
| **波形轮** | 读数是否只跟基波走 | 同幅值改方波、三角 | 同上 | 期望值 = **基波分量有效值**(同峰值下的基波 / 峰值比:方波 ≈ **0.90**,闭式 4/π ÷ √2 = 0.900、20 点整周期 DFT 实算 0.904;三角 ≈ **0.573**,闭式 8/π² ÷ √2 = 0.573、实算 0.578),**不是**真有效值(方波 = 1.000、三角 = 0.583 峰值);偏差 ≤2 %。算术与逐波形对照表见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.5 的波形卡。顺带把"这台仪表读的是基波"这条口径钉进文档——用户拿真有效值表去对会以为差了 10 % |
| **相位轮** | 相位 | UA 与 UN 两路**同片**(都走 TPAFE)注同幅、同相 | **录波档**:录波段文件 `test/host/wave_read.py fft`(浮点重算基波相位;段内表序 `UA` = 0、`UN` = 3);**心跳档**:`phasor(hb)` 各行 `Re=` / `Im=` | **录波档**:同段内两路相位差 ≤2°,把发生器相位改 90° 后差值跟到 ≈90°。**心跳档只判"跟随"**(差值落进 80°~100°)——`phasor` 串口行是 ×0.1 定点,Vpp 2.828 V(板上读数 ≈1000 mV)时每格 0.1 V,角度量化最坏 ≈ atan(0.1 / 0.707) ≈ 8°,判不动 2°(§4.6.3)。⚠ 段与发生器**无绝对相位锁定**(触发瞬间钉在段内点 159),只能比**同段内两路**的相对差,跨段比相位或拿发生器相位当绝对基准都不成立。**只许比同片内**——跨转换器两片没有共同采样触发,比相位无意义(见 `docs/硬件平台/ADC通道映射说明.md` §7 通道归属行),STM32 那五路还有 1 拍乒乓滞后 |
| **测频轮** | 测频 | 同幅值轮的 Vpp 2.828 V / 50 Hz | `freq(hb):` | **预期就是"不出数"**(幅值门 50 V 在引脚域恒不过,§2.3 #1)→ 这条的判据是"如实报不可测"(`freq_valid=0`、UI `Hz` 显示 `--`),**不是**报出一个错误的 50.00。想真验 45~55 Hz 精度(PC 侧判据 0.02 Hz)须临时把 `FREQ_AMP_MIN` 降到引脚域量级(如 0.5 V)单跑一轮 → §7 #8 |
| **削顶轮** | 削顶与品质路由(**负向用例**) | 给 UB(R52 / `AIN2`)注 **DC −1.00 V 并保持 ≥5 s**;或 Vpp 2.828 V 而频率 **2.0 Hz** 的正弦——两档都能造出"连续贴同一侧轨带"。⚠ **注 50 Hz 同幅正弦造不出锁存,且这是预期而非故障**:1 kHz 下一个周波只 20 点、正半周必落中带,而 `adc_health_rail_watch()` 任何一拍回中带就把计数清零(`App/algo/adc_health.c`),连续贴底最长 ≈ 209/360 × 20 ≈ 11 拍 < 20。TPAFE 侧在 ±2 V 判据上限内造不出这条(轨带 ±32112 码 ≈ ±4.9 V),只有 STM32 那五路能做 | `cal:` 行的 `rail=` / `edge=`;`rail: edge=…` 的 `[ERR]` 行;录波档另加 `wave_read.py shape` 的三把尺子(`--strict` / 再加 `--clip-superset` / 不带),逐条配法见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.5 的削顶卡 | 负半周钉下轨 → **连续 20 拍同侧后该路贴轨位锁存**(`ADC_RAIL_N_RUN = 20`,`App/algo/adc_health.h:174`)、`edge` 起沿。锁存另有**释放沿前提**:该通道此前须出现过中带样本 → **先上电见基线摆动、再开发生器输出**,开机就注会测出假不通过。撤掉注入后 `rail` 仍非 0 是 sticky 语义(只有 `adc_health_rail_init()` / 复位清)——**复位后仍不清才是 bug**。⚠ 这条会**故意造出 `[ERR]`**,而 `/serial-boot-test` 的 forbidden 标记含 `[ERR]` → 人工判读、排在最后单独一轮,且这一轮的结论不按 `/serial-boot-test` 判 |
| **谐波轮** | 谐波轨 | 基波 + 20 % 二次 + 20 % 五次(IA 上注)。⚠ 峰值预算:Vpp 2.828 V 基波 + 两个 20 % 分量的最坏对齐峰值 ≈ 1.98 V 已顶 ±2 V 红线 → 基波用 **Vpp 2.263 V**、二次与五次各 Vpp 0.453 V | **录波档**:段文件 `test/host/wave_read.py fft --ch 4 --all`(`IA` = 段内表序 4,直接给基波与 2 / 5 次谐波有效值,单位 mV);**旁证**:UI 交流量页 `Ia2` / `Ia5`(1 mV)与 `phasor(hb) C04-IA-F2` / `C05-IA-F5`(×0.1 定点,只证这根轨不是恒 0) | 谐波轨读数 = 注入分量(**±2 %,走录波档**;心跳档判不动:读数 0.160 V 在 ×0.1 串口行上只有 1~2 格)。⚠ 这两根轨**目前没有任何下游消费者**(`prot_elm.c` 无引用、`meas` 只算 `harm=1`),所以谐波轮只证"算得对",**不证"有人用"**——接到哪、给谁用,归 `docs/算法/继电保护功能复现规划.md` 的「遥测谐波轨(可选)」 |
#### 4.6.3 数字能从哪儿读(零固件改动)
| 读数的地方 | 有什么 | 坑 |
|---|---|---|
| 串口每 10 s 心跳(`App/task/adc_task.c` 心跳块) | `adc:`(9 路码值)、`cal:`(三路 mV + `vl`/`cl`/`rail`/`edge` 位图)、`phasor(hb)`(逐实例 `Re` / `Im` / `rms`)、`freq(hb)`、`meas:`(快照轨) | MicroLIB 无 `%f`,全是定点:`phasor` ×0.1(**1 V 注入只剩 10 格**)、`freq` ×0.01 Hz、`cal:` / `meas:` ×1000(1 mV)。10 s 一行的单点瞬时值对 50 Hz 等价于随机相位抽样 |
| UI 交流量页 | `Ua` / `U0` / `Ia` / `Ia2` / `Ia5` / `Hz` / 标定徽标 共 7 行 | 160×160 单色;`--` **同时**表示"没数"和"有数但不可信" → 不能当判据,只能当旁证 |
| **段文件(原始样本)** | 每次触发一段:`/wave/WAVE00.BIN` 起共 100 个号轮转(FTP 根下可见),8 路 × 320 点原始码值加封存瞬间的标定与品质快照;PC 侧 `test/host/wave_read.py` 提供 dump / fft / shape / plot 四个子命令(bench 工具,纯标准库,自带 `--selftest`) | 判据是「PC 独立重算 vs 板上读数」对表(执行步骤见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §4,格式属主见 `docs/子系统设计/故障录波设计说明.md` §6.2 与 §6.3)。**板级注入对表已随交流六轮跑过两轮**(2026-11-02 / 11-04,注 Vpp 2.828 V / 50 Hz、fft 与 `meas:` 互合,结论 `docs/硬件平台/ADC通道映射说明.md` §8.2;CRC 不符必须拒收的判据也在 2026-10-31 远程半轮验过),余下板级判据(周波数 / 极性等逐项)见 `docs/子系统设计/故障录波设计说明.md` §10;示波器只作旁证、不当判据。段内点序:触发瞬间落在段内点 159(预触发 160 点的最后一点),段的绝对相位与发生器无锁定关系,可核对的是相对相位与极性 |
| **没有的** | 没有命令控制台,也没有「把窗里 20 / 40 个点导出来」的定点 dump 子命令——原始样本走上一行的段文件(一次 320 点 / 8 路) | 现场取回一律走现成 FTP(21 端口),形状就地看回放页单通道、或在 PC 侧用同一脚本出图 |
## 5. 任务卡(完成即销项删行;标识列用语义短语,不配编号)
> 资源图例:🔴 台架(COM3 / ST-LINK,`bench.lock` 独占)· 🟡 外部(标准源 / 子板原理图)· 🟢 纯软件。
> 状态:⬜ 未开始 · 🟦 进行中。**已闭环 = 直接删行**。
> 本表**只写判据**;执行步骤在 `docs/测试说明/专项验证/ADC前端注入验证流程.md`,实测结论在
> `docs/硬件平台/ADC通道映射说明.md` §8.1(静态)与 §8.2(动态)。
| 标识(任务名)| DoD(可验证验收判据) | 硬依赖 | 资源 | 写范围 | 状态 |
|---|---|---|---|---|---|
| **信号发生器动态波形验证** | 按 §4.6.2 跑完六轮(测频轮允许以"如实报不可测"通过),逐条记实测 / 判据 / 结论;执行步骤与判据表在 `docs/测试说明/专项验证/ADC前端注入验证流程.md` 的交流节,实测结论在 `docs/硬件平台/ADC通道映射说明.md` §8.2;证据(串口日志 + 录波段文件)归档 `docs/测试说明/测试数据/boot_log_data/` | 静态注入闭环(✅ 2026-10-27)+ 一台能出 50 Hz 正弦、幅度可调到 Vpp 2.828 V 的交流信号发生器(**不需要标准源、不需要端子加压**) | 🔴 台架 + 手边发生器 | `docs/测试说明/`、`docs/硬件平台/` | ✅ **已验证(2026-11-02 / 11-04 两轮、六轮全部闭合)**:实测已回填执行手册各轮记录表、结论在 `docs/硬件平台/ADC通道映射说明.md` §8.2、证据已归档 `boot_log_data`。**未闭合项(均已裁定不做或另登记)**:① 谐波叠加工况(基波+二次+五次同段)未跑——发生器无谐波叠加/ARB 功能,属设备缺口;算法侧由 `test/host/phasor/phasor_test.c` TC-PHASOR-006 覆盖,待有谐波功能标准源复跑;② 削顶 2 Hz 低频档与 sticky 复位复核——用户裁定 2026-11-04 关闭;③ 测频"降幅值门证 0.02 Hz 测准"的改码档未做(现状档以如实报不可测通过);④ 谐波 B 行归因一阶低通模型(fc≈796 Hz)未做绝对仪器证伪(预测 250 Hz 额外滞后 ≈17°,示波器到手复核);谐波功能产品化需板改(C35 换小 + 清点各路容值),已登记 `docs/任务规划/登记簿.md` §3 |
| **端子/子板变比确认** | 给出"端子电压 → ADC 引脚电压"的比值(万用表同时量端子与引脚,或查子板原理图后实测核对),写入 `docs/硬件平台/ADC通道映射说明.md`;据此判定 `eng` 能否置 1;数据缺失则本波只交付引脚电压并登记缺口 | 已知电压注入验证(✅);**与动态验证无依赖关系**,可并行 | 🟡 子板实物或原理图 | `docs/硬件平台/` | ⬜ |
| **两点标定与精度验收** | 电压 4 路(UA/UB/UC/UN)+ 电流 4 路(IA/IB/IC/IN)各做两点标定(零点 + 满度,温度不纳入),写入 `[adc_cal]` 并置 `VALID`;误差 ≤ 目标精度(待定:0.5 级 / 1 级 → §7 #1);证据归档 | 端子/子板变比确认;削顶五路的处置结论(削顶轮) | 🟡 标准源 / 继保测试仪 | `docs/算法/`、`docs/测试说明/测试数据/boot_log_data/` | ⬜ |
---
## 7. 前置决策
> 一张表带状态列:🟡 是还没拍的(拍板前相应任务卡无法判定 DoD),✅ 是**口径锚点,勿删**——
> **第 3 行是 `CFG_VAL_INT`,`App/cfg/cfg_file.c:31` 引用的"§7 决策 3"就指它,勿改序。**
| # | 问题 / 决策 | 备选 | 现状 / 建议 | 状态 |
|---|---|---|---|---|
| 1 | **精度目标** | 0.5 级 / 1 级 | 决定两点标定的判据。**两点标定开跑前必须定**,否则"误差 ≤ 目标精度"这条 DoD 无法判定。保护判据本身只需 3~5 %,0.5 级是计量口径 | 🟡 开放 |
| 2 | **端子 / 子板变比从哪来** | ① 有子板原理图(直接算)② 只有子板实物(万用表同时量端子与引脚)③ 都没有 | 决定 `eng` 能否置 1。② 同样可行且够用;③ 则本波只交付"ADC 引脚电压",二次值登记为缺口 | 🟡 开放 |
| 3 | **`CFG_VAL_INT`(有符号零点)** | 补引擎值类型 / 零点改 uint16 + 32768 偏置 | 已定案:补值类型(`strtol` + `ERANGE` + 宽度上下界,`s_encode()` 带负号) | ✅ 已定案 |
| 4 | 未标定即闭锁 | 保持闭锁 / 用万用表走捷径提前解锁 | 已定案:用户裁定 2026-10-25 **保持闭锁到标准源到位**,不缩短解锁路径 | ✅ 已定案 |
| 5 | 遥测快照发布权 | `adc_task` 分频发布 / 消费者各自计时组装 | 已定案:`adc_task` 唯一发布者(§4.5),调用点数 = 1 由评审守 | ✅ 已定案 |
| 6 | 温度是否纳入线性标定 | 纳入 / 不纳入 | 已定案:不纳入,`adc_cal_flags(TEMP)` 恒 0,页面 `--` | ✅ 已定案 |
| 7 | 注入层级与上限 | 引脚侧 / `U5` 排针端子侧 | 已定案:端子侧(③ 段的"端子侧"),≤2 V 直流——`U5` 排针是可安全接触的最低一级,引脚侧要拆子板 | ✅ 已定案 |
| 8 | **`eng = 0` 期间的测频幅值门怎么处置** | 保持恒失效(现状,UI 恒 `--`)/ 台架临时把 `FREQ_AMP_MIN` 降到引脚域量级跑一轮测频轮再还原 / 换成"相对量"门限(如帧内最大值的一定时比例) | 建议**常态保持恒失效 + 需要时临时降门跑一轮**,换成相对量门限要先重新论证、别在过渡期改。**跑之前先定**;临时降门会改动产品头文件,收尾必须还原到 `git diff` 为空并重跑 `/keil-build` | 🟡 开放 |
| 9 | **动态验证的基准与发生器要求** | 万用表 AC 档 / 发生器自报刻度 / 借标准源 | 建议:以**万用表 AC 档为基准**,发生器只要求"波形干净、幅度稳定、频率能锁 50.000 Hz",**不拿它的刻度当精度**;判据档沿用静态 ±2 % | 🟡 开放 |
+17 -8
View File
@@ -1,7 +1,6 @@
# 后续待办与长期观察登记簿
> **这里不放当前 UI 任务。** 当前执行只看 `UI补齐.md`;本文件登记 UI 之后的工作、
> 等待外部条件的事项、独立立项和长期观察。推进顺序只看 `docs/任务规划/README.md` §2。
> **全部待办只在本文件。** 推进顺序只看 `docs/任务规划/README.md` §2;UI 补齐已于 2026-11-06 整体销项。
>
> 条目一律用语义短语标识;完成后删行并清理引用。§6~§9 是由原排期、送检、分道和
> 开放问题文件合并而来的唯一归属,不再在多处复制同一事项。
@@ -12,7 +11,6 @@
|---|---|---|---|---|
| 队列往返基线待重验 | **队列往返基线(1223/988µs)在发送分块握手改造后的重验**——队列往返测 DONTWAIT 队列全程;发送分块握手对该路径逐位不变 → 机制上无影响,但基线数值属分片时代,严格重锁需跑一轮 Phase 13(需 PC peer) | 2026-09-22(发送分块握手收尾留档) | 低风险:10ms/100ms 阈值余量 >8×;下次 Phase 13 窗口顺带重锁即可 | `链路延迟测试说明.md` §6.4 队列往返行的注¹ |
| 网络负向场景台架验证 | **负向场景台架验证待办**(拔线断链 / 芯片级 `net_init` 失败分支 / 短写压测;正常路径已实测零回归):① PHY 拔线负向测试——断链需断 **DTU 侧**线缆或关**受管交换机端口**;② 芯片级 `net_init` 失败分支(需 SPI 故障注入);③ 短写压测(需远显客户端 + UI 推流压力) | 2026-10-03(台架拓扑 = CH395↔交换机,拔线操作受限) | 待专项台架窗口 | `实机测试实施指南.md` §10 |
| reconcile 突发饿死 uiTask | **对时 reconcile/relisten 突发(0~4s 窗)把唯一 BelowNormal 的 uiTask 压成同一任务 800ms+ 单串缺席(饿死型,非等待型——F3 返回点喂位射程外)**:8 连窗级 UI 缺席期间喂狗面本身未断(cf=0 seg=1)、uisn=0(不在 sink 段内)、uip 在途 307→1083ms 而 uis 峰仅 183ms——被拖的 1s 在 feed/port 纯计算段墙钟。**2026-10-25 台架两轮分箱定案**:同负载换 :7003 churn 2200 周期 stall=0(阻塞型已被 F3 治愈),探针轮 3 事件 8 行全为该签名(漏检零、误报零,v1.1 口径 FAIL 面精确收缩)。处置方向 = 自愈设计 §11.3 脆弱点 1 实测样本并档「net 层跨上下文收口」项:优先级矩阵复核与 reconcile 突发分片让路两案并评;**排期 = UI 完成后的第一项**,与裸指针收口同批 | 2026-10-25(F2/F3 验收轮②,v1.1 判据下捕获) | `docs/测试说明/测试数据/boot_log_data/f3rounds_r2_probe_30min.log.gz`(3 事件 8 行 + STALL 证据行 + 同行 PROF);对照轮 `f3rounds_r1_7003_churn_30min.log.gz`;机理归档 `../网络/网络自愈架构设计.md` §4.6、`../子系统设计/看门狗设计说明.md` §11.3、`../UI设计/UI_设计架构.md` §5.8 | `../算法/继电保护功能复现规划.md`(裸指针收口项属主文档指针) |
| 104 端口改后立刻重 bind | **改了 `[comm]` 段 `port` 之后要求立刻重 bind**(不等拆链重建、不等网络代次重建)——用户裁定 2026-10-30:需求口径按「保存即生效」定,**代码语义是要改的一侧** | 现实现 = `App/task/iec104_serv.c` 的 `s_bind_listen` 每次现取 `iec104_comm_port()`,注释自陈「下次重 bind(拆链重建/网络代次重建)即生效」;连带隐性耦合:`.serialtest/config.json` 必检锚点写死 `i104: listening on 2404`,端口一改串口回归必假失败(要么锚点只查 `listening on`,要么由脚本把端口注入锚点) | 属固件行为变更,需真机验证;本笔只登记不动代码 | 用户裁定 2026-10-30;`docs/产品需求/产品需求设计文档.md` §通讯配置、`docs/测试说明/流程与规范/自动化测试流程.md` |
| relisten 沉降段原语化受阻 | **relisten 沉降段统一到驱动 `sock_reset` 原语受阻**——"去重复实现"的收口已实测回退:原语版 `ftp_abort_probe` RST **0/10**、FIN **0/5**(中止后首笔复连仍被截断到 ≤2048B),另新增 `sock_reset_sync timeout (600ms)` 与 `close: sock_reset not done` 两条 `[ERR]`;同场 net 层自建序列 **10/10 + 5/5** | 2026-10-14(同一块板 A/B,判据 `test/host/ftp_abort_probe.py`;快复连 50/50、背靠背 30/30 两版都过 → 失效面精确落在"中止后首笔复连") | **现状 = `net_listener.c` 保留自建排渣序列**(排空 + CLOSE + 排事件 + 等 CLOSED,30 ms 重试轮持续清)。重开前置三条语义:① 隔离窗内**持续**排空/关闭(残渣在 CLOSE 之后才落进 RX,一次排空接不住)② **复用让位**(复位机不得拆上层刚在同一芯片 Socket 上重建的监听)③ `net_sock_reset_sync` 改"已在运行 = 加入等待"(`begin` 返 -1 ≠ 失败) | `../网络/网络自愈架构设计.md` §8 延后项 1、§5.2 E16;`../问题记录/CH395F_Trap_Records.md` TRAP-NET-18 |
@@ -46,32 +44,42 @@
---
## 6. UI 完成后的编码队列
## 6. 编码队列
| 顺序 | 条目 | 要做什么 | 完成或关闭判据 |
|---|---|---|---|
| 1 | **网络性能资源建议簇** | 分别评估 PASV 重复建监听、PHY 强制 100M 无回退、`NET_MAX_SOCKETS` 与单连接语义不一致;DE 项随 RS-485,不在本项做。机理见 `../网络/Net层阻塞模型架构设计.md` 与 `Drivers/BSP/NET/README.md` | 每项形成“修改并验证”或“有理由不做”的结论;不为了清清单做无收益重构 |
| 2 | **uvprojx 空 TU 观察** | 201 个 LVGL `.c` 中 127 个在 `.map` 零产出,但当前增量构建仅 4~5 秒;有全量构建耗时痛点时先补计时基线,再用 Keil 原生 `<IncludeInBuild>0</IncludeInBuild>` 可逆排除 | 有实测收益才保留改动;否则继续观察 |
> 原第 1 项「net 层跨上下文收口」已于 2026-11-06 闭环并销项(子项 A 审计确认收口完成、子项 B 台架重验确认新负载下 uiTask ≥800 ms 饿死签名不复现;证据见 `../网络/网络自愈架构设计.md` 与 `../子系统设计/看门狗设计说明.md` 变更记录 2026-11-06 条目)。原「dhara 重试自旋与卷锁评估」项随 #45 复核(卷锁无第二写者)关闭销项。
> RS-485 白名单随 `暂缓-RS485.md` 整簇处理,不列为 UI 后的独立编码任务。
> RS-485 白名单随 `暂缓-RS485.md` 整簇处理,不列为独立编码任务。
> 并行写域、工作树与合并纪律统一见 `docs/环境与部署/并行任务工作树方案.md`。
## 7. 等台架或外部资源的事项
| 条目 | 需要条件 | 要做的事 | 去向 |
|---|---|---|---|
| **数据可信任务卡** | ① 一台能出 50 Hz 正弦的交流信号发生器(**手边即可,不等外部**)② 子板实物或原理图 ③ 标准源 | 信号发生器动态波形验证 → 端子/子板变比确认 → 8 通道两点标定 | 唯一任务卡与验收在 `数据可信.md` §5 |
| **端子/子板变比确认** | 子板实物或原理图 | 给出「端子电压 → ADC 引脚电压」的比值(万用表同时量端子与引脚,或查子板原理图后实测核对),写入 `docs/硬件平台/ADC通道映射说明.md`;据此判定 `eng` 能否置 1;数据缺失则本波只交付引脚电压并登记缺口 | `../硬件平台/ADC通道映射说明.md` §7.2(参数已算定:电压族 606.06:1、电流族 29.4118 A/V,等实物复核) |
| **两点标定与精度验收** | 标准源 / 继保测试仪;精度目标先定(0.5 级还是 1 级) | 电压 4 路(UA/UB/UC/UN)+ 电流 4 路(IA/IB/IC/IN)各做两点标定(零点 + 满度,温度不纳入),写入 `[adc_cal]` 并置 `VALID`;误差 ≤ 目标精度;证据归档 | 设计口径 `../算法/采集与算法层设计说明.md` §13.2/§13.3;`eng` 升 1 条件同节 §13.5 承诺边界 |
| **标准源送检与第三方 104 验收** | 两点标定完成、保护 VALID 置位、第三方主站 | 标准源注入判据全部通过;总召、周期、变位、遥控全流程通过;证据归档。送检窗口前 2 日冻结特性 | `../子系统设计/IEC104上行设计说明.md` §7/§8 |
| **队列往返基线待重验** | 台架 + PC peer | 下次 Phase 13 窗口重锁基线 | 本文件 §1 |
| **网络负向场景台架验证** | 拔线、SPI 故障注入、远显压力条件 | PHY 拔线、芯片级 `net_init` 失败、短写压测 | 本文件 §1 |
| **CI 远端闭环未验证** | runner 与第二台机器 | 验证远端两 job 闭环和不同工具路径 | 本文件 §4 |
| **SNTP 校时真机判据** | 台架:板与 PC SNTP 服务器(192.168.31.161 / .13)同网段可达 | `[sntp]` 使能 + 配服务器后上板复核:`[SNTP] step offset=` 步进日志、钟面与时间源一致(本地 UTC+8 口径)、`poll_min` 周期到点重对、拔线后指数退避与主备轮换、恢复后回到周期 | `../子系统设计/系统墙钟时间维护说明.md` §16 |
| **谐波叠加工况复跑** | 一台带谐波叠加 / ARB 功能的信号源 | 基波 + 20 % 二次 + 20 % 五次同段注入,核两轨各认各的次且叠加不串扰。**现有发生器无叠加功能,本轮只做了单注三档**(已证"两轨各认各的次",不证叠加工况);算法侧已被 `test/host/phasor/phasor_test.c` TC-PHASOR-006(3 条谱线各 ±1 %,57/57)覆盖 | `../测试说明/专项验证/ADC前端注入验证流程.md` 谐波轮「叠加」行 |
| **IA 前端一阶低通模型绝对仪器证伪** | 示波器 | 按 fc ≈ 796 Hz 一阶低通模型预测,250 Hz 分量应额外滞后 ≈17°;用示波器直测板上 250 Hz 相位差与该预测比对。模型本体与改板方向见本文件 §3「IA 前端差分滤波限制谐波带宽」 | `../硬件平台/ADC通道映射说明.md` §8.2 |
| **通讯设置页真机判据** | 台架 + 主站 | 页面与六态黄金已入库,剩两条实机判据:①「改后重启即生效」——改 `[comm]` 段端口后重启,看实际监听端口是否跟着变(现状 `iec104_serv.c` 的 `s_bind_listen` 每次现取、拆链重建才生效,见本文件 §1「104 端口改后立刻重 bind」);② 配置段数与键数上限核对(`CFG_FILE_MAX_KEYS = 16`) | `App/protocol/iec104/iec104_comm.{c,h}`、`../子系统设计/网络配置说明.md` |
**送检顺序不可倒过来**:产品构建当前要求 UA/UN/IA 的标定 VALID 全部置位才走保护判据。
未完成标准源标定就送检,保护会表现为不动作。保持该闭锁,不用非标准源标定走捷径。
**标定前必须先拍板的三件事**(拍板前相应 DoD 无法判定):
| 待定 | 备选 | 现状 |
|---|---|---|
| **精度目标** | 0.5 级 / 1 级 | 决定两点标定的判据,**开跑前必须定**,否则"误差 ≤ 目标精度"这条 DoD 无法判定。保护判据本身只需 3~5 %,0.5 级是计量口径 |
| **端子 / 子板变比从哪来** | ① 有原理图(直接算)② 只有实物(万用表同时量端子与引脚)③ 都没有 | 决定 `eng` 能否置 1。② 同样可行且够用;③ 则本波只交付"ADC 引脚电压",二次值登记为缺口。现状已按 ① 的参数算定(`../硬件平台/ADC通道映射说明.md` §7.2),等实物复核 |
| **`eng = 0` 期间的测频幅值门怎么处置** | 保持恒失效(现状,UI 恒 `--`)/ 台架临时把 `FREQ_AMP_MIN` 降到引脚域量级跑一轮再还原 / 换成相对量门限 | 建议**常态保持恒失效 + 需要时临时降门跑一轮**,换相对量门限要先重新论证、别在过渡期改。临时降门会改动产品头文件,收尾必须还原到 `git diff` 为空并重跑 `/keil-build` |
## 8. 等立项或硬件代次的事项
| 条目 | 当前不做的原因 | 重开条件 |
@@ -82,6 +90,7 @@
| **开入开出与遥信配置 3 页** | 固件和 V0.1 硬件均无可配开入对象;出口还涉及 GPIO 安全电平、保持/脉冲和回读自检 | 开入开出作为独立模块立项,再与 UI 页面同批 |
| **故障录波** | 独立子系统,不是补一个页面——**2026-10-29 已立项**:设计与板级判据属主 docs/子系统设计/故障录波设计说明.md(§10;原卡片登记簿 2026-10-30 销项并入后删除) | 已解除暂缓;执行按该文 §10 顺序图,UI 道互斥 |
| **104 文件传输(规约侧读文件)** | 录波取回走现成 FTP 已够用,规约侧文件服务是另一件事 | 送检或第三方交接需求明确后单独立项 |
| **主站地址白名单** | CH395F 单连接 socket 上「拒绝即 close + 重 listen」等于给扫描风暴开门,且该值现在没有任何既有消费点 | 有真实消费场景或多连接后端立项时再评 |
| **RS-485 整簇** | 用户决定暂缓 | `暂缓-RS485.md` |
## 9. 开放问题
@@ -49,7 +49,7 @@
折算层 2026-10-25 落地;二次值等两点标定置 VALID)。槽位值/品质整体透传,本层
**不再自行判新旧**(快照 `seq` 仅供 COV 去重)。
- 品质映射:快照 `MEAS_QDS_*` 低字节与线上 QDS 同值直传;**CLIPPED → IV**(「削顶通道
恒 IV」口径不变、改由品质驱动,`docs/任务规划/数据可信.md` §4.2 三态可用性表 +
恒 IV」口径不变、改由品质驱动,`docs/算法/采集与算法层设计说明.md §13.3` 三态可用性表 +
`test/host/prot_dim/` 的「CLIPPED 通道恒 IV」单测);
快照从未发布(开机 <200 ms)→ IV|NT;判定顺序 IV 优先于 NT。
- 死区(104 改读快照):从「越死区即报」改为**连续 2 个新测量点越限才确认**——板端测量点 =
@@ -6,7 +6,7 @@
> **相关文档**:
> `docs/子系统设计/ADC采样节拍设计说明.md`(节拍与时序账的属主;本文 §3 的数据源就是它)
> `docs/硬件平台/ADC通道映射说明.md`(网名 `AINn` 不等于板级 `ADCn`,也不等于转换器通道号;链路分段与削顶归属)
> `docs/任务规划/数据可信.md` §4.6(动态波形验证判据;录波落地后它的读数通路升级,见 §11)
> `docs/算法/采集与算法层设计说明.md §13.10`(动态波形验证判据;录波落地后它的读数通路升级,见 §11)
> `docs/架构设计/STM32F4-Base存储架构说明.md` §10.1(FatFs 两条实证陷阱与 8.3 短名限制)
> `docs/内存管理/内存内容分配策略.md` §6 与 R6 规则(新增静态缓冲大于 4 KB 的前置动作)
> `docs/UI设计/内容页架构.md`、`docs/UI设计/RemoDispBus协议与接收设计说明.md`(回放页与远端看图的能力边界)
@@ -23,7 +23,7 @@
- `§8` 现场回放显示契约
- `§9` 观测:只加一条周期行
- `§10` 测试与门禁,含 bench 自抓红线
- `§11` 与数据可信任务卡的三处口径变更
- `§11` 与标定任务卡(`../任务规划/登记簿.md` §7)的三处口径变更
- `§12` 风险 `§13` 范围边界 `§14` 与其它文档的关系
---
@@ -34,7 +34,7 @@
| 动机 | 谁提的 | 要求 |
|---|---|---|
| **现场能大概看一眼波形** | 产品(用户裁定 2026-10-29) | 装置上按几下就能看「这一路现在是不是正弦、削没削顶」,不必插串口、不必带笔记本 |
| **台架能把样本拿出来对表** | `docs/任务规划/数据可信.md` §4.6 | 把板上采到的原始样本导出,在 PC 上独立重算全周傅氏,与板上派生读数逐个对——这才是「验证我们后面的各种计算」唯一硬的做法 |
| **台架能把样本拿出来对表** | `docs/算法/采集与算法层设计说明.md §13.10` | 把板上采到的原始样本导出,在 PC 上独立重算全周傅氏,与板上派生读数逐个对——这才是「验证我们后面的各种计算」唯一硬的做法 |
两条共用同一个数据面:**录波环 + 段文件 + 取回通路**。区别只在「谁来触发、给谁看」。分开做会变成两套导出机制,所以并成一件。
@@ -80,7 +80,7 @@
|---|---|---|---|
| UA / UN / IA | TPAFE5160 | 16 bit,±5 V **双极性** | **可信类**:能录出真实的双向工频波形 |
| UB / UC / IB / IC / IN | STM32 ADC1 | 12 bit,0 到 3.3 V **单极性、无中点偏置** | **形状受限类**:交流必然把负半周钉在下轨。录它是为了如实呈现 V0.1 现状,不是为了当工频量用 |
| TEMP | STM32 ADC1 | 12 bit | 可选附带单点(非线性未折算,`docs/任务规划/数据可信.md` §7 已定案) |
| TEMP | STM32 ADC1 | 12 bit | 可选附带单点(非线性未折算,`docs/算法/采集与算法层设计说明.md §13.12` 已定案) |
两条硬件事实决定回放能做到什么,**必须进文件头,也必须进页面**:
@@ -91,7 +91,7 @@
| 理由 | 说明 |
|---|---|
| 现在根本没有工程量 | 两点标定未做,`adc_cal_flags()` 的 `ADC_CAL_F_VALID` 未置位 → `adc_cal_prot_blocked()` 返 1,帧值仍是引脚域电压(`docs/任务规划/数据可信.md` §4.3)。「录波必须先有工程量」这条旧前提被本条推翻 |
| 现在根本没有工程量 | 两点标定未做,`adc_cal_flags()` 的 `ADC_CAL_F_VALID` 未置位 → `adc_cal_prot_blocked()` 返 1,帧值仍是引脚域电压(`docs/算法/采集与算法层设计说明.md §13.4`)。「录波必须先有工程量」这条旧前提被本条推翻 |
| 绕开测频幅值门 | `App/algo/freq.h` 的 `FREQ_AMP_MIN 50.0f` 以二次值 V 为口径,`eng=0` 期间帧值远小于它恒不过门 → `freq_valid()=0`。**录波取的是这道门之前的原始帧**,所以不受影响,动态验证才有样本可对 |
| 最省且可追溯 | int16 码值 2 B/点;标定完成后不必重录,PC 端拿头里的 `k` / `b` 就能把老文件重算成工程量 |
| 诚实 | 文件里装的是「板子看见的东西」,不是「我们希望它看见的东西」 |
@@ -198,7 +198,7 @@ flowchart TD
| 18 | wall | 4 | 对时后的 epoch 秒(未对时为 0) |
| 22 | eng | 1 | 封存瞬间的折算档位:0 引脚域、1 二次值、2 一次值 |
| 23 | flags_seq | 1 | 每路 VALID 压成的位图:bit s = 语义通道 s 的 `ADC_CAL_F_VALID`(电气 8 路恰好占满 1 字节;TEMP 不参与标定,若要带 TEMP 连本行与下一行一起升版本) |
| 24 | clip_mask | 2 | 削顶归属位图:bit s = 语义通道 s,与 `App/algo/meas.h` 同名参数同口径(封存瞬间 `ADC_CAL_F_CLIPPED` 快照,V0.1 恒 0xE6 = UB/UC/IB/IC/IN,见 `docs/任务规划/数据可信.md` §2.7)。⚠ **这个位图的本体是「链路可信性标记(按来源派生)」,不是「本段实测饱和标记」**:置位条件一次样本都不看(`App/algo/adc_cal.c` 291 到 296 行,该路 ROM 系数属片内 ADC 侧即置位);「这一段有没有真钉轨」走另一条链——`App/algo/adc_health.c` 的 `adc_health_rail_watch()`(280 行起)与 `adc_health_rail_sticky()`,门限按满量程百分比由 `adc_cal_rail_ths()` 给、须连续 `ADC_RAIL_N_RUN` 拍。V0.2(8 路全接 TPAFE)后本位自动恒 0,届时「与 clip_mask 对表」这条判据退化为只查钉轨实测(§10) |
| 24 | clip_mask | 2 | 削顶归属位图:bit s = 语义通道 s,与 `App/algo/meas.h` 同名参数同口径(封存瞬间 `ADC_CAL_F_CLIPPED` 快照,V0.1 恒 0xE6 = UB/UC/IB/IC/IN,见 `docs/算法/采集与算法层设计说明.md §13.5`)。⚠ **这个位图的本体是「链路可信性标记(按来源派生)」,不是「本段实测饱和标记」**:置位条件一次样本都不看(`App/algo/adc_cal.c` 291 到 296 行,该路 ROM 系数属片内 ADC 侧即置位);「这一段有没有真钉轨」走另一条链——`App/algo/adc_health.c` 的 `adc_health_rail_watch()`(280 行起)与 `adc_health_rail_sticky()`,门限按满量程百分比由 `adc_cal_rail_ths()` 给、须连续 `ADC_RAIL_N_RUN` 拍。V0.2(8 路全接 TPAFE)后本位自动恒 0,届时「与 clip_mask 对表」这条判据退化为只查钉轨实测(§10) |
| 26 | frame_seq | 4 | 段首帧序号,可与串口周期行的 frames 对账 |
| 30 | 通道表 | 每路 12 | 语义号 1 + 来源转换器 1 + 位宽 1 + 可用性 1(= `adc_cal_flags(sem)` 低 8 位原值,不自造位义)+ `k_q16` 4(int32,µV/码 × 65536)+ `b_codes` 4(int32,码值)。**没有独立 LSB 字段**,LSB 就是 `k_q16`,见 §6.3 |
| — | CRC16(头) | 2 | CRC-16/MODBUS,**低字节在前**(与全文件小端统一);覆盖 `[0, 30+12×ch_count)`,本字段自身紧随其后 |
@@ -215,17 +215,17 @@ flowchart TD
|---|---|
| CRC 字节序 | **低字节在前**,与全文件小端一致。原稿「与屏板链路同一张 CRC-16/MODBUS 表」不成立:全仓**没有**可复用的 CRC-16 表——`App/util/README.md` 记 `crc.c/h` 已于 2026-10-02 删除,屏板链路 `Drivers/BSP/UI/ui_net_sink.c` 的 `remo_crc()` 是单字节异或、不是 CRC-16。本波在 `wave_store.c` 内自带**无表位运算** CRC-16/MODBUS(0x8005 反射、初值 0xFFFF、异或输出 0),单测锚点:串 123456789 的 CRC = 0x4B37 |
| CRC 覆盖范围 | 头 CRC 覆盖 `[0, 30+12×ch_count)`、自身在 `30+12×ch_count`;数据区自 `32+12×ch_count` 起;数据 CRC 覆盖整个数据区、自身在文件尾。8 路 320 点整段 5250 B |
| LSB 从哪来 | **不设独立 LSB 字段**:通道表的 `k_q16` 就是 LSB(µV/码 × 65536),与 `App/algo/adc_cal.h` 的 `ADC_CAL_K_Q16_TPAFE 10000000` / `ADC_CAL_K_Q16_STM32 52800000` 同口径,Q16 下无舍入(选型依据 `docs/任务规划/数据可信.md` §4.1)。PC 侧 `µV = k_q16 / 65536`,不许再乘一遍 |
| LSB 从哪来 | **不设独立 LSB 字段**:通道表的 `k_q16` 就是 LSB(µV/码 × 65536),与 `App/algo/adc_cal.h` 的 `ADC_CAL_K_Q16_TPAFE 10000000` / `ADC_CAL_K_Q16_STM32 52800000` 同口径,Q16 下无舍入(选型依据 `docs/算法/采集与算法层设计说明.md §13.2`)。PC 侧 `µV = k_q16 / 65536`,不许再乘一遍 |
| k / b 宽度与角色 | `k_q16` int32、`b_codes` int32 = 封存瞬间该路生效的两个标定量。`adc_cal_apply()` 的算式是 `eng = (code + b) × k × 1e-6`,文件里存的正是等号右边两个数加原始 code,PC 照此重算。**必须取 int32 原值**,不得经 `adc_cal_k_uv()` 的 float 通道回算(float 在 5.28e7 量级掉尾数)→ 接线道在 `App/algo/adc_cal.[ch]` 补一个 int32 直读入口 `adc_cal_k_q16()`(与 `adc_cal_k_uv()` 孪生);eng=0 时两者是 ROM 默认值,PC 折出来的单位是**引脚域 µV** 而非二次值——单位一律以头里的 `eng` 为准,PC 不许按当前固件口径猜 |
| `flags_seq` 位义 | bit s = 语义通道 s 的 `ADC_CAL_F_VALID`;本波 `ch_count` 固定 8 |
| 可用性字段真值表 | 两行,实现期按 `App/algo/adc_cal.c` 280 到 298 行核出(VALID 需文件位图与 k 合法带**同时**成立;CLIPPED 纯由来源派生——该路 ROM 系数属片内 ADC 侧即置位,与样本内容无关):① **未标定**(产品构建,两点标定未做)逐路 availability = UA / UN / IA 取 `0x00`,UB / UC / IB / IC / IN 取 `0x02`,`flags_seq` = `0x00`,`clip_mask` = 0xE6;② **已标定**(电气 8 路系数全部写入且落合法带)逐路 = `0x01`(TPAFE 三路)/ `0x03`(片内 ADC 五路,VALID 与 CLIPPED 同时为真),`flags_seq` = `0xFF`,`clip_mask` 仍是 0xE6。**VALID 与 CLIPPED 是两件独立事实**:写侧如实透传 `adc_cal_flags()` 逐路原值(`App/task/adc_task.c` 548 行),读侧不得据任何品质组合判废,PC 与回放页只给软告警(见下面「判废面与软告警面」一行) |
| eng 派生式 | `eng` 不是独立事实,是逐路有效位图的派生量:**电气 8 路全 VALID → 二次值(1),缺任意一路 → 引脚域(0)**。真机两处必须同口径,行号一并登记:判据本体 `App/app/ui_data_feed.c` 226 到 235 行的 `feed_eng()`(屏显侧),段头字段填写 `App/task/adc_task.c` 532 到 553 行(其中 552 到 553 行是段头侧的同一派生)。两处分布在**不同任务里现算**,理论上会撞上配置重载的毫秒级沉降窗而不一致——这是允许态,见下一行 |
| 判废面与软告警面 | **完整性判废面自始至终只有这些**:精确尺寸等式、`magic` 与 `ver`(含 `ver` 须等于魔数第三字节)、头 CRC 与数据 CRC、表序 `sem` 等于下标、`ch_count` 上限、`pts_per_cycle` / `pts_per_ch` / `pre_pts` 下限、长度为零、文件短读。**品质组合与单位标签永远不进这道门**。本轮新增的只是**软告警面**:`avail` 同时带 VALID 与 CLIPPED 时 PC 在 NOTE 列打「同时为真,两点标定完成后属正常,非故障」;`eng` 与 `flags_seq` 违反上一条派生式时打 WARN。两者都**不改退出码、不影响出图、不拒渲染**。理由:把「单位标签不一致」当数据损坏,等于让一次改标定文件的沉降窗销毁故障证据 |
| 通道表序与列序 | 第 i 个通道表项 ↔ 数据区第 i 列,按语义号**升序**:UA=0 UB=1 UC=2 UN=3 IA=4 IB=5 IC=6 IN=7(`App/algo/adc_input.h` 的 `adc_semantic_t`)。PC 必须校验表内语义号等于下标,不等即整段作废。交叉验证:`clip_mask` 恒 0xE6 = 2+4+32+64+128,恰好是 UB/UC/IB/IC/IN 五个语义号位,这份算术就是这个顺序的证据 |
| 样本编码 | int16 小端;TPAFE 侧 16 位补码双极性;STM32 侧 0..4095 原样存正数,**不加中点偏置**——V0.1 单极性无偏置是硬件现状,加偏置等于伪造双极性(`docs/任务规划/数据可信.md` §2.7) |
| 样本编码 | int16 小端;TPAFE 侧 16 位补码双极性;STM32 侧 0..4095 原样存正数,**不加中点偏置**——V0.1 单极性无偏置是硬件现状,加偏置等于伪造双极性(`docs/算法/采集与算法层设计说明.md §13.5`) |
| 三个时间字段 | `t0_ms`(上电毫秒)、`wall`(epoch 秒,未对时 0)、`frame_seq`(段首帧序号)均 u32 无符号小端 |
**本波 TEMP 不录**(`ch_count` = 8):温度非线性未折算,进录波只多占一路字节、不增加可解释信息(`docs/任务规划/数据可信.md` §7 的「温度不参与线性标定」已定案)。
**本波 TEMP 不录**(`ch_count` = 8):温度非线性未折算,进录波只多占一路字节、不增加可解释信息(`docs/算法/采集与算法层设计说明.md §13.12` 的「温度不参与线性标定」已定案)。
**为什么按通道分列而不是按帧交错**:回放页只画一路 → 只需连续读那一路;PC 重算全周傅氏也是逐路独立。交错布局两种用法都要跨步长取数,白付代价。
@@ -233,7 +233,7 @@ flowchart TD
1. `flags_seq` 的 V0.1 真值一度被写成 `0x27`:那是把「按来源派生的 CLIPPED」当成了 VALID。按 `App/algo/adc_cal.c` 280 到 298 行,未标定态就是 `0x00`(见上面真值表第一行)。凡引用这个数字的地方一律以真值表为准。
2. 一版互验夹具写成 `eng` = 0 而 `flags_seq` = `0xFF`——违反上面的 eng 派生式,是一串**真机写不出来**的字节。已改为按派生式自洽,并在 `test/host/wave_store` 那套单测里加了夹具自洽断言防复发。教训一句话:**互验夹具的资格来自「真机能写出这串字节」**,一份不可能状态的字节只能验证两个读者对幻觉的一致反应,正好掩盖真分歧。
3. 顺带钉一条因果,免得后文写反:PC 侧早期一次 `shape` 子命令在 `--strict` 下 rc=1,与品质位**无关**,那是「实测触轨路数 vs 段头 `clip_mask`」对表不符(合成夹具的波形本来就没真触轨)。那条对表是 `docs/任务规划/数据可信.md` §4.6.2 削顶轮与 `docs/子系统设计/故障录波设计说明.md` §10 板级判据的本职,不是解码器的判废扩展。
3. 顺带钉一条因果,免得后文写反:PC 侧早期一次 `shape` 子命令在 `--strict` 下 rc=1,与品质位**无关**,那是「实测触轨路数 vs 段头 `clip_mask`」对表不符(合成夹具的波形本来就没真触轨)。那条对表是 `docs/算法/采集与算法层设计说明.md §13.10` 削顶轮与 `docs/子系统设计/故障录波设计说明.md` §10 板级判据的本职,不是解码器的判废扩展。
---
@@ -284,7 +284,7 @@ flowchart TD
### 8.2 控件与菜单:两条省事且省 RAM 的裁定
- **不开 `LV_USE_CHART`**:它在 `Lib/lv_conf.h` 与 `simulator/lv_conf.h` 两份里都是 0,开它要过 `lv-conf-sync` 同步门禁、吃 Flash 与 RAM,而 UI 子系统配额已超;内容页框架本身是「一次性自绘、无子对象」,绘制链尾就是页面的 `draw_cb`(`docs/UI设计/内容页架构.md` 的「什么是内容页」一节),自绘线条有先例(`ui_deco`);
- **显示页要新增一条菜单叶子**(「录波回放」,放记录查询组),触发入口仍用装置维护组那条既有的「手动录波」叶子。新增叶子会改菜单树叶数与页面绑定口径:落地时必须同步 `docs/UI设计/页面补齐规划.md` 与 `docs/任务规划/UI补齐.md` 的叶数闭合,重跑 `tools/menu_gen/gen_menu.py`(`generated-fresh` 逐字节),新增汉字走中文字库链(`font-charset`)。菜单树与字库都是整文件生成物 → **UI 道单写者,同刻只允许一条道写**(`docs/任务规划/README.md` §1 的执行纪律)。
- **显示页要新增一条菜单叶子**(「录波回放」,放记录查询组),触发入口仍用装置维护组那条既有的「手动录波」叶子。新增叶子会改菜单树叶数与页面绑定口径:落地时必须同步 `docs/UI设计/页面补齐规划.md` 的叶数记录与 `docs/UI设计/菜单页面设计.md` §3.9 的复核口径(**该轮已落地,叶数为 43 节点 / 34 叶 / 已绑 31 / 未绑 3**),重跑 `tools/menu_gen/gen_menu.py`(`generated-fresh` 逐字节),新增汉字走中文字库链(`font-charset`)。菜单树与字库都是整文件生成物 → **UI 道单写者,同刻只允许一条道写**(`docs/任务规划/README.md` §1 的执行纪律)。
### 8.3 触发入口与回放页的分工
@@ -296,7 +296,7 @@ flowchart TD
### 8.4 现场之外,PC 侧必须同时具备
- **取回**:FTP 拉 /wave/WAVE 段文件(lftpd 与 config.ini 的 ftp 段鉴权现成,无需新代码);
- **PC 脚本**:仓内新增一个纯标准库脚本(与 `test/host/iec104_master.py` 同族风格)——读段、画图、重算全周傅氏,输出「板上报数 vs PC 重算」对照表。**这才是 `docs/任务规划/数据可信.md` §4.6 那套判据想要的东西**;
- **PC 脚本**:仓内新增一个纯标准库脚本(与 `test/host/iec104_master.py` 同族风格)——读段、画图、重算全周傅氏,输出「板上报数 vs PC 重算」对照表。**这才是 `docs/算法/采集与算法层设计说明.md §13.10` 那套判据想要的东西**;
- **远端看图不是波形通路**:RemoDispBus 一帧 3204 B、最坏约 4 s(`Drivers/BSP/UI/ui_net_sink.h` 的阻塞口径),只适合拍一张回放页的屏做留证。
---
@@ -590,7 +590,7 @@ Before/After 表与串口原文。
---
## 11. 与 `docs/任务规划/数据可信.md` 的口径变更(三处)
## 11. 与 `docs/算法/采集与算法层设计说明.md §13` 的口径变更(三处)
| 旧口径 | 新口径 | 原因 |
|---|---|---|
@@ -636,10 +636,10 @@ Before/After 表与串口原文。
| 文档 / 工作 | 关系 |
|---|---|
| 原任务规划《故障录波》卡片登记簿(2026-10-30 销项删除) | 卡片判据与顺序图已并入本文 §9 与 §10;排期顺位归 `docs/任务规划/README.md` §2.0「独立」行——判据不再另立文件 |
| `docs/任务规划/数据可信.md` | 上游:静态与动态信度、削顶归属由它定义;本文 §11 记录因录波而变的三处口径 |
| `docs/算法/采集与算法层设计说明.md §13` | 上游:静态与动态信度、削顶归属由它定义;本文 §11 记录因录波而变的三处口径 |
| `docs/子系统设计/ADC采样节拍设计说明.md` | 数据源与节拍属主;本波**不改**它,二期改节拍时必须回头改它 |
| `docs/架构设计/STM32F4-Base存储架构说明.md` §10.1 | FatFs 陷阱与 8.3 短名的属主;本文 §5.2 只是消费者 |
| `docs/UI设计/页面补齐规划.md`、`docs/任务规划/UI补齐.md` | 「手动录波」叶子旧状态是「不做(无录波模块)」;P2 与 P3 落地时两处的叶数闭合与重开条件要同步 |
| `docs/UI设计/页面补齐规划.md` | 「手动录波」叶子旧状态是「不做(无录波模块)」;P2 与 P3 落地时该处的叶数记录要同步(**两叶已绑,现值 43 节点 / 34 叶 / 已绑 31 / 未绑 3**,数法见 `docs/UI设计/菜单页面设计.md` §3.9) |
| `docs/问题记录/采集与数据处理短板评测.md` | 记录链缺口(波形数据面 / COMTRADE / 104 文件服务)的登记处;P1 落地后该行改指本文 |
| `docs/产品需求/参考产品复刻明细.md` | §7「录波采样率」行是本文 §2 偏离的对照基准 |
| `docs/硬件平台/ADC通道映射说明.md` | 通道归属与注入点清单的属主;回放页「削」徽标的判据出处 |
+2 -2
View File
@@ -164,7 +164,7 @@ write=1
| `db_freq` | 频率死区 | 500 | 0 ~ 5000(5 Hz) |
- 键数 9 ≤ 16,**通道系数覆盖不落本段**——系数唯一真源 = `[adc_cal]` / `[adc_cal_ofs]`
两段(标定落盘与整定入口布局,docs/任务规划/数据可信.md §4.4;104 `0x8040~0x804F` 写 =
两段(标定落盘与整定入口布局,docs/算法/采集与算法层设计说明.md §13.8;104 `0x8040~0x804F` 写 =
`adc_cal_set` 代理,lead 裁②a)。
- 守卫在**写路径**(104/壳 API 拒 NaN/负/越程);**文件通路引擎照收**(同 adc_cal 的
「人工编辑 + 沉降去抖」契约)——死区超程只让上送变钝、不毁量纲,无合法带哨兵。
@@ -184,7 +184,7 @@ write=1
| `port` | 被控站 TCP 监听端口 | 2404 | 1024 ~ 65535 |
- **生效 = 改后重启**(与 [network] 免重启重建**不同**,验收口径 →
`docs/任务规划/UI补齐.md` §2 第 5 行):iec104Task 启动时读一次 getter;
`docs/任务规划/登记簿.md` §7「通讯设置页真机判据」):iec104Task 启动时读一次 getter;
端口另在下次重 bind(拆链/代次重建)自然生效。不挂段回调、不新增事件位——
CH395F 单连接 socket 上「换端口/拒绝重听」= close + re-listen,做成热生效
会被端口扫描打成 SPI/看门狗风暴(详论 → 本段只登记,正文唯一详述处 =
@@ -1,6 +1,6 @@
# ADC 前端注入验证流程(台架)
> **这篇是什么**:已知电压注入验证的**执行侧**——怎么写表笔、读哪行日志、填哪张表、结果往哪回写。判据与实测记录在属主文档:直流轮 `docs/硬件平台/ADC通道映射说明.md` §8.1、交流轮 `docs/任务规划/数据可信.md` §4.6.2;**本文只写怎么跑**,分叉时判据从属主。证不到什么见 `docs/硬件平台/ADC通道映射说明.md` 的 §8.1 结论与「边界」段,本文不重抄。
> **这篇是什么**:已知电压注入验证的**执行侧**——怎么写表笔、读哪行日志、填哪张表、结果往哪回写。判据与实测记录在属主文档:直流轮 `docs/硬件平台/ADC通道映射说明.md` §8.1、交流轮 `docs/算法/采集与算法层设计说明.md §13.10`;**本文只写怎么跑**,分叉时判据从属主。证不到什么见 `docs/硬件平台/ADC通道映射说明.md` 的 §8.1 结论与「边界」段,本文不重抄。
>
> **两个轮次**:§1~§7 = **直流轮次**(2026-10-27 六项 PASS,只需万用表 + 电位器 + 串口日志);§8 = **交流轮次**(幅值 / 波形 / 相位 / 测频 / 削顶 / 谐波),一台信号发生器接 §3 同一批注入点就能跑,等标准源的只有**精度等级**。V0.1 五路单极性削顶(`UB/UC/IB/IC/IN`)在交流轮次只作"预期削顶"负向用例。
@@ -14,7 +14,7 @@
![UA 通道前端:端子 → R31 → ADC7 → TPAFE AIN_7P;C44 / R32 在差分负端,不在信号通路上](../../images/ADC前端电路.svg)
`ADC7` 节点只有 R31、C44、U3.61,**无对地电阻**;"1k 到地"是 R32 接 TPAFE 负输入脚 AIN_7GND,属差分滤波非信号分压。STM32 侧同样无分流电阻。结论:① **不存在 2:1 分压**(`docs/任务规划/数据可信.md` §2.1 已改引脚侧系数 152.59 / 805.66),只需确认转换器 LSB 与逐通道映射;② **端子侧斜率 = 引脚侧斜率**,端子侧注入安全且能直接验 LSB。
`ADC7` 节点只有 R31、C44、U3.61,**无对地电阻**;"1k 到地"是 R32 接 TPAFE 负输入脚 AIN_7GND,属差分滤波非信号分压。STM32 侧同样无分流电阻。结论:① **不存在 2:1 分压**(`docs/算法/采集与算法层设计说明.md §13.1` 已改引脚侧系数 152.59 / 805.66),只需确认转换器 LSB 与逐通道映射;② **端子侧斜率 = 引脚侧斜率**,端子侧注入安全且能直接验 LSB。
期望斜率(由转换器满量程推出):
@@ -56,7 +56,7 @@
| **段文件** `/wave/WAVE00.BIN` 起 100 号轮转(FTP 根下,与 /log 平级) | 每次触发一段 | 8 路 × 320 点 + 封存瞬间标定与品质快照(`docs/子系统设计/故障录波设计说明.md` §6.2) | **录波档要用的原始样本**:预触发 160 + 后触发 160 点,触发瞬间在段内点 159 |
| PC 侧 `test/host/wave_read.py`(纯标准库) | 手动跑;`--selftest` 自带回归 | 四子命令:dump(逐字段双 CRC)/ fft(全周傅氏重算基波有效值与相位)/ shape(削顶与形态,可 `--strict`)/ plot(SVG/PNG,PNG 用 `-o`) | 「PC 独立重算」执行体;CRC 不符或零长度必须**拒绝** |
> ⚠ 交流轮次(判据 `docs/任务规划/数据可信.md` §4.6)必须用 `meas:` 比幅值,别用 `phasor(hb)`——那行 ×0.1 定点,注 1 V 只剩 10 格。
> ⚠ 交流轮次(判据 `docs/算法/采集与算法层设计说明.md §13.10`)必须用 `meas:` 比幅值,别用 `phasor(hb)`——那行 ×0.1 定点,注 1 V 只剩 10 格。
**「码」是什么**:ADC 原始整数,**不是物理量**——电压 = 码 × LSB:
@@ -159,7 +159,7 @@ TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA
1. 实测斜率、零点、映射写进 `docs/硬件平台/ADC通道映射说明.md` §8("尚未执行"改实测值 + 日期);
2. 确认无分压后,把 `docs/硬件平台/ADC通道映射说明.md` §7.1 量纲链路的第 3 段(`AINn` 焊盘 ↔ 转换器引脚)改成实测结论;
3. `docs/任务规划/数据可信.md` 已知电压注入行按"完成即删"销项;判据与证据属主 `docs/硬件平台/ADC通道映射说明.md` §8.1。
3. `docs/算法/采集与算法层设计说明.md §13` 已知电压注入行按"完成即删"销项;判据与证据属主 `docs/硬件平台/ADC通道映射说明.md` §8.1。
## 6. 判据汇总
@@ -188,7 +188,7 @@ TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA
> **引用写法**:引用判据文档小节一律「路径 + 小节号」紧邻;只写 §8.x 的是本文自己的节。本节只写**怎么跑**(接哪个点、发生器怎么设、读哪行哪个字段、期望值怎么算、结果往哪回写)。
![六轮一图速查:注入信号形状 → 接法与设定 → 判据一句话 → 数字从哪儿读;过判据属主在 数据可信.md §4.6.2](../../images/交流六轮速查.svg)
![六轮一图速查:注入信号形状 → 接法与设定 → 判据一句话 → 数字从哪儿读;过判据属主在 采集与算法层设计说明.md §13.10](../../images/交流六轮速查.svg)
### 8.1 动手前先弄清楚:数字从哪儿读、能读到多细(决定今天判得动哪几轮)
@@ -216,7 +216,7 @@ TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA
| 项 | 要求 | 为什么 / 怎么核 |
|---|---|---|
| 信号发生器 | 正弦 / 方波 / 三角,**并有 DC 档**;频率可锁 50.000 Hz、也能设 2 Hz;幅度 0~3 Vpp | 只要求"波形干净、幅度稳、频率锁得住",刻度不当基准(`docs/任务规划/数据可信.md` §7 #9)。DC 档给削顶轮的直流削顶档 |
| 信号发生器 | 正弦 / 方波 / 三角,**并有 DC 档**;频率可锁 50.000 Hz、也能设 2 Hz;幅度 0~3 Vpp | 只要求"波形干净、幅度稳、频率锁得住",刻度不当基准(`docs/算法/采集与算法层设计说明.md §13.12` #9)。DC 档给削顶轮的直流削顶档 |
| ⚠ 发生器端接 | 接板子时设**高阻负载**,不按 50 Ω 端接 | 50 Ω 端接而实际高阻 → 面板值与真实电压差 2 倍;台架"差一倍"最常见来源 |
| 万用表 AC 档 | 能读 mV;**记明型号与响应类型**(真有效值 / 均值)——判别法:表身或说明书没印 "True RMS" 就当均值档;拿发生器注一个 Vpp 2.828 V 方波到 AC 档,读数 ≈1.41 V = 真有效值档、≈1.57 V = 均值档(差 11 %,一眼分辨) | 基准就是它;波形轮两种表读数都与基波期望差很多,不记响应类型说不清谁错 |
| 板子 | 产品构建(`test/board/test_config.h` 四 `TEST_SUITE_*` 全注释)+ `/keil-build` 0 错 0 警 + 烧录 `-Rst -Run` + 回读校验 | → `stlink-flash` skill 与 AGENTS.md「构建与验证」 |
@@ -232,7 +232,7 @@ TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA
|---|---|---|---|
| 1 | `adc:` 行 | 10 s 一行;`frames` 在涨;`idle=0`、`adc1_err=0` | **九路数值全 0 不等于"没数据"**(没输入当然读 0,判据是 `frames` 涨不涨,§4 尾注);`frames` 不涨或 `adc1_err≠0` → §5.5 |
| 2 | `meas:` 行 | `v=1`;`seq` 每 10 s 约 +500(200 ms 一条) | `seq` 不涨 = 发布闸门停 → §5.5 |
| 3 | `cal:` 行的 `cl=0xE6` | **开机就该是这个数,不是故障** | 这是来源派生静态掩码:V0.1 硬件上 `UB/UC/IB/IC/IN` 五路本就触底(`docs/任务规划/数据可信.md` §2.6)。非战果非故障,别去"修"它。位序(`App/algo/adc_input.h:38`):bit0~8 = `UA UB UC UN IA IB IC IN TEMP`,`0xE6` = bit1/2/5/6/7 恰好这五路 |
| 3 | `cal:` 行的 `cl=0xE6` | **开机就该是这个数,不是故障** | 这是来源派生静态掩码:V0.1 硬件上 `UB/UC/IB/IC/IN` 五路本就触底(`docs/算法/采集与算法层设计说明.md §13.5`)。非战果非故障,别去"修"它。位序(`App/algo/adc_input.h:38`):bit0~8 = `UA UB UC UN IA IB IC IN TEMP`,`0xE6` = bit1/2/5/6/7 恰好这五路 |
| 4 | **开机与注入的先后** | 先上电 → 在串口看到 `adc: UB` 数值有正常摆动 → **再**开发生器输出 | 顺序反了会埋雷:贴轨锁存要求该通道"此前出现过中带样本"(`App/algo/adc_health.c` `adc_health_rail_watch()`),开机就注大信号,削顶轮的锁存**装不上**,测出假"不锁存" |
| 5 | 开机单发行 | `first:`、`phasor(first)`、`freq(first)` 各只一条(`App/task/adc_task.c:478`/`:201`) | 数心跳周期时把它们剔掉,别算进"每 10 s 一行"里 |
| 6 | `phasor(hb)` 行 | 有数就打出来 | **有数 ≠ 数有效**:这行只查 `phasor_get()==0` 不看 valid 位(`App/task/adc_task.c:209`),判读必须配着 `vl`/`cl`/`rail` 一起看 |
@@ -250,7 +250,7 @@ TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA
| STM32(`UB`/`UC`/`IB`/`IC`/`IN`) | 0~3.3 V 单极性 | 无正向意义 | 只在削顶轮用:注交流 = **故意触底**,负半周本就钉 0 |
3. **一次只注一路**(相位轮除外,它要 `UA` 与 `UN` 两路同源),换表笔前先关输出。端子侧串阻 **1 k**(R31/R28/R19/R52…)。STM32 五路负半周经**片内**钳位灌向 VDDA(网表 `docs/硬件平台/V0.1.tel` :228-241 实证:无外置钳位二极管、无隔直电容);Vpp 2.828 V 时峰值电流 ≈ **1.1 mA**(量级估算),**别往上加幅度**——这种注入只允许出现在削顶轮。
4. **电流通道也是注电压**:`IA` 注入点同样是电压进 R19 端子侧。这一轮证"给定引脚电压算得对不对",不是"一次侧 1 A 怎么办"——后者要变比,属 `docs/任务规划/数据可信.md` §5 的端子 / 子板变比确认。
4. **电流通道也是注电压**:`IA` 注入点同样是电压进 R19 端子侧。这一轮证"给定引脚电压算得对不对",不是"一次侧 1 A 怎么办"——后者要变比,属 `docs/任务规划/登记簿.md §7` 的端子 / 子板变比确认。
### 8.4 记录表抬头(每条用例一份,与日志一起归档)
@@ -270,7 +270,7 @@ TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA
**通用动作(六张卡都按这个走)**:
1. 接好线、开发生器输出,等 ≥30 s 读数稳定;
2. 从串口取**连续 ≥10 行**心跳,先确认 `frames` 在涨、`adc1_err=0`(采不到算不得数),再核对卡片要求的读数——数字要取这 ≥10 行的**中位数**,别拿单行(`meas:` 是瞬时基波有效值透传、200 ms 是上送节拍非平均窗,`docs/任务规划/数据可信.md` §4.5,单行带拍频式跳动);
2. 从串口取**连续 ≥10 行**心跳,先确认 `frames` 在涨、`adc1_err=0`(采不到算不得数),再核对卡片要求的读数——数字要取这 ≥10 行的**中位数**,别拿单行(`meas:` 是瞬时基波有效值透传、200 ms 是上送节拍非平均窗,`docs/算法/采集与算法层设计说明.md §13.9`,单行带拍频式跳动);
3. 这张卡的判据要录波取证的:抄完数后,从面板第 26 叶「手动录波」触发一段,把录波页屏上显示的文件名(`WAVE<nn>`)抄进该轮记录表;分析前在本机跑一次 `test/host/wave_read.py --selftest`,**不通过,分析结果不算证据**(不赶时间,六轮跑完统一取回再做);
4. 关掉发生器输出,把数填进该卡记录表。
@@ -306,7 +306,7 @@ TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA
| 三角 | 0.578(闭式 8/π²/√2 = 0.573) | ≈817 | 0.583 |
- 判据:读数 = **基波**期望 ±2 %,**不是**真有效值。方波栏:真有效值表 ≈1414 mV、均值响应表 ≈1570 mV、板上 ≈1278 mV——**正是"读的是基波"的证据,不是 bug**;抬头必须写清万用表响应类型(判据文档同一条)。
- 系数算术以本节为准(4/π 与 8/π² 除 √2 得基波有效值;`docs/任务规划/数据可信.md` §4.6.2 引本表同值)。
- 系数算术以本节为准(4/π 与 8/π² 除 √2 得基波有效值;`docs/算法/采集与算法层设计说明.md §13.10` 引本表同值)。
记录表:
@@ -321,7 +321,7 @@ TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA
|---|---|
| 接法 | `UA`(R31)与 `UN`(R28)**都走 TPAFE**,同幅 Vpp 2.828 V(峰值 ±1.414 V)、同相(发生器单路分两路即天然同相;双通道机型两通道都设 0°) |
| 读数 | `phasor(hb) C02-UA-F1` 与 `C03-UN-F1`,各取 `atan2(Im, Re)` 再比差值 |
| 判据(`docs/任务规划/数据可信.md` §4.6.2) | **录波档**:同段内两路相位差 ≤2°,改 90° 后差值 ≈90°;**心跳档只判跟随**(差值落 80°~100°,容差写记录表) |
| 判据(`docs/算法/采集与算法层设计说明.md §13.10`) | **录波档**:同段内两路相位差 ≤2°,改 90° 后差值 ≈90°;**心跳档只判跟随**(差值落 80°~100°,容差写记录表) |
| ⚠ 分辨率 | 串口行的 ×0.1 向下截断:Vpp 2.828 V(板上 ≈1000 mV)时 Re/Im 各 ±10 格,**一格 0.1 V** → 角度量化误差最坏 ≈ 8°,**≤2° 串口判不出来** |
| 怎么取证 | ① **录波档(首选,零改代码)**:动作见下「录波档的具体动作」六步,比同段内 `UA`(表序 0)与 `UN`(表序 3)相位差,浮点重算不受 ×0.1 量化限制、≤2° 判得动;② **心跳档**:没录到段文件时退用,同相 ≈0°、改 90° 后差值落 80°~100° 即算跟随;③ **抬倍数退路**:临时 `log_phasors()` 倍数改 ×1000 并改行尾 `(x0.1)`,跑完撤销补丁并重编 + 重烧——录波档可用时基本不必走,要走**先问用户** |
| 红线 | **只许比同片内**:跨转换器无同刻性(V0.1 硬件缺陷)+ STM32 五路另有 1 拍乒乓滞后 → `docs/硬件平台/ADC通道映射说明.md` §7 |
@@ -338,7 +338,7 @@ TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA
1. `UA`(R31)与 `UN`(R28)两路接同一发生器输出(同相),注 **Vpp 2.828 V / 50.000 Hz**;稳定 ≥30 s 后在 UI「手动录波」确认页触发一次;成段有**秒级**延迟(落盘在 defaultTask,卷空闲后搬段)→ 等 `wave:` 行 `seg=` +1、`armed` 回 0 再取文件;
2. FTP 取 `/wave/WAVE<NN>.BIN`,**取完立刻改名**(100 号轮转会被覆盖);
3. 跑 `& '.venv\Scripts\python.exe' test/host/wave_read.py fft WAVE<NN>.BIN --all`——每个整周波给一行:基波有效值、相位、2 次与 5 次谐波有效值(mV,系数镜像 `App/algo/phasor.c`);
4. 判据:`UA`(`--ch 0`)与 `UN`(`--ch 3`)在**同一周波**内相位差——同相 ≈0°,改 90° 后 ≈90°,容差 ±2°(`docs/任务规划/数据可信.md` §4.6.2);
4. 判据:`UA`(`--ch 0`)与 `UN`(`--ch 3`)在**同一周波**内相位差——同相 ≈0°,改 90° 后 ≈90°,容差 ±2°(`docs/算法/采集与算法层设计说明.md §13.10`);
5. ⚠ 段**绝对**相位与发生器无锁定(触发瞬间落在段内点 159)→ **只能比同段内相对差**,跨段比相位不成立(段内点序 `docs/子系统设计/故障录波设计说明.md` §6.2);
6. 交叉旁证:同一段先 `dump`(逐字段 + 双 CRC16),再 `plot --ch 0`(CRC 不符或零长度**必须拒收**);板上 `phasor(hb)` 象限应与脚本一致(×0.1 只够核象限)。
@@ -353,7 +353,7 @@ TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA
| 期望(现状固件) | **就是不出数**:幅值门 `FREQ_AMP_MIN 50.0f`(`App/algo/freq.h:62`,`App/algo/freq.c:231` 拿它与基波有效值比)在引脚电压域恒不过 → `valid=0`、`f=0`、UI `Hz` 显 `--` |
| 判据 | **如实报不可测**,而不是报一个看起来对的 50.00。若门限没改却报出 50.00 → 反而是 bug,停下查 `App/algo/freq.c` |
| 另有一档(需先取得同意) | 临时把 `FREQ_AMP_MIN` 由 `50.0f` 降到 `0.5f` → 重编(`/keil-build`,要 build 锁)+ 重烧 → 扫 45.000 / 50.000 / 55.000 Hz 三点,PC 侧判据 0.02 Hz → 跑完**必须还原**(撤销补丁 + 重编 + 重烧,`git diff` 核对干净)。这一档要改固件重烧,动它之前先问过你;不做也不影响上面那条判据成立 |
| 坑 | 非整 50 Hz 时 `meas:` 拍频式跳动属预期 → **扫频读 `freq(hb)` 别读 `meas:`**(`docs/任务规划/数据可信.md` §4.5:200 ms 是上送节拍不是平均窗);取源先 `UA`(C02)再退 `IA`(C01)(`App/algo/freq.c:47`)——注 `UA` 走 UA 源;若只注 `IA`,测频跟 IA 走 |
| 坑 | 非整 50 Hz 时 `meas:` 拍频式跳动属预期 → **扫频读 `freq(hb)` 别读 `meas:`**(`docs/算法/采集与算法层设计说明.md §13.9`:200 ms 是上送节拍不是平均窗);取源先 `UA`(C02)再退 `IA`(C01)(`App/algo/freq.c:47`)——注 `UA` 走 UA 源;若只注 `IA`,测频跟 IA 走 |
记录表:
@@ -363,7 +363,7 @@ TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA
#### 削顶轮:触底与品质路由(负向用例)
- **判据**(`docs/任务规划/数据可信.md` §4.6.2"削顶轮"行):给 `UB`(R52 / `AIN2` / U5.B7)注 **DC −1.00 V 保持 ≥5 s** 或 **Vpp 2.828 V / 2.0 Hz** 正弦 → 负半周钉下轨 → 连续 20 拍同侧后该路贴轨位锁存、`edge` 起沿。
- **判据**(`docs/算法/采集与算法层设计说明.md §13.10`"削顶轮"行):给 `UB`(R52 / `AIN2` / U5.B7)注 **DC −1.00 V 保持 ≥5 s** 或 **Vpp 2.828 V / 2.0 Hz** 正弦 → 负半周钉下轨 → 连续 20 拍同侧后该路贴轨位锁存、`edge` 起沿。
- ⚠ **50 Hz 同幅正弦造不出锁存,是实现约束不是固件缺功能**:锁存条件"连续 `ADC_RAIL_N_RUN = 20` 拍贴同一侧轨带"(`App/algo/adc_health.h:174`),`adc_health_rail_watch()` 里**任何一拍回中带就清零**;1 kHz 下一个 50 Hz 周波只有 20 点、正半周必落中带 → 连续贴底最长 ≈ 209°/360° × 20 ≈ **11 拍 < 20**。
- **轨带数值**(`App/algo/adc_cal.c:452` `adc_cal_rail_ths()`,TEMP 不监视):STM32 贴底 = 码 ≤ **81**(2 % FS ≈ 65 mV)、贴顶 = 码 ≥ 4013;TPAFE = ±32112 码(≈ ±4.9 V)→ **TPAFE 侧在 ±2 V 判据上限内造不出来**,只有 STM32 五路能做。
- **直流削顶档(首选,零固件改动)**:发生器切 **DC −1.00 V** 注 `UB` 端子侧,保持 ≥5 s。期望:`rail=0x002`、`edge=0x002`、一条 `[ERR] rail: edge=0x2 sticky=0x2 (code-domain, 20-run+release)`(`App/task/adc_task.c:428`)、`adc: UB` 贴 0。撤掉注入后 **sticky 位不随输入恢复而清**(只有 `adc_health_rail_init()` / 复位才清)→ 复位一次记录"是否随复位清",本轮战果之一。
@@ -69,7 +69,7 @@ flowchart LR
1. **到你接线了**:发生器正弦 **50.000 Hz / 1.000 V rms** 接 **UA 端子**(接线四条件照 ADC 注入流程 §8.3:发生器端接高阻、端子侧焊盘、万用表并接、单点共地)——接好说"接上了"。
2. **[agent]** 先落一个基准:抓串口最近三条 `meas:` 与 `wave:` 心跳存证(对表分母)。
3. **到按键**(二选一,agent 会问):你面板走 主界面 → 装置维护 → 手动录波 →(修改密码 123)→ `e` 确认 → `e` 执行,页面出「已请求录波」即成;**或者**让 agent 从 7003 远程注键——键时序它已趟熟(drain 纪律见 `scripts/board_ui_nav.py` 文件头)。
4. **[agent]** 等 `wave:` 心跳 seg+1 → FTP 拉回新段 → `test/host/wave_read.py dump`(双 CRC 必须绿)→ 量:**周波数**(160 点窗内基波频率,应 ≈50 Hz)、**幅值**(与万用表读数对,误差口径看 `docs/任务规划/数据可信.md` §7 前置决策 #1「精度目标」——**该目标还没拍板,量完记实测数即可,别现场编合格线**)、**极性**(触发拍在段内点 159,正半周起点看符号)、**钉轨路数**(UA 不该钉;`clip_mask` 位图对表规则照 `docs/子系统设计/故障录波设计说明.md` §10 板级行——**V0.1 五路在交流注入时反而没钉,先怀疑接线**)。
4. **[agent]** 等 `wave:` 心跳 seg+1 → FTP 拉回新段 → `test/host/wave_read.py dump`(双 CRC 必须绿)→ 量:**周波数**(160 点窗内基波频率,应 ≈50 Hz)、**幅值**(与万用表读数对,误差口径看 `docs/算法/采集与算法层设计说明.md §13.12` 前置决策 #1「精度目标」——**该目标还没拍板,量完记实测数即可,别现场编合格线**)、**极性**(触发拍在段内点 159,正半周起点看符号)、**钉轨路数**(UA 不该钉;`clip_mask` 位图对表规则照 `docs/子系统设计/故障录波设计说明.md` §10 板级行——**V0.1 五路在交流注入时反而没钉,先怀疑接线**)。
5. **换点再来一遍**:发生器升到能钉住 UB/UC/IB/IC/IN 任一路的量级(削顶的老口径见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.5 削顶卡;片内 ADC 五路单极性、负半周钉 0 的机理在 `docs/硬件平台/ADC通道映射说明.md`)——**这一遍你只拧幅值键**,录波触发重复第 3~4 步,钉轨对表应见 ≥1 路实测钉轨且能由注入解释。
6. **[agent]** `meas:` 与 104 浮点遥测对表:参考主站 `test/host/iec104_master.py` 读 YC 浮点,和 `meas:` 行、和你注入的 1.000 V 三方对齐——**你只需报万用表读数**。
7. **坏段画面(这一幕的收尾,要第一幕修好)**:[agent] 造一份位翻转坏段上板(`RETR→翻一位→STOR 回同号`)→ 开回放页翻到该段——**判据:绝不许画成一条直线**,该显拒收态;agent 抓屏给你目检。
@@ -103,7 +103,7 @@ flowchart LR
**先讲人话**:过流启动录波的代码路已接在 `protect_task.c` 的启动边沿上(判据一 picked,录波同拍请求),但**保护判据现在整机闭锁**——`adc_cal_flags()` 的 VALID 位对 UA/UN/IA 三路都没置位,`protect_task` 直接停走判据。要让保护真出口,**必须先把这三路标定**;这正是 2026-10-25 你裁定"保持闭锁、不用万用表走捷径"守着的那道门。
- **决定一(解锁)**:这一幕要不要用**发生器为参考**给 UA/UN/IA 做两点标定换保护触发路(src=P)验证?它**不是送检级标定**(端子变比还挂着 `docs/任务规划/数据可信.md` §5 的原理图确认),做出来的工程量是"发生器刻度下的近似值"。**点头 → 往下走;摇头 → 第三幕整体顺延到标准源轮,本文其余各幕照做。**
- **决定一(解锁)**:这一幕要不要用**发生器为参考**给 UA/UN/IA 做两点标定换保护触发路(src=P)验证?它**不是送检级标定**(端子变比还挂着 `docs/任务规划/登记簿.md §7` 的原理图确认),做出来的工程量是"发生器刻度下的近似值"。**点头 → 往下走;摇头 → 第三幕整体顺延到标准源轮,本文其余各幕照做。**
- **决定二(还锁)**:这一幕验完,把标定清回闭锁(还原出厂系数)还是**留着 valid** 让保护继续在线(此后 UI 显示与 104 遥测的二次值都按这份近似标定出数——**留着就要在台账注明非送检级**)。
步骤(决定一通过后):
@@ -1,28 +1,28 @@
== build_log_verify.txt ==
Program Size line: Program Size: Code=255292 RO-data=30992 RW-data=2080 ZI-data=150104
Program Size line: Program Size: Code=255292 RO-data=30992 RW-data=2080 ZI-data=150104
linking...
Program Size: Code=255292 RO-data=30992 RW-data=2080 ZI-data=150104
Program Size: Code=255292 RO-data=30992 RW-data=2080 ZI-data=150104
FromELF: creating hex file...
".\STM32F407-Demo\STM32F407-Demo.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:16
== build_log_fix.txt ==
Program Size line: Program Size: Code=255284 RO-data=30992 RW-data=2080 ZI-data=150104
Program Size line: Program Size: Code=255284 RO-data=30992 RW-data=2080 ZI-data=150104
linking...
Program Size: Code=255284 RO-data=30992 RW-data=2080 ZI-data=150104
Program Size: Code=255284 RO-data=30992 RW-data=2080 ZI-data=150104
FromELF: creating hex file...
".\STM32F407-Demo\STM32F407-Demo.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:16
== build_log_final.txt ==
Program Size line: Program Size: Code=254820 RO-data=30896 RW-data=2072 ZI-data=150104
Program Size line: Program Size: Code=254820 RO-data=30896 RW-data=2072 ZI-data=150104
linking...
Program Size: Code=254820 RO-data=30896 RW-data=2072 ZI-data=150104
Program Size: Code=254820 RO-data=30896 RW-data=2072 ZI-data=150104
FromELF: creating hex file...
".\STM32F407-Demo\STM32F407-Demo.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:15
== build_log_final2.txt ==
Program Size line: Program Size: Code=254820 RO-data=30896 RW-data=2072 ZI-data=150104
Program Size line: Program Size: Code=254820 RO-data=30896 RW-data=2072 ZI-data=150104
linking...
Program Size: Code=254820 RO-data=30896 RW-data=2072 ZI-data=150104
Program Size: Code=254820 RO-data=30896 RW-data=2072 ZI-data=150104
FromELF: creating hex file...
".\STM32F407-Demo\STM32F407-Demo.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:15
@@ -120,4 +120,4 @@
"[RX] 2026-11-07T21:23:55.263+08:00 [2026-11-07 21:23:54][ADC_TASK] wave: seg=27 armed=0 src=T pts=320 err=15 ovf=18 drop=293616"
]
}
}
}
@@ -184,7 +184,7 @@
[RX] 2026-11-07T21:14:13.269+08:00 [2026-11-07 21:14:12] [FTP] CMD USER admin
[RX] 2026-11-07T21:14:13.269+08:00 [2026-11-07 21:14:12] [FTP] CMD PASS admin
[RX] 2026-11-07T21:14:13.280+08:00 [2026-11-07 21:14:12] [FTP] CMD TYPE I
[RX] 2026-11-07T21:14:13.290+08:00 [2026-11-07 21:14:12] [FTP] CMD PASV
[RX] 2026-11-07T21:14:13.290+08:00 [2026-11-07 21:14:12] [FTP] CMD PASV
[RX] 2026-11-07T21:14:13.332+08:00 [2026-11-07 21:14:12][NET] sock3 standalone accept
[RX] 2026-11-07T21:14:13.353+08:00 [2026-11-07 21:14:12] [FTP] CMD RETR /FILL3.BIN
[RX] 2026-11-07T21:14:14.287+08:00 [2026-11-07 21:14:13] [STACK] default peak_used=2188/5120 free_min=2932 (57%)
@@ -198,7 +198,7 @@
[RX] 2026-11-07T21:14:14.350+08:00 [2026-11-07 21:14:13] [STACK] heap free=15600 min_ever=8464
[RX] 2026-11-07T21:14:14.454+08:00 MISS start snap=0x00000177 req=0x000001F7 t=21918
[RX] 2026-11-07T21:14:15.593+08:00 [2026-11-07 21:14:14] [FTP] DOWNLOAD '/FILL3.BIN' OK
[RX] 2026-11-07T21:14:15.603+08:00 [2026-11-07 21:14:14] [FTP] CMD QUIT
[RX] 2026-11-07T21:14:15.603+08:00 [2026-11-07 21:14:14] [FTP] CMD QUIT
[RX] 2026-11-07T21:14:15.603+08:00 [2026-11-07 21:14:14][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:14:15.614+08:00 [2026-11-07 21:14:14] [FTP] waiting for connection...
[RX] 2026-11-07T21:14:15.635+08:00 [2026-11-07 21:14:14] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -230,7 +230,7 @@
[RX] 2026-11-07T21:14:21.267+08:00 [2026-11-07 21:14:20] [FTP] CMD USER admin
[RX] 2026-11-07T21:14:21.267+08:00 [2026-11-07 21:14:20] [FTP] CMD PASS admin
[RX] 2026-11-07T21:14:21.277+08:00 [2026-11-07 21:14:20] [FTP] CMD TYPE I
[RX] 2026-11-07T21:14:21.277+08:00 [2026-11-07 21:14:20] [FTP] CMD PASV
[RX] 2026-11-07T21:14:21.277+08:00 [2026-11-07 21:14:20] [FTP] CMD PASV
[RX] 2026-11-07T21:14:21.329+08:00 [2026-11-07 21:14:20][NET] sock3 standalone accept
[RX] 2026-11-07T21:14:21.340+08:00 [2026-11-07 21:14:20] [FTP] CMD RETR /FILL3.BIN
[RX] 2026-11-07T21:14:23.059+08:00 [2026-11-07 21:14:22][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
@@ -239,7 +239,7 @@
[RX] 2026-11-07T21:14:23.092+08:00 [2026-11-07 21:14:22][ADC_TASK] meas: seq=150 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-07T21:14:23.092+08:00 [2026-11-07 21:14:22][ADC_TASK] wave: seg=12 armed=1 src=T pts=320 err=1 ovf=1 drop=38656
[RX] 2026-11-07T21:14:23.610+08:00 [2026-11-07 21:14:22] [FTP] DOWNLOAD '/FILL3.BIN' OK
[RX] 2026-11-07T21:14:23.620+08:00 [2026-11-07 21:14:22] [FTP] CMD QUIT
[RX] 2026-11-07T21:14:23.620+08:00 [2026-11-07 21:14:22] [FTP] CMD QUIT
[RX] 2026-11-07T21:14:23.620+08:00 [2026-11-07 21:14:22][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:14:23.631+08:00 [2026-11-07 21:14:22] [FTP] waiting for connection...
[RX] 2026-11-07T21:14:23.652+08:00 [2026-11-07 21:14:22] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -253,12 +253,12 @@
[RX] 2026-11-07T21:14:29.158+08:00 [2026-11-07 21:14:28] [FTP] CMD USER admin
[RX] 2026-11-07T21:14:29.169+08:00 [2026-11-07 21:14:28] [FTP] CMD PASS admin
[RX] 2026-11-07T21:14:29.169+08:00 [2026-11-07 21:14:28] [FTP] CMD TYPE I
[RX] 2026-11-07T21:14:29.179+08:00 [2026-11-07 21:14:28] [FTP] CMD PASV
[RX] 2026-11-07T21:14:29.179+08:00 [2026-11-07 21:14:28] [FTP] CMD PASV
[RX] 2026-11-07T21:14:29.220+08:00 [2026-11-07 21:14:28][NET] sock3 standalone accept
[RX] 2026-11-07T21:14:29.231+08:00 [2026-11-07 21:14:28] [FTP] CMD RETR /FILL3.BIN
[RX] 2026-11-07T21:14:31.368+08:00 [2026-11-07 21:14:30] [WAVE][WARN] seg held 63 ms (idx=15)
[RX] 2026-11-07T21:14:31.410+08:00 [2026-11-07 21:14:30] [FTP] DOWNLOAD '/FILL3.BIN' OK
[RX] 2026-11-07T21:14:31.420+08:00 [2026-11-07 21:14:30] [FTP] CMD QUIT
[RX] 2026-11-07T21:14:31.420+08:00 [2026-11-07 21:14:30] [FTP] CMD QUIT
[RX] 2026-11-07T21:14:31.420+08:00 [2026-11-07 21:14:30][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:14:31.420+08:00 [2026-11-07 21:14:30] [FTP] waiting for connection...
[RX] 2026-11-07T21:14:31.451+08:00 [2026-11-07 21:14:30] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -277,12 +277,12 @@
[RX] 2026-11-07T21:14:37.362+08:00 [2026-11-07 21:14:36] [FTP] CMD USER admin
[RX] 2026-11-07T21:14:37.362+08:00 [2026-11-07 21:14:36] [FTP] CMD PASS admin
[RX] 2026-11-07T21:14:37.373+08:00 [2026-11-07 21:14:36] [FTP] CMD TYPE I
[RX] 2026-11-07T21:14:37.373+08:00 [2026-11-07 21:14:36] [FTP] CMD PASV
[RX] 2026-11-07T21:14:37.373+08:00 [2026-11-07 21:14:36] [FTP] CMD PASV
[RX] 2026-11-07T21:14:37.424+08:00 [2026-11-07 21:14:36][NET] sock3 standalone accept
[RX] 2026-11-07T21:14:37.445+08:00 [2026-11-07 21:14:36] [FTP] CMD RETR /FILL3.BIN
[RX] 2026-11-07T21:14:39.641+08:00 [2026-11-07 21:14:38] [FTP] DOWNLOAD '/FILL3.BIN' OK
[RX] 2026-11-07T21:14:39.641+08:00 MISS start snap=0x000001E7 req=0x000001F7 t=47112
[RX] 2026-11-07T21:14:39.662+08:00 [2026-11-07 21:14:38] [FTP] CMD QUIT
[RX] 2026-11-07T21:14:39.662+08:00 [2026-11-07 21:14:38] [FTP] CMD QUIT
[RX] 2026-11-07T21:14:39.673+08:00 [2026-11-07 21:14:38][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:14:39.673+08:00 [2026-11-07 21:14:38] [FTP] waiting for connection...
[RX] 2026-11-07T21:14:39.694+08:00 [2026-11-07 21:14:39] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -301,12 +301,12 @@
[RX] 2026-11-07T21:14:45.207+08:00 [2026-11-07 21:14:44] [FTP] CMD USER admin
[RX] 2026-11-07T21:14:45.207+08:00 [2026-11-07 21:14:44] [FTP] CMD PASS admin
[RX] 2026-11-07T21:14:45.217+08:00 [2026-11-07 21:14:44] [FTP] CMD TYPE I
[RX] 2026-11-07T21:14:45.217+08:00 [2026-11-07 21:14:44] [FTP] CMD PASV
[RX] 2026-11-07T21:14:45.217+08:00 [2026-11-07 21:14:44] [FTP] CMD PASV
[RX] 2026-11-07T21:14:45.269+08:00 [2026-11-07 21:14:44][NET] sock3 standalone accept
[RX] 2026-11-07T21:14:45.280+08:00 [2026-11-07 21:14:44] [FTP] CMD RETR /FILL3.BIN
[RX] 2026-11-07T21:14:47.420+08:00 [2026-11-07 21:14:46] [WAVE][WARN] seg held 62 ms (idx=20)
[RX] 2026-11-07T21:14:47.461+08:00 [2026-11-07 21:14:46] [FTP] DOWNLOAD '/FILL3.BIN' OK
[RX] 2026-11-07T21:14:47.461+08:00 [2026-11-07 21:14:46] [FTP] CMD QUIT
[RX] 2026-11-07T21:14:47.461+08:00 [2026-11-07 21:14:46] [FTP] CMD QUIT
[RX] 2026-11-07T21:14:47.461+08:00 [2026-11-07 21:14:46][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:14:47.471+08:00 [2026-11-07 21:14:46] [FTP] waiting for connection...
[RX] 2026-11-07T21:14:47.503+08:00 [2026-11-07 21:14:46] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -317,7 +317,7 @@
[RX] 2026-11-07T21:15:26.136+08:00 MISS start snap=0x000001E7 req=0x000001F7 t=93607
[RX] 2026-11-07T21:15:27.392+08:00 [2026-11-07 21:15:26] [WAVE][WARN] seg held 61 ms (idx=34)
[RX] 2026-11-07T21:15:27.433+08:00 [2026-11-07 21:15:26] [FTP] DOWNLOAD '/FILL3.BIN' OK
[RX] 2026-11-07T21:15:27.433+08:00 [2026-11-07 21:15:26] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:27.433+08:00 [2026-11-07 21:15:26] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:27.433+08:00 [2026-11-07 21:15:26][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:15:27.444+08:00 [2026-11-07 21:15:26] [FTP] waiting for connection...
[RX] 2026-11-07T21:15:27.475+08:00 [2026-11-07 21:15:26] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -335,13 +335,13 @@
[RX] 2026-11-07T21:15:33.278+08:00 [2026-11-07 21:15:32] [FTP] CMD USER admin
[RX] 2026-11-07T21:15:33.288+08:00 [2026-11-07 21:15:32] [FTP] CMD PASS admin
[RX] 2026-11-07T21:15:33.288+08:00 [2026-11-07 21:15:32] [FTP] CMD TYPE I
[RX] 2026-11-07T21:15:33.299+08:00 [2026-11-07 21:15:32] [FTP] CMD PASV
[RX] 2026-11-07T21:15:33.299+08:00 [2026-11-07 21:15:32] [FTP] CMD PASV
[RX] 2026-11-07T21:15:33.351+08:00 [2026-11-07 21:15:32][NET] sock3 standalone accept
[RX] 2026-11-07T21:15:33.351+08:00 [2026-11-07 21:15:32] [FTP] CMD RETR /FILL3.BIN
[RX] 2026-11-07T21:15:35.576+08:00 [2026-11-07 21:15:34][ERR] [WAVE] seg drop: ring abandoned (idx=36 written=5250)
[RX] 2026-11-07T21:15:35.576+08:00 [2026-11-07 21:15:34] [WAVE][WARN] seg held 124 ms (idx=36)
[RX] 2026-11-07T21:15:35.587+08:00 [2026-11-07 21:15:34] [FTP] DOWNLOAD '/FILL3.BIN' OK
[RX] 2026-11-07T21:15:35.587+08:00 [2026-11-07 21:15:34] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:35.587+08:00 [2026-11-07 21:15:34] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:35.597+08:00 [2026-11-07 21:15:34][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:15:35.597+08:00 [2026-11-07 21:15:34] [FTP] waiting for connection...
[RX] 2026-11-07T21:15:35.628+08:00 [2026-11-07 21:15:34] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -353,7 +353,7 @@
[RX] 2026-11-07T21:15:38.921+08:00 [2026-11-07 21:15:38] [FTP] CMD USER admin
[RX] 2026-11-07T21:15:38.931+08:00 [2026-11-07 21:15:38] [FTP] CMD PASS admin
[RX] 2026-11-07T21:15:38.941+08:00 [2026-11-07 21:15:38] [FTP] CMD SIZE /WAVE/WAVE36.BIN
[RX] 2026-11-07T21:15:38.941+08:00 [2026-11-07 21:15:38] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:38.941+08:00 [2026-11-07 21:15:38] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:38.941+08:00 [2026-11-07 21:15:38][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:15:38.952+08:00 [2026-11-07 21:15:38] [FTP] waiting for connection...
[RX] 2026-11-07T21:15:38.982+08:00 [2026-11-07 21:15:38] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -364,7 +364,7 @@
[RX] 2026-11-07T21:15:39.480+08:00 [2026-11-07 21:15:38] [FTP] CMD USER admin
[RX] 2026-11-07T21:15:39.480+08:00 [2026-11-07 21:15:38] [FTP] CMD PASS admin
[RX] 2026-11-07T21:15:39.491+08:00 [2026-11-07 21:15:38] [FTP] CMD SIZE /WAVE/WAVE00.BIN
[RX] 2026-11-07T21:15:39.501+08:00 [2026-11-07 21:15:38] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:39.501+08:00 [2026-11-07 21:15:38] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:39.501+08:00 [2026-11-07 21:15:38][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:15:39.501+08:00 [2026-11-07 21:15:38] [FTP] waiting for connection...
[RX] 2026-11-07T21:15:39.574+08:00 [2026-11-07 21:15:38] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -385,7 +385,7 @@
[RX] 2026-11-07T21:15:41.838+08:00 [2026-11-07 21:15:41] [FTP] CMD USER admin
[RX] 2026-11-07T21:15:41.838+08:00 [2026-11-07 21:15:41] [FTP] CMD PASS admin
[RX] 2026-11-07T21:15:41.849+08:00 [2026-11-07 21:15:41] [FTP] CMD SIZE /WAVE/WAVE36.BIN
[RX] 2026-11-07T21:15:41.859+08:00 [2026-11-07 21:15:41] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:41.859+08:00 [2026-11-07 21:15:41] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:41.859+08:00 [2026-11-07 21:15:41][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:15:41.869+08:00 [2026-11-07 21:15:41] [FTP] waiting for connection...
[RX] 2026-11-07T21:15:41.891+08:00 [2026-11-07 21:15:41] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -405,7 +405,7 @@
[RX] 2026-11-07T21:15:50.907+08:00 [2026-11-07 21:15:50] [FTP] CMD USER admin
[RX] 2026-11-07T21:15:50.918+08:00 [2026-11-07 21:15:50] [FTP] CMD PASS admin
[RX] 2026-11-07T21:15:50.929+08:00 [2026-11-07 21:15:50] [FTP] CMD SIZE /WAVE/WAVE36.BIN
[RX] 2026-11-07T21:15:50.929+08:00 [2026-11-07 21:15:50] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:50.929+08:00 [2026-11-07 21:15:50] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:50.929+08:00 [2026-11-07 21:15:50][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:15:50.939+08:00 [2026-11-07 21:15:50] [FTP] waiting for connection...
[RX] 2026-11-07T21:15:50.971+08:00 [2026-11-07 21:15:50] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -416,12 +416,12 @@
[RX] 2026-11-07T21:15:51.470+08:00 [2026-11-07 21:15:50] [FTP] CMD USER admin
[RX] 2026-11-07T21:15:51.470+08:00 [2026-11-07 21:15:50] [FTP] CMD PASS admin
[RX] 2026-11-07T21:15:51.470+08:00 [2026-11-07 21:15:50] [FTP] CMD TYPE I
[RX] 2026-11-07T21:15:51.480+08:00 [2026-11-07 21:15:50] [FTP] CMD PASV
[RX] 2026-11-07T21:15:51.480+08:00 [2026-11-07 21:15:50] [FTP] CMD PASV
[RX] 2026-11-07T21:15:51.532+08:00 [2026-11-07 21:15:50][NET] sock3 standalone accept
[RX] 2026-11-07T21:15:51.594+08:00 [2026-11-07 21:15:50] [FTP] CMD RETR /WAVE/WAVE36.BIN
[RX] 2026-11-07T21:15:51.604+08:00 [2026-11-07 21:15:50] [WAVE][WARN] seg held 62 ms (idx=44)
[RX] 2026-11-07T21:15:51.781+08:00 [2026-11-07 21:15:51] [FTP] DOWNLOAD '/WAVE/WAVE36.BIN' OK
[RX] 2026-11-07T21:15:51.781+08:00 [2026-11-07 21:15:51] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:51.781+08:00 [2026-11-07 21:15:51] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:51.791+08:00 [2026-11-07 21:15:51][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:15:51.791+08:00 [2026-11-07 21:15:51] [FTP] waiting for connection...
[RX] 2026-11-07T21:15:51.822+08:00 [2026-11-07 21:15:51] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -433,16 +433,16 @@
[RX] 2026-11-07T21:15:52.323+08:00 [2026-11-07 21:15:51] [FTP] CMD PASS admin
[RX] 2026-11-07T21:15:52.333+08:00 [2026-11-07 21:15:51] [FTP] CMD CWD /WAVE
[RX] 2026-11-07T21:15:52.333+08:00 [2026-11-07 21:15:51] [FTP] CMD TYPE A
[RX] 2026-11-07T21:15:52.333+08:00 [2026-11-07 21:15:51] [FTP] CMD PASV
[RX] 2026-11-07T21:15:52.333+08:00 [2026-11-07 21:15:51] [FTP] CMD PASV
[RX] 2026-11-07T21:15:52.385+08:00 [2026-11-07 21:15:51][NET] sock3 standalone accept
[RX] 2026-11-07T21:15:52.406+08:00 [2026-11-07 21:15:51] [FTP] CMD LIST
[RX] 2026-11-07T21:15:52.406+08:00 [2026-11-07 21:15:51] [FTP] CMD LIST
[RX] 2026-11-07T21:15:52.582+08:00 [2026-11-07 21:15:51] [FTP] CMD CWD /
[RX] 2026-11-07T21:15:52.582+08:00 [2026-11-07 21:15:51] [FTP] CMD TYPE A
[RX] 2026-11-07T21:15:52.593+08:00 [2026-11-07 21:15:51] [FTP] CMD PASV
[RX] 2026-11-07T21:15:52.593+08:00 [2026-11-07 21:15:51] [FTP] CMD PASV
[RX] 2026-11-07T21:15:52.635+08:00 [2026-11-07 21:15:51][NET] sock3 standalone accept
[RX] 2026-11-07T21:15:52.635+08:00 MISS start snap=0x00000177 req=0x000001F7 t=120110
[RX] 2026-11-07T21:15:52.666+08:00 [2026-11-07 21:15:51] [FTP] CMD LIST
[RX] 2026-11-07T21:15:52.781+08:00 [2026-11-07 21:15:52] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:52.666+08:00 [2026-11-07 21:15:51] [FTP] CMD LIST
[RX] 2026-11-07T21:15:52.781+08:00 [2026-11-07 21:15:52] [FTP] CMD QUIT
[RX] 2026-11-07T21:15:52.791+08:00 [2026-11-07 21:15:52][NET] sock1 DISCONNECTED, releasing (chip st=0x05/0x00)
[RX] 2026-11-07T21:15:52.791+08:00 [2026-11-07 21:15:52] [FTP] waiting for connection...
[RX] 2026-11-07T21:15:52.823+08:00 [2026-11-07 21:15:52] sock1 relisten settle (sock=0x00 tcp=0x00)
@@ -256,4 +256,4 @@
"root": "226 Closing data connection."
},
"t_end": "2026-11-07T21:15:52.779+08:00"
}
}
@@ -767,4 +767,4 @@
},
"abort": "deadline without STOP line (window misbehaving?)",
"t_end": "2026-11-07T19:33:16.284+08:00"
}
}
@@ -238,7 +238,7 @@ D:/Code/DTU Code/
### 7.3 并行道与写范围规则(规划层 ↔ 执行层映射)
规划层(当前任务卡在 `docs/任务规划/UI补齐.md`,后续事项在 `docs/任务规划/登记簿.md`;
规划层(任务卡在 `docs/任务规划/登记簿.md §7`,其余待办在 `docs/任务规划/登记簿.md`);
五字段 = **DoD / 硬依赖 / 资源 / 写范围 / 状态**)
按**资源属性**把任务切进三条道,本方案(工作树 + 锁)是它的执行层:
+58 -4
View File
@@ -141,7 +141,7 @@ STM32(U17)为 LQFP144 脚号。
| TPAFE5160 量程档 | 板上 RANGE(U3 pin8)接 GND → **±5 V 双极性**(−5 ~ +5 V);RANGE = HIGH 的 ±10 V 档本板未用 | [`V0.0_网表详细分析报告.md`](V0.0_网表详细分析报告.md) §4.5 + [`../芯片手册/TPAFE5160.md`](../芯片手册/TPAFE5160.md) 输入量程表(RANGE = 0 → −5 ~ +5;RANGE = 1 → −10 ~ +10) |
| TPAFE 码值格式 | 16 位二进制补码(−32768 ~ +32767,全量程 65536 码 = 10 V 跨度) | 芯片手册 DC Accuracy(16 bit / NO missing code);`Drivers/BSP/TPAFE5160/tpafe5160.c` 的 `tpafe5160_to_voltage()` |
| TPAFE LSB(@ 引脚) | 10 V / 65536 ≈ **152.59 µV/码**(≈6553 码/V) | 由上两行推得;与 §7「TPAFE 量程」行一致 |
| STM32 ADC1 LSB(@ 引脚) | 12 位单极性 0 ~ 3.3 V:3.3 V / 4096 ≈ **805.66 µV/码**(≈1241 码/V) | §7 配置行;`docs/任务规划/数据可信.md` §2.1 同口径 |
| STM32 ADC1 LSB(@ 引脚) | 12 位单极性 0 ~ 3.3 V:3.3 V / 4096 ≈ **805.66 µV/码**(≈1241 码/V) | §7 配置行;`docs/算法/采集与算法层设计说明.md §13.1` 同口径 |
**③ 段(板内串联电阻那一节)实际接了什么**(UA 为例,按 [`V0.1.tel`](V0.1.tel) 逐通道追线;图由 `tools/arch_diagram/gen_adc_frontend_svg.py` 生成,改图请改脚本重跑,勿手改 SVG):
@@ -151,14 +151,14 @@ STM32(U17)为 LQFP144 脚号。
**口径要点**:
1. **ROM 默认系数按 ② 段(引脚电压 ↔ 码值)冻结**:TPAFE 通道 `k = 152.59 µV/码`、STM32 通道 `k = 805.66 µV/码`;标定折算的输出单位 = **ADC 引脚电压 V**(`eng = 0`)。该口径与 ③④ 变比何时定死无关,冻结当日即成立且此后不因 ④ 到手而改动——这是 M4 承诺边界止于"引脚电压"的依据(`docs/任务规划/数据可信.md` §2.6)。
1. **ROM 默认系数按 ② 段(引脚电压 ↔ 码值)冻结**:TPAFE 通道 `k = 152.59 µV/码`、STM32 通道 `k = 805.66 µV/码`;标定折算的输出单位 = **ADC 引脚电压 V**(`eng = 0`)。该口径与 ③④ 变比何时定死无关,冻结当日即成立且此后不因 ④ 到手而改动——这是 M4 承诺边界止于"引脚电压"的依据(`docs/算法/采集与算法层设计说明.md §13.5`)。
2. **板级系数 = 引脚侧系数**(152.59 / 805.66)。305.18 / 1611.3 µV/码 只属 ±10 V 档的 LSB(芯片手册口径),**不是本板系数**,不得当板级系数用。
3. **满量程必须写明参考点**:TPAFE 通道满量程 = ±5 V **@ 引脚**(跨度 10 V);③④ 均已定死(④ 值见 §7.2),端子侧换算允许写"引脚侧数值 × ④ 段变比";但两点标定置 `VALID` 之前**严禁**把"码 × 152.59 µV"当端子二次值写进代码/文档(那是引脚电压),§7.2 的标称系数只是算定值、不是已验证二次值。
4. **仍待实测的只有两点标定**(给端子域系数、置 `VALID`,`eng` 随之升 1);完成前 `eng` 保持 0、输出单位仍是 ADC 引脚电压。实测斜率与 ② 段理论值偏差 >2 % 时**先查前端**(分压/变比/焊接),**不得用系数凑错斜率**——那会把硬件的错固化成"标定值"。
### 7.2 ④ 段变比登记(2026-11-06 定死)
> **来源**:用户现场报的子板参数(2026-11-06,Issue #41),按 `docs/任务规划/数据可信.md` §7 #2 的路 ①「按图(参数)直接算」
> **来源**:用户现场报的子板参数(2026-11-06,Issue #41),按 `docs/算法/采集与算法层设计说明.md §13.12` #2 的路 ①「按图(参数)直接算」
> 算得;子板原理图仍不在仓库内,路 ②「万用表同时量端子与引脚」未做——数值上的理想化偏差与逐路差归两点标定
> (见本节末「复核口径」)。
@@ -205,7 +205,7 @@ STM32(U17)为 LQFP144 脚号。
- 下游机器面核对跟着在:两点标定的逐路实测系数吸收 ④ 段实际偏差;`App/algo/adc_cal.c` 合法带哨兵
(k ∉ ROM×[0.5, 2.0] → 回退 ROM)是「④ 数量级错了」的兜底。
- **本节标称系数是给「两点标定与精度验收」卡的输入,且带着两道存储口径题**(本卡不替它定案):
k 按 µV/码 int32 Q16 存储、上限 32767 µV/码(`docs/任务规划/数据可信.md` §4.1 的"远够"论断做在引脚域
k 按 µV/码 int32 Q16 存储、上限 32767 µV/码(`docs/算法/采集与算法层设计说明.md §13.2` 的"远够"论断做在引脚域
假设上)——电压族端子域标称已越上限(92.48 mV/码 ≈ 92479 µV/码,UB/UC 达 488.28 mV/码 ≈ 488278 µV/码),
电流族两档(4488 / 23696 µV 等效)尚在带内;且合法带基准读 ROM 出厂表(现为引脚域系数),端子域 k
会被 [0.5, 2.0] 哨兵顶回。标定写入端子域系数之前,存储单位(或每路标度因子)与出厂表基准须一并换血,
@@ -256,3 +256,57 @@ STM32(U17)为 LQFP144 脚号。
**IA 前端差分滤波 = 低通 fc ≈ 796 Hz**:C35 = 100 nF 跨接差分对,与 R19/R21 各 1 k([`V0.1.tel`](V0.1.tel):49)构成一阶低通;拓扑为 1 k 串联 + 1 k 接差分负端、不分压(`docs/产品需求/产品需求设计文档.md` FR-ADC-5)。**250 Hz 的 −4.4 % 就是这颗电容在该频点的真实衰减,板端读数忠实**,工频 50 Hz 仅 −0.2 % 不受影响。谐波测量不够用——同拓扑外推:5 次 ≈ −4.6 %(出 ±2 % 判据)、7 次 −8.5 %、9 次 −13.0 %、11 次 −17.7 %、13 次 −22.6 %、15 次 −27.2 %、21 次(1050 Hz)−39.6 %;C35 改 10 nF 则 fc ≈ 8 kHz、21 次仅 −0.9 %。**谐波功能产品化的硬件前置 = 板改小 C35 + 清点其余各路差分滤波电容容值**(登记 `docs/任务规划/登记簿.md` §3)。**为什么改板而不是软件逐阶修正**:修正系数依赖这颗电容的实际容值,而它有容差、随温度漂,每块板、每个温度都不一样,修正表跟不上;二次谐波制动这类“拿某次谐波幅值与基波比值”的判据,比值被前端畸变后判定就不可信。换 10 nF 后测量带内是平的,板端读数直接可信。证伪条件(有示波器再复核):该低通预测 250 Hz 差分分量额外滞后 ≈17°;模型与三点拟合 `docs/测试说明/测试数据/boot_log_data/20261104_ac_ia_rc_model.txt`。
**边界**:本节不证端子二次值(④ 段变比已算定、两点标定未做,`eng` 仍为 0,见 §7.2)/ 精度等级(要标准源)/ 跨转换器相位(V0.1 硬件缺陷)/ THD。
---
## 9. 数据可信的五个台阶与波次退出判据
这一节回答一件事:**这些数到底能信到什么程度,还差什么**。判据与实测逐条在 §8,设计口径与品质位语义在
`docs/算法/采集与算法层设计说明.md` §13。
### 9.1 五级台阶:现在踩在哪一级
图由 `tools/arch_diagram/gen_data_trust_ladder_svg.py` 生成(改图改脚本重跑,勿手改 SVG)。
![数据可信是五级台阶,现在踩在第 3 级](../images/数据可信台阶.svg)
每升一级只多答一个问题,台阶之间的高度差就是"下游能多信多少":
| 台阶 | 多答的问题 | 状态 |
|---|---|---|
| 1 通路活 | 9 路都在转换、没串道、极性没反? | ✅ 2026-10-27 已证 |
| 2 静态引脚电压 | 注 1 V 直流,读数是不是 1 V? | ✅ 2026-10-27 已证(六项判据全 PASS,§8.1) |
| **3 动态引脚波形** | **注 Vpp 2.828 V 正弦(板上读数 ≈1 V),算出来还是不是 1 V?** | **✅ 2026-11-02 / 11-04 已跑两轮、六轮全部闭合**(削顶 2 Hz 档与复位复核经用户裁定 2026-11-04 关闭;谐波 B 行超差已归因板端前端 RC fc≈796 Hz → §8.2;实测结论 §8.2) |
| 4 端子二次值 | 引脚上这 1 V 对应端子侧几 V? | 🟡 等子板原理图或实物(变比参数已算定,见 §7.2) |
| 5 精度等级验收 | 额定工况下整条链误差够几级? | 🟡 等标准源 |
**三条结论**:
1. **第 1、2 级已闭环**,证据在 §8.1,执行步骤属主是
`docs/测试说明/专项验证/ADC前端注入验证流程.md`。
2. **第 3 级已于 2026-11-02 / 11-04 台架闭环,全程没用到任何外部资源**:一台能出 50 Hz 正弦的交流信号发生器,
接在**已经验证过的那个注入点**上就行。它比第 4、5 级安全一个量级——只需 ±2 V 以内的正弦,
而端子级验证要上 100 V / 220 V 二次值。
3. **第 4、5 级在等外部**:④ 子板/端子板变比(仓库里没有原理图)与标准源两点标定,
两者完成前 `eng` 保持 0,本波只承诺"ADC 引脚电压"。两张待做任务卡见
`docs/任务规划/登记簿.md` §7。
### 9.2 波次退出判据与现状
**波次目标**:把"数"从原始码值推进到**有物理含义、有品质、有死区、能上送**的工程量。
| 退出判据 | 状态 | 证据 / 缺口 |
|---|---|---|
| ① 至少 1 路电压通道经已知电压注入验证,斜率与理论 LSB 偏差 ≤2 % | ✅ 2026-10-27 | UA 6544.2 vs 6553.6 码/V(−0.14 %),§8.1 |
| ② `adc_cal` 折算落地,采样环里是**引脚电压 V** 而非码值 | ✅ | `App/task/adc_task.c:425`(全仓唯一折算点) |
| ③ 8 通道系数 / 零点可落盘,加载失败回退 ROM 默认 | ✅ | `[adc_cal]` / `[adc_cal_ofs]`,口径 `docs/算法/采集与算法层设计说明.md` §13.8 |
| ④ 三处下游常数按工程量重定并注明依据 | ✅(有尾巴) | `docs/算法/采集与算法层设计说明.md` §13.7;幅值门在 `eng=0` 恒失效已记因于 `freq.h:58-60` |
| ⑤ "未标定 → 保护闭锁"生效 | 🟡 软件道 ✅;**"解锁"这半程要等 `VALID` 置位**才能上台架验 | `adc_cal_prot_blocked()` + `App/task/protect_task.c:268` |
| ⑥ 量纲回归用例(不该动作时不动作)通过 | ✅ | `test/host/prot_dim/`,口径 `docs/算法/采集与算法层设计说明.md` §13.6 |
**所以差的是"台架面",它分两半**:动态这半已于 2026-11-02 / 11-04 台架闭环(§8.2);
端子与精度那半要等子板与标准源(`docs/任务规划/登记簿.md` §7)。
遥测链(快照发布)与运行参数/点表均已达成,口径沉淀在 `App/algo/meas.h`、`App/algo/run_par.h`
头注释与 `docs/算法/采集与算法层设计说明.md` §13.9;其中"104 上送值与**工程量**一致"仍挂在
变比确认与两点标定上(注入验证只证到引脚电压口径)。
+264 -7
View File
@@ -5,8 +5,9 @@
> 边界与代价。**目录级索引(文件清单、构建与测试命令、新增模块动作)在 `App/algo/README.md`**,
> 本文不重复其内容;本文不写历史演进、门禁复测记录与修订日志(需要时查 git 历史)。
> **状态**:语义取数与有效性 → 全周傅氏相量 → 保护判据主线已闭环到板端消费者(`protectTask`,20 ms 判据节拍);
> 标定折算层 `App/algo/adc_cal` 已于 2026-10-25 落地(标定折算与落盘整定,`docs/任务规划/数据可信.md` §4.1,
> 引脚电压量纲 + 系数落盘 + 未标定闭锁);**幅值精度判据**仍待标准源两点注入复核(两点标定,`docs/任务规划/数据可信.md` §5)。
> 标定折算层 `App/algo/adc_cal` 已于 2026-10-25 落地(标定折算与落盘整定,§13.2,
> 引脚电压量纲 + 系数落盘 + 未标定闭锁);**幅值精度判据**仍待标准源两点注入复核(§13 状态段与
> `docs/任务规划/登记簿.md` §7)。
> **相关文档**:
> 分层与功能项(语义取数与有效性~动作留痕)的唯一属主登记处:`docs/算法/继电保护功能复现规划.md` §2.1(分层)、§3(功能清单)、§4.2(精度)、§7(路线图)
> `docs/硬件平台/ADC通道映射说明.md`(**语义映射唯一权威口径**)
@@ -28,7 +29,8 @@
- [10. 关键约定与禁令](#10-关键约定与禁令)
- [11. 资源足迹(改容量前先看这里)](#11-资源足迹改容量前先看这里)
- [12. 验证与判读](#12-验证与判读)
- [13. 相关文档](#13-相关文档)
- [13. 标定折算:量纲、系数、闭锁与快照](#13-标定折算量纲系数闭锁与快照)
- [14. 相关文档](#14-相关文档)
---
@@ -414,9 +416,9 @@ UA 无幅值落 IA → 0.0020 Hz。
2. **禁止跨转换器运算**(V0.1 硬件缺陷**双转换器无共同采样触发**):`UA/UN/IA` 在 TPAFE、`UB/UC/IB/IC/IN` 在
STM32 ADC1,两片转换器没有共同采样触发 → 无同一时刻性、相位不确定。故本层**不做**跨转换器的
相位 / 功率 / 功率因数 / 负序零序类矢量运算;**8 路全接 TPAFE(V0.2 硬件)后方可解禁**。
3. **标定折算已落地、精度复核未做**(2026-10-25 `App/algo/adc_cal`;标准源两点注入见
`docs/任务规划/数据可信.md` §5(两点标定):帧值现 = 引脚侧工程量(ROM 默认系数 = 转换器 LSB 事实值),
前端分压读法判别与端子变比仍待台架——**精度结论前不得把幅值当计量证据**。
3. **标定折算已落地、精度复核未做**(2026-10-25 `App/algo/adc_cal`;两点标定与精度目标见
`docs/任务规划/登记簿.md` §7):帧值现 = 引脚侧工程量(ROM 默认系数 = 转换器 LSB 事实值),
前端分压读法判别与端子变比仍待台架——**精度结论前不得把幅值当计量证据**(§13)。
4. **本层无副作用外溢**:不建任务、不等事件、不写日志(日志由调用侧打)、不碰寄存器
(例外只有 `adc_input.c` 驱动 ADC1)。
5. **上下文纪律**:内核启动前只允许调 `*_init()`;`adc_input_poll()` / `phasor_run()` /
@@ -516,7 +518,262 @@ adcTask 静态最坏链与余量的**台账在** `docs/内存管理/RAM使用分
---
## 13. 相关文档
## 13. 标定折算:量纲、系数、闭锁与快照
这一节回答四个问题:**码值怎么变成工程量、什么时候算"可测"、未标定时下游怎么被挡住、
104 与 UI 拿到的数从哪来一份**。它是 `App/algo/adc_cal.*`、`meas.*`、`App/cfg/cfg_file.*`、
`App/task/protect_task.c`、`Drivers/BSP/UI/ui_data*` 这些模块头注释里引用的口径出处。
**当前状态**:折算链已落地,量纲停在 **ADC 引脚电压 V**(`eng = 0`);保护判据因此处于
**未标定闭锁**态(§13.3)。精度、端子二次值都在等外部资源(子板变比、标准源)。
### 13.1 通道量纲与折算点
| 语义通道 | 转换器 | 码值格式 | LSB(@ 引脚) | 前端 | ROM 默认系数(@ 引脚) | 交流可用性 |
|---|---|---|---|---|---|---|
| UA | TPAFE5160 | 16 位双极性 ±5 V | 152.59 µV | 1k 串 + 滤波 C(串阻不分压) | **152.59 µV/码** | ✅ 可用 |
| UN | TPAFE5160 | 同上 | 152.59 µV | 同上 | **152.59 µV/码** | ✅ 可用 |
| IA | TPAFE5160 | 同上 | 152.59 µV | 同上 | **152.59 µV/码** | ✅ 可用(缺 A/V 变比) |
| UB / UC | STM32 ADC1 | 12 位单极性 0~3.3 V | 805.66 µV | 同上 | **805.66 µV/码** | ❌ 削顶(无中点偏置) |
| IB / IC / IN | STM32 ADC1 | 同上 | 805.66 µV | 同上 | **805.66 µV/码** | ❌ 削顶 |
| TEMP | STM32 ADC1 | 同上 | 805.66 µV | 同上 | 热敏非线性 | — 不纳入线性标定 |
- 通道数 `ADC_SEM_COUNT = 9`(8 电气 + 温度),枚举定义 `App/algo/adc_input.h:38-49`(`adc_semantic_t`)。
- **唯一折算点**:`App/task/adc_task.c:425` 的 `frame[s] = adc_cal_apply((adc_semantic_t)s, code)`——
全仓只有这一处把码值变成工程量,现单位 = **ADC 引脚电压 V**(`eng = 0`)。
- 端到端链路分四段(① 语义↔网名↔通道、② 引脚电压↔码值、③ `AINn` ↔ 引脚、④ 端子 ↔ `AINn`),
属主 `docs/硬件平台/ADC通道映射说明.md` §7.1:①②③ 已定死(③ 串阻不分压、比值 1:1),**只有 ④ 是缺口**。
### 13.2 折算模型:板级事实进 ROM,现场标定进 cfg
```
工程量[V 或 A] = (code + b) × k_f
k_f = k[µV/码] × 1e-6 (float,init/load 时算一次)
```
| 符号 | 含义 | 存哪 | 定标 |
|---|---|---|---|
| `k` | µV/码(通道灵敏度) | cfg 段,int32 **Q16**(µV/码 × 65536) | 默认 = 板级理论系数(§13.1 表) |
| `b` | 零点偏移(码值) | cfg 段,int32 | 默认 0 |
| `k_f` | V/码(运行时) | RAM,`adc_cal_init/load` 时由 `k` 派生 | 不落盘 |
- **为什么存 µV 而不是 V/码**:`k` 在 V/码 量级是 3×10⁻⁴,Q16 只有 20 个刻度(5 % 分辨率);
换成 µV/码是 305,Q16 有 2000 万个刻度。
- **为什么 Q16 而不是参考项目的 Q10**:TPAFE 通道 Q10 只能表达 312(+0.16 %),Q16 误差 < 0.001 %;
两者都占 4 字节,Q16 把"系数定点舍入"这一项从误差预算里直接抹掉。参考项目用 2^10 是因为定点 DSP
乘法成本,本机有 FPU、运行时本来就是 float。int32 上限可表达 32767 µV/码,远够。
- **运行时不走定点**:`k` 预乘成 `float k_f`,逐点只做一次浮点乘——1 kHz × 9 通道 = 9k 次/秒,可忽略。
- **系数合法带**:`adc_cal_set()` / `adc_cal_two_point()` 只接受落在板级 ROM 系数 ×[0.5, 2.0] 内的 `k`。
实测斜率与理论值偏差大时**先查前端**(分压 / 变比 / 焊接),不许用系数把硬件的错凑回来——
那等于把故障固化成"标定值"。零点越 ±`ADC_CAL_B_MAX` 同样直接拒绝(口径在 `App/algo/adc_cal.h`)。
### 13.3 三态可用性:标定 ≠ 可测
`k` 的默认值是**板级理论系数**,此时工程量单位是"ADC 引脚电压",不是二次值——还缺互感器/子板变比。
所以通道状态必须让消费者区分三档,不能把引脚电压当二次值用:
```c
#define ADC_CAL_F_VALID 0x01u /* 该通道 k 已按变比标定 → 工程量为二次值 */
#define ADC_CAL_F_CLIPPED 0x02u /* 硬件削顶(单极性无偏置)→ 交流量不可信 */
```
| 通道 | `VALID` | `CLIPPED` | 消费者应如何对待 |
|---|---|---|---|
| UA / UN / IA | 标定后置位 | 0 | 可用于保护、计量、上送 |
| UB / UC / IB / IC / IN | 永不置位(V0.2 硬件改版前) | **1,且是来源派生**(不是实测削顶,判据见 §13.5) | 只作码值监视;点表**已绑定**,靠品质位把 104 侧驱动成 IV、值清零 |
| TEMP | 0 | 0 | 不参与线性标定,页面显示 `--` |
`adc_cal_flags(sem)` 是三处(UI / 104 / 保护)唯一的可用性查询入口;`adc_cal_apply()` **不返回**可用性,
所以"只看系数不看 flags"这种用法在接口层就被堵掉(CLIPPED 通道恒报 IV 的单测见 `test/host/prot_dim/`)。
### 13.4 未标定即闭锁
保护判据拿"ADC 引脚电压"跟"二次值定值"比必然误动作,所以 `protect_task` 多一个闭锁源:
**UA / UN / IA 的 `VALID` 未全置位 → 判据停走**(实现在 `App/algo/adc_cal.c` 的
`adc_cal_prot_blocked()`,`App/task/protect_task.c:268` 消费并打 INFO + 记 SOE)。
- 与"自检失败 / 采样故障闭锁"同构(`PROT_HF_LOCK_MASK` 那一套),**不新增机制**。
- 台架 `/serial-boot-test` 的期望与未闭锁构建不同(判据已同步),这是有意为之。
- 台架调试要旁路只能走编译期开关 `DTU_BENCH`,不进 cfg、不进 104。
⚠ **`DTU_BENCH` 只旁路这一处**:它**不**旁路 §13.7 的测频幅值门,也不产生任何新的读数通道。
### 13.5 静态验证证到哪一步、按构造证不到什么
判据与实测记录的属主 = `docs/硬件平台/ADC通道映射说明.md` §8.1,执行步骤属主 =
`docs/测试说明/专项验证/ADC前端注入验证流程.md`。一块万用表 + 一个电位器 + 串口 `adc:` 心跳行就够,
**不需要**示波器、信号源、标准源;注入点在串联电阻的端子侧 `U5` 排针(不碰 LQFP 引脚)。
已知电压注入验证已于 2026-10-27 台架闭环,六项判据全 PASS ⇒ ③ 段(`AINn` ↔ 转换器引脚)
**串阻不分压、比值 = 1:1**(若存在 2:1 分压,斜率应约 3277)、`k_adc_map[]` 逐路对应、
TPAFE 补码符号位解释正确、§13.1 的 ROM 默认系数被实测支持。空载浮空读数(TPAFE ~11450 /
STM32 ~1000)是**上电瞬态 + 输入悬空**,不是零点,别拿首帧当零点用。
**这一轮证到的是"一条水平线的高度"**:给定直流电压 → 码值 → 折算,斜率、零点、线性度、极性、
通道对位、节拍全在 ±2 % 内。**直流信号在时间轴上没有形状**,所以相位、频率、波形相关性、真实削顶、谐波
这五类**按构造**不在本节证据范围内——动态那半由正弦注入单独证,结论在
`docs/硬件平台/ADC通道映射说明.md` §8.2。另有两项**本轮未覆盖**:
串扰(零点步骤时其余七路浮空本身在漂)与"注入进行中"的节奏(只测了注入前后)。
**一个必须记住的区分**:`CLIPPED` 位是**来源派生**(`App/algo/adc_cal.c:291-293`:系数来自 STM32 就置位,
V0.1 恒命中 UB/UC/IB/IC/IN,位图 `0xE6`),它表示"这路不能测交流",**不等于**"这路此刻正在削顶"。真削顶的签名是
`cal:` 行的 `rail=` 位图与 `rail: edge=…` 那行 `[ERR]`——这条路径至今只在直流饱和里起过(判据见
`docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.5 削顶卡)。
> **承诺边界**:只到 **ADC 引脚电压**(`eng = 0`)。"端子二次值"要等子板变比确认、
> 标准源两点标定写入 `[adc_cal]` 并置 `VALID`;`eng` 升 1 的条件是电气 8 路 VALID **全置位**
> (`App/app/ui_data_feed.c` 的 `feed_eng()`)。两张待做任务卡见
> `docs/任务规划/登记簿.md` §7。
**动态验证已跑两轮(2026-11-02 / 11-04),六轮全部闭合**——幅值 / 波形 / 相位 / 测频 / 谐波 /
削顶直流档都过了;实测数与逐轮结论只详述在 `docs/硬件平台/ADC通道映射说明.md` §8.2,本节不抄第二份。
下游逐项"现在能不能信":
| 下游 | 现在 | 为什么 |
|---|---|---|
| 基波有效值 | ✅ 过(±2 % 内,三档幅值两点复现) | 台架幅值轮 + 波形轮(基波分量口径)实证;**端子二次值仍不归这一档**——从引脚到端子还隔着 ④ 段变比 |
| 相位 | ✅ 同片内过(录波档 ≤2° 判据) | 同段 UA/UN 两路实测(0° 与 90° 两工况);**跨转换器仍禁比**——两片转换器无共同采样触发,是 V0.1 硬件边界(`docs/硬件平台/ADC通道映射说明.md` §7 通道归属行),不是待修缺陷 |
| 频率 | ✅ 「如实报不可测」成立(这就是现状判据) | 含满幅注入段全不可测、UI 恒 `--`;**45~55 Hz 精度仍未验**——要验须降 `FREQ_AMP_MIN` 单跑一轮 |
| 削顶 / 品质 | ✅ DC −1.00 V 档锁存 + sticky 实证;2.0 Hz 低频档与复位复核经用户裁定 2026-11-04 关闭 | `[ERR] rail: edge=0x2 sticky=0x2` 唯一一条、撤注恒持 |
| 谐波 C04 / C05 | 🟡 选择性轨已证(单注 100/250 Hz 分别只进对应桶、纯基波两桶为 0);**仍无消费者、无处上送** | 250 Hz→`Ia5` 行 −4.4 % **已按板端前端真实衰减关闭(2026-11-04)**:IA 前端差分滤波 C35 = 100 nF + R19/R21 各 1 k 构成一阶低通 fc ≈ 796 Hz,板端读数忠实、工频不受影响;谐波产品化需板改(模型与数据 `docs/硬件平台/ADC通道映射说明.md` §8.2);这两根轨归谁用,见 `docs/算法/继电保护功能复现规划.md` 的「遥测谐波轨(可选)」 |
| 保护判据 | 🔒 闭锁中 | §13.4 |
### 13.6 量纲错配与量纲回归
**没有一条判据检查"不该动作时不动作",台架就会一路"通过"**:"码值当工程量"的错配会让 OC
拿 ~11000 码值去比 10 A 定值 → **恒假动作**。这类错不是"测不准",而是**每次都跳**,且三处消费者
(判据、104、UI)一起错、一处都不报错。
固化它的回归 = `test/host/prot_dim/`:从 **ADC 码值**出发、**显式写出码值↔二次值换算**,走真实的
折算 → 采样环 → 全周傅氏 → 元件判据链;任何一环把量纲弄丢(例如折算点被旁路),断言立刻翻转
(TC-PROTDIM-002 就是反错配对照,专门复现那次事故)。它用的是**合成系数 10 mV/码**,
不是板上 152.59 / 805.66 µV/码——**它证的是"链条别丢量纲",不证"变比数值对不对"**(后者归
§13.5)。
| 量纲档 | 怎么进入这个档 | 现在的处置 |
|---|---|---|
| `eng = 0`(ADC 引脚电压 V) | `VALID` 未置位——**当前产品构建恒此态** | §13.4 闭锁停走整条判据链;UI 第 7 行显示"未标定"徽标 |
| `eng = 1`(二次值 V / A) | ④ 变比到手 **且** 电气 8 路 `adc_cal_flags()` 的 VALID 全置位(`App/app/ui_data_feed.c` 的 `feed_eng()`) | 定值与工程量同域,判据才名副其实 |
| 混档(最坏情况) | 只改折算系数、不改下游常数 | §13.7 那三处必须跟着动,这正是 §13.7 存在的理由 |
### 13.7 三个必须同步重定的下游常数
> 这节的意义是**"动一处量纲要同步三处"**,不是待办清单——三行现在两行已落地。
| # | 位置 | 现值与语义 | 状态 |
|---|---|---|---|
| 1 | `App/algo/freq.h:62` | `FREQ_AMP_MIN 50.0f`——测频幅值门,已按**二次值 V 口径**重定(50 V = 0.5×Un,与 `prot_set.c` 头部量纲基准同源) | ✅ 已重定;⚠ **副作用**:`eng=0` 期间帧值 ≤5 V < 50 V → 本门**恒不过** → `freq_valid()` 恒 0(`freq.h:58-60` 自陈)。这条直接决定测频轮怎么读、为什么那一轮的"过判据"是"如实报不可测" |
| 2 | `App/protocol/iec104/iec104_pts.c:69-80` | `k_yc[].deadband` 已按点重定:电压 0.5 V、电流 0.005 A、频率 0.5 Hz(真源在 `run_par`,UI 可改) | ✅ 已重定;④ 变比到手后需再复核一次量纲 |
| 3 | `App/algo/prot_set.c:25-70` | `g_prot_set_meta[]` 定值 = 二次值 A / V(基准 100 V / 1 A):OC1 10 A、OV 120 V、UV 20 V、3U0 15 V… | 🟡 口径对,但**标定前无法在板上验真**;精度目标定了之后连同 `min`/`max` 复核 |
### 13.8 落盘:拆两段,不碰引擎
`CFG_FILE_MAX_KEYS = 16`,8 通道 ×(k + b)= 16 正好顶格,将来加一个键就爆。故拆两段:
| 段名 | 键 | 字节 | 回调 |
|---|---|---|---|
| `[adc_cal]` | `k_ua` `k_un` `k_ia` `k_ub` `k_uc` `k_ib` `k_ic` `k_in` + `valid`(uint8 位图) | 8×4 + 1 = 33 | 不挂(RAM 副本即生效值) |
| `[adc_cal_ofs]` | `b_ua` … `b_in` | 8×4 = 32 | 不挂 |
段名 7 / 11 字符、键名 4 字符,均在 15 字符上限内;段数总计 5/8(含 `[run_par]` 9 键死区),未逼近上限。
- 系数唯一真源仍是这两段——104 写 k/b 经 `adc_cal_set()` 代理,`run_par` **不存第二份**;
落盘链走 `SYS_EVT_RUN_PAR_SAVE`(iec104Task peek 投递 → defaultTask 整档 save),`p_cb` 依旧未用。
谁写 RAM / 谁落盘 / 什么时机的完整链条见 §10.1。
- ⚠ **负零点**:零点偏移是带符号量,引擎只有 `CFG_VAL_UINT`(`strtoul` + 上界校验)时 −5 会落成
`4294967291`。所以 `[adc_cal_ofs]` 走 `CFG_VAL_INT`(定案口径见 §13.12)。
### 13.9 遥测快照:让 104 与 UI 共用一份上游
104 的 `s_src_yc_read()` 自己遍历相量、UI 也要一份 → 两处各自决定"什么时候算新值""品质怎么判",
迟早打架。故引入 `App/algo/meas.c`:每 **200 ms** 从相量使用区取一次,产出
```c
typedef struct {
uint32_t seq; /* 只增;消费者据此判断是否换帧 */
uint32_t tick_ms;
uint8_t valid; /* 整帧有效 */
uint8_t rsv[3];
float yc[9]; /* 工程量(二次值或 ADC 引脚电压,由 flags 决定) */
uint16_t qds[9]; /* 每点品质:IV / NT / OV / CLIPPED */
uint8_t freq_valid;
float freq_hz;
} meas_snap_t; /* 72 B,双区共 ≈144 B;改字段 = 改协议,须同步 104 与 UI */
```
- **发布者 = `adc_task`**,在 `phasor_run()` / `freq_run()` 之后按 200 ms 分频发布;生产者在自己上下文里
发布,消费者不组装、不判断新旧。全仓 `meas_tick()` **调用点数 = 1** 是评审判据。
- **跨任务读沿用 `phasor` 的双区原子交换**(写侧填非使用区、末尾翻单字节索引;读侧先取索引再整体拷),
**不是新机制**、不引入锁。
- 104 与 UI 都读这份快照 → **同一份数据、两个消费者**;104 侧值与品质整体透传,不做本地判断。
- **200 ms 是上送节拍,不是平均窗**:相量本身已是 1 ms 刷新的基波有效值,再平均只会引入滞后。
⚠ 这条在动态验证里有个可读的后果:注入非整 50 Hz 的正弦时,快照轨会呈现拍频式跳动,**属预期**。
### 13.10 动态波形验证的判据(六轮)
图由 `tools/arch_diagram/gen_data_trust_dc_ac_svg.py` 生成(改图改脚本重跑,勿手改 SVG)。
![上排直流静态标定、下排交流正弦验证:同一个注入点、同一套前端,两种证法](../images/ADC直流标定与交流验证.svg)
**这一轮证的是功能性**(算得对不对、品质报得实不实、节拍稳不稳),**不是计量**(误差几级)——
发生器不当"标准":判据基准一律取万用表 AC 档,发生器只要求"波形干净、幅度稳定、频率能锁
50.000 Hz",不拿它的刻度当精度。
**注入幅度一律按峰峰值 Vpp 设定(用户裁定 2026-11-04)**:发生器面板的有效值显示不当设定基准
(同一个 Vpp 换波形后有效值显示跟着变,切波形瞬间还残留上一波形的值);万用表 AC 档与板上读数
天然是有效值刻度,正弦下 有效值 = Vpp ÷ 2.828,换算着比。
**范围与幅度上限**:
| 边界 | 口径 |
|---|---|
| 注入点 | `docs/测试说明/专项验证/ADC前端注入验证流程.md` §3 的注入点清单(串联电阻端子侧 = `U5` 排针);③ 段 1:1 已拿到台架证据(§13.5) |
| 不知道 ④ 变比也能验 | 注入点在 ④ **之前**,发生器给的电压就是引脚电压,这一轮要证的正是"引脚域里算得对不对" |
| 幅度上限 | ±2 V 以内的正弦(TPAFE 侧判据上限);端子二次值验证要上 100 V / 220 V,风险与设备都在那一级 |
| 读数的地方 | 串口心跳,零固件改动 |
**分工**:本节定"验什么、过判据是多少";**期望值的算术、接法细节与执行步骤**在
`docs/测试说明/专项验证/ADC前端注入验证流程.md` §8。
| 轮次 | 验什么 | 接法 | 读哪 | 过判据 |
|---|---|---|---|---|
| **幅值轮** | 基波幅值计量 | UA(R31 / `AIN1`)注 Vpp 2.828 V(= 峰值 ±1.414 V)、50.000 Hz 正弦 | `meas:` 的 `ua_mv` | 读数 = 万用表 AC 档读数,偏差 ≤2 %(与静态同档)。⚠ 别用 `phasor(hb)` 行比幅值——那是 ×0.1 定点,注 1 V 只剩 10 格 |
| **波形轮** | 读数是否只跟基波走 | 同幅值改方波、三角 | 同上 | 期望值 = **基波分量有效值**(同峰值下的基波 / 峰值比:方波 ≈ **0.90**,闭式 4/π ÷ √2 = 0.900、20 点整周期 DFT 实算 0.904;三角 ≈ **0.573**,闭式 8/π² ÷ √2 = 0.573、实算 0.578),**不是**真有效值(方波 = 1.000、三角 = 0.583 峰值);偏差 ≤2 %。算术与逐波形对照表见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.5 的波形卡。顺带把"这台仪表读的是基波"这条口径钉进文档——用户拿真有效值表去对会以为差了 10 % |
| **相位轮** | 相位 | UA 与 UN 两路**同片**(都走 TPAFE)注同幅、同相 | **录波档**:录波段文件 `test/host/wave_read.py fft`(浮点重算基波相位;段内表序 `UA` = 0、`UN` = 3);**心跳档**:`phasor(hb)` 各行 `Re=` / `Im=` | **录波档**:同段内两路相位差 ≤2°,把发生器相位改 90° 后差值跟到 ≈90°。**心跳档只判"跟随"**(差值落进 80°~100°)——`phasor` 串口行是 ×0.1 定点,Vpp 2.828 V(板上读数 ≈1000 mV)时每格 0.1 V,角度量化最坏 ≈ atan(0.1 / 0.707) ≈ 8°,判不动 2°。⚠ 段与发生器**无绝对相位锁定**(触发瞬间钉在段内点 159),只能比**同段内两路**的相对差,跨段比相位或拿发生器相位当绝对基准都不成立。**只许比同片内**——跨转换器两片没有共同采样触发,比相位无意义(见 `docs/硬件平台/ADC通道映射说明.md` §7 通道归属行),STM32 那五路还有 1 拍乒乓滞后 |
| **测频轮** | 测频 | 同幅值轮的 Vpp 2.828 V / 50 Hz | `freq(hb):` | **预期就是"不出数"**(幅值门 50 V 在引脚域恒不过,§13.7 #1)→ 这条的判据是"如实报不可测"(`freq_valid=0`、UI `Hz` 显示 `--`),**不是**报出一个错误的 50.00。想真验 45~55 Hz 精度(PC 侧判据 0.02 Hz)须临时把 `FREQ_AMP_MIN` 降到引脚域量级(如 0.5 V)单跑一轮(动产品头文件,跑完必须还原并重跑 `/keil-build`) |
| **削顶轮** | 削顶与品质路由(**负向用例**) | 给 UB(R52 / `AIN2`)注 **DC −1.00 V 并保持 ≥5 s**;或 Vpp 2.828 V 而频率 **2.0 Hz** 的正弦——两档都能造出"连续贴同一侧轨带"。⚠ **注 50 Hz 同幅正弦造不出锁存,且这是预期而非故障**:1 kHz 下一个周波只 20 点、正半周必落中带,而 `adc_health_rail_watch()` 任何一拍回中带就把计数清零(`App/algo/adc_health.c`),连续贴底最长 ≈ 209/360 × 20 ≈ 11 拍 < 20。TPAFE 侧在 ±2 V 判据上限内造不出这条(轨带 ±32112 码 ≈ ±4.9 V),只有 STM32 那五路能做 | `cal:` 行的 `rail=` / `edge=`;`rail: edge=…` 的 `[ERR]` 行;录波档另加 `wave_read.py shape` 的三把尺子(`--strict` / 再加 `--clip-superset` / 不带),逐条配法见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.5 的削顶卡 | 负半周钉下轨 → **连续 20 拍同侧后该路贴轨位锁存**(`ADC_RAIL_N_RUN = 20`,`App/algo/adc_health.h:174`)、`edge` 起沿。锁存另有**释放沿前提**:该通道此前须出现过中带样本 → **先上电见基线摆动、再开发生器输出**,开机就注会测出假不通过。撤掉注入后 `rail` 仍非 0 是 sticky 语义(只有 `adc_health_rail_init()` / 复位清)——**复位后仍不清才是 bug**。⚠ 这条会**故意造出 `[ERR]`**,而 `/serial-boot-test` 的 forbidden 标记含 `[ERR]` → 人工判读、排在最后单独一轮,且这一轮的结论不按 `/serial-boot-test` 判 |
| **谐波轮** | 谐波轨 | 基波 + 20 % 二次 + 20 % 五次(IA 上注)。⚠ 峰值预算:Vpp 2.828 V 基波 + 两个 20 % 分量的最坏对齐峰值 ≈ 1.98 V 已顶 ±2 V 红线 → 基波用 **Vpp 2.263 V**、二次与五次各 Vpp 0.453 V | **录波档**:段文件 `test/host/wave_read.py fft --ch 4 --all`(`IA` = 段内表序 4,直接给基波与 2 / 5 次谐波有效值,单位 mV);**旁证**:UI 交流量页 `Ia2` / `Ia5`(1 mV)与 `phasor(hb) C04-IA-F2` / `C05-IA-F5`(×0.1 定点,只证这根轨不是恒 0) | 谐波轨读数 = 注入分量(**±2 %,走录波档**;心跳档判不动:读数 0.160 V 在 ×0.1 串口行上只有 1~2 格)。⚠ 这两根轨**目前没有任何下游消费者**(`prot_elm.c` 无引用、`meas` 只算 `harm=1`),所以谐波轮只证"算得对",**不证"有人用"**——接到哪、给谁用,归 `docs/算法/继电保护功能复现规划.md` 的「遥测谐波轨(可选)」 |
### 13.11 数字能从哪儿读(零固件改动)
| 读数的地方 | 有什么 | 坑 |
|---|---|---|
| 串口每 10 s 心跳(`App/task/adc_task.c` 心跳块) | `adc:`(9 路码值)、`cal:`(三路 mV + `vl`/`cl`/`rail`/`edge` 位图)、`phasor(hb)`(逐实例 `Re` / `Im` / `rms`)、`freq(hb)`、`meas:`(快照轨) | MicroLIB 无 `%f`,全是定点:`phasor` ×0.1(**1 V 注入只剩 10 格**)、`freq` ×0.01 Hz、`cal:` / `meas:` ×1000(1 mV)。10 s 一行的单点瞬时值对 50 Hz 等价于随机相位抽样 |
| UI 交流量页 | `Ua` / `U0` / `Ia` / `Ia2` / `Ia5` / `Hz` / 标定徽标 共 7 行 | 160×160 单色;`--` **同时**表示"没数"和"有数但不可信" → 不能当判据,只能当旁证 |
| **段文件(原始样本)** | 每次触发一段:`/wave/WAVE00.BIN` 起共 100 个号轮转(FTP 根下可见),8 路 × 320 点原始码值加封存瞬间的标定与品质快照;PC 侧 `test/host/wave_read.py` 提供 dump / fft / shape / plot 四个子命令(bench 工具,纯标准库,自带 `--selftest`) | 判据是「PC 独立重算 vs 板上读数」对表(执行步骤见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §4,格式属主见 `docs/子系统设计/故障录波设计说明.md` §6.2 与 §6.3)。**板级注入对表已随交流六轮跑过两轮**(2026-11-02 / 11-04,注 Vpp 2.828 V / 50 Hz、fft 与 `meas:` 互合,结论 `docs/硬件平台/ADC通道映射说明.md` §8.2;CRC 不符必须拒收的判据也在 2026-10-31 远程半轮验过),余下板级判据(周波数 / 极性等逐项)见 `docs/子系统设计/故障录波设计说明.md` §10;示波器只作旁证、不当判据。段内点序:触发瞬间落在段内点 159(预触发 160 点的最后一点),段的绝对相位与发生器无锁定关系,可核对的是相对相位与极性 |
| **没有的** | 没有命令控制台,也没有「把窗里 20 / 40 个点导出来」的定点 dump 子命令——原始样本走上一行的段文件(一次 320 点 / 8 路) | 现场取回一律走现成 FTP(21 端口),形状就地看回放页单通道、或在 PC 侧用同一脚本出图 |
---
### 13.12 已定案的前置决策(改这些之前先看这里)
标定与快照这条链上,有几处当时按备选拍过板。它们现在不是"待选方案",是已经定下来的设计;要改先改这一节。
| 决策 | 定成了什么 | 为什么 |
|---|---|---|
| 未标定时的保护判据 | **整条判据链停走**(`adc_cal_prot_blocked()` 单点判定),不做"用引脚电压近似跑" | `eng=0` 域是 ADC 引脚电压,拿去比二次值定值必然错判,UV 尤甚 |
| 台架怎么绕过闭锁 | **只认编译期 `-DDTU_BENCH`**,产品工程档一律不定义 | 让每个调用方自己写 `#ifndef` 会出现"有人只给单个 TU 加宏"→ 屏上徽标与判据停走当场分叉,且 0 错误 0 警告 |
| 零点负值怎么存 | 配置引擎**新增 `CFG_VAL_INT`**(有符号十进制、小端补码),而不是把零点整体偏置成正数再回读时减法还原 | 偏置方案要在每个读点都记得减,漏一处就是静默错值;INT 类型是一次性成本 |
| 系数落盘用什么单位 | **µV/码的 Q16 定点**,不存 V/码 浮点 | Q16 只剩 20 个刻度,V/码 直存会把有效位丢掉 |
| 系数的合法带 | 只接受板级 ROM 系数的 **×[0.5, 2.0]** | 超带说明前端错了,应该去查硬件而不是用系数凑 |
| 遥测快照的字段布局 | 由协议侧定、单测按偏移钉死(72 B × 双区) | 布局漂移只能靠"读侧按名字取"掩盖,抓不到真正的错位 |
| 非交流量(TEMP) | **不参与线性标定**,`qds` 恒置 `NT`;也不进录波 | 温度是片内 12 位单极性原始值、非线性;进录波只多占 640 字节,还会让回放页多一格被误读成电气量 |
| 快照的并发读 | **双区 + 指针原子交换**,读侧无锁 | 加锁会把读侧拖进临界区,而快照是 200 ms 一次的发布、读侧是 104 与 UI 两个消费者 |
| 快照由谁发布 | **`adcTask` 唯一发布者**,消费者各自计时组装被否 | 两个消费者各算一遍就成了两份真相源;评审判据 = 全仓 `meas_tick()` 调用点数 == 1 |
| `meas` 的时间口径 | **200 ms 是上送节拍,不是平均窗** | 平均窗会引入滞后,保护判据不能吃这个滞后 |
新增决策照上表格式往下加:一行一个问题、一行定成了什么、一行为什么。
## 14. 相关文档
- 目录索引与构建 / 测试入口:`App/algo/README.md`
- 「采样有效性校验」判定层深设计(判据推导 / 盲区 / 验证分工):`docs/算法/采样有效性校验设计说明.md`
@@ -283,7 +283,7 @@
这四项合起来是**一次完整的"测量子系统"立项**,建议按一个波次做,因为它们共享同一批参数与同一条数据通路;拆开做会互相返工。
> **已立项(2026-10-23)**:本阶段 = **「数据可信」**,任务卡、事实基线与验收判据见
> `docs/任务规划/数据可信.md`。排序已由 `docs/任务规划/README.md` §2 接管,本文只保留成因分析。
> `docs/算法/采集与算法层设计说明.md §13`。排序已由 `docs/任务规划/README.md` §2 接管,本文只保留成因分析。
### 阶段二:精度与安全网