From ae09c5737a0bc56cddc469fc2ca0afe78e6cbd74 Mon Sep 17 00:00:00 2001 From: Wanderingss <1624155937@qq.com> Date: Mon, 9 Nov 2026 16:10:55 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=88=A0=E4=BB=BB=E5=8A=A1=E8=A7=84?= =?UTF-8?q?=E5=88=92=E4=B8=A4=E4=BB=BD=E5=B7=B2=E5=AE=8C=E6=88=90=E6=96=87?= =?UTF-8?q?=E6=A1=A3=EF=BC=8C=E6=95=B0=E6=8D=AE=E5=8F=AF=E4=BF=A1=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E8=BF=81=E5=85=A5=E7=AE=97=E6=B3=95=E5=B1=82/?= =?UTF-8?q?=E7=A1=AC=E4=BB=B6=E5=B9=B3=E5=8F=B0/=E7=99=BB=E8=AE=B0?= =?UTF-8?q?=E7=B0=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 任务规划目录从 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。 --- .dsh/skills/draw-diagram/SKILL.md | 2 +- .../reference/steps-chinese-prefix-family.md | 2 +- App/algo/README.md | 16 +- App/algo/adc_cal.c | 16 +- App/algo/adc_cal.h | 16 +- App/algo/freq.h | 3 +- App/algo/meas.c | 8 +- App/algo/meas.h | 16 +- App/algo/prot_set.c | 2 +- App/algo/run_par.c | 2 +- App/algo/run_par.h | 2 +- App/algo/wave_ring.h | 2 +- App/algo/wave_store.h | 2 +- App/app/ui_data_feed.c | 6 +- App/cfg/cfg_file.c | 2 +- App/cfg/cfg_file.h | 2 +- App/log/sys_log.h | 4 +- App/log/sys_log_mcu.c | 4 +- App/protocol/iec104/iec104_comm.h | 2 +- App/protocol/iec104/iec104_pts.c | 10 +- App/protocol/iec104/iec104_pts.h | 2 +- App/task/adc_task.c | 4 +- App/task/protect_task.c | 6 +- Drivers/BSP/UI/ui_data.h | 12 +- Drivers/BSP/UI/ui_page_calib.c | 6 +- Drivers/BSP/UI/ui_page_clear.c | 4 +- Drivers/BSP/UI/ui_page_clear.h | 2 +- Drivers/BSP/UI/ui_page_clock.c | 4 +- Drivers/BSP/UI/ui_page_clock.h | 2 +- Drivers/BSP/UI/ui_page_comm.c | 6 +- Drivers/BSP/UI/ui_page_deadband.c | 6 +- Drivers/BSP/UI/ui_page_reset.c | 4 +- Drivers/BSP/UI/ui_page_reset.h | 2 +- Drivers/BSP/UI/ui_page_runreport.c | 2 +- Drivers/BSP/UI/ui_page_wave_manual.c | 3 +- Drivers/BSP/UI/ui_w_setlist.h | 2 +- Drivers/BSP/UI/ui_w_setview.h | 4 +- Drivers/BSP/UI/ui_w_ytview.h | 4 +- docs/README.md | 8 +- docs/UI设计/UI_数据供给设计说明.md | 6 +- docs/UI设计/内容页架构.md | 8 + docs/UI设计/菜单页面设计.md | 17 + docs/UI设计/页面扩充详细方案.md | 2 +- docs/UI设计/页面补齐规划.md | 4 +- docs/images/交流定数取中位数.svg | 2 +- docs/产品需求/产品需求设计文档.md | 10 +- docs/任务规划/README.md | 50 ++- docs/任务规划/UI补齐.md | 122 ------ docs/任务规划/数据可信.md | 353 ------------------ docs/任务规划/登记簿.md | 25 +- docs/子系统设计/IEC104上行设计说明.md | 2 +- docs/子系统设计/故障录波设计说明.md | 30 +- docs/子系统设计/网络配置说明.md | 4 +- docs/测试说明/专项验证/ADC前端注入验证流程.md | 28 +- .../专项验证/故障录波板级到场轮执行手册.md | 4 +- .../20261012_B6_iec104_roundtrip_log.txt | Bin 9007 -> 4412 bytes ...261012_B6_iec104_roundtrip_pre-fix_log.txt | Bin 8143 -> 3988 bytes .../20261012_B9_iec104_soe_post_log.txt | Bin 9163 -> 4500 bytes .../20261012_B9_iec104_soe_pre_log.txt | Bin 12727 -> 6248 bytes .../20261012_B9_prod_boot_log.txt | Bin 6855 -> 3365 bytes .../20261012_B9_soe_decode_post.txt | Bin 9521 -> 4700 bytes .../20261012_B9_soe_decode_pre.txt | Bin 7861 -> 3880 bytes .../wave_bench_20261107/build_log_tails.txt | 16 +- .../final_wave_listing.txt | Bin 522 -> 255 bytes .../测试数据/wave_bench_20261107/phase1.json | 2 +- .../serial_excerpt_sweep7_window.txt | 48 +-- .../wave_bench_20261107/sweep7_211352.json | 2 +- .../wave_bench_20261107/sweep_1794051196.json | 2 +- .../wave_fix_20261107/boot_new3_stdout.txt | Bin 7351 -> 3612 bytes docs/环境与部署/并行任务工作树方案.md | 2 +- docs/硬件平台/ADC通道映射说明.md | 62 ++- docs/算法/采集与算法层设计说明.md | 271 +++++++++++++- docs/问题记录/采集与数据处理短板评测.md | 2 +- scripts/archive/id_gate/编号治理历史.md | 26 +- scripts/ram_baseline.tsv | 1 + scripts/size_attestation.json | 24 +- simulator/main.c | 4 +- test/host/adc_cal/adc_cal_test.c | 2 +- test/host/adc_cal/run_unit_test.py | 4 +- test/host/meas/meas_test.c | 2 +- test/host/meas/run_unit_test.py | 4 +- test/host/prot_dim/prot_dim_test.c | 2 +- test/host/prot_dim/run_unit_test.py | 4 +- test/host/run_par/run_unit_test.py | 2 +- tools/arch_diagram/README.md | 4 +- tools/arch_diagram/gen_ac_median_svg.py | 2 +- tools/arch_diagram/gen_ac_rounds_svg.py | 2 +- 87 files changed, 613 insertions(+), 746 deletions(-) delete mode 100644 docs/任务规划/UI补齐.md delete mode 100644 docs/任务规划/数据可信.md diff --git a/.dsh/skills/draw-diagram/SKILL.md b/.dsh/skills/draw-diagram/SKILL.md index ea5c716b..560db380 100644 --- a/.dsh/skills/draw-diagram/SKILL.md +++ b/.dsh/skills/draw-diagram/SKILL.md @@ -152,7 +152,7 @@ console.log(r.image.width + "x" + r.image.height, "bytes=" + r.image.bytes); / ## 四、md 引用(相对路径) -`docs/` 根的 md:`![标题](images/xxx.svg)`;`docs/任务规划/`、`docs/UI设计/` 等子目录 md:`![…](../images/xxx.svg)`(本窗实例:`docs/任务规划/数据可信.md` 写 `![数据可信是五级台阶,现在踩在第 2 级](../images/数据可信台阶.svg)`)。alt 文本写成"这张图的结论是什么",别只重复文件名。 +`docs/` 根的 md:`![标题](images/xxx.svg)`;`docs/任务规划/`、`docs/UI设计/` 等子目录 md:`![…](../images/xxx.svg)`(本窗实例:`docs/硬件平台/ADC通道映射说明.md` §9.1 写 `![数据可信是五级台阶,现在踩在第 3 级](../images/数据可信台阶.svg)`)。alt 文本写成"这张图的结论是什么",别只重复文件名。 ## 五、generated-fresh:逐字节幂等门禁(新图长期不假红的前提) diff --git a/.dsh/skills/id-family-semantic-migration/reference/steps-chinese-prefix-family.md b/.dsh/skills/id-family-semantic-migration/reference/steps-chinese-prefix-family.md index df2c208c..67398cc6 100644 --- a/.dsh/skills/id-family-semantic-migration/reference/steps-chinese-prefix-family.md +++ b/.dsh/skills/id-family-semantic-migration/reference/steps-chinese-prefix-family.md @@ -51,7 +51,7 @@ - `docs/文档规范.md` **§7.1「已停发、只读的旧号」段加一行**,三列齐全,第三列直写「⚠ **这一族从来没有机器面**:中文前缀不进任何编号语料(族 pattern 全是拉丁形态),而两道编号门禁已于 2026-10-28 / 29 退役 → 只有本表 + 归档换算表 + 评审三条兜;`id_aliases.json` 刻意不登记(没有机器读者,登记等于多一张没人核的表)」; - `scripts/archive/id_gate/编号治理历史.md` **§9.3 逐号换算表**(旧号形态 → 语义短语 → 现行口径出处;本族实测 14 行 = 0、0b、1~12)+ 同篇 §9 批次段落(裁定原文与逐号结论都落在归档正文),**写明旧号永久作废、不得重新取走**; - 表内**把形态写成「卡」+ 数字而不复述字面量**:规范本身是门禁语料,复述字面量会把「讲规则的文档」变成自己的引用站点; - - **同步叙述**:`AGENTS.md`「文档与图形」的销项条目、`docs/README.md`(例:`数据可信.md = 三项阻塞任务` → 两项)、`docs/任务规划/README.md`、`docs/任务规划/登记簿.md`——「剩余三项」这类旧口径实测归零; + - **同步叙述**:`AGENTS.md`「文档与图形」的销项条目、`docs/README.md`(历史实例:当时把「数据可信.md = 三项阻塞任务」改成两项;该文档已于 2026-11-09 拆分迁出并删除)、`docs/任务规划/README.md`、`docs/任务规划/登记簿.md`——「剩余三项」这类旧口径实测归零; - **与有识别面族的判别写进同一张表**:能被脚本按字面量匹配 → 走 `rename_ids.py` + 别名登记;匹配不到(中文前缀、纯散文号、圈号)→ 走规范换算表,**不登记别名**; - 要机械化怎么办:得先给「中文前缀 + 数字」设计候选形态,属追溯机制改造,按 §7.3 单独开卡,**别夹在清退批里顺手做**。 8. **替换后三道二次清洗**(缺一必留疤,全部实测过): diff --git a/App/algo/README.md b/App/algo/README.md index 812a518e..25b2524a 100644 --- a/App/algo/README.md +++ b/App/algo/README.md @@ -51,7 +51,7 @@ ADC 引脚电压 V)+ `adc_health_rail_watch()` ×9(「采样通道自检」 > **改本目录前先记五条红线**:① 取数只经 `adc_input_raw()`,不写死下标;② **禁止跨转换器**做 > 相位 / 功率 / 矢量运算(双转换器无共同采样触发);③ 帧值已是 标定折算工程量,但 **未标定(`adc_cal_flags()` 无 -> VALID)时单位只是 ADC 引脚电压**,不是端子二次值——下游消费精度判据见「数据可信」§4.2 三态 +> VALID)时单位只是 ADC 引脚电压**,不是端子二次值——下游消费精度判据见docs/算法/采集与算法层设计说明.md §13.3 三态 > 表;④ 工程量 → 帧的唯一折算点是 `adc_cal_apply()`,禁止旁路再乘系数;⑤ 本层不建任务、 > 不等事件、不写日志(`adc_cal` 的 `[ERR]` 哨兵留痕是唯一例外,且每通道每开机一次), > `*_init()` 才可在内核前调。 @@ -102,13 +102,13 @@ ADC 引脚电压 V)+ `adc_health_rail_watch()` ×9(「采样通道自检」 ### 3.8 `adc_cal.c` / `.h` — 标定折算通道标定折算(「数据可信」标定折算与落盘整定) - 折算模型:工程量 = (code + b) × k;**k 落盘用 int32 Q16(µV/码 × 65536)**、b 用 int32 码值(负零点靠 `CFG_VAL_INT`)——单位与定点格式的选型依据见 - `docs/任务规划/数据可信.md` §4.1,勿改回 V/码 直存(Q16 只剩 20 个刻度)。 + `docs/算法/采集与算法层设计说明.md §13.2`,勿改回 V/码 直存(Q16 只剩 20 个刻度)。 - **ROM 默认 = 量程口径冻结定死的引脚侧 LSB**(TPAFE 152.59 / STM32 805.66 µV/码, `docs/硬件平台/ADC通道映射说明.md` §7.1);表下标 = 语义枚举(UA0…IN7), V0.2 改版与本目录 `adc_input` 映射表同步改。 - 三态可用性 `adc_cal_flags()`:VALID(已按变比标定,二次值成立——端子变比确认与两点标定前恒 0) / CLIPPED(运行期按来源派生,V0.2 后自动清零)。**消费者判「能不能信」只许查它**, - `adc_cal_apply()` 不返回可用性(「数据可信」§4.2 三态可用性表)。 + `adc_cal_apply()` 不返回可用性(docs/算法/采集与算法层设计说明.md §13.3 三态可用性表)。 - 合法带哨兵:k ∉ ROM×[0.5,2.0] 或 |b| > 8192 → 折算回退 ROM + 每通道每开机一条 `[ERR]` + VALID 被压制(**即便文件位图说已标定**);这层兜底同时挡坏文件与坏标定。 - `adc_cal_set()` / `adc_cal_two_point()`:整定与两点公式的算术核已齐备(单测还原合成 @@ -118,18 +118,18 @@ ADC 引脚电压 V)+ `adc_health_rail_watch()` ×9(「采样通道自检」 ### 3.9 `meas.c` / `.h` — 遥测快照发布(全周傅氏相量发布侧,「数据可信」波次) - **唯一发布者 = adcTask**:`phasor_run()`/`freq_run()` 同拍、200 ms **tick 经过**分频 - 调 `meas_tick()`(非拍计数——idle/skip 拍拉长名义节拍)。`docs/任务规划/数据可信.md` §4.5 + 调 `meas_tick()`(非拍计数——idle/skip 拍拉长名义节拍)。`docs/算法/采集与算法层设计说明.md §13.9` 定"唯一发布者 = `adc_task`" = 评审判据:全仓 `meas_tick` 调用点数须为 1;iec104Task / uiTask 只读。 - 值口径(第二轮「遥测快照发布」的 A-lite 裁决):**基波有效值瞬时透传**,与 phasor 使用区 **同拍同核逐位相等**(单测钉死);**不做** 4 点平均 / 谐波方和根——按 - docs/任务规划/数据可信.md §4.5"上送节拍非平均窗,再平均引入滞后";谐波 k-bin 轨 + docs/算法/采集与算法层设计说明.md §13.9"上送节拍非平均窗,再平均引入滞后";谐波 k-bin 轨 (docs/算法/继电保护功能复现规划.md 「遥测谐波轨(可选)」)扩展只许结构尾部追加, - docs/任务规划/数据可信.md §4.5 字段序 = 协议(布局由单测按偏移钉死,72 B × 双区)。 + docs/算法/采集与算法层设计说明.md §13.9 字段序 = 协议(布局由单测按偏移钉死,72 B × 双区)。 - 并发 = phasor 双区 + 单字节索引翻转(「双区指针原子交换」同型,无锁);seq 只增供消费者判换帧。 -- 品质注入:削顶位图唯一源 = `adc_cal_flags()`(口径 docs/任务规划/数据可信.md §4.2 +- 品质注入:削顶位图唯一源 = `adc_cal_flags()`(口径 docs/算法/采集与算法层设计说明.md §13.3 三态表;由 adc_task 编排注入,本层不链 `adc_cal`);TEMP = 最新一拍原始值透传 + - `NT`(「数据可信」决策 5);`MEAS_QDS_*` 低字节与 104 QDS 线上字节同值 + `NT`(`docs/算法/采集与算法层设计说明.md` §13.3 三态表);`MEAS_QDS_*` 低字节与 104 QDS 线上字节同值 (本层**不** include 协议层头——分层方向)。 - 104 死区迁移 / 频率点绑定 = 104 改读快照那一波(道D 后续分支);读数与注入源比对 = **待台架实测**。 diff --git a/App/algo/adc_cal.c b/App/algo/adc_cal.c index f770862b..3cc27f3f 100644 --- a/App/algo/adc_cal.c +++ b/App/algo/adc_cal.c @@ -2,14 +2,14 @@ * 模块名称:通道标定与量纲折算(标定折算)——实现 * 模块功能:见 adc_cal.h。折算模型(工程量 = (code + b) × k × 1e-6,k 为 Q16 * µV/码)与两段 cfg 布局([adc_cal]:k_* + valid 位图;[adc_cal_ofs]: - * b_*)照 docs/任务规划/数据可信.md §4.1 / §4.4 落地;系数口径 + * b_*)照 docs/算法/采集与算法层设计说明.md §13.2 / §4.4 落地;系数口径 * (ROM 默认 = 量程口径冻结定死的引脚侧 LSB)见 docs/硬件平台/ADC通道映射说明.md * §7.1。 * 并发契约:cfg RAM 副本属主 = 配置引擎(defaultTask 的 load/poll 原地 * 改写),本层逐点折算现读——int32 对齐字在 Cortex-M4 上读写原子, * poll 重载「复位默认 + 逐键解析」存在 µs 级窗口,撞上则该拍该通道 * 为默认值/半新值(相量 20 点窗摊薄,且触发面 = 用户改文件后 4 s - * 沉降一次性事件)——「数据可信」§4.4 明载此设计(不挂回调)。 + * 沉降一次性事件)——docs/算法/采集与算法层设计说明.md §13.8 明载此设计(不挂回调)。 * 合法带哨兵(防损坏文件/错误标定把假电压送进下游):k ∉ ROM×[0.5,2.0] * 或 |b| > ADC_CAL_B_MAX → 该通道折算回退 ROM + b=0,flags 不报 * VALID,每通道每次开机首见沿打一条 [ERR](adc_cal_init 重置留痕)。 @@ -46,12 +46,12 @@ /* 常量定义区 */ /* 段名(≤ CFG_FILE_MAX_NAME_LEN)与键名(k_ua…b_in,均 4/5 字符) - * ——「数据可信」§4.4 布局;键的书写顺序按该表,存储下标按语义枚举 */ + * ——docs/算法/采集与算法层设计说明.md §13.8 布局;键的书写顺序按该表,存储下标按语义枚举 */ #define ADC_CAL_SEC_K "adc_cal" #define ADC_CAL_SEC_B "adc_cal_ofs" /* Q16 → V 的合并比例因子:1e-6 / 65536(float 常量,精确到 1 ulp 以内即可: - * 系数本身 Q16 舍入误差 < 0.001 %,见「数据可信」§4.1) */ + * 系数本身 Q16 舍入误差 < 0.001 %,见docs/算法/采集与算法层设计说明.md §13.2) */ #define ADC_CAL_K_SCALE (1.52587890625e-11f) /* 静态变量定义区 */ @@ -73,7 +73,7 @@ typedef struct { static adc_cal_kcfg_t s_kcfg; /* 生效系数副本(引擎原地更新) */ static adc_cal_bcfg_t s_bcfg; /* 生效零点副本 */ -/* 工厂默认(ROM 理论系数,量程口径冻结定死,「数据可信」§4.4):**下标 = 语义枚举** +/* 工厂默认(ROM 理论系数,量程口径冻结定死,docs/算法/采集与算法层设计说明.md §13.8):**下标 = 语义枚举** * (UA0 / UB1 / UC2 / UN3 / IA4 / IB5 / IC6 / IN7)——UA/UN/IA 走 TPAFE * (16 位 ±5 V 档),UB/UC/IB/IC/IN 走 STM32 ADC1;逐路对过 * docs/硬件平台/ADC通道映射说明.md §3(IN=ADC11/STM32,勿再按分组顺序误写)。 @@ -232,7 +232,7 @@ void adc_cal_init(void) { reg.data_size = (offsetof(adc_cal_kcfg_t, valid) + 1u); /* 33:覆盖到 valid */ reg.p_keys = s_k_keys_tbl; reg.key_count = 9u; - reg.p_cb = NULL; /* 不挂回调:RAM 副本即生效值(「数据可信」§4.4) */ + reg.p_cb = NULL; /* 不挂回调:RAM 副本即生效值(docs/算法/采集与算法层设计说明.md §13.8) */ if (cfg_file_register(®) != 0) { DBG_ERROR("register '%s' FAIL (dup/full?) - calibration file values inactive", ADC_CAL_SEC_K); @@ -253,7 +253,7 @@ void adc_cal_init(void) { } /* - * 函数功能:码值 → 工程量折算(「数据可信」§4.1 模型) + * 函数功能:码值 → 工程量折算(docs/算法/采集与算法层设计说明.md §13.2 模型) * 入口参数:sem - 语义通道;code - 原始码值 adc_semantic_t / int32_t * 返 回 值:工程量浮点(未标定 = ADC 引脚电压 V;TEMP/越界 = 原样透传码值) float * 限定条件:无(任意上下文,纯读) @@ -290,7 +290,7 @@ uint32_t adc_cal_flags(adc_semantic_t sem) { } /* CLIPPED 由**来源**派生(R5:STM32 侧单极性无偏置 → 负半周削顶)—— * V0.2 改版(8 路全接 TPAFE,消除双转换器无共同采样触发)后本位自动恒 0,无需改码, - * 对应「数据可信」§4.2 三态可用性表「页面与 104 绑定零改动」的要求 */ + * 对应docs/算法/采集与算法层设计说明.md §13.3 三态可用性表「页面与 104 绑定零改动」的要求 */ if (s_rom_k_stm32((unsigned)sem) != 0) { f |= ADC_CAL_F_CLIPPED; } diff --git a/App/algo/adc_cal.h b/App/algo/adc_cal.h index 278d45db..3aba3ff5 100644 --- a/App/algo/adc_cal.h +++ b/App/algo/adc_cal.h @@ -4,11 +4,11 @@ * 工程量 = (code + b) × k_f,k_f = k[µV/码] × 1e-6 * k 以 int32 **Q16**(µV/码 × 65536)落盘、b 以 int32 码值落盘, * RAM 副本注册进 cfg_file 引擎([adc_cal] / [adc_cal_ofs] 两段, - * 布局见 docs/任务规划/数据可信.md §4.4);**不挂回调**——RAM 副本 + * 布局见 docs/算法/采集与算法层设计说明.md §13.8);**不挂回调**——RAM 副本 * 即生效值,逐点折算现取现用(1 kHz × 9 通道 = 9k 次/秒浮点乘,可忽略)。 * 三态可用性:ADC_CAL_F_VALID(已按变比标定 → 工程量为二次值)与 * ADC_CAL_F_CLIPPED(V0.1 硬件削顶)由 adc_cal_flags() 单点查询, - * 104 / UI / 保护闭锁(未标定即闭锁)共用(docs/任务规划/数据可信.md §4.2)。 + * 104 / UI / 保护闭锁(未标定即闭锁)共用(docs/算法/采集与算法层设计说明.md §13.3)。 * **未标定闭锁的判定本身也归本层**(`adc_cal_prot_blocked()`):它讲的是 * 「这几路标定齐了没」,属标定层事实,不是任务编排逻辑——保护任务与 UI * 组装器都只是它的消费者(道F task-16 把此前的两份实现收成一份)。 @@ -57,12 +57,12 @@ extern "C" { * TPAFE ±5 V 档:10 V 跨度 / 65536 码 = 152.587890625 µV/码 → ×65536 = 10,000,000(整) * STM32 0~3.3 V:3.3 V / 4096 码 = 805.6640625 µV/码 → ×65536 = 52,800,000(整) * 两个默认值在 Q16 下**无舍入**(系数定点舍入项从误差预算里抹掉, - * 选型依据 → docs/任务规划/数据可信.md §4.1) + * 选型依据 → docs/算法/采集与算法层设计说明.md §13.2) */ #define ADC_CAL_K_Q16_TPAFE (10000000L) #define ADC_CAL_K_Q16_STM32 (52800000L) -/* 系数合法带(「数据可信」§4.1 尾注):k 必须落在板级 ROM 系数的 ×[0.5, 2.0] +/* 系数合法带(docs/算法/采集与算法层设计说明.md §13.2 尾注):k 必须落在板级 ROM 系数的 ×[0.5, 2.0] * 区间内;带宽用 ROM 值移位实现(>>1 / <<1),不设独立宏防两处真相 */ /* 零点偏移幅值上限(码值):超此即判文件损坏/异常标定,回退 ROM 并留痕 */ @@ -81,7 +81,7 @@ extern "C" { void adc_cal_init(void); /* - * 函数功能:码值 → 工程量折算(「数据可信」§4.1 模型) + * 函数功能:码值 → 工程量折算(docs/算法/采集与算法层设计说明.md §13.2 模型) * 入口参数:sem - 语义通道(TEMP 透传不折算) adc_semantic_t * code - 原始码值(TPAFE 16 位补码 / STM32 0..4095) int32_t * 返 回 值:工程量浮点(未标定时单位 = ADC 引脚电压 V;VALID 后置位 = 二次值) float @@ -127,7 +127,7 @@ uint32_t adc_cal_flags(adc_semantic_t sem); * 永不置位 → 徽标与停走**永不解除**; * · 逐通道打印 VALID/CLIPPED 位图是诊断输出(`App/task/adc_task.c`), * 不是判定。 - * ④ 台架调试旁路 = 编译期 `-DDTU_BENCH`(「数据可信」§4.3 决策 1 的例外通道, + * ④ 台架调试旁路 = 编译期 `-DDTU_BENCH`(`docs/算法/采集与算法层设计说明.md` * 仅本地台架自行定义;本仓任何工程档都不定义 = 产品恒强制)。旁路**只在 * 本函数实现内部这一处**,调用方不再各自写 `#ifndef`:否则有人只给单个 * TU 加宏,屏上「未标定」徽标与判据停走当场分叉,且 0 错误 0 警告。 @@ -173,7 +173,7 @@ int32_t adc_cal_k_q16(adc_semantic_t sem); * 返 回 值:0 - 成功;-1 - 参数非法/越出合法带(RAM 不动,[ERR] 留痕) int * 限定条件:**整定路径上下文**(defaultTask 标定流程/整定链;运行参数段落地起 iec104Task * 经 App/algo/run_par.c 的 0x8040~/0x8048~ 直通写亦为授权写者——写的仍是 - * 引擎对齐 int32 单字,µs 级混窗契约同「数据可信」§4.4)。勿在 adcTask 调用 + * 引擎对齐 int32 单字,µs 级混窗契约同docs/算法/采集与算法层设计说明.md §13.8)。勿在 adcTask 调用 * 函数说明:**只写 RAM 副本,不置脏、不落盘、不返回"稍后会存"的承诺**——落盘由属主经 * cfg_file_save 完成,而"要不要落盘"这件事只有一个真源:run_par 的脏标志。 * 因此授权写者是 run_par 的语义 setter(写值 + 置脏成对发生,lead 裁②); @@ -188,7 +188,7 @@ int adc_cal_set(adc_semantic_t sem, int32_t k_q16, int32_t b_codes); * v_lo_uv/v_hi_uv - 两点实测电压(µV,v_hi > v_lo,端子/引脚域均可) int32_t * p_k_q16 / p_b - 输出:系数(Q16)与零点偏移(码值) int32_t * * 返 回 值:0 - 成功;-1 - 参数/斜率非法;-2 - 零点越 ±ADC_CAL_B_MAX(先查前端, - * 不得用系数凑错斜率,「数据可信」§4.1 尾注) int + * 不得用系数凑错斜率,docs/算法/采集与算法层设计说明.md §13.2 尾注) int * 限定条件:无(纯整数运算,主机侧可直接单测) * 函数说明:k = (v_hi−v_lo)×65536/(c_hi−c_lo)(四舍五入),b = v_lo×65536/k − c_lo; * 实测注入未做(台架待跑),本函数即「公式齐备」的交付物 diff --git a/App/algo/freq.h b/App/algo/freq.h index a71ff5e8..31f51a47 100644 --- a/App/algo/freq.h +++ b/App/algo/freq.h @@ -50,7 +50,8 @@ #define FREQ_INST_MIN_HZ 35.0f #define FREQ_INST_MAX_HZ 65.0f -/* 幅值门限(有效值,**二次值 V 口径**,「数据可信」下游常数按工程量重定的结果,依据其 §2.3 表第 1 行): +/* 幅值门限(有效值,**二次值 V 口径**,下游常数按工程量重定的结果,依据 + * `docs/算法/采集与算法层设计说明.md` §13.7 表第 1 行): * 低于该值判"无有效波形"。取值 50 V = 0.5×Un(相电压标称 100 V,与 * App/algo/prot_set.c 头部量纲基准同源):正常带载 UA 在 0.9~1.1×Un, * 50 V 之下只可能是断保险/PT 空载/浮空噪声(浮空实测 ~1.7 V 引脚域、 diff --git a/App/algo/meas.c b/App/algo/meas.c index e9c4c07e..ecff6d05 100644 --- a/App/algo/meas.c +++ b/App/algo/meas.c @@ -1,9 +1,9 @@ /* - * 模块名称:遥测快照发布层(全周傅氏相量派生·发布侧,「数据可信」§4.5) + * 模块名称:遥测快照发布层(全周傅氏相量派生·发布侧,docs/算法/采集与算法层设计说明.md §13.9) * 模块功能:实现见 meas.h——200 ms 基波有效值 + 品质快照,双区无锁读。 * 本文件纯算法:输入 = sample_ring 取窗 + 调用方注入(频率/削顶位图), * 无 RTOS / 无寄存器 / 无日志(「数据可信」层内禁令:本目录不写日志)。 - * 双区不变量(docs/任务规划/数据可信.md §4.5,双区指针原子交换 同型,先例 = App/algo/ + * 双区不变量(docs/算法/采集与算法层设计说明.md §13.9,双区指针原子交换 同型,先例 = App/algo/ *(保护功能清单见 docs/算法/继电保护功能复现规划.md) * phasor.c 的双区注释):写侧只碰**非使用区**,全部字段填完后一次 * volatile 单字节 store 翻转使用区;读者先取索引再整体拷贝 → 拷贝期 @@ -84,7 +84,7 @@ int meas_init(void) { * docs/硬件平台/ADC通道映射说明.md)逐路一周波基波 DFT;任一路取窗 * 不足(开机未满一周波)→ 该路 IV|NT + 整帧 valid=0,但照常发布 * (品质节拍性刷新,见 meas_tick 头注)。TEMP 只取最新一点透传 + - * NT(「数据可信」决策 5)。品质值不因 IV 清零——"值在场但不可信" + * NT(docs/算法/采集与算法层设计说明.md §13.3)。品质值不因 IV 清零——"值在场但不可信" * 与"值缺失"分开,消费者按 qds 裁决。 */ void meas_tick(uint32_t tick_ms, uint8_t freq_valid_in, float freq_hz_in, @@ -113,7 +113,7 @@ void meas_tick(uint32_t tick_ms, uint8_t freq_valid_in, float freq_hz_in, } } - /* TEMP:非交流量语义(「数据可信」决策 5),最新一点原始帧值透传 + NT; + /* TEMP:非交流量语义(docs/算法/采集与算法层设计说明.md §13.3),最新一点原始帧值透传 + NT; * clip_mask 位 8 不参与(adc_cal_flags(TEMP) 恒 0,无削顶语义) */ { float tv = 0.0f; diff --git a/App/algo/meas.h b/App/algo/meas.h index 3e598b0f..7514a494 100644 --- a/App/algo/meas.h +++ b/App/algo/meas.h @@ -1,7 +1,7 @@ /* - * 模块名称:遥测快照发布层(全周傅氏相量派生·发布侧,「数据可信」§4.5) + * 模块名称:遥测快照发布层(全周傅氏相量派生·发布侧,docs/算法/采集与算法层设计说明.md §13.9) * 模块功能:每 **200 ms** 从 全周傅氏相量层取一次基波有效值 + 品质,产出一份全仓唯一的 - * 遥测快照(meas_snap_t,布局权威 = docs/任务规划/数据可信.md §4.5), + * 遥测快照(meas_snap_t,布局权威 = docs/算法/采集与算法层设计说明.md §13.9), * 让 104 与 UI **共用同一份上游**——"什么时候算新值、品质怎么判"只此 * 一处决定(M5 遥测链的地基;104 侧消费见「数据可信」104 改读快照,UI 侧 ui_data_feed 属 * 「UI 扩展」波次,两者都只是本快照的读者)。 @@ -9,15 +9,15 @@ * (同拍 phasor 使用区口径,系数已在 标定折算折算进帧值——现单位 = ADC * 引脚电压 V,二次值语义等 adc_cal_flags() 出 VALID,见 * docs/算法/采集与算法层设计说明.md §10 红线③);**不做** 4 点平均 / - * 谐波方和根——docs/任务规划/数据可信.md §4.5 明示"200 ms 是上送节拍 + * 谐波方和根——docs/算法/采集与算法层设计说明.md §13.9 明示"200 ms 是上送节拍 * 不是平均窗,再平均引入滞后";谐波 k-bin 轨(docs/算法/继电保护功能 * 复现规划.md 遥测谐波轨(可选))将来扩展时只许在本结构**尾部追加**或留在发布侧 *(保护功能清单见 docs/算法/继电保护功能复现规划.md) * 内部状态,既有字段序不得变更。 - * TEMP 通道(「数据可信」决策 5:不参与线性标定):yc = 最新一拍原始 - * 帧值透传,qds 恒置 NT——值在场但非交流量语义,UI 按「数据可信」§4.2 + * TEMP 通道(docs/算法/采集与算法层设计说明.md §13.3:不参与线性标定):yc = 最新一拍原始 + * 帧值透传,qds 恒置 NT——值在场但非交流量语义,UI 按docs/算法/采集与算法层设计说明.md §13.3 * 三态表显示占位符,104 无对应点。 - * 并发(docs/任务规划/数据可信.md §4.5 原文口径):沿用 phasor 的 + * 并发(docs/算法/采集与算法层设计说明.md §13.9 原文口径):沿用 phasor 的 * **双区 + 单字节活跃索引翻转**(双区指针原子交换 同型,不是新机制)——写侧填满 * 计算区后一次 store 翻转,读者先取索引再整体拷贝,全程无锁; * seq 只增,消费者据此判"是否换帧"。 @@ -58,10 +58,10 @@ extern "C" { #define MEAS_QDS_NT (0x0020u) /* 非当前值:未就绪 / 语义未处理(TEMP) */ #define MEAS_QDS_IV (0x0080u) /* 无效:该路取窗失败,无有效读数 */ #define MEAS_QDS_CLIPPED (0x0100u) /* 硬件削顶(adc_cal_flags 位图直通, - * 「数据可信」§4.2 三态表;AC 量不可信, + * docs/算法/采集与算法层设计说明.md §13.3 三态表;AC 量不可信, * 消费者应映射为品质无效,如 104 改读快照侧的 IV) */ -/* 遥测快照(docs/任务规划/数据可信.md §4.5 权威布局;实测 72 B,2×72 ≈ 144 B +/* 遥测快照(docs/算法/采集与算法层设计说明.md §13.9 权威布局;实测 72 B,2×72 ≈ 144 B * 双区 = 本项 DoD 预算口径,由 test/host/meas/ 的布局钉死用例锁字段偏移—— * 改字段 = 破协议,须同步 104 改读快照 / UI) */ typedef struct { diff --git a/App/algo/prot_set.c b/App/algo/prot_set.c index 5724d393..fe9e2d04 100644 --- a/App/algo/prot_set.c +++ b/App/algo/prot_set.c @@ -12,7 +12,7 @@ * 三段递升与过负荷低于速断均自洽)。ADC 帧仅在 adc_cal VALID 置位后才处 * 于此域(未标定 = 引脚电压域,由未标定即闭锁停走判据,见 protect_task.c); * min/max 范围覆盖 0~4×标称,无需随这一项改动数值——换算依据与三处下游 - * 常数同源,见 docs/任务规划/数据可信.md §2.3。 + * 常数同源,见 docs/算法/采集与算法层设计说明.md §13.7。 * * 创建日期:2026-10-11 */ diff --git a/App/algo/run_par.c b/App/algo/run_par.c index a5680219..08507c7d 100644 --- a/App/algo/run_par.c +++ b/App/algo/run_par.c @@ -45,7 +45,7 @@ /* 静态变量定义区 */ -/* [run_par] 段 RAM 副本(引擎原地更新;属主契约与 µs 级混窗见「数据可信」§4.4, +/* [run_par] 段 RAM 副本(引擎原地更新;属主契约与 µs 级混窗见docs/算法/采集与算法层设计说明.md §13.8, * 同 adc_cal——本层不挂回调,副本即生效值,消费侧实时读) */ typedef struct { int32_t db[RUN_PAR_DB_N]; diff --git a/App/algo/run_par.h b/App/algo/run_par.h index fbc3180a..aa68e6c3 100644 --- a/App/algo/run_par.h +++ b/App/algo/run_par.h @@ -35,7 +35,7 @@ * 改档 → 沉降去抖 → 重载),拿它"兜住"未落盘的改值会把 FTP 侧的旧档倒灌 * 回 RAM,比不兜更坏。设计依据见 docs/算法/采集与算法层设计说明.md §10.1。 * 并发契约:引擎副本 int32 对齐字读写在 Cortex-M4 上原子;poll 重载 µs 级窗口 - * 为「数据可信」§4.4 明载设计(adc_cal 同款)。写路径 = 104 执行段 + * 为docs/算法/采集与算法层设计说明.md §13.8 明载设计(adc_cal 同款)。写路径 = 104 执行段 * (iec104Task)与引擎读路径互不加锁,勿改成"读侧缓存"(缓存 = 新真源)。 * 纯算法:只用 stdint/stddef/math + cfg_file.h/adc_cal.h 头(注册/直通均为 * 接口级)→ 主机侧可单测(test/host/run_par,链真 cfg 引擎 + 真 adc_cal)。 diff --git a/App/algo/wave_ring.h b/App/algo/wave_ring.h index d70ff782..261792fd 100644 --- a/App/algo/wave_ring.h +++ b/App/algo/wave_ring.h @@ -23,7 +23,7 @@ * - 按通道分列(一路连续 320 点),不按帧交错:回放页只画一路、PC 重算全周傅氏也逐路 * 独立,交错布局两种用法都要跨步长取数(§6.2 末段「为什么按通道分列」); * - 通道数固定 8,TEMP 不录:温度是片内 ADC 的 12 位单极性原始值、非线性且未参与线性 - * 标定(docs/任务规划/数据可信.md §7 已定案),进录波只多占 640 字节,并让回放页多一 + * 标定(docs/算法/采集与算法层设计说明.md §13 已定案),进录波只多占 640 字节,并让回放页多一 * 格会被误读成电气量的通道;带 TEMP 属二期,且必须连 flags_seq 与 clip_mask 一起升 * 版本(§6.2 那两行的括注); * - 落位 SRAM1:本层全部是普通文件级静态,链接脚本 MDK-ARM/STM32F407-Demo/ diff --git a/App/algo/wave_store.h b/App/algo/wave_store.h index 4c0ec498..c39b26d9 100644 --- a/App/algo/wave_store.h +++ b/App/algo/wave_store.h @@ -86,7 +86,7 @@ extern "C" { #define WAVE_ST_CH_OFF_BCODE (8u) /* 4 字节 int32 */ #define WAVE_ST_CH_BYTES (12u) -/* 本波通道数固定 8(TEMP 不录:理由见 §6.3 末段与 docs/任务规划/数据可信.md §7) */ +/* 本波通道数固定 8(TEMP 不录:理由见 §6.3 末段与 docs/算法/采集与算法层设计说明.md §13.3) */ #define WAVE_ST_CH_NUM (8u) /* 通道数上限:给二期「带 TEMP 且同时升版本」留位;真正的口径是 meta 里的 ch_count 字段 */ #define WAVE_ST_CH_MAX (9u) diff --git a/App/app/ui_data_feed.c b/App/app/ui_data_feed.c index 679b9a82..b3fcc992 100644 --- a/App/app/ui_data_feed.c +++ b/App/app/ui_data_feed.c @@ -10,7 +10,7 @@ * (locked = prot_set_locked / check = g_prot_set_meta 上下限 / * apply = prot_set_set_sealed)注入给 BSP;值域与落盘事实都留在 App * 侧,BSP 只有队列与状态机(契约 §6.1"UI 不能直写"的落地形态) - * 量纲诚实性:eng 字段按**真值**填——docs/任务规划/数据可信.md §2.6 把承诺边界定在 + * 量纲诚实性:eng 字段按**真值**填——docs/算法/采集与算法层设计说明.md §13.5 把承诺边界定在 * "引脚电压",故未做两点标定前 eng = UI_DATA_ENG_PIN(值 = ADC 引脚电压 V, * 不是端子二次值);电气 8 路 adc_cal_flags() 的 VALID 全置位才升 * UI_DATA_ENG_SEC。TEMP 按决策不参与线性标定 → 恒带 UI_DATA_Q_RAW, @@ -309,7 +309,7 @@ static uint64_t feed_yx_bits(void) { * 返回值:无 * 限定条件:uiTask 上下文;映射表已建(feed_map_phasor) * 函数说明:取数口径与 104 上送同源不同路——本函数读**相量使用区**(1 ms 刷新、 - * 双区原子交换),不做死区与平均;遥测链快照(docs/任务规划/数据可信.md + * 双区原子交换),不做死区与平均;遥测链快照(docs/算法/采集与算法层设计说明.md §13 * §4.5 的 meas 快照)落地后,本函数改成读该快照即可,页面零改动 * (这正是本层存在的意义:换数据源只改这里) */ @@ -436,7 +436,7 @@ static void feed_fill_rt(ui_data_rt_t *p_snap, uint32_t tick_ms) { * 限定条件:uiTask 上下文(只读 prot_set 状态位) * 函数说明:这里的"闭锁"是**定值闭锁**(= par.locked = YX31 遥信),**不是**未标定 * 闭锁(= par.cal_block):后者仍可改定值、只是判据停走,两者在屏上不得 - * 互认(三词三源口径 docs/任务规划/数据可信.md §4.3 + 落地简报 §7-6) + * 互认(三词三源口径 docs/算法/采集与算法层设计说明.md §13.4 + 落地简报 §7-6) */ static uint8_t feed_param_locked(void) { return prot_set_locked(); diff --git a/App/cfg/cfg_file.c b/App/cfg/cfg_file.c index e68955d6..2cea2901 100644 --- a/App/cfg/cfg_file.c +++ b/App/cfg/cfg_file.c @@ -28,7 +28,7 @@ * v1.5 2026-10-25 DTU 项目组 「数据可信」有符号零点类型:新增值类型 CFG_VAL_INT(有符号十进制, * len 1/2/4 小端补码)——s_decode_int() 用 strtol + ERANGE + * 宽度上下界校验,s_encode() 带负号输出;负零点偏移从此可 - * 干净落盘(动因见 docs/任务规划/数据可信.md §4.4 与 §7 决策 3) + * 干净落盘(动因见 docs/算法/采集与算法层设计说明.md §13.8) * v1.6 2026-11-05 DTU 项目组 热重载/保存视图一致性守卫(issue #73 SNTP 补验揪出)—— * poll stat→read→复 stat 三点校验 + 内容合法性 s_view_bad * (空读或任意偏移含 NUL = 坏视图;台架 15:21 实证同尺寸 diff --git a/App/cfg/cfg_file.h b/App/cfg/cfg_file.h index 71d12ff6..611c7a65 100644 --- a/App/cfg/cfg_file.h +++ b/App/cfg/cfg_file.h @@ -17,7 +17,7 @@ * CFG_FILE_MAX_NAME_LEN(段名/键名上限 15 字符) * v1.4 2026-10-25 DTU 项目组 「数据可信」有符号零点类型:新增 CFG_VAL_INT 有符号十进制值类型 * (len = 1/2/4,小端补码)——标定零点偏移等负值需有符号 - * 落盘,动因与取舍见 docs/任务规划/数据可信.md §4.4 + * 落盘,动因与取舍见 docs/算法/采集与算法层设计说明.md §13.8 * v1.5 2026-11-05 DTU 项目组 契约同步视图一致性守卫(issue #73 SNTP 补验揪出): * poll 读视图与 stat 令牌不符或内容坏 = 拒绝应用(RAM/基线不动、2s * 重试自愈);save 读视图不符 = 拒存返回 -1(原文件不动)。 diff --git a/App/log/sys_log.h b/App/log/sys_log.h index df675d54..dc36973e 100644 --- a/App/log/sys_log.h +++ b/App/log/sys_log.h @@ -8,7 +8,7 @@ * 修改记录: * v1.0 2026-09-14 王建锋 创建初始版本(设计见 docs/子系统设计/运行与自检记录设计说明.md §4) * v1.2 2026-10-26 王建锋 新增「记录删除」API(UI 装置维护「清除记录」的前置, - * 道F task-4;判据 docs/任务规划/UI补齐.md §2 第 3 行 + * 道F task-4;判据 docs/UI设计/内容页架构.md §7.1 * 「不允许只做一个没有实际效果的按钮」): * 共享层 syslog_request_clear() / syslog_clear_state() * (双端都实现,UI 侧只准用这两个)+ MCU 后端专属 @@ -217,7 +217,7 @@ int syslog_last_epoch(syslog_id_t id, uint32_t *p_epoch); * "WAIT 也正常"写判断,别把 WAIT 当失败。 * 刻意**不**在删除成功后补一条 "records cleared" 留痕:判据要求 * syslog_count() 归零,写了立刻变 1;要留痕归操作记录/SOE - * (docs/任务规划/UI补齐.md 第 6 项的写入方),不是本 API 的职责。 + * (docs/UI设计/内容页架构.md §7.1 第 2 条的写入方),不是本 API 的职责。 */ int syslog_request_clear(syslog_id_t id); diff --git a/App/log/sys_log_mcu.c b/App/log/sys_log_mcu.c index a68d43c5..1aa03922 100644 --- a/App/log/sys_log_mcu.c +++ b/App/log/sys_log_mcu.c @@ -608,7 +608,7 @@ static int s_read_raw(syslog_id_t id, uint32_t idx, uint8_t *p_rec) { * 不去做无谓的失效(与 s_append_rec"失败也一律失效"不同——那边失败 * 伴随过 unlink/重建,本函数失败时盘上什么都没动)。 * 刻意不在删除成功后补一条 "records cleared":判据要求 syslog_count() - * 归零,写了立刻变 1;要留痕归操作记录/SOE(UI补齐.md 第 6 项)。 + * 归零,写了立刻变 1;要留痕归操作记录/SOE(docs/UI设计/内容页架构.md §7.1 第 2 条)。 */ static int s_clear_try(syslog_id_t id) { FRESULT fr; @@ -650,7 +650,7 @@ static int s_clear_try(syslog_id_t id) { * 1) 排在条目排空**之后**(调用位置见 syslog_drain):删除必须是本轮对 * run.log/selftest.log 的最后一次盘上动作,否则本轮刚排空的旧记录 * 会在删除之后又落回去,count 不归零,"清除"就成了没实际效果的按钮 - * (判据出处 docs/任务规划/UI补齐.md §2 第 3 行)。 + * (判据出处 docs/UI设计/内容页架构.md §7.1 第 2 条)。 * 副作用照实登记:**先排空再删** = 请求受理时仍在队列/preboot 里的 * 条目也一并被删掉(用户按下的就是"把现在这些记录清掉"), * 只有删除之后新投递的记录才会留下。 diff --git a/App/protocol/iec104/iec104_comm.h b/App/protocol/iec104/iec104_comm.h index 3bc24b73..bf3c0a58 100644 --- a/App/protocol/iec104/iec104_comm.h +++ b/App/protocol/iec104/iec104_comm.h @@ -15,7 +15,7 @@ * netTask/uiTask 不得直接触碰引擎);getter = 任意消费上下文(u16 * 半字对齐读天然原子,重载瞬间最坏 = 单字段新旧值之一);setter = * UI 保存交接路(task-9,net_cfg_set_* 先例)。 - * 生效语义:**改后重启生效**(通讯设置页验收口径,docs/任务规划/UI补齐.md §2)—— + * 生效语义:**改后重启生效**(通讯设置页验收口径,见 `docs/任务规划/登记簿.md` §7)—— * iec104Task 启动时取一次 getter 填 link cfg;端口另在下次重 bind * (拆链/网络代次重建)自然生效,不必整机重启。不挂段回调、不新增 * 事件位、不走 SYS_EVT_NET_RECONFIG(网络代次链语义不同;且 CH395F diff --git a/App/protocol/iec104/iec104_pts.c b/App/protocol/iec104/iec104_pts.c index 8b19bca6..78be100c 100644 --- a/App/protocol/iec104/iec104_pts.c +++ b/App/protocol/iec104/iec104_pts.c @@ -55,16 +55,16 @@ typedef struct { uint8_t src; /* PTS_SRC_* 源类型 */ } pts_yc_def_t; -/* 死区规则 = 额定二次值的 0.5 %(「数据可信」§2.3 表第 2 行建议规则,随下游常数按工程量重定采纳; +/* 死区规则 = 额定二次值的 0.5 %(docs/算法/采集与算法层设计说明.md §13.7 表第 2 行建议规则,随下游常数按工程量重定采纳; * 额定基准 100 V / 1 A 与 App/algo/prot_set.c 头部同源,勿在此另立口径): * 电压类 0.5 % × 100 V = 0.5 V 电流类 0.5 % × 1 A = 0.005 A * 频率点不适用"额定百分比"(额定附近 0.5 Hz 与旧值同量级,维持 0.5 并随 * 运行参数段可调)。自 104 改读快照起本表**只作工厂默认载体**:生效死区 = * App/algo/run_par.c 的 [run_par] 引擎副本(运行参数段真源收编,本层不再存副本);削顶五路不再 sem=-1 绑死,而是绑快照槽、由品质 CLIPPED - * 驱动线上 IV——V0.2 削顶消失后点位零改动自动启用(口径见 docs/任务规划/ - * 数据可信.md §4.2 三态可用性表)。 + * 驱动线上 IV——V0.2 削顶消失后点位零改动自动启用(口径见 + * docs/算法/采集与算法层设计说明.md §13.3 三态可用性表)。 * ⚠ 过渡期(eng=0 引脚电压域,两点标定完成前):上送值本身非二次值,死区 - * 数字按本域偏保守(迟报不漏报);标定落地后复核(「数据可信」§2.3 表 + * 数字按本域偏保守(迟报不漏报);标定落地后复核(docs/算法/采集与算法层设计说明.md §13.7 表 * 第 2 行)。判定 = 死区连续 2 点确认(104 改读快照),见 iec104_pts.h COV 说明。 */ static const pts_yc_def_t k_yc[] = { { 0x4011u, (int8_t)ADC_SEM_UA, 0.5f, PTS_SRC_MEAS }, /* 1Ua:0.5 % × 100 V */ @@ -176,7 +176,7 @@ uint32_t iec104_pts_yc_ioa(uint8_t idx) { * 入口参数:q16 - 源侧品质(低字节与线上同值;高字节为 MEAS_QDS_CLIPPED 域内位) * 返 回 值:线上 QDS 字节 uint8_t * 函数说明:CLIPPED(硬件削顶,104 无对应位)映射为 IV——「削顶通道 104 恒 - * IV」口径(docs/任务规划/数据可信.md §4.2 三态可用性表) + * IV」口径(docs/算法/采集与算法层设计说明.md §13.3 三态可用性表) * 改由快照品质驱动,不再靠点表绑死 -1;OV/NT/IV 透传,其余高位丢弃。 */ static uint8_t s_q_map(uint16_t q16) { diff --git a/App/protocol/iec104/iec104_pts.h b/App/protocol/iec104/iec104_pts.h index 6fe8da91..6abd33bb 100644 --- a/App/protocol/iec104/iec104_pts.h +++ b/App/protocol/iec104/iec104_pts.h @@ -9,7 +9,7 @@ * 测频与遥测快照(App/algo/meas.h,「数据可信」104 改读快照与频率点绑定):电气 8 路绑快照槽, * 有效性由快照品质驱动——V0.1 削顶路(docs/算法/继电保护功能复现规划.md * §1.6)快照置 CLIPPED → 本层映射为线上 IV(V0.2 后自动启用,绑定零 - * 改动,见 docs/任务规划/数据可信.md §4.2 三态可用性表);0x401d 绑频率源, + * 改动,见 docs/算法/采集与算法层设计说明.md §13.3 三态可用性表);0x401d 绑频率源, * freq_valid()==0 → IV; * - YX:IOA 1~33(§1.5 表(3));双点 = 开关位置类(YX1~4,本期无硬件 → IV), * 保护动作类 YX15~23 映射 prot_elm 状态,闭锁类 YX31~33 映射 prot_set; diff --git a/App/task/adc_task.c b/App/task/adc_task.c index f2438d6d..6ee0ff66 100644 --- a/App/task/adc_task.c +++ b/App/task/adc_task.c @@ -417,7 +417,7 @@ void adc_task_func(void *arg) { all_ok = 0u; break; } - /* 标定折算折算(「数据可信」标定折算落地,§4.1 模型):工程量 = (code + b) × k。 + /* 标定折算(`docs/算法/采集与算法层设计说明.md` §13.2 模型):工程量 = (code + b) × k。 * 现口径 = **ADC 引脚电压 V**(eng=0,量程口径冻结的 ROM 系数,见 * docs/硬件平台/ADC通道映射说明.md §7.1);端子变比确认与两点标定写入标定 * 系数(adc_cal_flags() 出 VALID)后才按二次值消费。TEMP 透传码值 @@ -443,7 +443,7 @@ void adc_task_func(void *arg) { /* 测频与遥测快照发布(「数据可信」这一项,道D,M5):200 ms tick 经过分频。 * 唯一发布者 = 本任务(全仓 meas_tick 调用点数 = 1 为评审判据, - * 「数据可信」§4.5 定"唯一发布者 = adc_task");只在**压环成功的真新帧拍**发布 + * docs/算法/采集与算法层设计说明.md §13.9 定"唯一发布者 = adc_task");只在**压环成功的真新帧拍**发布 * ——idle/skip 拍压环未推进,发布 = 重复旧窗。品质注入唯一源 = * adc_cal_flags()(§4.2 三态表;纯读,每 200 ms 才跑一遍)。 */ if ((uint32_t)(now - s_meas_ms) >= MEAS_PERIOD_MS) { diff --git a/App/task/protect_task.c b/App/task/protect_task.c index 2cb2e5c4..c773b3a3 100644 --- a/App/task/protect_task.c +++ b/App/task/protect_task.c @@ -16,7 +16,7 @@ * 默认构建(未标定)恒闭锁是**期望行为**:边沿用 DBG_INFO 而非 * [ERR](未标定是出厂常态、不是故障;每次开机都走这条沿, * [ERR] 还会误触 /serial-boot-test 禁用标记);台架旁路只走编译期宏 - * DTU_BENCH(「数据可信」§4.3:不进 cfg、不进 104,本仓任何 + * DTU_BENCH(docs/算法/采集与算法层设计说明.md §13.4:不进 cfg、不进 104,本仓任何 * 提交目标都不定义它),且该宏**只作用于判定本体** * adc_cal_prot_blocked()(App/algo/adc_cal.c,全仓唯一一处 #ifndef; * 道F task-16 之前本文件另有一份判定,两处可被分别开关 = 屏上 @@ -34,7 +34,7 @@ * 节拍源一停本任务就再没有任何人判"数据新不新", * 而相量冻在最后一帧上还会被本任务继续用于判据 * v1.2 2026-10-25 DTU 项目组 未标定即闭锁:新增第⑤路「未标定闭锁」(adc_cal_flags - * VALID 口径,docs/任务规划/数据可信.md §4.3): + * VALID 口径,docs/算法/采集与算法层设计说明.md §13.4): * 采样恢复分支内、巡检/压板之前判;边沿 INFO 对 * + SOE_T_CAL_BLOCK/RESUME(不用 [ERR]:未标定是 * 常态非故障,且 /serial-boot-test 禁用 [ERR]);DTU_BENCH @@ -262,7 +262,7 @@ void protect_task(void *argument) { } /* 未标定即闭锁——夹在「采样可信」与「巡检/压板」之间: * eng=0 域(引脚电压)拿去比二次值定值必然错判(UV 尤甚), - * 标定 VALID 未全置位前整条判据链停走(「数据可信」§4.3 决策 1) */ + * 标定 VALID 未全置位前整条判据链停走(`docs/算法/采集与算法层设计说明.md` §13.4) */ /* 判定本体在 adc_cal_prot_blocked()(标定层单点,道F task-16):本任务 * 只是消费者,不再自带一份三路判定 */ if (adc_cal_prot_blocked() != 0u) { diff --git a/Drivers/BSP/UI/ui_data.h b/Drivers/BSP/UI/ui_data.h index 66942b6b..32e27ea1 100644 --- a/Drivers/BSP/UI/ui_data.h +++ b/Drivers/BSP/UI/ui_data.h @@ -27,14 +27,14 @@ * v1.0 2026-10-25 王建锋 创建(道E task-14:契约 §4 快照层落地;相对契约 * 两通道新增第三条 info,划分理由见本头"通道划分"注 * 与契约 §4.4) - * v1.1 2026-10-26 DTU 项目组 道F task-1(docs/任务规划/UI补齐.md §2 第 1 行): + * v1.1 2026-10-26 DTU 项目组 道F task-1(docs/UI设计/内容页架构.md §7): * 新增定值写路径(param_request/param_state/ * param_drain,契约 §6.2 深度 4 环形队列)+ 参数帧尾 * 追加 cal_block(UI_DATA_VER 1→2,整定页"未标定"徽标 * 的数据源);写路径仍不引入任何 App 依赖(执行事实 * 经 ui_data_param_ops_t 由 App 侧注入,同契约 §7.2 * 记录页注入式 reader 的路子) - * v1.2 2026-10-26 DTU 项目组 道F task-3(docs/任务规划/UI补齐.md §2 第 3 行 + * v1.2 2026-10-26 DTU 项目组 道F task-3(docs/UI设计/内容页架构.md §7.1 第 2 条 * 「装置维护 3 页」的前置):新增通道四——维护写请求 * (ui_data_maint_*:墙钟设置 / 强制复归 / 清除记录, * 常驻注入 ui_data_maint_ops_t)与时钟字段换算 @@ -85,7 +85,7 @@ extern "C" { /* ── 量纲口径 eng(诚实性字段:数值 val 的单位由它决定)───────────────────── */ /* - * 真值语义(现场口径 = docs/任务规划/数据可信.md §2.6 的承诺边界 + §4.2 三态 + * 真值语义(现场口径 = docs/算法/采集与算法层设计说明.md §13.5 的承诺边界 + §4.2 三态 * 可用性;契约文档原先写的"0 = 原始码值(未标定)"是标定落地前的旧口径, * 已按本表更正,勿再照抄旧表述): * ENG_PIN 引脚电压 V —— 现状:adc_cal 的 ROM 默认系数是「数据可信」量程口径冻结定死 @@ -107,7 +107,7 @@ extern "C" { #define UI_DATA_Q_SB 0x08u /* 取代值(虚拟注入/替身值,页面应带角标) */ #define UI_DATA_Q_BL 0x10u /* 闭锁:该量被业务闭锁(未标定闭锁/采样闭锁) */ /* 原始码值域:val 不是工程量而是转换器码值——TEMP 不参与线性标定 - * (docs/任务规划/数据可信.md §4.2 的"TEMP 透传码值"决策),有此位即页面 + * (docs/算法/采集与算法层设计说明.md §13.3 的"TEMP 透传码值"决策),有此位即页面 * 不得给 val 挂 V/A 单位,也不得与工程量互比 */ #define UI_DATA_Q_RAW 0x20u @@ -186,7 +186,7 @@ typedef struct { * "标定做完屏上仍永不解锁"。三路口径的权威实现 = App/task/protect_task.c * 的 s_cal_locked()(写侧 App/app/ui_data_feed.c 按同一条判据现算,本层只存 * 真值、不判断)。与上面 locked(定值校验和自检闭锁 = 禁编辑)是两件事, - * 屏上不得互认(三词三源见 docs/任务规划/数据可信.md §4.3) */ + * 屏上不得互认(三词三源见 docs/算法/采集与算法层设计说明.md §13.4) */ uint8_t cal_block; } ui_data_par_t; @@ -348,7 +348,7 @@ uint32_t ui_data_info_seq(void); * 任何判定;先 memset 再填也完全可以,两种写法都安全)。 * 绝不允许"从显示值回提全表"——Q10 存不下 0.95 这类返回系数(真存 972/1024), * 按显示域往返会把用户没动的项顺手改掉 - * (docs/任务规划/UI补齐.md §2 第 2 行判据"值不落盘"的前提)。 + * ("编辑提交前的值只在 RAM、不落盘"这条交接语义的前提)。 */ typedef struct { uint64_t mask; /* bit i = 1 → 第 i 项随本请求提交 */ diff --git a/Drivers/BSP/UI/ui_page_calib.c b/Drivers/BSP/UI/ui_page_calib.c index 7c4d0056..4fb60507 100644 --- a/Drivers/BSP/UI/ui_page_calib.c +++ b/Drivers/BSP/UI/ui_page_calib.c @@ -15,9 +15,9 @@ * 作者:DTU 项目组 * 创建日期:2026-10-27 * 修改记录: - * v1.0 2026-10-27 DTU 项目组 创建(道F task-7;判据 docs/任务规划/UI补齐.md - * §2 第 4 行「改死区能改变 104 上送门限 / 改 k 后 - * 页面值按比例变化 / 只走既有落盘链不加第二真源」) + * v1.0 2026-10-27 DTU 项目组 创建(道F task-7;通用判据 = docs/UI设计/ + * 内容页架构.md §7.1;本页另须「改死区能改变 104 上送门限 / + * 改 k 后页面值按比例变化 / 只走既有落盘链不加第二真源」) */ /* 头文件包含区 */ #include "ui_page_calib.h" diff --git a/Drivers/BSP/UI/ui_page_clear.c b/Drivers/BSP/UI/ui_page_clear.c index acc95b0b..d3128b92 100644 --- a/Drivers/BSP/UI/ui_page_clear.c +++ b/Drivers/BSP/UI/ui_page_clear.c @@ -20,8 +20,8 @@ * 作者:DTU 项目组 * 创建日期:2026-10-26 * 修改记录: - * v1.0 2026-10-26 DTU 项目组 创建(道F task-3;判据 docs/任务规划/UI补齐.md - * §2 第 3 行「清除记录…不允许只做没有实际效果的按钮」; + * v1.0 2026-10-26 DTU 项目组 创建(道F task-3;判据 docs/UI设计/ + * 内容页架构.md §7.1 第 2 条「清除记录…不允许只做没有实际效果的按钮」; * 删除 API 与请求/落地分离 = task-4,口径真源 * App/log/README.md 与 App/log/sys_log.h) */ diff --git a/Drivers/BSP/UI/ui_page_clear.h b/Drivers/BSP/UI/ui_page_clear.h index 0eabefbb..a7b8e0a4 100644 --- a/Drivers/BSP/UI/ui_page_clear.h +++ b/Drivers/BSP/UI/ui_page_clear.h @@ -7,7 +7,7 @@ * 创建日期:2026-10-26 * 修改记录: * v1.0 2026-10-26 DTU 项目组 创建(道F task-3「装置维护 3 页」,判据 = - * docs/任务规划/UI补齐.md §2 第 3 行;形态 = + * docs/UI设计/内容页架构.md §7.1 第 2 条;形态 = * docs/UI设计/页面扩充详细方案.md §3.4) */ #ifndef UI_PAGE_CLEAR_H diff --git a/Drivers/BSP/UI/ui_page_clock.c b/Drivers/BSP/UI/ui_page_clock.c index d92fdd43..80a43af4 100644 --- a/Drivers/BSP/UI/ui_page_clock.c +++ b/Drivers/BSP/UI/ui_page_clock.c @@ -17,8 +17,8 @@ * 作者:DTU 项目组 * 创建日期:2026-10-26 * 修改记录: - * v1.0 2026-10-26 DTU 项目组 创建(道F task-3;判据 docs/任务规划/UI补齐.md - * §2 第 3 行「时钟设置写入 sys_clock_set_unix() + * v1.0 2026-10-26 DTU 项目组 创建(道F task-3;判据 docs/UI设计/内容页架构.md + * §7.1 第 2 条「时钟设置写入 sys_clock_set_unix() * 并回读」;形态 = 页面扩充详细方案.md §3.4 表单 6 字段) */ diff --git a/Drivers/BSP/UI/ui_page_clock.h b/Drivers/BSP/UI/ui_page_clock.h index 58407d54..429cfd1e 100644 --- a/Drivers/BSP/UI/ui_page_clock.h +++ b/Drivers/BSP/UI/ui_page_clock.h @@ -7,7 +7,7 @@ * 创建日期:2026-10-26 * 修改记录: * v1.0 2026-10-26 DTU 项目组 创建(道F task-3「装置维护 3 页」,判据 = - * docs/任务规划/UI补齐.md §2 第 3 行;形态 = + * docs/UI设计/内容页架构.md §7.1 第 2 条;形态 = * docs/UI设计/页面扩充详细方案.md §3.4) */ #ifndef UI_PAGE_CLOCK_H diff --git a/Drivers/BSP/UI/ui_page_comm.c b/Drivers/BSP/UI/ui_page_comm.c index 78b5cb87..2bb76631 100644 --- a/Drivers/BSP/UI/ui_page_comm.c +++ b/Drivers/BSP/UI/ui_page_comm.c @@ -21,9 +21,9 @@ * 作者:DTU 项目组 * 创建日期:2026-10-27 * 修改记录: - * v1.0 2026-10-27 DTU 项目组 创建(道G task-9;判据 = docs/任务规划/ - * UI补齐.md §2 第 1 行「重启即生效 + 104 侧读回 - * 真值 + 段数键数上限核对」,台架判据见该卡与 + * v1.0 2026-10-27 DTU 项目组 创建(道G task-9;验收口径 = 本页须 + * 「重启即生效 + 104 侧读回真值 + 段数键数上限核对」, + * 台架判据见 docs/任务规划/登记簿.md §7「通讯设置页真机判据」与 * IEC104上行设计说明.md §8) */ /* 头文件包含区 */ diff --git a/Drivers/BSP/UI/ui_page_deadband.c b/Drivers/BSP/UI/ui_page_deadband.c index e49bc5ac..b25e0e49 100644 --- a/Drivers/BSP/UI/ui_page_deadband.c +++ b/Drivers/BSP/UI/ui_page_deadband.c @@ -14,9 +14,9 @@ * 作者:DTU 项目组 * 创建日期:2026-10-27 * 修改记录: - * v1.0 2026-10-27 DTU 项目组 创建(道F task-7;判据 docs/任务规划/UI补齐.md - * §2 第 4 行「改死区能改变 104 上送门限 / 改 k 后 - * 页面值按比例变化 / 只走既有落盘链不加第二真源」) + * v1.0 2026-10-27 DTU 项目组 创建(道F task-7;通用判据 = docs/UI设计/ + * 内容页架构.md §7.1;本页另须「改死区能改变 104 上送门限 / + * 改 k 后页面值按比例变化 / 只走既有落盘链不加第二真源」) */ /* 头文件包含区 */ #include "ui_page_deadband.h" diff --git a/Drivers/BSP/UI/ui_page_reset.c b/Drivers/BSP/UI/ui_page_reset.c index c3c516f4..d664b696 100644 --- a/Drivers/BSP/UI/ui_page_reset.c +++ b/Drivers/BSP/UI/ui_page_reset.c @@ -16,8 +16,8 @@ * 作者:DTU 项目组 * 创建日期:2026-10-26 * 修改记录: - * v1.0 2026-10-26 DTU 项目组 创建(道F task-3;判据 docs/任务规划/UI补齐.md - * §2 第 3 行「强制复归确认后动作位复归且有 SOE」) + * v1.0 2026-10-26 DTU 项目组 创建(道F task-3;判据 docs/UI设计/内容页架构.md + * §7.1 第 2 条「强制复归确认后动作位复归且有 SOE」) */ /* 头文件包含区 */ diff --git a/Drivers/BSP/UI/ui_page_reset.h b/Drivers/BSP/UI/ui_page_reset.h index b3777349..2d66da18 100644 --- a/Drivers/BSP/UI/ui_page_reset.h +++ b/Drivers/BSP/UI/ui_page_reset.h @@ -7,7 +7,7 @@ * 创建日期:2026-10-26 * 修改记录: * v1.0 2026-10-26 DTU 项目组 创建(道F task-3「装置维护 3 页」,判据 = - * docs/任务规划/UI补齐.md §2 第 3 行;形态 = + * docs/UI设计/内容页架构.md §7.1 第 2 条;形态 = * docs/UI设计/页面扩充详细方案.md §3.4) */ #ifndef UI_PAGE_RESET_H diff --git a/Drivers/BSP/UI/ui_page_runreport.c b/Drivers/BSP/UI/ui_page_runreport.c index 1bcafa1c..f46a8aea 100644 --- a/Drivers/BSP/UI/ui_page_runreport.c +++ b/Drivers/BSP/UI/ui_page_runreport.c @@ -4,7 +4,7 @@ * 分 2 页(UI_LIST_ROWS=8 行/页 → 8 + 5);数据全部经 ui_data 装置信息帧下发 * (写侧 App/app/ui_data_feed.c 搬 boot_stats_get() 与 iec104_serv_get_stats(), * 本文件零 App include,分层方向由 layer-deps 门禁守护) - * 口径纪律(判据 docs/任务规划/UI补齐.md §2「运行报告」行 + App/util/boot_stats.h 四数台账): + * 口径纪律(判据 = 本页四个数逐个挂范围标签 + App/util/boot_stats.h 四数台账): * ① **四个数逐个挂范围标签**,不许含糊——上电次数=自 RTC 电池周期(换电池即清零, * **禁写终身次数**,固件里压根没有跨开机计数器)、复位原因/运行时长/104 统计 * =本次开机以来(104 四枚跨重连不清零,但**断电即归零**); diff --git a/Drivers/BSP/UI/ui_page_wave_manual.c b/Drivers/BSP/UI/ui_page_wave_manual.c index 91741a56..4c1ebade 100644 --- a/Drivers/BSP/UI/ui_page_wave_manual.c +++ b/Drivers/BSP/UI/ui_page_wave_manual.c @@ -7,8 +7,7 @@ * 等待也不查询结果(录波从触发到成段最快也要一秒后,页面上做同步 * 等待等于把 uiTask 绘制定律「零 I/O」当场破掉); * 只读进入(查看密码)整页拒执行并显式 LOCK——与强制复归同一条 - * 「触发是操作不是查看」的权限判据(docs/任务规划/UI补齐.md §2 - * 维护组的既有口径,本页不自造第二种); + * 「触发是操作不是查看」的权限判据(装置维护组的既有口径,本页不自造第二种); * 本文件零 App include、零存储触点(分层方向由注入表守住)。 * 适用平台:STM32F407ZGTx / PC 模拟器(两端共用) * 作者:DTU 项目组 diff --git a/Drivers/BSP/UI/ui_w_setlist.h b/Drivers/BSP/UI/ui_w_setlist.h index 64c2beae..dd9e0d5a 100644 --- a/Drivers/BSP/UI/ui_w_setlist.h +++ b/Drivers/BSP/UI/ui_w_setlist.h @@ -54,7 +54,7 @@ typedef enum { * ⚠ 与「未标定」是两件事、屏上两条通道:未标定 * (= par.cal_block)仍可改定值、只是判据停走, * 用标题右侧徽标表达;LOCK 才是"写不进去"。 - * 三词三源 → docs/任务规划/数据可信.md §4.3 */ + * 三词三源 → docs/算法/采集与算法层设计说明.md §13.4 */ } ui_w_setlist_st_t; /* 行种类 */ diff --git a/Drivers/BSP/UI/ui_w_setview.h b/Drivers/BSP/UI/ui_w_setview.h index 8859bf68..bdfcee36 100644 --- a/Drivers/BSP/UI/ui_w_setview.h +++ b/Drivers/BSP/UI/ui_w_setview.h @@ -104,8 +104,8 @@ uint8_t ui_w_setview_key(ui_w_setlist_t *a_inst, lv_key_t a_key); * 当前是整定视图(attach_edit)+ 参数帧已就位 + par.cal_block 非 0 * 函数说明:为什么值得占标题带一个角:整定页的存在就是"让用户改保护定值", * 而产品构建下 UA/UN/IA 未标定 → 判据恒停走 → **改完也不会动作**。 - * 不写这件事,页面就是在暗示"改了就算数"(UI补齐.md §4 末段"保护闭锁 - * 必须可见";口径 docs/任务规划/数据可信.md §4.3)。 + * 不写这件事,页面就是在暗示"改了就算数"(判据 docs/UI设计/内容页架构.md + * §7.1 第 3 条"保护闭锁必须可见";口径 docs/算法/采集与算法层设计说明.md §13.4)。 * ⚠ 与保存行的 LOCK 是两件事:LOCK = 定值闭锁(写不进去、禁编辑), * 徽标 = 未标定(仍可改,只是判据停走)——合成一个词就等于互相冒充。 * ⚠ 查看页不画(s_edit=0):那四页是既有黄金参考,像素零变化是硬约束 diff --git a/Drivers/BSP/UI/ui_w_ytview.h b/Drivers/BSP/UI/ui_w_ytview.h index 81e7923a..8dd98cb1 100644 --- a/Drivers/BSP/UI/ui_w_ytview.h +++ b/Drivers/BSP/UI/ui_w_ytview.h @@ -27,8 +27,8 @@ * 作者:DTU 项目组 * 创建日期:2026-10-27 * 修改记录: - * v1.0 2026-10-27 DTU 项目组 创建(道F task-7;判据 docs/任务规划/UI补齐.md - * §2 第 4 行;Lead 裁定:注入表八口形状、结果锁存、 + * v1.0 2026-10-27 DTU 项目组 创建(道F task-7;通用判据 = docs/UI设计/ + * 内容页架构.md §7.1;Lead 裁定:注入表八口形状、结果锁存、 * 粗守 + 注释两层守卫、真带访问器归 task-43) */ #ifndef UI_W_YTVIEW_H diff --git a/docs/README.md b/docs/README.md index a0ff3b20..482edc23 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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/` 生成) | diff --git a/docs/UI设计/UI_数据供给设计说明.md b/docs/UI设计/UI_数据供给设计说明.md index e79f2bf5..31f77512 100644 --- a/docs/UI设计/UI_数据供给设计说明.md +++ b/docs/UI设计/UI_数据供给设计说明.md @@ -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` 完全同构** diff --git a/docs/UI设计/内容页架构.md b/docs/UI设计/内容页架构.md index cec05f18..e76ec2fa 100644 --- a/docs/UI设计/内容页架构.md +++ b/docs/UI设计/内容页架构.md @@ -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`): diff --git a/docs/UI设计/菜单页面设计.md b/docs/UI设计/菜单页面设计.md index 33d3122b..bb3d4204 100644 --- a/docs/UI设计/菜单页面设计.md +++ b/docs/UI设计/菜单页面设计.md @@ -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` = 已绑叶数。 + --- ## 四、显示规范:横向级联子框模型 diff --git a/docs/UI设计/页面扩充详细方案.md b/docs/UI设计/页面扩充详细方案.md index 4f514ce2..627b0a63 100644 --- a/docs/UI设计/页面扩充详细方案.md +++ b/docs/UI设计/页面扩充详细方案.md @@ -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 个空叶子清单(按菜单顺序) diff --git a/docs/UI设计/页面补齐规划.md b/docs/UI设计/页面补齐规划.md index b7b1be1c..c193881e 100644 --- a/docs/UI设计/页面补齐规划.md +++ b/docs/UI设计/页面补齐规划.md @@ -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),口径复核方法与上一段相同 diff --git a/docs/images/交流定数取中位数.svg b/docs/images/交流定数取中位数.svg index f0a66a58..d17fe7c0 100644 --- a/docs/images/交流定数取中位数.svg +++ b/docs/images/交流定数取中位数.svg @@ -1,7 +1,7 @@ 交流轮为什么连取 10 行、取中位数 —— 机理与操作 -meas: 是瞬时基波有效值透传:200 ms 是上送节拍、不是平均窗(数据可信 §4.5)——单行可能恰好抓到波峰或波谷,毛刺行会拖偏算术平均,中位数对两头都钝感 +meas: 是瞬时基波有效值透传:200 ms 是上送节拍、不是平均窗(§13.9)——单行可能恰好抓到波峰或波谷,毛刺行会拖偏算术平均,中位数对两头都钝感 机理:窗定宽 20 拍,截到的相位逐窗滑动 diff --git a/docs/产品需求/产品需求设计文档.md b/docs/产品需求/产品需求设计文档.md index b0c013b5..20a8a892 100644 --- a/docs/产品需求/产品需求设计文档.md +++ b/docs/产品需求/产品需求设计文档.md @@ -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) | diff --git a/docs/任务规划/README.md b/docs/任务规划/README.md index 548e9323..66a24318 100644 --- a/docs/任务规划/README.md +++ b/docs/任务规划/README.md @@ -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`)。 diff --git a/docs/任务规划/UI补齐.md b/docs/任务规划/UI补齐.md deleted file mode 100644 index 4fe66d8d..00000000 --- a/docs/任务规划/UI补齐.md +++ /dev/null @@ -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」等于给扫描风暴开门,且该值现在没有任何既有消费点 | 有真实消费场景或多连接后端立项时再评 | diff --git a/docs/任务规划/数据可信.md b/docs/任务规划/数据可信.md deleted file mode 100644 index d2509036..00000000 --- a/docs/任务规划/数据可信.md +++ /dev/null @@ -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 % | 🟡 开放 | diff --git a/docs/任务规划/登记簿.md b/docs/任务规划/登记簿.md index bcaa1552..db64f63e 100644 --- a/docs/任务规划/登记簿.md +++ b/docs/任务规划/登记簿.md @@ -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 原生 `0` 可逆排除 | 有实测收益才保留改动;否则继续观察 | -> 原第 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. 开放问题 diff --git a/docs/子系统设计/IEC104上行设计说明.md b/docs/子系统设计/IEC104上行设计说明.md index 7494b1c5..a66afc9d 100644 --- a/docs/子系统设计/IEC104上行设计说明.md +++ b/docs/子系统设计/IEC104上行设计说明.md @@ -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 个新测量点越限才确认**——板端测量点 = diff --git a/docs/子系统设计/故障录波设计说明.md b/docs/子系统设计/故障录波设计说明.md index fe4622be..41c062fd 100644 --- a/docs/子系统设计/故障录波设计说明.md +++ b/docs/子系统设计/故障录波设计说明.md @@ -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` | 通道归属与注入点清单的属主;回放页「削」徽标的判据出处 | diff --git a/docs/子系统设计/网络配置说明.md b/docs/子系统设计/网络配置说明.md index ae70cfa5..d3257019 100644 --- a/docs/子系统设计/网络配置说明.md +++ b/docs/子系统设计/网络配置说明.md @@ -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/看门狗风暴(详论 → 本段只登记,正文唯一详述处 = diff --git a/docs/测试说明/专项验证/ADC前端注入验证流程.md b/docs/测试说明/专项验证/ADC前端注入验证流程.md index a1944f20..e71899aa 100644 --- a/docs/测试说明/专项验证/ADC前端注入验证流程.md +++ b/docs/测试说明/专项验证/ADC前端注入验证流程.md @@ -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`)抄进该轮记录表;分析前在本机跑一次 `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.BIN`,**取完立刻改名**(100 号轮转会被覆盖); 3. 跑 `& '.venv\Scripts\python.exe' test/host/wave_read.py fft WAVE.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()` / 复位才清)→ 复位一次记录"是否随复位清",本轮战果之一。 diff --git a/docs/测试说明/专项验证/故障录波板级到场轮执行手册.md b/docs/测试说明/专项验证/故障录波板级到场轮执行手册.md index 5c5d3f42..bd08a36b 100644 --- a/docs/测试说明/专项验证/故障录波板级到场轮执行手册.md +++ b/docs/测试说明/专项验证/故障录波板级到场轮执行手册.md @@ -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 遥测的二次值都按这份近似标定出数——**留着就要在台账注明非送检级**)。 步骤(决定一通过后): diff --git a/docs/测试说明/测试数据/boot_log_data/20261012_B6_iec104_roundtrip_log.txt b/docs/测试说明/测试数据/boot_log_data/20261012_B6_iec104_roundtrip_log.txt index fef4976953986e2481a36ad9c679b2d382443469..ce3f56befc63cfcacdc68fe36ce3c4ddd06c209f 100644 GIT binary patch literal 4412 zcmbVQZBN@s5dMC@Vm=1x&bPaMiG$>mkOL~JfR@nHRj9Ju#L%cTp|Q)szrUG%$-X#F zIHIbUW}khYot=4R+*`m8ix^AWFR*OpoF(w1Zo6g!^M_@#>fn#RfKNokvpnJvXY5!c zxCTb$)!)!f0OfT7$nh$v1d_f)0bFDoqDoplCa zE6oSB^LkaiJXedy5$0inb>@5yfm#XTnTOgBniCCsP8iQ!)Lzitrun&rO)YE)qymAa z`NKJjc^m?Lt=r~dxoR*NJge4scLqQ|2?X>-F=D^NS^dy9+CNP+>B7#*w`Qk+8#U;k z+J6h_z)W5uN8cdp07jPxF+TeShJKw>zCk&KvV^3BcnY~rKM^Ipgi1XxdllTxt#OcB zWU#6-;wXt77jG(cs$D*ALux>7G@9pT{>!$bFdXEKz@)LiG8}^nHPa4>uEJDIf}(sy z3@v9Gn|5j3KKEnDsSTMJX0g+KLbvDE?a`r>+sE4N<48f>%bEm4wh5Wly3JW4)f)~G zh5ZYU;8`HI4J?WHz9Tsetal^>b&te@#>%ZV({d6vaHc~{y)y+(nOj>=A`xf1m{e2V z7d->@&J?s8Zd-y`K5(W(Ok))3F$JxP+t!dqI2ht`J%l~3SDkXUt4r6|jJc_N9RQ`( zYd|Dy$N}ZV$zY@>P_%IDuw;gEc9XLAnISm@1HmBSTQdx_HkICchfmq+Hy~GQ&z}ax zN@MYeAQzM zCKtRwyF8W4dxg-OgSR%4YG+I%1@)MMJ|?U+;&M47^_Y5N^DZU{^_T*;7uFiHC{1n2 z$uZ*U>@2J{`8!=QJS}TzsW9tRv;NgWd3967su0aq#4KxSTEge|XqI}k7=4_UMK0c{ zLZa?T9s^Pg#3;$1D)8G(mQXIt{#oL@OQ_Tm-doWS#0y5yk%V>cag?RxsVd`NzH`2# zFjZ`9#v4%Y*rrD1xtV)zIY&v}edlKS+=jqW)vv&Vs;;MIwv$~Ff0N^jQjuW{F#0Lo z2R$$_LzxQwI2tETv)LDVt6D+a&|@umEn3)iHjZ+a;i9@Ytu9OXnyE)pdezh}_jAz} z>={+kJ7;Pnstr88piv9k)R1pt8ud)SFXw8fJen~2O2vD#z#Qlv*Gue0MDLY`EQw81 kFSIg$gW0Exi<9fm$H4PHc@Fb$&HQ_-#&Y~05t%{%0Ui7DF#rGn literal 9007 zcmc&)Yj4{&6uqAd>_6yZ0_n~jRpF;l-D@e>qE5sXIdzw z!1H(LXMphx%rB0vXWse;_pfnvgZ~`UTXV$`D29FcP98{zt&RH@+cWtK?-%liIgjO; zJd!hCE6N3=)on8feLZIk&uXQ%(uAD(5UKXNHkq2O}+w=BO__(vkckkD;+& zA(dFCz`Brg{7o=QzOVMn{eKF4V;sd2X{wiF)9VN_jv>3&$e#QT+a1f$VB9xP(c09` zV{`Vk!*;gxD-D+BnZEO+ZHd2C;w@jl)J_{mS!qZ0Ysb5gkMa&aF|7QKe)<-g8XC*J z#PvCz7*=DlBeUn_l2kL)VIjZ4i_c`=NaAnRf%Ov?Q@g?%$I%Y_G3=dh=X$sDS_v(6 zqFOqERmbua{a!*NQ-gtVb&KmOqaEJ4t*%sqlvE(1T;wmdmP=2#54nuw`;f~>`Sx<# z(zzG89mL_+z?+IiqRd5$=AC#fYQ|0VZX+Na={5_dVo|GVs&__UZtRb6m$|Ar_73vl zAR6iEe8{n`pATJ0DIC;s4hO4A69;)i2iacppn(HN&rM^knDYV`u(q6(x=3p9R!Poe2y@eK=pr*dU5lYeDwKVz{-xxwKE%_dA zJVCElrr(gih90ZYXL%2K+Su?fJ0|k>1^V+D^w6|e7EQjTQA)nbXO*e&dSqJo6l0z( zIp$^=I=MQZ+e7T>JW?$gdL<(+?UkGl+lXxXNgut(XHm=M z2lV>p{J?TAcYe^pDnedv3f18fRGO*sz56zcp>k&*+oMwMl0s#zk+YUYmXE8898zv< zEqcIa)(YjOaZz_UTyfs5{j1*Av)A^xRBjp<{Vaz|>s`}coN@J|xg+L>?(BPWKcqfg zxoKSac~XhBqFB}l`(Mvq+v7T@^qIz$pP`k8hct6-&*+T|I98+IfzNT3(`9(4SOuYH zUhS;G&Wx2!YRvQ9ZP}#dl=jTE zRdP!DQc{rcGBtSqPB4l=1mzMpaG z)s6L7*m~aN%2)e_EUYy961hsDJlU@l^w#b-!xy(EPZq2F`}SK_ z30JM~y#~*uUR}9qT=`iYcN$`q(Dq-iRxQWnGR;kXocUB!+}jd_k; zveHxrzn*c|icbttG1}NqbL*APVU_a~ctW+qS*^WhwP}ITS*`JGTWHIc;Y)q|*SnO` zM8G|;_>PR5$>?$MRgO*MsHU13D?i6-f5GbGIDm)r5nIY_-F4cJ@~_eUYBkmMk=jG@ z(iBbF?tZl)Q&G!veJgJHnw`|BH?=&adSeOdHwR6s_R0pny``2}bAb+2tAG^nIzgP*^l*2KM p@twyB4u0eD+TK#5_F1;hZz0d%zFz2#MM+P_v4X5Ppxx^HX^4Qsni!+>&zv)}F&S&C%Ke*iuKES8t^ z<#Y*U)d9o^4uK>mwGR$zi6USXnZ;}IUSmw4E2MPp#eP_YTjPp+y}3iA*qx&w}+YU zD_`Cdskn-x5N_(selgWbnK0=XBr97j4(bWhniEu%^aq7 z4k>R#Du)RT^@X`^Pqo{lLrJ#}dbbZe2{nn%9U|R?_-Z~f?6eix8{Q(~P?HFcU|As5 z4J){?6%G06~^^pg!*13EVsnV1Pg*oQ>M zE02IrAf$uHoLE`W?>$ogx~de&jCH5(_XaBj|G$D&1*Uihk*Z*KrCSiDnL4QM^07w}?jrJ%MSGfEU%P4(zw=9mm%4J!gDHuXAc39(Y|Oq*zqN{WdW z_`a#F+pFR(7q2h_yza@@l=ZBar0 E0c14xj>ooS;VGB(>9`K@kXw?4(8xI4{L!2h= zrvIN~q>%6AN1RL9l`iHeWhi6)<~3)0gz*e8Q+bDjvp&Me-#S7m z1@6DbJY%e9tiQOrfj;#o{y)dn1-`kak9x%w7>0-PjXaPxwsD2+rTmWP3;9*gNAgl0 z%OTEt_!L08P+Wx~;Y!FrM@D+?1n0J#uCCK@c$k&5z{<}XD=ooXSGjaEOywte0>*xZ zRAQY2>r#&KnPHWD-t?FIegS+(IEoe0jF)|#bqX2#kXMdnv7hCGvPm-rcah)%xsH zMB-jl;%%h)R^qDE4-p-0i^(^zkxNt>tb)(+?W~0wn<1yZ#SxRlu^Jogi%(3zOGm!N ze@`*%naNhp z)p)LQa}_#kb?4g!p5MduROjjIxu+vz%pFEwA{&5*UKM@ATBWY&26!@6&uvq_G25)f zSTPu5wjc28Jga^~bUj7KS~*tD({6l?ty|I8Hk6lUSejOH0?VU~e1?^@cUr6L#A;6J z+E8!XPTCn_HIpH#^|;J2Is9r?8At2OH%&IJk{*|~N>&}tBinW|0=jztiXp zxvIuh?w0LrFTiJw_uED>`mbd^#`;2Q*#a7CX1hGQ%m-mlYrXuit}avThLLkS{MNO= zm*ck`H#g@u#2(KYIey2mAM^Y$;@q}&+02@J`KI4ymMF2te4a3GXh)u1JZq8X%i@b` z)0dydm+zAiK`ajrG-jmm#WKd~K3O{t4qADzDL0MF&6espl<4ZFaSanSbqtrE2^qiE z$?qv#wcIo=M%-K`wEahDk3-eh=%#M*GohdTo?<7J%6skc+PklSdyXgTtjbQn2{P3JnLKolpVwlg^Rp%WO*l8F2em`GXjcuA{zA|>0uUzhO zI}!6@+JqZ%d5O;sy&Od;Z3N7WwogfWIz7#L!rT-2U8K$B7*p+tmG6g@H#?6I#|Rd} zy`=3XLkoGY?5~$oeLJZwBrna-r1c(V8&)c&dG5dCnyDbJ5+p7sNUD<(S>Hy?}^n^uDhX zy{k3bd6QnizD+l|zdL~c%&<$KZP{C(kaO$Whn4jw^g}Q8&CqqluEl~u#IF1`q%r0@ zD@5Tm+16DL8gJGnO%BJ6b@9z~5BsUziW}eFFM!TPho$bT*xTdI$~f>XJiM+W1nc)X z=5g;JZBG)ey}5=XyoWx(!FSNF^gTFhk{=+Kb<0BdzI!3>H3!v_+*^11O$iVF2hXUP A5dZ)H diff --git a/docs/测试说明/测试数据/boot_log_data/20261012_B9_iec104_soe_post_log.txt b/docs/测试说明/测试数据/boot_log_data/20261012_B9_iec104_soe_post_log.txt index 0b1853b5f62a89a9dbdacd7e546213ae4ac65271..f62ed5fab63667df7da5b9b866b922101feecb7d 100644 GIT binary patch literal 4500 zcmbtYZBOG!4E}z*F{$z-5h zVG)9qj_qe2+mBst0Kb^WSloPrO3XP6;l6BIv4Q!r5~~&t{{TMrJszhX_c&umeu!t_ zzFvrIT{rD-H`)c~=wkK-;2K~$JHDDtW>C&sfH(!TUx+lw%oLfw!pV3-tg=4csd;#5sp)Uyg1Dzh!H_OP*_enAoLI;G!875f5Zok zksf$xocckek)qS~c`Y(z0_Js_C2(6Wp0m!(wILu=fb-GSLB=~SR2(0J^bzQ;_G#Za zjX15-Nss5Om|j9vml=;>TP`yO)fRscI!x4!3jM7Q^r~t6ant1Ers;=G{ouo<0pHuy z&PU+ngDR#cHFdIw%s1bLhHXCtU*HUfPo4OVAw!%hVR84ui6pI7Jvk6M~lFfZJ0rr%pQK~M7uc)Pf z(d8h<1R?j4{EJKio=f{Y_+BXUpqV`@&Q6N+TsD$+O3lPc92xw#XfpPM57bqWfukJQ zG$#(tq&4bv;Dr&%ouYXyHci#E#b!}Z1e-4a$=F7e3lsgZT($an=&WO6dIFdNq|FeL zk*Y@wM$7t9=^jUJNJD^00SxdZvSR6;p$GB_n1QSR*_)$m#Z`UEZw}H$^*xEx7Q3@~*leq< zSU~$-V1qV74}0UcV|s!O_Y^bs*%aYFlRQiH0K;mdrUMBK0+nv7?9eKfLpSwR_7g7& z&0=6AFY@hD+i7C+f=L}nFsI^I5mGO)B=7kL_ltT(MfS45`uZ|PuiTo->;Va*Yoi3o zuy}1!aa5fWC>`F;g zrF4!5IGmMi=J{>Fazb#{)i` z&BO1;0P>-ZD`C;oR9Bg!EuGqRMs~#xrzswx&FE#l%Jo9V-?v^}#yX@lQujgntHQ98 z<`=@?EG>RFR5dbb(lVyy?JK;Bsg zGZV)(SXS1%v);M)o_p?NX7kVAznH4|bj+8ggU`S$&0CCJm~*o*HAecldS~VsUt#P9 zR||7#?_Xi0GGCalajebQbTLPb8AkS-=bZ5=#{11Yoax$}VV;S3k2B8snR#MjJ!(8F zdYqV_FneWww8vv}VxE~J9G~N_f>sNwLuI8_jg*cV;vQxD$F`i>^zacmM@2ac=z0}t zT3ai7_lQl+cjkqenpcoYyXL@Z1zT5U1}*u#VqN-v1N)BgsUDD~xV*HpP9ftZWIIIm z?(yBXzo1u$#tVB4kx`Te*4G_i&yj)mOBqQ&RpY4;TO!j1vIh~iqU*}sK{ql$_(48h z1Eq=e+9}S@@QX>yf8^Lhk`xuC)^X zFE{%ziP9lFdTicc-U}cyw>BK$>I2R%EjqmOp*d3oDXBs<`If)UShc=fGGP~T8O6Jh z%SieEtLqDAvgI;V`9Xvxhk5s;5`$%5%vWR(i5PMk*=fhFCa z;V$b=TX$9()m>}NL-~-pK0Y7%l5!{!Cg?vtx{C26OSv_uVIA998787jstcs#(_wfPmFho$Kg6I6+g`5aGtYjZ2-WzA#- zy~GHusmyD1ASd{qV{Yw(Zg7YGVfE5J=sl`Fuh~7VZ0=^=Kf~D)&z@q&b6o9542f-3 zzX?NF-H*`m&?mQG(Fi^uH=GCMo>npbZfbwc>NaR9xzunnSUV$E)nz`;ob!9%_HbdZ zB-*i39ip$8q3Teo)~irg%`dF^(rHq+KY_*4*09?~E3IS)350wd6rngmSu-3i%m!hl z*ZwDr&>nQ^16Az?eP**)xq+7SAbYtR=sdH%3+>49jN^{kWXc@RNzdc#|AtZRG)EYu}&Ck)pq{gx+=;a+~rM<(OY#+{OGNyNO$DT_60Sb$xJ% zt1F*h^xF*M%x1I3FC|vFdyZcrma#OoC1%VyI6}UB3R|>VvpZMYE5wm-X*+D$1W&PT zdw6nf)NQ=?-*Pi;tuJ5w8FO2yU`QXyp0abQO?w^)H+M!hFbT zHbV}(#&Lz*c!8=J<~}!vtD>?#mdd)syf^5#xtif@73TRJXB9@zZCu2A1hK}7hvWBi zn`@W@2R0hN!E9lE`~i7rio83rOm(P9eb72cR=cX&0|yu@C02I~Wl^f+fyzn<_=UHP+I zR*R*nHD#}Bjw5%;DfN3N>38kleVduhd_-KvQznS7W4}{E==azHKhk2nMDILG?oJ7> z(bid(wu*AJwy9s*EMwf1SfhFNYdqmr)0EuaE$Lx&g}g9< zr)bvzdzp*{9vOMug?tLTxQEHLh3nhGJ(dA#dRgZ@CX`dcL^Dx(e#LxUOo*`S#CL;< z>YT@fekoz1Q5s@0hJVKJlFsi(*V3*;*=hSL#n)J|aLuYKI`;PdijG?3qAQlB*0^l6 zURO@OIbQ8GHE)HiNnQ3mB(xGuF(xax+9(p6c3d)#92o-@&||E`{kdw%x|Ui4x;@>; z_2-+*SG?OvdRkJvW?d(t&|y(~lgJ~hj*Hy|pUE6g&(D9f~U&SO&Ex2o^o z3ZyYf?_1?D@w3dXFj1ZJm{7|+Pb3=Xhc+f-8y~4S$YZkYYQ$dRF+A~g&SO&EJ?Yx2 z_%J46=Ji*%($Q;nBmVhMI`azaQ`W?pS35su%XlwD^O?liI$2lujVfT^uL$J4v?6Hl zN{CcB`dN1qWObdpO=Pu#?y9TUgxjifp4;V}8@{7%uW{G`GS0X&nu_;r*S$6aV)=Rd z%Bz2Nw>kT`zKiQ#Tvta?9+bD=W32yDxU824w^1ANTp6|MWvp`!ONq%+ZAf+H!WBLn zV=0*_kIA;{kgT8^$cQ!M0;(VXOH{AKUz&oxs zaNlT-5!c~!NB!LHRxL3;#haTGtnhjfe`CG46MupA0atxXtoN!w7rwvYe{jsM zZ*#a`#rH;hrz2NY@XqKZ))yffe9u5M#!b{5Ps&%&foq_J-3MD> QCxwh7*zgOrnK2)gP-;YeDwsw&GQ<{C95Tx<&b``C%kM93j#-3d-2vpbr@$dlZFDpVYSL2Lxk zv8SIF!PAJ-c{;Ip&dbRqEY{VKr|_#<4jC+d;a`Lfuj!i#{oMxYHO*dcn!nz(c(tjB zUu_!mgH7Gri-Y^1jIpGq!R;aQUD~U=#u9Lzrdo4-r@_-F&eI8}r>RK7+$(nGp0aTx zWI=?Hi6Ejx*fRTPQDV(v_1~6QF@BYSEi>Qfx@zj>VpW$w83BDUJYv7Y zS+#8HH;OmygmB7Qos0n;)uQn=id5`~6iYgIh_!%!Ll^A6`XqGimnN)f=$q%>{ zdje(d-b&%$3a50?!E!#ZDR5q%kIRoEDWF}}k%+3i`*+?9*&{MbVw(E)ZnQxV%_@5m z<%0U6%7M*XGFzhe{v3c!UCq1T57i3$3+2BGtX-MRIK>Kh%ouyGtLE?1(Xi;c3=%J^ zfa(RyWV_3~hfLN;!L|EBW~+Az!fSH7Ok66EX;1mM?OSP7I7;*MlMB)cs){W#Y&~eB zo>Nm<+_yE*u`$17SUfg~C-&|=$7bEJwSRR%1{C^!38)_B!kG$l_-MI)u)-xJtAn;% zxJIWi8bLCG_|yoO53^BPg1)yvf}_&f$Z&@+eJ$w&DNFW6Aa#c7ct-F@O7?>sh;X_} z`}5A;nKJS6E|{*k?ax`nWZrq1-7orm)N6AuS}>h)+u!l=LXWk&WA6|%H=5?qHP@qH zp(<2=PG00%A>$v)ixy-Z)F7q#@BpNPEfwESrV~?|dt?Ta zKx`E~j@ZC?-{Q%}q5743iXL~0u04A|g62i5d)K^TeAT+EwH&HnyMQRq9+05N(Z1LL zNf3yAKcwIAl+_KsBnmE1&PKl$6*N@S)v8|KH!!-G4rA4jwJVc!{j-r-<0)1HmHYc(Sm4>ah%_@PxP*T@^w;}MlqJu;M0{{yeWi}(Nl literal 12727 zcmc&*ZEq7t5Z=#7{SWssk=o+-*hr~F4XCIJ&=^org{&lmHXlyy4YcC|MER|yodEcy$^S~G;grazWIQ?PR)1bj)}SGn|{s3 zbMrg)uFMO2otfw6zB$D80sd9s>BMqSS(;T%qht2)9Vz?Qlupm`C(<4k>70P)i-^-M zWaJLxn$xNI#XK}q^DC$lsUt|YfTRmE2ba8GkuLpx2Ki=qRZFNTE|2Z5Q_y$}+76MO z8r@y{JvBls9@=Y&i()jgdhS3Xu8h22%1ZNHUECESOI-TcrCZ~o$O@+ma|6z(eX$MN z(j_q3w>mqvwsC_`vG!VsgBClgyLrbNcL*TgAn3G)QrVP2fy-E6tbDVLR85A+8PQ!ez zRZb{f-%8g5?^5xF^%|{6^f$lNOwNk@b!Sm!YAQ=?GpDc;S`78HzP)IT!Ch4PP1{Qv z5tbt=(tRsL578CGI66C#?=-)JNR8@xS3HYxUh7X+`^J`?>U#v=(dd|q@|*FUW?lI7 z)!t&?VO(&Sh}}3DS(A(GsdRggZqgVTSgjtw?&hdG8LhNt4J}%0DnAPTjsED`R`d` zu*MGBUoG>cQoAVfpw17UVZpSDpCNykhkk=sOhID|{rS3=IN|by<{nx=A31_{AeQ0# zjI$M?MXKs8q>%DIM%L1poA(OpMRm{k?pHpPX*D{EQ*8ZW-zEFkNE*s9gw`mBdbgiD zZji%?oz@6oy?+ltyQJ3Rt>JFcTy-zP{vC* zcev!*zW zb~mp%&!HHue<`MFbwnYqU)tj7DweN@XPPmWb3~6TsS0+_>a2|y#Psv>5l0vG zQu#FVHOWWs3+KWTd)MuOa`L5CDe|TCWBrYzh#TLR$ECjn7tIVIE)(dTGhOWs{fPbn z5$DKe9p*shpE>H9OI#P|aL+IYSne&aFn<@DdygGBKi4Vx4cZ!F5@omEnMwP?@<(Kf#OM0 zIjz%M2zQJOO*Xk&_3g*x_SJXHf#MTerNr-&*JTVn9s{<4E9 zMb4u9br*|W{q4)|>TkDN=1b*vcCkwR9Y!Q(J-_De+UzfN#d>uZE7UUoKCXV#&yGd;2Tp6zU!{MyeotJDO| zR^Zc7y`XGGDU^Smz3=2P^2 zuJfpr=cYZ&NnDW#D$G62+SQZF6cy@VyQuhF=TRw7#Q5Yw&Q>_HZ>|&bsL;a{73%lf z+ltS19+mPOjTT%&MXSWHJIJHr+sgJ(QLb~SNZcsJm8PCTJZKNL(%duUQSohMJ8{M5 zI*&@ZlkDBr!fD*%{`r}5bF}qsWqYV7*LhUJ>Lu8_HJ)U0gkRrLj<&NBky@^+(O10Vx=)@xDaAFN(1o_j z^I}S;^-^f7{zQ`fm($RCwi;7YX=3ZqeuDWao=C24IU3PvIf}xjEr+^X6$r<=l^q2eS1;dCC^QCgT=(oxwDy-OK66GeA zI(?#c^*!&%KNZY=xO76xxgejG=Hza(vySlOF{Pt8rLm;k4Rg-W6iaw&L^(8;g!U1i z1iyv0FQD&p*oU0TH|IWQAEDM`YAQ`x>zV=6iCUB1{d!1cURUq&c@$?O>*7_KueHUC z6W%j;D6{u9W-D?Mz~}OLsv!SwVP;<8S?f8n`%8G<921^H>w|m(`=MQ#p@Vs8v%lPN z*FM?EQwGuM0x}+3O^4cJyr->bUpd1m#Q|RY9}KT7H=L^6#c!yW6P#`E)Z(3u15QGr Jsh>&V&i}>?l=%Pv diff --git a/docs/测试说明/测试数据/boot_log_data/20261012_B9_prod_boot_log.txt b/docs/测试说明/测试数据/boot_log_data/20261012_B9_prod_boot_log.txt index 35693e678b99f2118b03ec21f554dcbff68cd76a..fabbb571d2cbd933366abe70509717a19939eb7f 100644 GIT binary patch literal 3365 zcmb_eTW{hz5Pr|En74v@h-@b$BvPcqLOF}tLd9kGp{bBboHnPqZERZl?{}Q^vR!R& z>hi)cjK8^kGxlgcn@s=nVeE&aG8W-@wT4F6+^X=4*OR5_)gmhEI5efGQ=TayRTz~; zl3tqs%d#-$>y-~xy(>fv6v`|HUaK_Wk%A=6L`QZZEnwt_YXp#?<1(9t!>Sr{#lw>_ z;#s&7c@?(sy=_^lo^}GAYayzDk**O00enF{GRAKJ0{quFD{JM$XnyLz zzd&i95dt8EQke(_gpgbU#8CG}dsw_;g z7huNnDwNl0mdQ}6EG@2kNyfGA-nLb48l_p?K_eId!#J*ml;8u|6YU>A#;M55`VLD~ zUe-L%)8f)J&EK_HM68x0ffq4Y)XJr4oIRbu=Hyi-lrRnBbhL(rz$8(|@&m7`ERDEI z%K}shVxKAl>-?yb3L7J0(^!l!E&!47N{V=s%fRV7tgVR;^J8PVI+@OnH;Yj~?kn|& zBM$2ulkYGc`{=3?5kdpH$SXKVZehDivlzjU1(bnq8Bou+s81Y_yHtr_HlH0qEL9zp zNpb+4q%Lzaiv6!D_|={fn1slrzdY)9W55~#oK0Ic^yyqE_-ak%YM%h^5Owe zPZ4Z+Q6RDQ6gu}DJHX9|REYRa3jd&MoKI(y`2|w(QHxiG53)?uEw2T1X5Xfx&GHU= zn>Xw3@kqogwL=S8@xq5gz2r?34w*;oKFS?Ep?Y65TM0?7=N7Ra&o=>T1HCQ}e&y$Z z4-WMJFN$_fIbKJ!{{R4G0=ONTi|7215sRU_3pm%?qDM&&7apa)HSqg`i}T@lv{?<8 znr2tH!RpS{whJS|dh20tLVeue0fT8C^em`x6Wh?)6O&?$8rX6^3~cq*vjlt$YUC0S;G+kjIl7PSs&(avbbxBEE zQ%W4W3Gr+(pIm?n7^Q9>c4-t)hY=L2fReuFd0H$2$MYPNGE}y@+rV>($54k?0Cij~ z6zGG;5x!O2zO5xJ4s$&%>Ax;B-1peeXTI5!^H?M?UMIxHM+?d_uxxuk0SQ?Jp6hDi z-h+-!qyG2>)go?Nn#YVRd>CO^n9+dfK%ZxXX?!3f=DO_Vj4U#E^4(_CIR9KmeSF_26s+wjgF*{;{r@XtMZ=DW?PasIiCTuRyVj9kVv!;mx7(e3z5kDLJ+ zyxb#~vM1kdMve2&W#m!ow>k2dt-F93S@z(yj0VW4UHa-A4F>pLd~uH2{f-M)GrrBJ gasG*njBiJa@pOdm%(LNgX)M;W&FW~mYM;PA0Y7K&PXGV_ literal 6855 zcmd6sZBH9V5Xbj*q<)8c2UTjz4;XMHOC=^WCpL}s7^li_GV{i=08t+{PTA+Y=zCR7S_Wb;YCQos_y%t8P38{=xVeY-i2MwXEW{a zC0yvu%TN!6a4yQO{*HA&)Of6Q`=O}$uEzb)38$j&>X|iA3`0-z$D;YuRu983;hCh^ z)lNt-(z;7gb;T(OW&O^?gK^OWrz zWzlv7=eQQ@pxKJ{Jd$jnfv#ApBzZ~`8@MH)e=DkiS@fHz@UJuZ-&oQNbm232BiHw- z-7DSC7H#K_*5jR3AyYN`I-l*S`*Xj#l)L2TPKYmcNI6m8R~ArGwSSGndr*nKO!v040R zLz!e#&u#frQ=V74M(^{E)?ItCQ!QQlL3^xQW^xTjl8g9vEL15LdHuzY1{$OH zTk)wVk1mMQlDvIYJn*@q;sR7WJA4o->uH?fyTk+dHN?L!`mUZXHO4Yyt!hgXA`UNa zNLpk^&O};v4Cy>VG0Mwkw=4slitDji;%8*W{YkcL3jua+Pi#It^A)Ax*Hr6y^KG&} z8WT}<)Av|2*r_ZF`wSVW5uTfOx^-JZYeklSse4mC7=078hLQv%sUAJ?!umt`1^KII zRws(7Az1!UoZWL{KBr0?>m9j~8b|!a{QUUUW)_=fRb@j`yJfMA+x9n&G9UAKf8+Y^ zS#%$W$}Q6kpDjkPA6btIGqy@N)>CFlIC%#0s!UeOGQ})hH?{MH{GSSWBA)BgDdxOc z_+lAk#76Lo-a{^(g|F8eV%U2YvM+U#Y!fr_tb6o@W=WBO%w&8xjzb8GZ z=g_j_W_T|iP1VgERez7=fuxW7PTL1b=+ZA!F6ZV6L&N;JqTWvg^tg#?W<@oWN?J?j z=hJFHAL)IF=O(%;&+}vzEaQ?-lOVHWe>TJ%^8M{F8VTl+q2%6PM2>Y)E0W-Od`HrR8r@rvlF|w`*RRsyj8hXZEDS zrW4~E1*a0`k+`b41?3++!~0PzQ5UAXV6Fy6?mEi<#i@JUkr%3s* zI4#Ooh>82*gy!gVGn3?T%5;BPoal7Pt2d?1>JxPX-_7I18Z7i<@pK(0@=eT|_peXO zl7Rmh+z+RGkMEsitju|wGTomFC;I*Oc0yZK57$h;k8WGvy<;b~mU`<=>&0K$w}-1= Hm!JI$qvrH) diff --git a/docs/测试说明/测试数据/boot_log_data/20261012_B9_soe_decode_post.txt b/docs/测试说明/测试数据/boot_log_data/20261012_B9_soe_decode_post.txt index f477f601b4eef418837978c416b998cf4e188666..6d62e6d3139a01ca511733778b21d02e290e05d6 100644 GIT binary patch literal 4700 zcmb`L&1&N?6ovPB3PCp=Xr}sgY(W-TWKn3QB|nQEi-RFlCE9JRmlYD zY7+?I<4E#n9i?sR@B8LS6QN2;wttUxdqq@14)w3*uxm$zTu@3$TmPO?@-gPOi-*~2 zHD9jnSM~m7s?6v6<91-4VeVqkBKHGlDbBOOu@u zoMB#??2OiR1IrevUf(HbTdP&G>2IWq;6)20`^)Ub+dqo z)XfZ0O1IYnshb5vq;3`vk-AwxMCxV%5viMbqD1OumIx=8MCxV%5viM5BHU*rQa1~T zNZl+TM%^r}Q&=LrDP+{m(mI8t{oPd}bu&xsb_S`NSt8tqWz@~$bLO1;j3=t7o2B)h zfQZ!10wPj3vqU&u6;d|~h)CTmAfD09&gm3}$knK=pI++MV@oc#O>?|H)Z4e`{f=y# lx7Xd{;kjA05s0!JI3dD}A|xOp3xYonylPLStK9Z< zlrVP7(k#8rH?Q1&u4@1Nb4{1DpqKO&?-#U71=ZBjj2e78r{8pgz1Q>t-&)$n>lMC# z#<5p4$Mz?*fo%mnrLC?N*tVb_w1;oJ-ERl8RN&gA5})|B!an}Ii|g#*wZyxnEOErtC>#7IOUeI3 zD4BTJj-cf}^gDo_@99h_Ss(^Z%gyC^aVX}T z1?4flyE{rK$0PnYO76=-$;88^wS1!p`ADH0*OKFOUoBhoOdD}lK`5Dc*hI@!caPk6 z@raM#J$=N7lspCqrNqsW3gxPZk5jS&57(0aqfj#OunA>OEoX|7iHA)nQ)*dx{c=Z9 zGV!npWlAkAC6D-h#F=>5gfgF&CGPp2(lPs-LYY%b>pda&5z3reYVUErKSeFI_mr4h z`HTg8(ani+YN@@a?B;$xr%>kXm)d)HUgtATLrd*FWjAN`Ij5kd_MWnvQO77#_RHFM zPl*}49xp@gqi1euX2GqOQE(2TDMRj~Dc3*0th>4T%xGB|?{Unrh^M*7!<5>49CM5^ zO}`9NYVWDKoHIt5Q%mhV)dajJtflszY69L9rqte3O~88`<&JlcYwzK@h~F!FhfLWo zeM;>;)dakUwQMnp>wLU2-cz9>_Ao7Fmh$*~+)>(5y*Az>S+ym-&urs=QP$9j>qI`K z&U>an$(2F&KppYA8^@(;5XyQA(muZK*+$*fFZtC{TJN#3cHbo8s~mDX;vA>(3QUYr zdrv6qv0AQsPUI*X^h~Rz_8ul4HqkQ0cp0PA-Xn3dq(ZqW;&R``Mz7Zd4sl6xU zJZZfrrlt0t{57{2rOtao&NBrq8{<8ptf!|;*)Q$$p2p-o`D<J+4k@@9;cY z+UGq@mqYXp8G7O)BT>rn(x=qklfULB5%(#z_k?S1>1P{_H{0MRe!8|1avx2(ZXf3{ zXZTE)pPp*Uko%HF-q+{53jk28^kjT9+$^63P;IRHO|g> zesO`7KnwcbomcS7L922-U$(75(=nIWwM&BUL8J zrclbmo1A$%Z>rM#-Ie#6i9#v1c|VxyjH#UM&Hr-0tp<#paL!p}o+q4ruGz)>cDh{7 z7AyCa**#7&`}umeoA5XLbGJt9P)!6E`4IRJ1Ou+KLPLf`NJdm6BnnT2&xq{$V!E2$ zUafsZpK~R zW9Es9h~3G!u^pd`-*rRGJ<*M`Ufo@Hi0Wv@ktgO2kFn^CV^18liS5b!Hlx6EEIe`C zCbpmO4zcru<2fP`(3zr5jL8V-j0HEV|2ftfYiCHB{iPdDwHo`30-dqo zX7xNrBBC=E+^nAGNW}U*6YUHU(HRl#3=z>85$y~S(HRl#j3pL0Yjj3LJ3~ZtMnpR! zb;dCxIwQ!L?(_I_ld|s_OT;H!Ch2CN<+yQ1Ch2CDSZIN}mWjHVB}$yNOw`Q+Vxn$l ziAwod%S7EQASUW&0WncG3y6ujSwKwG&4{QHbu&lAHrVgZsv%1pHYdrSwKwG z%>rVloAv7yj#vyTbN^_b4i)>eDa*sZz1h4x?6z!EzC3O3_7A2y)l8j**OB_xYj49a RSgz;u>EcGSYkLnEd;lXNZnOXZ literal 7861 zcmd6sPjAye5XI+QiSJ;E3rG~=KM75w9&*S5i9(gO2Tq8Rs6qlN(iFj$2j1*v>Y4RA ziKw!+R&`>>aesNUyKi>q@1Hxmr6s+juXw$o31w8!m@2f4uIV?e@#!7Cz*$8j99KC1 zjC)tK!1X6|glic+rGaZ1t}W>Yo#KqIhiyi0>5M+olrGR_G^fjldzN7MhHnlxSANnb zT;V7E+C1I=j{&{L9c%ojQ?L&3H=<+8@s5uLKI8WjJZFq!j#o>W;jJx)T z?;bsM#G8~n2MDFa&5{b`wutYhWCi|TOa6^Q$;8bjlwE3hq9~cT*@QBsmPODn$BL4P zn@uQFYH2BX#;+sJ#LXs@-D#O)%-58jIph?|F157Y6LTM->{3hZJ>K{GsHOIvoMP_N z2Q9VtNd)hT9(Fpa%Av& zzKpq#&fL;u!NXuh!D|pr8FL>^dHDRYbh-M8(Xue!MDYf@_<~GVS{W4Ce zy{B+%&Nj*}wbb5I^uT-KT59hpdf+{AO6@&G54^`yj)O6-y@&Tj!d_WBWXgUSQfluh zdf+{*Swbh?CkiR`x~C76 zyferis3Tswd0ci4Vym8vw2vP;+bG@sB_A!N^&T5*epf`tDc%NWxurbp31Cyy5Dn?h=-JV-Q)KO?FjEi%aNHc zE4PNI9Wqw&k(nsvd>K+|@9BQeO(GsrYVV2fxuwrGs!g`RF}^`Hc1hozBV_ap)!nfV!Ogst{6W@hQ&2wt{lhvgsmj|%CoPDU7${QhBigD P@Pm8K`KDsb?tSzR5)X4Y diff --git a/docs/测试说明/测试数据/wave_bench_20261107/build_log_tails.txt b/docs/测试说明/测试数据/wave_bench_20261107/build_log_tails.txt index 29d3f4c4..93ebc532 100644 --- a/docs/测试说明/测试数据/wave_bench_20261107/build_log_tails.txt +++ b/docs/测试说明/测试数据/wave_bench_20261107/build_log_tails.txt @@ -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 diff --git a/docs/测试说明/测试数据/wave_bench_20261107/final_wave_listing.txt b/docs/测试说明/测试数据/wave_bench_20261107/final_wave_listing.txt index 08fc0ffc4a744eda87d7ac2bc03100ade9365e86..4e9bc1bb24f9c0005765785b5fea568d4abdc528 100644 GIT binary patch literal 255 zcmYezD=ErMEw)lHG%(;Q$uCLFQAnyRNi9~eRj@R-G&2Q?hC7D28k+$H3=Kfsw9KO7 z5)&(hXbp9cjDdlklc%4$j)I|yp}DDnrj7zs+z^Mj5e{)O&zutR3 zGA@)9oXNN`CBo3xY0{8>)f~vB9=YponTVMtCDDu-edsN7HY|yydd6=0zMte#=zq!3 z`Rr)Z;{D5d_E@lDEw!r+Mx2q0-OzDLl{bO>Adru1`Mql>S3Ca_*>Pm?-}7soEY1? zepnu)_Gr}Ir~8~9xjP*6`hWU#=3jSne+#7Zt08>)k4Zt1TJGNtBJC37Z|Ydht|97j6coClg?=3Q~O5b zH`n83m6XV#yp`XJye)Qu+EM-ex?U$~iqvG9)d9;)cj+T1MRS zIr9yh>P;d=Fc=QbDXL`^6mfh+$8l9;G@e`;de3A|>kQRue;2zG?OUghCRHK?6#|)L zqS#2HYByipf)4?@?RrGp5KbE~=rPbVd`XLyPfr-8n7AmyD!N{PQ1e`DjlG4f^Iw?N zmOBJGM&DH!%OP5cJg|sl9h_$Mi8ea#oPF$cFI3U!I4>wl;#gE7UkZwgO&*;f&n1ee z2z*(r=tfjgvIJA#my=@rrOL_&MVt@R6auzkxP~?zUd#w_#g9!=p(j~btwpuZ$0ra1 z1WTl9^UFI2LT-y{O?~WsWos^E$Rdw1>aZw@p$%I!h_-DKIw!r z)2B44rN|*00>O2YnXhCug}l3{#a+lZ?oPxK(cZZEy9moyw*Gr9Xwy&q30fEz)gp-^ zky9B;DXQG3UZ;Oa#~h`|#c_Rdf>G1_E*;&c>8b8`W>(K=s)*d;yu~0r!-w#gJ)547 zMzd)j;AXTh=mG2P#kg2UTBL2Vz~_~ zLC1ry{qB5x3zlZhTz+_E8J2Q`9d#L^iKpr`YPacB_n=tV$7;5y!PbmVNcN$Jx34SoJ~7t-T9<5hG5i; z1TL`(7==|PBHU}tu@>Qc3=Ex-s4A=#H!-eJRg@TUjeq9={gnUlM|G&6e!IXis93A( zTHMxfu~b8nQVdr{aVBxy2UsMChZB^c=tug$5 zRl=OZNrNI>6bekd2yiqlLIrkH2NpJ{4+h(@X#E3gIHYimVkF+&QfyS9IlC+B=h3h? zBN^zNn>KBdC5{ZwgHZ;a=jyt$@_;kfvS6mj03QXgwt;I~7Kf$IGS5+lDnuA91D)Bn ztE?-+{jOR({J)S1^`|y|^2FSB2_MWKB<4R??zFTFM#rW$Xp)wcJ zP%2aRLn;F)e^Qz8HkCQ}-hbLeN5|o&NU3vEvGWNj4M+-WZxosB=-%NbI-Ea--Z!y{ z{jMf@Tz_PGBV13{Rm#9)=t@ve@IYh_q=bH75t-|l&S5AdzvI!qo{!G@ XU3{dg?-OnGWiX$dk0auTZHG^~eO$cug)3R<@j%G!OZRcoRQ z#jB^C$D)k1=be5!qV`0&5T&E{QD|xQN?bYfEabxPqVoPjcoORNB;mOzS6Z9g?MifB zUO#0?u&z->dJuW0oTsO%VRO8B)aE&W-c4CsDfDW2%>ddxe z!y@R4r9gZgdW(4Qy{umO0jnp4kE~yV5Kc z>1hnN%{eQ<+C3dz{Deb!nIj0c9m9Vh?O4$=o$#%a{BHf8_ps|A{AyJEsG->1*LzF; zv?b5W-&^nWub;JH9*Z73;jPZtwOrsD4kQ=x>9%lvKr{&}@{~{ddm^;(!?tO)FKj-F znkeSdD8ynl%@d2y6d`5JUE4l5*QEuy=!K|w_ej>Pi%(b2ifF6)iy!qhM(;gwC`i_l zxK-rs+v0)GIB*aGK?XLKM z>!tjI%+%E!anlz5j_Ij5yHCbU-O!pd%~Cbcn#l6Z`W4i|i^=zgrdozCzJ!c;75t)SEQ^9y38D*cAiol;NS@|TKVwh29O(h=uOUrNd98J+Um|bM za!|=+Cq6gC;et zDA?Yna%e$sHDOQR$GOeBY`rFa>#9`LE4-_yJzf#>s)g^h@`Y;np^bJmg9YJ`^;V?! z?q^`y5Gm156IDa1UBj{!kwFcm17i=GP+MkM@9W6W2c1YGQ1h5~Sq~)dv^Olm@1;(l z8tmxrjb!zns;PdN`uz|Kra1neY#2KS>J%L^d74^tD^CK4$qKZhIeG%m<#e_;_V!G@ zmUjS6;m*zQz_6da+GB!@N>|mD&FE=Z%ZdBpjd*OSmpPIbdXDYOU*fs5&Os9HJ~v}7 z*A}53nNJlFe$V3OkXWqMq#bqG=|rq|II+9)+Ci`CbvSlI*=U~BG{rIUh`s)bVLGe! ztyuI|EDuoY{l-UJq&*MSjJ-&BKdVr2x<>WRDD6c&qmT(U##(-BP9ZChQ|RKb0XNPg zb#m;Fou^x_qi&2IjTj$FdXVz>YrWIIt!d70q}*)jKDieR_4qov{qA_o9g!>(yS`L| z$^)}v)Zj>6XuRbhJ$-szSQjSh|f1aLn@tjnUByDL*M5pf&Wok+??kuA{$ko)k zsPTzLe%~TDMC%gqb;;@+;+KoEki|pK)xr9Hzk~U>ZJiXDgO9&)>*L+)02PqhHR-Rf z6!!d4mgg-gVQ$X;B`Rm=&q4(TdZua(BhMQeU065?{;8I?oYwD^Ich*L!=8tJ3zRFbfOv{=^5*|*JWNm~u;WHjJ z^CHP@G#N+OD2>9!N~*u8m3-qp6MJ_nG+}e?dE_&a-P9T}`ZQ zKK?J%HgYL>=X>bswT-Xm+1eK0A6nZyYtF81M8Ws0Z51Iv{zy@n&YIi@{gy}kd0nB} z#XLGcYw|^js+G-}oX4|l)}*rIcZ)?NdQ)?z_0C3Qs`+C^Br(JNdRo>rYu2=)aEG+p zh~73d2WAVkaW>pB2ITy20_BMp3P5ocX`>w2wQq3R7M)Zkq>|4jS-49<+ ae0O2?Q2&+Lw>!%V`*s%px8eT_dGZh9j66pG diff --git a/docs/环境与部署/并行任务工作树方案.md b/docs/环境与部署/并行任务工作树方案.md index 36510e87..8db1b6ff 100644 --- a/docs/环境与部署/并行任务工作树方案.md +++ b/docs/环境与部署/并行任务工作树方案.md @@ -238,7 +238,7 @@ D:/Code/DTU Code/ ### 7.3 并行道与写范围规则(规划层 ↔ 执行层映射) -规划层(当前任务卡在 `docs/任务规划/UI补齐.md`,后续事项在 `docs/任务规划/登记簿.md`; +规划层(任务卡在 `docs/任务规划/登记簿.md §7`,其余待办在 `docs/任务规划/登记簿.md`); 五字段 = **DoD / 硬依赖 / 资源 / 写范围 / 状态**) 按**资源属性**把任务切进三条道,本方案(工作树 + 锁)是它的执行层: diff --git a/docs/硬件平台/ADC通道映射说明.md b/docs/硬件平台/ADC通道映射说明.md index 8c1a2480..fc5b7556 100644 --- a/docs/硬件平台/ADC通道映射说明.md +++ b/docs/硬件平台/ADC通道映射说明.md @@ -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 上送值与**工程量**一致"仍挂在 +变比确认与两点标定上(注入验证只证到引脚电压口径)。 diff --git a/docs/算法/采集与算法层设计说明.md b/docs/算法/采集与算法层设计说明.md index bc123613..56030a26 100644 --- a/docs/算法/采集与算法层设计说明.md +++ b/docs/算法/采集与算法层设计说明.md @@ -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` diff --git a/docs/问题记录/采集与数据处理短板评测.md b/docs/问题记录/采集与数据处理短板评测.md index 2da7e3fb..442052e6 100644 --- a/docs/问题记录/采集与数据处理短板评测.md +++ b/docs/问题记录/采集与数据处理短板评测.md @@ -283,7 +283,7 @@ 这四项合起来是**一次完整的"测量子系统"立项**,建议按一个波次做,因为它们共享同一批参数与同一条数据通路;拆开做会互相返工。 > **已立项(2026-10-23)**:本阶段 = **「数据可信」**,任务卡、事实基线与验收判据见 -> `docs/任务规划/数据可信.md`。排序已由 `docs/任务规划/README.md` §2 接管,本文只保留成因分析。 +> `docs/算法/采集与算法层设计说明.md §13`。排序已由 `docs/任务规划/README.md` §2 接管,本文只保留成因分析。 ### 阶段二:精度与安全网 diff --git a/scripts/archive/id_gate/编号治理历史.md b/scripts/archive/id_gate/编号治理历史.md index 7ea932e7..85961d35 100644 --- a/scripts/archive/id_gate/编号治理历史.md +++ b/scripts/archive/id_gate/编号治理历史.md @@ -239,7 +239,7 @@ P-6 号必须能反查到定义(属主登记处得存在)· P-7 编号不语 用户指令(2026-10-27):「**数据可信.md 已经完成的内容请进行销项删除,去除相关编号**」。两件事同做: -1. **销项**:`docs/任务规划/数据可信.md` 原编号规范 §5 里 2026-10-27 台架闭环的「已知电压注入验证」行**删行**。 +1. **销项**:原数据可信 5 节 里 2026-10-27 台架闭环的「已知电压注入验证」行**删行**。 上一笔曾特意标 ✅ 保留,理由是该行被 `App/task/adc_task.c` 的 v3.3 修订行按卡号当口径出处引用; 引用侧改成语义短语后该理由不再成立 → **例外撤销**。判据与实测记录的属主 = `docs/硬件平台/ADC通道映射说明.md` §8.1(六项判据全 PASS、斜率 6544.2 码/V、偏差 −0.14 %), @@ -250,19 +250,19 @@ P-6 号必须能反查到定义(属主登记处得存在)· P-7 编号不语 | 旧号形态 | 语义短语 | 现行口径出处 | |---|---|---| | 「卡」+ 数字 0 | 已知电压注入验证 | `docs/硬件平台/ADC通道映射说明.md` §8.1(✅ 2026-10-27,已销项删行) | -| 「卡」+ 数字 0b | 端子/子板变比确认 | `docs/任务规划/数据可信.md` 原编号规范 §5;缺口面 = `docs/硬件平台/ADC通道映射说明.md` §7.1 链路分段表 ④ 行 | -| 「卡」+ 数字 1 | 量程口径冻结 | `docs/任务规划/数据可信.md` §2.1 | -| 「卡」+ 数字 2 | 标定折算落地 | `docs/任务规划/数据可信.md` 原编号规范 §4.1 | -| 「卡」+ 数字 3 | 有符号零点类型(CFG_VAL_INT) | `docs/任务规划/数据可信.md` 原编号规范 §4.4 | -| 「卡」+ 数字 4 | 标定落盘与整定入口 | `docs/任务规划/数据可信.md` 原编号规范 §4.4 | -| 「卡」+ 数字 5 | 未标定即闭锁 | `docs/任务规划/数据可信.md` 原编号规范 §4.3 | -| 「卡」+ 数字 6 | 下游常数按工程量重定 | `docs/任务规划/数据可信.md` §2.3 | -| 「卡」+ 数字 7 | 量纲回归用例 | `docs/任务规划/数据可信.md` 原编号规范 §3 退出判据第 ⑥ 条;用例在 `test/host/prot_dim` | -| 「卡」+ 数字 8 | 遥测快照发布 | `docs/任务规划/数据可信.md` §4.5 | -| 「卡」+ 数字 9 | 104 改读快照 | `docs/任务规划/数据可信.md` §4.5 | +| 「卡」+ 数字 0b | 端子/子板变比确认 | 原数据可信 5 节;缺口面 = `docs/硬件平台/ADC通道映射说明.md` §7.1 链路分段表 ④ 行 | +| 「卡」+ 数字 1 | 量程口径冻结 | 原数据可信 2.1 节 | +| 「卡」+ 数字 2 | 标定折算落地 | 原数据可信 4.1 节 | +| 「卡」+ 数字 3 | 有符号零点类型(CFG_VAL_INT) | 原数据可信 4.4 节 | +| 「卡」+ 数字 4 | 标定落盘与整定入口 | 原数据可信 4.4 节 | +| 「卡」+ 数字 5 | 未标定即闭锁 | 原数据可信 4.3 节 | +| 「卡」+ 数字 6 | 下游常数按工程量重定 | 原数据可信 2.3 节 | +| 「卡」+ 数字 7 | 量纲回归用例 | 原数据可信 3 节 退出判据第 ⑥ 条;用例在 `test/host/prot_dim` | +| 「卡」+ 数字 8 | 遥测快照发布 | 原数据可信 4.5 节 | +| 「卡」+ 数字 9 | 104 改读快照 | 原数据可信 4.5 节 | | 「卡」+ 数字 10 | 运行参数段 | `App/algo/run_par.h` 头注释 + `docs/子系统设计/IEC104上行设计说明.md` | | 「卡」+ 数字 11 | 频率点绑定 | `docs/子系统设计/IEC104上行设计说明.md` 的 `0x401D` 行 | -| 「卡」+ 数字 12 | 两点标定 | `docs/任务规划/数据可信.md` 原编号规范 §5(未开始,等标准源) | +| 「卡」+ 数字 12 | 两点标定 | 原数据可信 5 节(未开始,等标准源) | **本表把形态写成「卡」+ 数字、不复述字面量**:本文是门禁语料,复述形态会把"讲规则的文档"变成 自己的引用站点(§9.1 批次四第 2 条同一条教训);要查旧号,看左列形态 + 属主文档的历史行。 @@ -270,7 +270,7 @@ P-6 号必须能反查到定义(属主登记处得存在)· P-7 编号不语 - **旧号永久作废、不得重新取走**:这一族**没有机器识别面**(中文前缀不进语料),停发今天只有 原编号规范 §4.1.1 本行 + 本表 + 评审兜住。要机械化,得先给"中文前缀 + 数字"设计候选形态——那与 §9.1 末尾 「族级加字面量上限」同属追溯机制改造,**按 §7.3 单独开卡**,别夹在清退批里顺手做。 -- **同形态不同属主**:`docs/任务规划/UI补齐.md` 的条目现在写「第 N 项」,历史上被别处写成同一形态的 +- **同形态不同属主**:UI 补齐执行清单(已删除,2026-11-09 整体销项)的条目当时写「第 N 项」,历史上被别处写成同一形态的 4 处(其实指已入库的 `[comm]` 段前置项)已随本批改成不带号的语义形态。同一裸形态跨两个属主文档, 正是 原编号规范 §4.1「别拿同形当同族」的实证——清号必须**按属主文档逐处判语义**,不许全局查找替换。 - **不在本批的**:里程碑号(字母 M + 数字)与并行道号(道A/道D/道G)一律保持原样,是否清退等用户 diff --git a/scripts/ram_baseline.tsv b/scripts/ram_baseline.tsv index 5b45cf50..68d4bae6 100644 --- a/scripts/ram_baseline.tsv +++ b/scripts/ram_baseline.tsv @@ -18,3 +18,4 @@ date code ro rw zi er_irom1 er_pct iram1 iram1_pct ccm ccm_pct top_rwzi 2026-11-03 249112 29836 2052 149996 278948 26.6 94624 72.2 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132 2026-11-04 254332 30824 2072 150104 285156 27.2 94752 72.3 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6236;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132 2026-11-05 254820 30896 2072 150104 285716 27.2 94752 72.3 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6236;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132 +2026-11-09 255160 31204 2080 152152 286364 27.3 96808 73.9 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;nand_ftl.o=8288;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132 diff --git a/scripts/size_attestation.json b/scripts/size_attestation.json index 825265f4..69a020b2 100644 --- a/scripts/size_attestation.json +++ b/scripts/size_attestation.json @@ -1,25 +1,25 @@ { - "built_at": "2026-11-07T21:54:57+08:00", - "fingerprint": "d0c0ee6de624bacff30a5a05a35f633315ae7d94c174d287897184b338736205", + "built_at": "2026-11-09T16:09:17+08:00", + "fingerprint": "a7e57c2a7e70ba95944f64b9254e5ec3ed4c0b4482dfc73276912cf53bea4df5", "fingerprint_files": 1479, "fingerprint_source": "git-index", "gated_regions": [ "RW_IRAM1", "RW_CCM" ], - "git_head": "06baf7a53123781cb7a830407e81c7c5f1c5623b", + "git_head": "7027718dcd67cfe84128b9dabf3acc53b5cf740c", "map": "MDK-ARM/STM32F407-Demo/STM32F407-Demo.map", - "map_mtime": 1794059567, + "map_mtime": 1794211736, "pct": { - "ER_IROM1": 27.25, + "ER_IROM1": 27.31, "RW_CCM": 87.89, - "RW_IRAM1": 72.29, + "RW_IRAM1": 73.86, "UNINIT_CCM": 18.75 }, "regions": { "ER_IROM1": { "max": 1048576, - "size": 285716 + "size": 286364 }, "RW_CCM": { "max": 65280, @@ -27,7 +27,7 @@ }, "RW_IRAM1": { "max": 131072, - "size": 94752 + "size": 96808 }, "UNINIT_CCM": { "max": 256, @@ -37,10 +37,10 @@ "schema": 2, "scope_note": "\u540c\u7801\u51ed\u8bc1\uff1a\u6307\u7eb9\u8986\u76d6\u56fa\u4ef6\u4f53\u79ef\u76f8\u5173\u6e90\u7801\uff0c\u53e3\u5f84\u89c1\u672c\u811a\u672c docstring", "sizes": { - "code": 254820, - "ro_data": 30896, - "rw_data": 2072, - "zi_data": 150104 + "code": 255160, + "ro_data": 31204, + "rw_data": 2080, + "zi_data": 152152 }, "threshold_pct": 92.0, "worktree_dirt_at_stamp": 0, diff --git a/simulator/main.c b/simulator/main.c index 7de794aa..a22032ae 100644 --- a/simulator/main.c +++ b/simulator/main.c @@ -920,8 +920,8 @@ static const ui_soe_reader_t s_soe_reader = { sim_soe_count, sim_soe_get }; * 函数说明:模拟器不链接装配器(无硬件数据源;真值还会让像素参考天天变), * 这里发布一帧**固定合成值**,页面数据来源因此可注入——像素回归不再 * 依赖真实硬件(UI_数据供给设计说明.md §9.2)。要点三条: - * 1. eng 固定 = UI_DATA_ENG_PIN,与真机未标定态同口径(数据可信.md - * §2.6 承诺边界 = 引脚电压),页面据此显示"未标定"; + * 1. eng 固定 = UI_DATA_ENG_PIN,与真机未标定态同口径 + * (docs/算法/采集与算法层设计说明.md §13.5 承诺边界 = 引脚电压),页面据此显示"未标定"; * 2. build_date 用固定串而**不是** __DATE__——否则跨天重建会把装置 * 信息页的黄金参考刷掉(黄金参考是判据本身,不得随手刷); * 3. 定值取 prot_set 出厂默认(App/algo/prot_set.c 是纯算法,双端可编), diff --git a/test/host/adc_cal/adc_cal_test.c b/test/host/adc_cal/adc_cal_test.c index b609fee0..4321ecde 100644 --- a/test/host/adc_cal/adc_cal_test.c +++ b/test/host/adc_cal/adc_cal_test.c @@ -6,7 +6,7 @@ * 虚拟盘,同 cfg_file 套件先例)、syslog_post(计数)、 * adc_input_desc()(按 ADC通道映射说明.md 权威表给 V0.1 来源映射)。 * - * 为什么必须主机侧(数据可信 §2.6):板端无标准源,「读数 = 系数 × 码值」 + * 为什么必须主机侧(docs/算法/采集与算法层设计说明.md §13.5):板端无标准源,「读数 = 系数 × 码值」 * 这一根本判据在台架上不可验;Q16 舍入、系数翻倍口径、负零点落盘、合法带 * 哨兵漏放,只有离线端能用独立推导的期望值 + 坏文件注入一次性钉死。 * diff --git a/test/host/adc_cal/run_unit_test.py b/test/host/adc_cal/run_unit_test.py index 0096bf6a..35bf463a 100644 --- a/test/host/adc_cal/run_unit_test.py +++ b/test/host/adc_cal/run_unit_test.py @@ -10,7 +10,7 @@ 工具链探测 / 编译运行全部委托 test/host/common/unit_test_harness.py。 为什么要主机侧单测(而不是只用板端套件): - 标定折算的判据是"读数 = 系数 × 码值"——板端**无标准源**(数据可信 §2.6), + 标定折算的判据是"读数 = 系数 × 码值"——板端**无标准源**(docs/算法/采集与算法层设计说明.md §13.5), 系数错、Q16 舍入错、哨兵漏放、负零点落盘错,在台架上全都看不出来; 主机侧用独立推导的期望值 + 坏文件注入把它们一次性钉死。 @@ -18,7 +18,7 @@ python test/host/adc_cal/run_unit_test.py 退出码:0=PASS / 1=测试失败 / 2=环境错误。 -设计依据:docs/任务规划/数据可信.md 标定折算与落盘整定(道A); +设计依据:docs/算法/采集与算法层设计说明.md §13 标定折算与落盘整定(道A); 创建日期:2026-10-25 """ import os diff --git a/test/host/meas/meas_test.c b/test/host/meas/meas_test.c index eefa68f6..19fa8bb1 100644 --- a/test/host/meas/meas_test.c +++ b/test/host/meas/meas_test.c @@ -12,7 +12,7 @@ * * 覆盖点(TC-MEAS-xxx;属主登记处 = 本目录,族 TC-HOST-MEAS): * TC-MEAS-001 init 语义:seq=0 / get=-2 且清零填充 / 发布后可见 / init 幂等复位 - * TC-MEAS-002 布局钉死(docs/任务规划/数据可信.md §4.5):sizeof=72 + 八字段偏移 + * TC-MEAS-002 布局钉死(docs/算法/采集与算法层设计说明.md §13.9):sizeof=72 + 八字段偏移 * TC-MEAS-003 窗不足发布:seq=1 照常发布,电气 8 路 + TEMP 全 IV|NT,valid=0 * TC-MEAS-004 基波有效值透传:50 Hz 整周波窗 yc = A/√2(≤0.1 %),零幅路=0 且品质 0 * TC-MEAS-005 同拍同值(§4.5"从相量使用区取"口径钉死):yc[UA/UN/IA] 与 diff --git a/test/host/meas/run_unit_test.py b/test/host/meas/run_unit_test.py index 65e6ce6b..5a9aaeec 100644 --- a/test/host/meas/run_unit_test.py +++ b/test/host/meas/run_unit_test.py @@ -11,7 +11,7 @@ 工具链探测 / 编译运行全部委托 test/host/common/unit_test_harness.py。 为什么要主机侧单测(而不是只等台架): - 遥测快照发布(docs/任务规划/数据可信.md)判据一半是并发与结构类——双区撕裂窗在 + 遥测快照发布(docs/算法/采集与算法层设计说明.md §13)判据一半是并发与结构类——双区撕裂窗在 台架上不可观测,削顶品质要等两点标定才真实出现;读数与注入源比对类 判据仍归台架(实测采样类,本套件不覆盖)。 @@ -21,7 +21,7 @@ python test/host/meas/run_unit_test.py 退出码:0=PASS / 1=测试失败 / 2=环境错误。 -设计依据:docs/任务规划/数据可信.md 遥测快照发布(道D,§4.5 快照布局); +设计依据:docs/算法/采集与算法层设计说明.md §13 遥测快照发布(道D,§4.5 快照布局); 创建日期:2026-10-25 """ import os diff --git a/test/host/prot_dim/prot_dim_test.c b/test/host/prot_dim/prot_dim_test.c index 93b7d58a..6fe8a8b9 100644 --- a/test/host/prot_dim/prot_dim_test.c +++ b/test/host/prot_dim/prot_dim_test.c @@ -6,7 +6,7 @@ * 平台依赖桩:dbg_log.h(stub/)、cfg_file_register(捕获计数)、 * adc_input_desc(V0.1 权威来源表,同 adc_cal 套件)。 * - * 本套件的存在理由(短板评测 + 「数据可信」§2.2):台架此前"通过"是因为没有 + * 本套件的存在理由(短板评测 + docs/算法/采集与算法层设计说明.md §13.6):台架此前"通过"是因为没有 * 一条判据检查**不该动作时不动作**——"码值当工程量"的错配曾让 OC 拿 ~11000 * 码值比 10 A 定值恒假动作。本套件把这条固化成回归:用例从 **ADC 码值** 出发、 * **显式写出码值↔二次值换算**,走真实 折算→采样环→全周傅氏→元件判据 链; diff --git a/test/host/prot_dim/run_unit_test.py b/test/host/prot_dim/run_unit_test.py index 590a4cf4..56b9984e 100644 --- a/test/host/prot_dim/run_unit_test.py +++ b/test/host/prot_dim/run_unit_test.py @@ -8,7 +8,7 @@ 用"码值→二次值显式换算"的全链路合成波驱动七类保护元件,钉死 「不该动作时不动作」。工具链细节委托 unit_test_harness.py。 -为什么要这个套件(数据可信 §2.2 / 量纲回归用例): +为什么要这个套件(docs/算法/采集与算法层设计说明.md §13.6 / 量纲回归用例): 台架此前"通过"是因为没有一条判据检查不该动作时不动作——"码值当工程量" 的错配曾让 OC 恒假动作。本套件把换算写进用例:折算点被旁路或量纲再错位, 断言立刻翻转;纯合成数据,零硬件零台架。 @@ -17,7 +17,7 @@ python test/host/prot_dim/run_unit_test.py 退出码:0=PASS / 1=测试失败 / 2=环境错误。 -设计依据:docs/任务规划/数据可信.md 量纲回归用例(M4 退出判据⑥); +设计依据:docs/算法/采集与算法层设计说明.md §13 量纲回归用例(M4 退出判据⑥); 创建日期:2026-10-25 """ import os diff --git a/test/host/run_par/run_unit_test.py b/test/host/run_par/run_unit_test.py index f4512e01..16293276 100644 --- a/test/host/run_par/run_unit_test.py +++ b/test/host/run_par/run_unit_test.py @@ -12,7 +12,7 @@ 退出码:0=PASS / 1=测试失败 / 2=环境错误。 -设计依据:docs/任务规划/数据可信.md(运行参数段)+ docs/子系统设计/IEC104上行设计说明.md §3.4。 +设计依据:docs/算法/采集与算法层设计说明.md §13(运行参数段)+ docs/子系统设计/IEC104上行设计说明.md §3.4。 创建日期:2026-10-25(道D 运行参数段) """ import os diff --git a/tools/arch_diagram/README.md b/tools/arch_diagram/README.md index f43afc26..ffbbf306 100644 --- a/tools/arch_diagram/README.md +++ b/tools/arch_diagram/README.md @@ -23,8 +23,8 @@ | **采集与算法** | | | | | | `ADC前端电路.svg` | `gen_adc_frontend_svg.py` | 端子 → 串阻 → 转换节点 → 转换器引脚;含差分负端与 STM32 侧对照 | `SUB1` / `NOTE_*` 等文案常量 + 面板坐标(电路拓扑固定,网表变了才重画) | `docs/测试说明/专项验证/ADC前端注入验证流程.md`:31、`docs/硬件平台/ADC通道映射说明.md`:161 | | `ADC码值刻度.svg` | `gen_adc_code_scale_svg.py` | 「码」的直观定义:两片转换器的刻度尺对照(16 位双极性 vs 12 位单极性) | `PANELS`(码范围 / LSB / 实测码标记位置)+ `FOOT`(换芯片才重画) | `docs/测试说明/专项验证/ADC前端注入验证流程.md`:104 | -| `ADC直流标定与交流验证.svg` | `gen_data_trust_dc_ac_svg.py` | 上排直流注入链、下排信号发生器正弦验证,中间列只有正弦能证的六件事 | `BOXES_A` / `BOXES_B` 两条泳道 + `CHIPS` 六件事 + `NOTES` 红线与"证不到"清单 | `docs/任务规划/数据可信.md`:294 | -| `数据可信台阶.svg` | `gen_data_trust_ladder_svg.py` | 采集数据可信度的五级台阶:现在踩在哪一级、下一级挡什么 | `STEPS` 五级台阶(状态 / 问题 / 依据)+ `BAND_LABEL_1` / `GATE_LABEL` / `FOOTNOTE`(台阶状态变了才重画) | `docs/任务规划/数据可信.md`:21 | +| `ADC直流标定与交流验证.svg` | `gen_data_trust_dc_ac_svg.py` | 上排直流注入链、下排信号发生器正弦验证,中间列只有正弦能证的六件事 | `BOXES_A` / `BOXES_B` 两条泳道 + `CHIPS` 六件事 + `NOTES` 红线与"证不到"清单 | `docs/算法/采集与算法层设计说明.md §13`:294 | +| `数据可信台阶.svg` | `gen_data_trust_ladder_svg.py` | 采集数据可信度的五级台阶:现在踩在哪一级、下一级挡什么 | `STEPS` 五级台阶(状态 / 问题 / 依据)+ `BAND_LABEL_1` / `GATE_LABEL` / `FOOTNOTE`(台阶状态变了才重画) | `docs/算法/采集与算法层设计说明.md §13`:21 | | `采样有效性校验数据流.svg` | `gen_adc_health_flow_svg.py` | 观测计数 → 快照 → 判定 → 位图 → 消费者:三条量车道(TPAFE / STM32 / 时基)平行流过五个阶段 | `STAGES` 五阶段 + `LANES` 三条车道 + `COLS` + `FOOT` | `docs/算法/采样有效性校验设计说明.md`:81 | | `采样有效性位图与掩码.svg` | `gen_adc_health_bitmap_svg.py` | 出口位图与消费者掩码对照——同一 bit 在三张位图与四个掩码里落同一列(Mermaid 控不住列位,故必须等宽网格) | `GROUPS` 位图组 + `C_LEVEL` / `C_LATCH` / `C_EVENT` / `C_MASK` 四类位 + `WARN` / `FOOT` | `docs/算法/采样有效性校验设计说明.md`:303 | | `采样有效性判定时间轴.svg` | `gen_adc_health_timeline_svg.py` | 四个工况的时序与门限(100 ms 门限线、静默计时线、电平位与锁存位的存续区间——按时间比例画,Mermaid 只画拓扑不保比例) | `PANELS` 四工况 + `T_MAX` / `V_MAX` 比例轴 + `WARN` / `FOOT` | `docs/算法/采样有效性校验设计说明.md`:212 | diff --git a/tools/arch_diagram/gen_ac_median_svg.py b/tools/arch_diagram/gen_ac_median_svg.py index 9da983a2..8c286996 100644 --- a/tools/arch_diagram/gen_ac_median_svg.py +++ b/tools/arch_diagram/gen_ac_median_svg.py @@ -58,7 +58,7 @@ C_AMBER = "#d97706" # ----------------------------- 数据(改这里) ----------------------------- TITLE = "交流轮为什么连取 10 行、取中位数 —— 机理与操作" -SUB1 = ("meas: 是瞬时基波有效值透传:200 ms 是上送节拍、不是平均窗(数据可信 §4.5)——" +SUB1 = ("meas: 是瞬时基波有效值透传:200 ms 是上送节拍、不是平均窗(§13.9)——" "单行可能恰好抓到波峰或波谷,毛刺行会拖偏算术平均,中位数对两头都钝感") # 十行 ua_mv(1 mV 分辨率):第 9 行是偶发毛刺行 diff --git a/tools/arch_diagram/gen_ac_rounds_svg.py b/tools/arch_diagram/gen_ac_rounds_svg.py index 5303d859..4efd9824 100644 --- a/tools/arch_diagram/gen_ac_rounds_svg.py +++ b/tools/arch_diagram/gen_ac_rounds_svg.py @@ -80,7 +80,7 @@ LABEL_W = 36 # 「注入 / 判据 / 读数」标签列宽 TITLE = "交流动态验证六轮 —— 每一轮注什么信号、读哪个口" SUB1 = ("一卡一轮:注入信号缩略图 → 接法与设定 → 判据一句话 → 数字从哪儿读。" "先看图建立全局轮廓,再按 §8.5 的对应执行卡逐轮跑") -SUB2 = ("六轮共用同一套接线与通用动作;过判据的属主是 docs/任务规划/数据可信.md §4.6.2," +SUB2 = ("六轮共用同一套接线与通用动作;过判据的属主是 采集与算法层设计说明.md §13.10," "本图只是导航,不含新判据") # 每卡:(轮名, 角标, 主色, 底色, 波形类型, 注入, 判据, 读数的地方)