From f10869f04809efbd6920955022e9aa68cf56dd5e Mon Sep 17 00:00:00 2001
From: Wanderingss <1624155937@qq.com>
Date: Wed, 28 Oct 2026 08:55:21 +0800
Subject: [PATCH] =?UTF-8?q?docs(=E4=BA=A7=E5=93=81=E9=9C=80=E6=B1=82):=20?=
=?UTF-8?q?=E6=94=B9=E4=B8=BA=201:1=20=E5=A4=8D=E5=88=BB=E5=8F=A3=E5=BE=84?=
=?UTF-8?q?=E5=B9=B6=E8=A1=A5=E5=8F=82=E8=80=83=E6=BA=90=E7=A0=81=E5=AE=9E?=
=?UTF-8?q?=E6=B5=8B=E6=B8=85=E5=8D=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
参考工程 Scatter_P_HV03.01_SV01.01 的源码常量表是唯一需求清单,
不再引用其分析文档(实测有两处不准:元件 89 vs 实为 45、
定值约 260 vs 实为 249)。
- 2.4 范围反转为参考能力全集,只允许 5 项不可移植项落在范围外
- 2.5 重写为 1:1 复刻基线:19 项能力清单、104 八段地址表、
定值 23 单元分布、45 元件九类归集、规约全集、差异归因
- 更正 104 段基址笔误:参考 Rly_IEC104.h 为 1 起编,
遥测 0x4001、遥控 0x6001(旧文档写 4000H+ / 6000H+)
- 9 重写为复刻进度与路线图,缺口分阻塞型与规模型两表
- 5.9~5.15 补全采集链与 104 需求,6.8 点表摘要补差额说明
---
docs/产品需求/产品需求设计文档.md | 859 ++++++++++++++++++++++++++----
1 file changed, 766 insertions(+), 93 deletions(-)
diff --git a/docs/产品需求/产品需求设计文档.md b/docs/产品需求/产品需求设计文档.md
index 40380e13..1dcf4b73 100644
--- a/docs/产品需求/产品需求设计文档.md
+++ b/docs/产品需求/产品需求设计文档.md
@@ -7,9 +7,14 @@
> 待实现项与路线图、验收判据。
> **事实来源**:本文所有数值与结论均取自仓库内**受管事实源**(代码、`.ioc`、`.map`、网表分析报告与
> 各模块设计文档),凡与其它文档冲突处,以本文标注的权威来源为准。
-> **版本**:v1.0 **日期**:2026-10-05 **状态**:现状基线(含已实现项 + 待实现项)
+> **版本**:v1.2 **日期**:2026-10-27 **状态**:现状基线(含已实现项 + 待实现项)
> **阅读前提**:建议先读 [`docs/README.md`](../../docs/README.md)(文档索引)与
> [`docs/架构设计/项目架构总览.md`](../../docs/架构设计/项目架构总览.md)(全景架构)。
+> **范围口径:1:1 复刻**——本产品是参考产品 **CLS100**(`Scatter_P_HV03.01_SV01.01`,OMAP-L138
+> ARM+DSP 双核 + VxWorks 配电保护测控装置)的**逐模块复刻**。产品范围 = 参考源码的能力全集,
+> 差异只允许来自物理不可移植项(§2.4.1)。§2.5 以**参考工程源码的常量表与模块文件**为唯一清单,
+> 给出 19 项能力对照与复刻进度;§9 的缺口一律表述为"复刻进度"而非"不做"。
+> 产品定义的技术细化见 [`docs/算法/继电保护功能复现规划.md`](../算法/继电保护功能复现规划.md)。
---
@@ -44,6 +49,20 @@
| **就绪屏障** | 用 CMSIS-RTOS2 Event Flags 表达"子系统就绪"的启动顺序机制 |
| **双端** | MCU(Keil/ARMCC)与 PC 模拟器(CMake/MSVC)共用同一份 UI/配置源码 |
| **@build / @test** | 仓库约定的构建 / 自动化测试命令别名 |
+| **L1 / L1.5 / L2 / L2.5 / L3** | 采集链路分层:语义取数与有效性(L1)→ 标定折算(L1.5)→ 全周傅氏相量(L2)→ 测频与遥测快照(L2.5)→ 保护判据(L3) |
+| **全周傅氏** | 单频 DFT 取基波相量,窗长 = 整周波(20 点);幅值即基波有效值 |
+| **相量** | `{fRe, fIm, fAm, fAmSQ}`,实部 / 虚部 / 幅值 / 有效值 |
+| **双区交换** | 相量(及遥测快照)计算区 / 使用区索引单字节翻转,读者无锁取整份快照 |
+| **等周波采样** | 软件测频 + 调采样周期,使窗长恒等于实际周波(严格 20 点/周波) |
+| **标定 k / b** | 通道折算系数(µV/码,Q16 定点)与零点(码值);`工程量 = (code + b) × k` |
+| **QDS** | IEC 60870-5-104 的品质描述符字节(OV / NT / IV 等位) |
+| **SOE** | Sequence of Event,带时标的事件顺序记录(本产品落 `/log/soe.log`) |
+| **CP56Time2a** | 104 的 7 字节时标格式(毫秒 / 分 / 时 / 日 / 月 / 年 + 时标标志位) |
+| **点表 / IOA** | 104 上送对象表与信息体地址;本产品点表口径见 §6.8 |
+| **固有 / 运行 / 保护定值** | 三类参数:只读身份信息、可整定的运行参数、可整定的保护定值(§5.13) |
+| **软压板** | 软件投退开关(全局软压板 = 保护总投入,可经 104 遥控投退) |
+| **遥测死区** | 遥测变化上送门槛;本产品按"连续 2 个新测量点越限才确认" |
+| **CLS100** | 参考产品(配电保护测控装置,ARM + DSP 双核 / VxWorks),仅作能力对照,非本产品代次 |
### 1.3 读者与相关文档
@@ -64,12 +83,17 @@
**以太网通信、SPI NAND 存储、ADC 采集、RS-485 通信与 FTP 文件服务**,并自带
**远程显示(UI 推流)、墙钟对时、看门狗自恢复、运行/自检记录**等工业现场能力。
-它既是一台可独立部署的现场设备(通过以太网与远端客户端交互),也是一套
-**可复用的平台底座**——后续产品(保护测控、馈线自动化终端等)在此底座上补齐采集与协议。
+它的**产品目标是 1:1 复刻参考产品 CLS100**(配电保护测控装置)——按参考工程源码的
+常量表与模块文件逐项对齐点表、定值、保护元件与规约栈(§2.4、§2.5)。在此过程中沉淀出的
+分层底座(采集链 L1~L4、配置引擎、就绪屏障、双端测试)同时是可复用的平台能力。
> **产品现状一句话**:平台能力(网络 / 存储 / 时间 / UI / 日志 / 看门狗 / FTP / 配置)
-> **已实现并台架验收**;DTU 的**核心采集职责(ADC / RS-485)尚未接线**,是当前最大功能缺口
-> (见 §9)。这不是缺陷难修,而是**产品定义未落定**。
+> **已实现并台架验收**;采集主线(L1 采集 → L1.5 标定 → L2 相量 → L2.5 遥测快照 → L3 保护判据
+> → L4 SOE → IEC 60870-5-104 上送)**软件链路已全线贯通并台架闭环**;与参考产品的差距
+> 集中在三处:① 保护判据处于**未标定闭锁**态(等标准源两点标定)、② **点表规模**远小于参考
+> (定值 40 vs 249 项、遥测 9 vs 31 点、开入开出 0 vs 138/31 点)、③ **独立子系统未立项**
+> (故障录波、电度、多规约、SNTP)。即:**"数"与"判据"已可信到引脚电压口径,
+> 缺的是标定、点表铺开与一次设备接口**(明细见 §2.5.2、§9)。
### 2.2 产品形态与部署
@@ -106,7 +130,7 @@ flowchart LR
| # | 目标 | 落地手段 |
|---|---|---|
| G1 | **可靠**:现场死机可自恢复、掉电不丢配置、错误可追溯 | IWDG + 任务心跳位图、原子写 + 迁移、错误码通道四要素 |
-| G2 | **可维护**:分层解耦、单一事实源、双端复用、门禁强制 | 六层架构、就绪屏障、生成器(菜单/字体/任务表)、pre-commit 18 钩子 |
+| G2 | **可维护**:分层解耦、单一事实源、双端复用、门禁强制 | 六层架构、就绪屏障、生成器(菜单/字体/任务表)、pre-commit 钩子族 |
| G3 | **可移植**:UI/配置源码 MCU 与 PC 模拟器共用 | 平台后端抽象(`*_mcu.c` / `*_sim.c`),核心零平台依赖 |
| G4 | **可扩展**:新子系统/新配置段/新页面按模板接入 | 事件位扩展、段注册三步、页面插件描述符、`App/protocol/` 预留 |
| G5 | **可验收**:每项能力有明确判据与自动化门禁 | `@build` / `@test` / L0 静态 / L0.5 主机侧单测 / 台架验证 |
@@ -118,14 +142,203 @@ flowchart LR
3. **能推导的就不存**——持久化"不可推导"的状态(导航历史、配置、日志),其余现算。
4. **单写者**——配置文件属主 = `defaultTask`;syslog 唯一写者 = `defaultTask`;控制台唯一发送者 = `defaultTask`。
5. **一切写入 = 临时文件 + rename**(原子替换),半截窗口结构消除。
+6. **测量不可信就不判据**——未标定(VALID 未置位)或采样故障时保护停走,品质位如实上送,
+ 绝不用"看起来对"的数去动作(§5.12、§5.15)。
+7. **点表优先于实现**——本期做不了的 104 点照常入表并置 IV;缺行比置 IV 更糟,
+ 主站将无法区分"没做"与"接线错"(§6.8)。
-### 2.4 产品范围
+### 2.4 产品范围(1:1 复刻口径)
-**本期(已实现)**:网络通信与配置、NAND 存储栈、时间子系统、运行/自检记录、UI 远程显示、
-看门狗、FTP 服务、LED 指示、启动屏障与任务调度。
+**产品范围 = 参考产品 CLS100 的可移植能力全集。** 本产品不是"在参考产品里挑一部分做",
+而是**按参考工程源码逐模块复刻**:凡参考源码中存在的点表、定值单元、保护元件、记录类型、
+规约栈,都属本产品目标范围;差异只允许来自**物理不可移植项**(§2.4.1)。
-**非本期(待实现 / 待定义)**:ADC 采集链路、RS-485 采集链路与协议状态机、DTU 核心转发职责
-(MODBUS RTU / 上行 TCP 等,取决于产品定义)、UI 部分叶子内容页、SNTP 客户端等。
+范围按**复刻完成度**分三档,判定口径见 §2.5.1:
+
+| 档 | 含义 | 处置 |
+|---|---|---|
+| ✅ **已对齐** | 参考源码能力在本产品上已实现,且有台架/单测证据 | 进 §10 验收判据 |
+| 🔶 **部分对齐** | 骨架、口径、地址编排已对齐,覆盖范围小于参考(通道数 / 元件数 / 点数) | 差额逐条进 §9 |
+| ⬜ **未开始** | 参考源码存在、本产品无对应实现 | 逐条进 §9,**不等于"不做"** |
+
+**当前分布**(19 项能力,明细见 §2.5.2):✅ **2 项**(采样节拍、自检类型)、🔶 **9 项**、
+⬜ **7 项**、— **1 项**(双核分工,不可移植)。
+
+#### 2.4.1 不可移植项(唯一允许落在范围外的部分)
+
+| # | 不可移植项 | 参考实现 | 本产品 | 归因 |
+|---|---|---|---|---|
+| X1 | 双核 ARM + DSP 分工 | OMAP-L138(ARM 跑通信/HMI,DSP 跑保护) | 单核 Cortex-M4F 按任务划分承担 | 芯片形态 |
+| X2 | 实时操作系统与工具链 | VxWorks 5.x + CCS | FreeRTOS V10.3.1 + Keil ARMCC | 平台形态 |
+| X3 | 本地人机 | 板载 LCD + 按键 | 无屏:160×160 1bpp TCP 推流 + 远端按键(§8) | 硬件形态 |
+| X4 | 一次设备接口 | KO / KI 板卡(出口、开入、硬压板) | V0.1 无该硬件(§4.6 H3) | 硬件缺失 |
+| X5 | 独立计量通道 | 专用计量芯片(电度) | 无(跨转换器无同刻,§4.6 H1) | 硬件缺失 |
+
+> **X1~X5 是范围外项的全部。** 除此以外**不存在"参考有、我们决定不做"的能力**——
+> v1.1 曾把故障录波、开入开出、多规约、SNTP 等列为"非本期/不做",与 1:1 复刻口径冲突,
+> 本版已全部改为"未开始"并入 §9。
+
+### 2.5 1:1 复刻基线(参考源码能力清单)
+
+**判定口径**:本节所有"参考能力"的数字,**一律从参考工程源码的常量表与模块文件中直接统计**,
+不引用参考项目自带的 `docs/` 与 `项目分析文档/`——那些是二手描述,与源码存在偏差
+(实测已发现"89 个元件模块"实为 45 个、定值"约 260 项"实为 249 项两处偏差)。
+每行均标注"源码出处",可原样复核。
+
+#### 2.5.1 复刻基线三要素
+
+1. **点表即契约**:参考源码用常量表(`g_t*Tab[]`)定义点表、定值、事件、压板。
+ 这些表就是"要复刻什么"的**唯一清单**——表有几行,目标就有几个点。
+2. **地址即接口**:104 的 IOA 由 `Rly_IEC104.h` 的基址宏划分段,**段基址必须逐字对齐**(§2.5.3)。
+3. **模块即元件**:`RelayUnit/` 下一个 `.c` 对应一个保护元件,元件数 = 文件数(§2.5.5)。
+
+#### 2.5.2 能力清单与复刻进度(源码实测)
+
+| # | 能力 | 参考源码出处 | 参考数量 | 本产品现状 | 状态 |
+|---|---|---|---|---|---|
+| 1 | 定值项 | `APP/EquipCfg/Const_Set.c` `g_tSetModelTab` | **249 项** | 40 项(`PS_ID_COUNT`) | 🔶 |
+| 2 | 定值单元 | `APP/EquipCfg/Const_Set.h` `EN_SET_CELL_*` | **23 个有项**(枚举 28) | 5 组(短路/接地/过负荷/电压/频率) | 🔶 |
+| 3 | 104 定值映射 | `Comm/Pub/Const_CommSetPara.c` `g_tCommSetParaTab` | **107 项**,`0x8820~0x8891` | 40 项(`0x8820~0x8890` 局部) | 🔶 |
+| 4 | 遥测 YC | `APP/EquipCfg/Const_Ana.c` `g_tYcIndexTab` | **31 点** | 9 点(`0x4011~0x4018` + `0x401D`) | 🔶 |
+| 5 | 遥测模型 | 同上 `g_tAnaModelTab` | 35 行 | 0 | ⬜ |
+| 6 | 电度 YM | 同上 `g_tYmIndexTab` | **8 种** | 0 | ⬜ |
+| 7 | 开入 KI | `APP/EquipCfg/Const_IO.c` `g_tInputModelTab` | **138 点** | 0(无硬件,X4) | ⬜ |
+| 8 | 开出 KO | 同上 `g_tOutputModelTab` | **31 点** | 0(无硬件,X4) | ⬜ |
+| 9 | 动作事件 | `APP/EquipCfg/Const_Rec.c` `g_tActRecTab` | **33 条**(421~453) | 7 类记录(`App/log/sys_log.h`) | 🔶 |
+| 10 | 录波测量通道 | 同上 `g_tMeasureModelTab` | **65 通道** | 0 | ⬜ |
+| 11 | 软压板 | `APP/EquipCfg/Const_Soft.c` `g_tSoftTab` | **9 面**(表容量 32) | 1 面(`PS_GLOBAL_EN`) | 🔶 |
+| 12 | 保护元件 | `RelayUnit/*.c` | **45 个模块** | 9 个实例 | 🔶 |
+| 13 | 记录队列 | `RecUnit/RecFile.c` + `GlobalDef/Const_Sys.h` | **13 类**(128/256 条) | 8 通道(7 文本 + SOE) | 🔶 |
+| 14 | 自检类型 | `GlobalUnit/SelfChk.c` | **3 类型 + 2 闭锁** | 3 类 | ✅ |
+| 15 | 故障录波 | `APP/EquipCfg/Const_Wave.h` | **3 类型 / 6 段 / RAM 16 个** | 0 | ⬜ |
+| 16 | 采样节拍 | `APP/EquipCfg/Const_VisEquip.h` | **20 点/周波**(50 Hz) | 20 点/周波(1000 Hz) | ✅ |
+| 17 | 上行规约 | `Comm/Pub/`、`Comm/Mon/` | **12 种** | 1 种(104) | 🔶 |
+| 18 | 加密算法 | `Comm/Ecc/` | SM2 / SM3 / ECDSA | 0 | ⬜ |
+| 19 | 双核分工 | `CLS100_Arm/`、`CLS100_Dsp/` | ARM + DSP | 单核(X1) | — |
+
+> **读法**:🔶 / ⬜ 行**全部是待办**,逐条对应 §9.1;`—` 只出现在 X1~X5 不可移植项上。
+> 本表是范围判定的唯一出处,§9 不再重复解释"为什么缺"。
+
+#### 2.5.3 104 地址空间(段基址逐字对齐)
+
+| 段 | 基址 | 范围 | 容量 | 本产品使用 |
+|---|---|---|---|---|
+| 遥信 YX | `0x0001` | `0x0001~0x1000` | 4096 | 定义 1~31,有效 6(YX15~18/23/31) |
+| 保护 BH | `0x1001` | `0x1001~0x4000` | 12288 | 0 |
+| 遥测 YC | `0x4001` | `0x4001~0x5000` | 4096 | `0x4011~0x4018`、`0x401D` |
+| 参数 PM | `0x5001` | `0x5001~0x6000` | 4096 | 0 |
+| 遥控 YK | `0x6001` | `0x6001~0x6200` | 512 | `0x600A`(信号复归)、`0x600B`(全局压板) |
+| 设定 YS | `0x6201` | `0x6201~0x6400` | 512 | 0 |
+| 电能 YM | `0x6401` | `0x6401~0x6600` | 512 | 0 |
+| 步位置 STEP | `0x6601` | `0x6601~0x6700` | 256 | 0 |
+
+> ⚠ **段基址是 `0x4001` / `0x6001`,不是 `0x4000` / `0x6000`**。参考源码
+> `Comm/Pub/Rly_IEC104.h` 的 `CONST_104_BASEADDR_YC` / `_YK` 明确 1 起编
+> (注释即写 `4001-5000H`、`6001-6200H`)。本仓 v1.1 及更早文档按 `4000H+` / `6000H+` 描述
+> 属笔误,以本表为准;§5.15、§6.8 已同步更正。
+
+#### 2.5.4 定值单元(23 个有项单元,合计 249 项)
+
+| 单元 | 语义 | 项数 | 本产品 |
+|---|---|---|---|
+| `EN_SET_CELL_WatchDog` | 看门狗功能 | 63 | ⬜ |
+| `EN_SET_CELL_SYS3` | 系统参数 | 45 | 🔶 |
+| `EN_SET_CELL_VolTimeRecv` | 电压时间型自愈 | 17 | ⬜ |
+| `EN_SET_CELL_AutoReCls` | 重合闸 | 16 | ⬜ |
+| `EN_SET_CELL_SYN` | 同期元件(FTU 型) | 13 | ⬜ |
+| `EN_SET_CELL_OverCurI0` | 接地告警 | 13 | 🔶 |
+| `EN_SET_CELL_VolPro` | 电压保护 | 13 | 🔶 |
+| `EN_SET_CELL_WAVESTART` | 录波启动 | 12 | ⬜ |
+| `EN_SET_CELL_MeaLimit` | 遥测越限 | 10 | ⬜ |
+| `EN_SET_CELL_OverCurSpeed` | 过流加速 | 8 | ⬜ |
+| `EN_SET_CELL_SYS1` | PT 参数 | 6 | 🔶 |
+| `EN_SET_CELL_SYS2` | CT 参数 | 4 | 🔶 |
+| `EN_SET_CELL_Auto_FG` | 自动分闸 | 4 | ⬜ |
+| `EN_SET_CELL_Auto_HH` | 自动合闸 | 4 | ⬜ |
+| `EN_SET_CELL_InRush` | 励磁涌流闭锁 | 3 | ⬜ |
+| `EN_SET_CELL_OverCur` | 短路告警 | 3 | 🔶 |
+| `EN_SET_CELL_VolQuaRate` | 电压合格率 | 3 | ⬜ |
+| `EN_SET_CELL_FZDDL` | 非遮断电流闭锁 | 3 | ⬜ |
+| `EN_SET_CELL_BHKO` | 保护出口展宽 | 2 | ⬜ |
+| `EN_SET_CELL_MeaRecord` | 遥测记录 | 2 | ⬜ |
+| `EN_SET_CELL_PowerSet` | 功率电压设置 | 2 | ⬜ |
+| `EN_SET_CELL_PTBreak` | PT 断线告警 | 2 | ⬜ |
+| `EN_SET_CELL_AutoCtrl` | 自动控制(活化/复归) | 1 | ⬜ |
+
+> 枚举中另有 4 个单元在参考源码表内**无项**(`EN_SET_CELL_YB_TY` 功能软压板、`OnceCch`
+> 一次重合闸、`TwiceCch` 二次重合闸、`OverLoad` 过负荷保护)——已被条件编译或注释掉,
+> 因此 249 项分布在 **23** 个单元而非枚举的 28 个。另有 3 个单元(`SYN` / `OverCurSpeed` /
+> `VolTimeRecv`)受 `CN_DEV_TYPE_FTU` 宏控制,属 FTU 型专属。
+>
+> **104 定值地址编排**:107 项占 `0x8820~0x8891` 连续段中的 107 个地址,**8 个空洞**
+> (`0x8822`、`0x8823`、`0x883E`、`0x883F`、`0x8842`、`0x8851`、`0x8852`、`0x8853`)
+> 对应参考源码中被注释掉的 4 条映射(`ULTV_PARA_2`、`ULTV_Phase` 等)。
+
+#### 2.5.5 保护元件(45 个模块 → 已复刻 9 个元件 + 1 个记录模块)
+
+按功能归类(`RelayUnit/` 文件名去 `PRS_` 前缀):
+
+| 类别 | 元件模块 | 个数 | 本产品 |
+|---|---|---|---|
+| 过流类 | `OverCurrent`、`OverCurrent_I0`、`OverCurrent_SpeedUp`、`OverCurrentI0_SpeedUp`、`FZDOverCur`、`OverCurWarn`、`OverCurWarn_I0`、`OverLoad` | 8 | 🔶 过流 Ⅰ/Ⅱ/Ⅲ + 过负荷(4) |
+| 电压类 | `OverVol`、`OverVol_U0`、`LackVol`、`LineHaveVol`、`HaveVolCls`、`NoVolTrip`、`PTBreak`、`CTBreak` | 8 | 🔶 过压 / 欠压 / 零序过压(3) |
+| 频率类 | `OverFr`、`LackFr` | 2 | ✅ 过频 / 低频(2) |
+| 重合闸 | `AutoReCls`、`AutoReCls_JD`、`OnceCch`、`TwiceCch`、`ConnectBrkCls` | 5 | ⬜ |
+| 方向 / 功率 | `DirCell`、`PowDirJudge`、`PowerSet`、`YcOverLimit` | 4 | ⬜ |
+| 涌流 / 故障 | `InRushCur`、`FaultIsola`、`FaultRecov`、`BusEarthAlm`、`SgzAlarm` | 5 | ⬜ |
+| 自动控制 | `AutoCtrlTrip`、`ManualTrip`、`MusterRecov`、`ExvRec`、`ExvRecGW` | 5 | ⬜ |
+| 记录类 | `SOERecord`、`CORecord`、`FrzRecord`、`YcMeaRecord`、`YcMeaLimitRec`、`YcVolQuaRate` | 6 | 🔶 SOE 落盘(1,非判据元件) |
+| 录波 / 采样 | `WaveQdCell`、`RlyCommSam` | 2 | ⬜ |
+
+**判据结构对齐**(以 `PRS_OverCurrent.c` 为样板,三段过流共用一个核):
+
+```
+M_GRly_OverRelay(&bRelay, fAmp, fSetStart, fSetRet) 越限 + 返回系数滞回
+ ∧ bFyOpen ∧ bDirOpenX ∧ bNOVOpen 复压 / 方向 / 低压闭锁
+GRly_TimeRelay(&bRelay, &tTimer, dwSetDelay, CN_T10MS) 定时限(10 ms 基准)
+tTimer_KeepKI 电流保持(返回后仍延时保持)
+tTimer_NoUI 无压无流判据(CN_T20MS / CN_T200MS)
+```
+
+> 本产品 `prot_elm.c` 的"越限 + 返回系数滞回 + 定时限"三元核与上述结构**同构**;
+> 差异在于本产品用**每元件独立实例表**替代参考的全局定时器数组——这是单核移植的必要调整,
+> 不改变判据语义。逐元件复刻计划见
+> [`docs/算法/继电保护功能复现规划.md`](../算法/继电保护功能复现规划.md)。
+
+#### 2.5.6 上行规约全集(12 种 → 已复刻 1 种;加密算法另计)
+
+| 方向 | 规约 | 参考源码 | 本产品 |
+|---|---|---|---|
+| 主站侧(对上) | IEC 60870-5-101 | `Comm/Pub/Rly_IEC101.c`、`Rly_IEC101_B.c` | ⬜ |
+| | IEC 60870-5-102(电度) | `Comm/Pub/Rly_IEC102.c` | ⬜ |
+| | IEC 60870-5-103 | `Comm/Pub/RLY_IEC103.c`、`RLY_IEC103-tcp.c`、`Rly_IEC103T.c` | ⬜ |
+| | **IEC 60870-5-104** | `Comm/Pub/Rly_IEC104.c` | ✅ |
+| | ModBus | `Comm/Pub/Rly_ModBus.c` | ⬜ |
+| | CDT | `Comm/Pub/Rly_Cdt.c` | ⬜ |
+| | 国标电度 `Whm_GB` | `Comm/Pub/Whm_GB.c` | ⬜ |
+| | IEC 61850(MMS / GOOSE / SV) | `Comm/Pub/struct61850.h`、`GlobalUnit/SttnLvlGoose.c` | ⬜ |
+| | CAN | `Comm/Pub/Rly_Can.h` | ⬜ |
+| 子站侧(对下) | IEC 101(含 ABB / 西门子 / 无优先级变体) | `Comm/Mon/Rtu_IEC101*.c` | ⬜ |
+| | IEC 104(含调试 / RIS 变体) | `Comm/Mon/Rtu_IEC104.c`、`Rtu_Dbg104.c`、`Rtu_RIS104.c` | ⬜ |
+| | BALA101 / ModBus | `Comm/Mon/Rtu_BALA101*.c`、`Rtu_ModBus.c` | ⬜ |
+| 加密 | SM2 / SM3 / ECDSA | `Comm/Ecc/` | ⬜ |
+
+> **排期判断**:104 已对齐;**对下 ModBus RTU 与 101 是"配网终端"的必要项**(接一次开关 / FTU),
+> 与 RS-485 簇同批解冻;61850 依赖以太网多播与 MMS 栈,单核 M4 资源上需单独评估,属最末批。
+
+#### 2.5.7 差异归因与结论
+
+| 归因 | 涉及条目 | 解除方式 |
+|---|---|---|
+| **外部资源**(标准源、端子变比) | 定值标定、保护判据解卡 | 两点标定(§9.2 第 4 步) |
+| **硬件缺失**(X4 / X5) | 开入 138、开出 31、电度 8、同期、三相通道 | V0.2 硬件 |
+| **立项未排** | 录波、多规约、SNTP、记录 5 页、定值铺开 | 按 §9.2 顺序 |
+| **算力 / 形态**(X1~X3) | 双核分工、VxWorks、本地屏 | 不解除(已用等价方案替代) |
+
+> **结论**:本产品与参考产品的差距**全部是"进度"而非"范围"**——没有一项是"参考有而我们不做"。
+> 已对齐的是**软件骨架**(采样节拍、相量算法、定值模型、104 上行、SOE 落盘、自检闭锁);
+> 未对齐的是**点表规模**(249 / 31 / 138 / 31 / 33 / 65 vs 40 / 9 / 0 / 0 / 7 / 0)
+> 与**独立子系统**(录波、电度、多规约)。因此 §9 统一表述为"复刻进度",不再出现"不做"。
---
@@ -145,7 +358,7 @@ flowchart LR
|---|---|---|---|
| ① 业务层 | `Drivers/BSP/NETCFG/` | 顶层共享配置(被 UI 与基础服务共用) | `net_cfg` |
| ② UI 层 | `Drivers/BSP/UI/` | LVGL 界面(与 PC 模拟器共用源码) | `ui_port` `ui_menu` `ui_menu_view` `ui_menu_tab` `ui_content_page` `ui_page_*` `ui_net_sink` `ui_font_cn_12` `ui_deco` |
-| ③ 基础服务层 | `App/`、`Drivers/BSP/NET/lftpd/` | 应用侧服务与编排 | `app_main` `sys_events` `app_cfg` `task/*` `lftpd` `time_sync` |
+| ③ 基础服务层 | `App/`、`Drivers/BSP/NET/lftpd/` | 应用侧服务、采集算法与协议编排 | `app_main` `sys_events` `app_cfg` `task/*` `algo/*`(L1~L3)`protocol/iec104/*` `log/soe_store` `lftpd` `time_sync` |
| ④ 中间件层 | `Drivers/BSP/NET/`、`Lib/`、`App/util/` | 通用库 / 协议栈 | `net_socket` `net_select` `FatFs` `nand_ftl`(dhara) `LVGL` `sys_clock` |
| ⑤ 驱动层 | `Drivers/BSP/{CH395F,GD5F2GQ5UE,TPAFE5160,SD2506,RS485}/` | 芯片寄存器 / 时序 / 中断 | `ch395f` `gd5f2gq5ue` `tpafe5160` `sd2506` `rs485` |
| ⑥ 内核 / HAL | `Middlewares/`、`Drivers/STM32F4xx_HAL_Driver/`、`Drivers/CMSIS/` | 任务调度、外设 HAL、启动 | FreeRTOS V10.3.1 · STM32 HAL · CMSIS |
@@ -153,19 +366,30 @@ flowchart LR
### 3.2 运行时任务模型
-六个 FreeRTOS 任务(`Src/freertos.c` 创建,任务体在 `App/task/`、`App/sync/`):
+**九个** FreeRTOS 任务(`Src/freertos.c` 创建,任务体在 `App/task/`、`App/sync/`):
-| 任务 | 栈 | 优先级 | 职责 |
+| 任务 | 栈(words / B) | 优先级 | 职责 |
|---|---|---|---|
-| `defaultTask` | 4096 B | Normal | FatFS 挂载(无卷 `f_mkfs`)→ 卷健康探针/自愈 → `net_cfg_load`(配置引擎属主)→ 置 `STORAGE_READY` → 日志落盘(唯一写者)+ 配置保存执行/2s poll + LED 闪烁 + 栈水位观测 + **看门狗唯一喂狗者** |
-| `netTask` | 4096 B | Normal | 等存储 → `net_stack_bring_up()` → 置 `NET_READY` → `net_poll` 轮询(CH395F 操作串行化) |
-| `ftpTask` | 4096 B | Normal | 等网络**且**存储(`WaitAll`)→ `lftpd_start("/", 21)` → 单客户端会话循环 |
-| `testTask` | 8192 B | BelowNormal | 测试套件入口(`test/board/test_config.h` 选择)。**产品构建不创建**(未选套件时立即 `vTaskDelete` 回收其 8 KB CCM 栈) |
-| `uiTask` | 16384 B | BelowNormal | 等网络 → `ui_port_init`/`ui_menu_init`/`ui_standby_init`(空闲 60s 切待机屏)/`ui_net_sink` → 10 ms 刷新 |
-| `timeSyncTask` | 2048 B | Normal | 等网络 → TCP :8888 收 PC 推送时间 → 写 RTC |
+| `defaultTask` | 1280 / 5120 | Normal | FatFS 挂载(无卷 `f_mkfs`)→ 卷健康探针/自愈 → `net_cfg_load` + 定值/运行参数/通讯参数装载(**配置引擎属主**)→ 置 `STORAGE_READY` → 日志落盘(唯一写者)+ 2 s 配置轮询 + 各模块脏位落盘(`prot_set` / `run_par` / `comm`)+ SOE 排空 + LED 闪烁 + 栈水位观测 + **看门狗唯一喂狗者** |
+| `netTask` | 960 / 3840 | Normal | 等存储 → `net_stack_bring_up()` → 置 `NET_READY` → `net_poll` 轮询 + CH395F 操作串行化(消息队列执行者) |
+| `ftpTask` | 1024 / 4096 | Normal | 等网络**且**存储(`WaitAll`)→ `lftpd_start("/", 21)` → 单客户端会话循环 |
+| `testTask` | 2048 / 8192 | BelowNormal | 测试套件入口(`test/board/test_config.h` 选择)。**产品构建不创建**(未选套件时立即 `vTaskDelete` 回收其 8 KB CCM 栈) |
+| `uiTask` | 4096 / 16384 | BelowNormal | 等网络 → `ui_port_init`/`ui_menu_init`/`ui_standby_init`(空闲 60 s 切待机屏)/`ui_net_sink` → 10 ms 刷新 + 数据注入 |
+| `timeSyncTask` | 640 / 2560 | Normal | 等网络 → TCP :8888 收 PC 推送时间 → 写 RTC |
+| `adcTask` | 640 / 2560 | AboveNormal | **采集主线唯一消费者**:每拍 `adc_input_poll()`(TPAFE 快照 + ADC1 DMA 帧)→ `adc_health` 有效性 → `phasor_run()` 相量 → `freq_run()` 测频 → 每 200 ms `meas_tick()` 发布遥测快照 |
+| `iec104Task` | 640 / 2560 | Normal | 等网络 → TCP :2404 监听 → 104 链路状态机(总召/变位/周期/遥控/定值/对时)+ 断链重听 + 网络代次自愈 |
+| `protectTask` | 512 / 2048 | Normal | **20 ms 判据节拍**:采样故障闭锁判定 → 定值校验和巡检 → `prot_elm_run()` 元件判据 → 动作边沿投递 SOE(**不做 NAND I/O**) |
-> `idle`(128 words)/ `timer`(256 words)由 FreeRTOS 内核创建。所有任务栈从 48 KB `heap_4` 堆(CCM)分配。
-> 任务表与 `Src/freertos.c` 的 `osThreadAttr_t` 一致,由 `scripts/gen_task_table.py` 生成并门禁校验。
+> `idle`(128 words)/ `timer`(256 words)由 FreeRTOS 内核创建。所有任务栈从 **56 KB** `heap_4` 堆
+> (CCM)分配;CCM 水位 87.9%(<92% 门禁)。
+> 任务表与 `Src/freertos.c` 的 `osThreadAttr_t` 一致,由 `scripts/gen_task_table.py` 生成并门禁校验;
+> **栈配置与实测余量**见 §7.3,改栈前后必须重跑 `scripts/stack_report.py`。
+>
+> ⚠ **节拍同源**:TIM3 更新事件(1 kHz)同时触发 TPAFE `CONVST` 与(经 TRGO)ADC1 一轮 9 通道扫描,
+> 并在 ISR 内唤醒 `adcTask`——采集节拍与任务唤醒**不允许**各自计时。
+> ⚠ **ADC1 必须在挂 DMA 的瞬间处于关闭态**:`app_main_init()` 步骤 4b-pre 的 `adc1_disable()` 不可删、不可后移,
+> 否则 DMA 乒乓缓冲整体旋转 2 格(表象与"映射表写错"一致)。证据见
+> [`docs/子系统设计/ADC采样节拍设计说明.md`](../子系统设计/ADC采样节拍设计说明.md) §4.5。
### 3.3 就绪屏障(Event Flags)
@@ -183,9 +407,11 @@ flowchart LR
| bit4 | `SYS_EVT_NET_RECONFIG` | 命令位 | UI:请求立即应用新网口配置 |
| bit5 | `SYS_EVT_CFG_SAVE` | 命令位 | UI:网口配置保存请求(defaultTask 消费并写盘) |
| bit6 | `SYS_EVT_CONSOLE_TX` | 命令位 | 控制台单写者:生产者入环形缓冲后置位 |
+| bit7 | `SYS_EVT_PROT_SET_SAVE` | 命令位 | 保护定值落盘请求:104 检测到定值脏后置位,defaultTask 原子写 `/prot_set.bin` |
+| bit8 | `SYS_EVT_RUN_PAR_SAVE` | 命令位 | 运行参数段落盘请求:104 写运行参数后置位,defaultTask 整档外科保存 |
> ⚠️ **铁律**:状态位(bit0~3)表达**持久状态**,任何消费者都**不许消费**——必须
-> `osFlagsWaitAny|osFlagsNoClear`。命令位(bit4~6)表达"请做一件事",必须**恰好被消费一次**(消费型等待)。
+> `osFlagsWaitAny|osFlagsNoClear`。命令位(bit4~8)表达"请做一件事",必须**恰好被消费一次**(消费型等待)。
> 历史事故:就绪位被先到的等待者消费,导致 `ftpTask` 的 `WaitAll(bit0|bit1)` 永不成立、21 端口从未监听(静默)。
### 3.4 启动时序
@@ -198,34 +424,46 @@ sequenceDiagram
participant K as osKernelStart
participant D as defaultTask
participant N as netTask
+ participant S as adcTask / protectTask
participant F as ftpTask
participant U as uiTask
- participant T as timeSyncTask
+ participant I as iec104Task / timeSyncTask
- M->>M: HAL_Init + CubeMX 外设初始化
(SPI1/SPI2/I2C1/UART4/USART1/DMA/GPIO/TIM7)
+ M->>M: HAL_Init + CubeMX 外设初始化
(SPI1/SPI2/I2C1/UART4/USART1/DMA/GPIO/TIM3/TIM7)
M->>A: app_main_init()
Note over A: 时间子系统优先,使后续日志带时间戳
A->>A: sd2506_init() → sys_clock_init()(墙钟基准)
A->>A: rs485_init() → gd5f2gq5ue_init()(BBT 扫描)
- A->>A: tpafe5160_init() → SD2506 诊断 → start_conv_irq()
+ A->>A: tpafe5160_init() → adc_input_init()(语义映射自检)
+ A->>A: 配置段注册(adc_cal / run_par / prot_set / comm)→ 定值/元件初始化
+ A->>A: adc1_disable() → ADC1 挂 DMA(4b-pre,顺序不可变)→ 启动 TIM3 1 kHz 节拍
A-->>M: "App init OK"
M->>K: osKernelStart()
K->>D: 调度
- D->>D: f_mount(无卷则 f_mkfs FAT32)→ 卷健康探针/自愈 → net_cfg_load()
+ D->>D: f_mount(无卷则 f_mkfs FAT32)→ 卷探针/自愈 → 配置装载
→ 定值整表原子装载(损坏则保出厂默认 + 自检留痕)
D-->>N: set SYS_EVT_STORAGE_READY
+ S->>S: adcTask:等 TIM3 节拍 → 采集 → 相量/测频 → 200 ms 遥测快照
+ S->>S: protectTask:20 ms 判据(未标定/采样故障则停走)
N->>N: wait STORAGE_READY(Any|NoClear)→ net_init(ip,mask,gw,mac)
→ PHY 强制 100M 全双工 → 等链路 ≤3s
N-->>F: set SYS_EVT_NET_READY
F->>F: wait NET_READY|STORAGE_READY(All|NoClear)→ lftpd_start("/", 21)
U->>U: wait NET_READY(Any|NoClear)→ ui_port_init → ui_menu_init → ui_net_sink_start(7003)
- T->>T: wait NET_READY(Any|NoClear)→ TCP listen :8888
+ I->>I: wait NET_READY(Any|NoClear)→ TCP listen :2404 / :8888
```
+> **顺序铁律**:① 配置段注册必须**先于** `cfg_file_load`(否则 FTP 上传的段不生效);
+> ② `adc1_disable()` 必须在挂 DMA 之前;③ `osKernelStart` 之前禁调任何内核 API(含 `osDelay` / 队列)。
+
### 3.5 线程间通信
| 机制 | 对象 | 用途 |
|---|---|---|
| Event Flags | `sys_evtHandle` | 启动就绪屏障 + 命令位(§3.3) |
| Message Queue | `netMsgQueue`(深度 8,`net_msg_t`) | 所有 CH395F 操作经队列**串行化**到 netTask 执行,保证 SPI 单线程访问 |
+| 双区 + 序号(无锁) | `phasor` 相量区、`meas` 遥测快照 | 写侧填满计算区后单字节翻转活跃索引;读者先取索引再整份拷贝,`seq` 判"是否换帧" |
+| SPSC 环(无锁) | `soe_store`(深度 8) | protectTask 只投递动作边沿,defaultTask 排空落盘——**保护路径零 NAND I/O** |
+| 脏位 + 事件位 | `prot_set` / `run_par` / `comm` | 写入方置脏;104 侧 peek 后投递事件位,配置属主(defaultTask)落盘,失败保留脏位下轮重试 |
+| 单字请求标志 | `prot_elm_request_reset()` | 跨上下文复归请求(104 遥控 YK11 在 iec104Task 落请求,protectTask 下一拍消费) |
---
@@ -296,6 +534,22 @@ sequenceDiagram
| **SDIO** | V0.1 主板 SDIO 固定引脚组被 TPAFE/UART 全部占用 → **无 SDIO 能力**(当前设计不受影响,FatFs 卷在 SPI NAND 上) |
| **新源文件** | 必须双端注册(Keil `.uvprojx` + `simulator/CMakeLists.txt`),否则不参与编译 |
+### 4.6 V0.1 硬件能力边界(对产品的硬约束)
+
+下列五条是**硬件事实**,不是软件缺陷;§5 的功能范围与 §9 的"等条件"项均由它们推导:
+
+| # | 约束 | 具体内容 | 产品影响 | 解除条件 |
+|---|---|---|---|---|
+| H1 | **双转换器无共同采样触发** | 8 路电气量分属 TPAFE5160(16 位、8 通道同步、±5 V 双极性)与 STM32 ADC1(12 位、顺序扫描、0~3.3 V 单极性)两片;两片无共同触发,STM32 侧 9 通道一轮约 67 µs | 跨转换器的**相位 / 功率 / 功率因数 / 对称分量 / 三相同时刻判据**一律不成立 → 方向元件、PT/CT 断线、三相过流、零序过流延后 | **V0.2 硬件**:8 路电气量全部接 TPAFE(与备用路对调串联电阻,料号不变,走线级改动);固件只改映射表内容 |
+| H2 | **STM32 侧无中点偏置** | 单极性 0~3.3 V,交流量负半周削顶 | `UB/UC/IB/IC/IN` 无有效值/相量,只能读码值**监视**;104 对应点恒置 IV | V0.2 补偏置 |
+| H3 | **无出口继电器与开入回路** | 无跳闸/告警出口、无硬压板与开入遥信 | 保护动作只体现为**遥信 + 日志 + SOE**;104 遥控 `YK1~4/13/14` 否定确认 | 开入开出独立立项 + 硬件 |
+| H4 | **无本地屏与按键** | 160×160 单色屏仅存在于远端客户端 | UI 以 TCP :7003 推流 + 远端按键回注(§8) | 产品形态即如此,不解除 |
+| H5 | **无 SDIO** | SDIO 固定引脚组被 TPAFE/UART 占用 | FatFs 卷只能落 SPI NAND(当前设计不受影响) | 不解除 |
+
+> **量纲口径**(由 H1/H2 派生):在端子/子板变比确认与两点标定完成前,遥测与保护读数的单位是
+> **ADC 引脚电压**(`eng=0`),不是二次值;此时 `ADC_CAL_F_VALID` 未置位,
+> **保护判据整体停走**(§5.12)。这是刻意设计,不是"保护不动作"的缺陷。
+
---
## 5. 功能需求
@@ -443,19 +697,261 @@ sequenceDiagram
- 实现:`defaultTask` 循环驱动(闪烁指示系统活跃)。
- 判据:目检 6 路 LED 随系统状态变化。
-### 5.9 ADC 采集(FR-ADC)🔶 采集链路已实现(B1);保护/遥测算法与上行待实现
+### 5.9 ADC 采集与标定(FR-ADC)✅
-- **需求(B0 已确认,2026-10-10)**:**持续采集** 8 路电气量(Ua/Ub/Uc/U0、Ia/Ib/Ic/I0,**1000 Hz / 20 点/周波**),经保护/遥测算法后**上送 IEC 60870-5-104**(以太网 TCP 2404;遥测上送短浮点、采集上传系数 = 1)。
-- **现状(采集链路 B1 + L1 已实现,2026-10-10)**:启动序列调用一次 `tpafe5160_init()`;**运行期周期 CONVST 重触发已由 TIM6 更新中断(1 kHz)接管**(`Src/main.c` 的 `HAL_TIM_PeriodElapsedCallback`,2026-10-10)+ `adcTask` 经 L1 层 `adc_input_poll()` 消费(`tpafe5160_snapshot()` 8 通道 + STM32 ADC1 9 通道扫描)+ 帧统计,台架 `@test` 确认 `frame_seq` 严格 1000 Hz 递增、`frst_err=0`、`adc1_rc=0` / `adc1_err=0`;STM32 侧 ADC1 **消费者已落地**(`App/algo/adc_input.c` 的 `stm32_scan()`,「STM32 ADC1 启动与扫描」,2026-10-10),受双转换器无共同采样触发所限,仅逐通道独立监视。
-- **后果**:上电后仅采集 1 个样本,此后数据永久陈旧。
-- **B0 结论**(2026-10-10,详见 `docs/算法/继电保护功能复现规划.md` §1.5):① 持续采集 ② 1000 Hz(20 点/周波),通道 = 4U+4I(点表 `4011~4018`)③ 上行 **IEC 60870-5-104**(2404,非 ModBus RTU 上行)④ ADC 采集链路为遥测/保护的必需来源 → **常驻编译**;原 `APP_ADC_ENABLE` 占位宏零消费点,已于 2026-10-22 删除(将来若要裁剪,需在真实初始化点接入门控并登记进 `App/app/app_cfg.h`)。
-- **实现约束**(见 §9):周期 CONVST 重触发 + `adc_task` 消费 `tpafe5160_snapshot()`;**原子快照 API 已就位**(2026-10-10 修三条采集契约缺陷,旧的 `get_buf` / `data_ready` / `clear_ready` 已删 → 取数不再撕裂、重触发不再丢帧、芯片不驱动总线会被 `init()` 首帧自检抓到);栈预算核算;V0.1 通道映射已固化 → `docs/硬件平台/ADC通道映射说明.md`(13/17 路置换;语义 UA/UB/UC/UN、IA/IB/IC/IN、V_ZL2=温度,其余备用;网名 ADC17 = PC4 用 `ADC_CHANNEL_14`,**不是** `ADC_CHANNEL_12`)。⚠ **8 路电气量分属 TPAFE / STM32 两片转换器属 V0.1 硬件缺陷**(跨转换器无同一时刻性、精度与量程不一致,登记簿条目「双转换器无共同采样触发」,V0.2 改版要求全部走 TPAFE)→ 在 V0.1 上主板侧只做**逐通道独立监视**,功率 / 功率因数 / 相角 / 矢量类量一律取子板计量模块结果,不得由主板混算。
+**FR-ADC-1 采样节拍与触发**
+- 需求:8 路电气量(`UA/UB/UC/UN`、`IA/IB/IC/IN`)**持续采集**,1000 Hz(50 Hz 下 20 点/周波),
+ 采集节拍与任务唤醒**同源**;不得用任务周期软定时冒充硬件节拍。
+- 实现:TIM3 更新事件(1 kHz)在 ISR 内触发 TPAFE `CONVST`,同一事件经 TRGO 触发 ADC1 一轮
+ 9 通道并由 DMA2 循环搬入乒乓双缓冲;ISR 只置"消费者就绪"门并唤醒 `adcTask`(不做重运算)。
+- 判据:`frame_seq` 每 10 s 精确 +10000(1000.0 Hz)、`frst_err=0`、`adc1_err=0`、`adc1_hw=0`;
+ 单拍消费耗时 ≤10 µs(DMA 搬运后实测 8 µs,软件轮询时为 122 µs)。
-### 5.10 RS-485 采集(FR-RS485)⬜ 待实现
+**FR-ADC-2 语义通道映射**
+- 需求:按**语义**取数(`UA`/`UN`/`IA` 等),不写死缓冲区下标——V0.2 换映射表即可切换硬件归属。
+- 实现:`App/algo/adc_input.c` 的语义表(TPAFE `buf[6]/[5]/[2]`;ADC1 `CH14/3/6/1/2/5`)+ 开机
+ **映射自检**(STM32 映射通道必须落在扫描序列内,否则拒绝并自检留痕)。
+- 判据:`ADC input layer init: OK`;8 路 + 温度首帧全部读出、互异、非饱和。
-- **需求(B0 已确认,2026-10-10)**:半双工 RS-485 **对下 ModBus RTU 采集**(下行采集口,非上行口;上行走以太网 IEC 60870-5-104)。
-- **现状**:`rs485_init()` 已调用;`rs485_task.c` 为空桩,未在 `freertos.c` 创建;`App/protocol/` 预留(仅 README + `.gitkeep`)。
-- **实现约束**:双缓冲 + 序号(防包撕裂)+ DE 收尾(超时路径等 TC)+ 协议状态机;解析必须与硬件 I/O 分离(`App/protocol/` 正为此预留)。B0 结论详见 `docs/算法/继电保护功能复现规划.md` §1.5。
+**FR-ADC-3 标定与量纲折算(L1.5)**
+- 需求:把码值折算为工程量 `(code + b) × k`,系数与零点可落盘、掉电保持;未标定不得冒充二次值。
+- 实现:`App/algo/adc_cal.c`——`k` 以 Q16(µV/码 ×65536)、`b` 以码值存 `[adc_cal]` / `[adc_cal_ofs]`
+ 段;ROM 默认 = 引脚侧 LSB(TPAFE 152.59 µV/码、STM32 805.66 µV/码);
+ 三态可用性 `ADC_CAL_F_VALID` / `ADC_CAL_F_CLIPPED` 由 `adc_cal_flags()` 单点查询,104 / UI / 保护闭锁共用。
+- 判据:已知电压注入斜率与理论 LSB 偏差 ≤2%(2026-10-27 台架实测端子侧 **6544.2 码/V**,与引脚侧
+ 理论 6553.6 差 **−0.14%**,零点 0~5 码、R²=0.9999997、极性对称 ≤0.34%);8 通道系数/零点往返一致。
+- 证据与现场步骤:[`docs/硬件平台/ADC通道映射说明.md`](../硬件平台/ADC通道映射说明.md) §8.1、
+ [`docs/测试说明/ADC前端注入验证流程.md`](../测试说明/ADC前端注入验证流程.md)。
+
+**FR-ADC-4 采样有效性校验**
+- 需求:芯片静默、丢帧、序号倒退、转换错误必须被检出并可闭锁保护,且**不误报**。
+- 实现:`App/algo/adc_health.c` 纯逻辑判定层——静默 100 ms 门限(电平位、可自愈)、丢帧边沿计数、
+ 序号倒退锁存、FRSTDATA/HAL 错误/STM32 停摆计数增量;严重事件与上升沿写自检记录(每类每次开机一次)。
+- 判据:主机侧 31 用例全绿;台架零 `[ERR]`(健康不误报),人为制造丢帧时 `tgap` 与 `adc1_gap` 同步可见。
+
+**FR-ADC-5 前端物理口径(已实测盖章)**
+- `1k 串联 + 1k 到地` 是**源阻抗匹配、不是分压**:`ADCn` 节点只有 {串阻、滤波电容、转换器引脚},
+ 「1k 到地」接在差分负端(`ADC7_GND` → R32 → AGND),故 AINn↔引脚变比 **1:1**。
+- 旧口径「2:1 分压 → 305.18 / 1611.3 µV/码」**作废**(那是芯片手册 ±10 V 档 LSB,不可混用)。
+- 剩余未知量只有**子板/端子板变比**,因此系数只能推到"µV/码 @ 引脚"(§4.6 量纲口径)。
+- 拓扑图 [`docs/images/ADC前端电路.svg`](../images/ADC前端电路.svg)。
+
+### 5.10 RS-485 采集(FR-RS485)⬜ 冻结
+
+- **需求(已确认)**:半双工 RS-485 **对下 ModBus RTU 采集**(下行采集口;上行走以太网 104)。
+- **现状**:`rs485_init()` 已调用;`rs485_task.c` 为空桩、未在 `freertos.c` 创建;`App/protocol/` 为该
+ 协议族预留(当前仅 104 在用)。**整簇冻结**(用户决定,2026-10-12)。
+- **重启门禁**:先修「单缓冲包撕裂」「TX 超时拉 DE 未等 TC」两条,再谈接消费者;实现须满足
+ 双缓冲 + 序号、DE 收尾超时路径、协议解析与硬件 I/O 分离。
+- 详见 [`docs/任务规划/暂缓-RS485.md`](../任务规划/暂缓-RS485.md)。
+
+### 5.11 遥测与相量(FR-MEAS)✅
+
+**FR-MEAS-1 全周傅氏相量**
+- 需求:每 1 ms 产出基波/谐波相量,幅值直接是**基波有效值**,读者无锁取整份快照。
+- 实现:`App/algo/phasor.c`——N=20 全周 DFT,系数表离线预乘 `√2/N`;5 个实例
+ (`IA`/`UA`/`UN` 基波 + `IA` 二次/五次);每来新点整窗重算,算完单字节翻转计算区/使用区。
+- 判据:主机侧 57 用例全绿(系数表逐项复核、合成正弦幅值误差 ≤1%、双区交换);台架开机即产出 5 行
+ `phasor(first)`,心跳持续刷新。
+- **双轨有效值**:保护用**基波有效值**(抗衰减直流与谐波误动),计量/遥测要**真有效值**(谐波方和根)
+ ——两者不可混用;本产品当前只实现基波轨,谐波方和根轨未做(§9)。
+
+**FR-MEAS-2 频率测量(L2.5)**
+- 需求:45~55 Hz 内测频,精度优先于响应速度。
+- 实现:`App/algo/freq.c`——共轭乘积相位增量 + 解缠绕 + **自适应窗长**(对齐纹波周期整数倍);
+ 假值钳制带与系统合理带分离;幅值门 <50 码判无效;`UA` → `IA` 优先级。
+- 判据:45~55 Hz 扫频最坏误差 **0.0101 Hz**、1% 噪声 0.0160 Hz、启动收敛 ≤40 ms、阶跃 50→51 Hz ≤120 ms;
+ 浮空(无信号)时 `valid=0` 不发散。
+
+**FR-MEAS-3 遥测快照(200 ms)**
+- 需求:104 与 UI **共用同一份上游**——"什么时候算新值、品质怎么判"只此一处决定;快照必须可无锁整体读。
+- 实现:`App/algo/meas.c`——每 200 ms(**经过时间**分频,非拍计数)取基波有效值 + 逐点品质,双区 + `seq`;
+ **唯一发布者 = adcTask**(`meas_tick` 全仓仅一处调用),其余任务只读。
+- 判据:主机侧布局用例钉死字段偏移(改字段 = 破协议);台架 104 与 UI 读数同源一致;快照未发布时
+ 消费者得到 `IV|NT` 而不是 0。
+
+**FR-MEAS-4 品质与死区**
+- 需求:品质必须如实反映"这一路能不能信";遥测变化上送不得被单点噪声触发。
+- 实现:品质位低字节与 104 `QDS` 同值直传;`CLIPPED`(削顶)由 104 侧映射为 `IV`;
+ 死区 = **连续 2 个新测量点越限才确认**(基准恒为上次上送值,防慢漂移吃掉基准),品质翻转当拍直报。
+- 判据:`UB/UC/IB/IC/IN` 五路恒 IV(品质驱动,V0.2 消除 H1 后零改动自动启用);死区两拍确认、
+ 回摆撤销;`TEMP` 通道恒 NT。
+
+### 5.12 保护功能(FR-PROT)🔶 软件就绪,判据现闭锁
+
+**FR-PROT-1 元件框架**
+- 需求:统一"越限 + 返回系数滞回 + 定时限"元件核,判据为**纯逻辑**(吃测量值 + 定值),可离线单测;
+ 新增元件只加实例表一行,不改核。
+- 实现:`App/algo/prot_elm.c`——数据驱动实例表 9 行;`prot_elm_eval()` 纯判据、`prot_elm_run()` 为
+ 相量/频率到测量值的薄适配;延时用 `now_ms` 差值法(与节拍无关,精度不受 20 ms 节拍影响)。
+- 判据:主机侧 47 断言全绿(1.01× 启动 / 0.9× 返回 / 滞回保持 / 欠量方向 / 投退 / 闭锁联动 / 时基回绕)。
+
+**FR-PROT-2 元件清单(V0.1 有效子集)**
+
+| 元件 | 测量量 | 判据要点 | 104 遥信 |
+|---|---|---|---|
+| 过流 Ⅰ/Ⅱ/Ⅲ 段 | `IA` | 越定值经延时动作,返回系数滞回 | `YX16/17/18`(并汇入 `YX15` 故障总) |
+| 过负荷 | `IA` | 越定值告警(默认不跳闸) | `YX23` 过载 |
+| 过压 / 欠压 | `UA` | 过量 / 欠量方向,各自延时 | **无遥信点**(仅 SOE + 日志) |
+| 零序过压 | `UN`(外部零序专用通道) | 越定值经延时 | 汇入 `YX15` 故障总 |
+| 过频 / 低频 | 测频结果 | 过量 / 欠量方向,默认 51.0 / 49.0 Hz | **无遥信点**(仅 SOE + 日志) |
+
+> ⚠ **`YX15` 故障总的构成是 OC1∨OC2∨OC3∨3U0**——电压类与频率类元件**不在其中**,其动作目前只能从
+> SOE、`[PROT]` 日志与 UI 记录看到。这是**点表层面的已知缺口**(送检点表要求独立分点时再补),
+> 不要把它误读成"元件没动作"。
+
+- **未复刻的元件**(建接口不使能,等条件):三相完整过流(B/C 相)、零序过流、方向/功率类、
+ PT/CT 断线、涌流制动、重合闸、故障隔离——原因见 §4.6 的 H1/H2,属 §9.1.1「三相与同期」,
+ 解除条件为 V0.2 硬件。
+- 判据:`[PROT] elm` 边沿日志与 104 变位一致;未使能元件不误动。
+
+**FR-PROT-3 判据节拍**
+- 需求:判据独立于采集任务,周期稳定,且不得阻塞在存储 I/O 上。
+- 实现:`protectTask` 20 ms 节拍(元件吃 50 Hz 基波有效值,相量每工频周更新,20 ms 足够);
+ 纳入 IWDG 必需位;动作只投递 SOE(SPSC 环),**不做 NAND I/O**。
+- 判据:静态最坏链 872 B / 配置 2048 B(余 57%);动作到 104 上送端到端 ≤120 ms。
+
+**FR-PROT-4 闭锁(四源,任一命中即停走判据)**
+
+| 闭锁源 | 判据 | 行为 |
+|---|---|---|
+| **未标定** | `UA`/`UN`/`IA` 的 `ADC_CAL_F_VALID` 未全部置位 | 整条判据链停走(产品构建默认态,等两点标定) |
+| **采样故障** | `adc_health_flags()` 电平位(TPAFE/STM32 静默、序号倒退) | 元件全部复位 + 本拍不判据,自愈后自动恢复 |
+| **定值非法** | 定值校验和(sum32 正/反码)复核失败 | 闭锁相关保护并告警,需重写定值解除 |
+| **全局软压板退出** | `PS_GLOBAL_EN` = OFF(104 遥控 `YK12`) | 元件复位 + 停判据,压板恢复即重返联 |
+
+- 判据:`YX31` 保护闭锁遥信如实反映;锁存类事件位(FRSTDATA/HAL 错误)**不构成**"当前测量不可信",
+ 只登记不闭锁(口径见 [`docs/算法/继电保护功能复现规划.md`](../算法/继电保护功能复现规划.md) §3.5)。
+
+**FR-PROT-5 出口(⬜ 未实现)**
+- 需求:判据满足驱动跳闸/告警出口继电器,带保持/脉冲与回读自检。
+- 现状:**V0.1 无出口硬件** → 保护"动作"= 遥信 + SOE + 日志;104 遥控 `YK1~4` 为否定确认。
+- 判据(立项后):动作驱动对应出口;出口回路自检可检出断线;遥控执行有确认与回读。
+
+### 5.13 定值与运行参数(FR-SET)✅
+
+**FR-SET-1 三类参数**
+
+| 类 | 地址范围 | 内容 | 属性 | 本产品状态 |
+|---|---|---|---|---|
+| 固有参数 | `8001H~800AH` | 终端类型 / 操作系统 / 制造商 / 硬件版本 / 软件版本 / 校验码 / 规约类型 / 型号 / ID / MAC | 只读 | ⬜ 未实现(字符串类无法短浮点上送,未知 IOA 应答) |
+| 运行参数 | `8020H~8058H` | 遥测死区、PT/CT 变比、负荷越限/重载/过载报警、录波投退与定值、功率置负 | 可整定 | 🔶 已落死区 9 点 + `k/b` 覆盖 16 点(`0x8030~0x804F`);其余类别无消费者,留白不预埋 |
+| 保护定值 | `8820H~8882H` | 过流 Ⅰ/Ⅱ/Ⅲ 段、零序过流、重合闸、低压/低频、励磁涌流闭锁、小电流接地等 | 可整定 | 🔶 **40 项**(Q10 定点):过流三段、过负荷、过压/欠压、零序过压、过频/低频 + 本地项(投退/返回系数/全局软压板) |
+
+**FR-SET-2 定值模型与封存**
+- 需求:定值改动必须**原子可见**——保护巡检任何时刻都看到自洽快照;范围校验失败整笔拒绝。
+- 实现:`App/algo/prot_set.c`——影子区写好后重封 sum32 正/反码,再**单字交换**活跃区;
+ `prot_set_selfcheck()` 用 seqlock 式复核(提交撞见则本轮跳过);范围校验 + 整表 all-or-nothing 装载。
+- 判据:主机侧 90 断言(含伪造自洽越界对抗样本);104 写定值与巡检并发无 µs 级误锁。
+
+**FR-SET-3 持久化**
+- 需求:定值掉电保持;档案损坏与版本换代必须能区分,损坏不得静默使用。
+- 实现:`/prot_set.bin`(magic + 版本 + 计数 + 值区 + sum32 正/反码对),走临时文件 + rename 原子写;
+ 写路径 = 脏标志 → 事件位 → defaultTask 落盘(失败保留脏位下轮重试);
+ 装载在 `STORAGE_READY` 之前整表原子完成。
+- 判据:非默认定值跨复位保持(台架 7.5 A 往返读回一致);**版本换代**(旧档)记 INFO,
+ **真损坏**记 ERROR + 自检留痕并回落出厂默认。
+
+**FR-SET-4 运行参数段**
+- 需求:死区与通道系数可由主站整定并持久化,且**系数只有一份真源**。
+- 实现:`App/algo/run_par.c`——`[run_par]` 段 9 键(死区,毫单位 int32)+ `k/b` 覆盖 16 点;
+ `k/b` 写为 `adc_cal_set` **代理**(合法带 `ROM×[0.5,2.0]` 由执行段裁决),run_par 不存系数。
+- 判据:`0x8027~0x802A`(过压/欠压告警段)永不被覆盖(路由 run_par 先、未命中落 prot_set);
+ 越带写回否定确认;整档保存一趟覆盖 `[run_par]` 与被改写的 `[adc_cal]`。
+
+**FR-SET-5 主站读写**
+- 需求:主站可读定值、两段式写定值,失配/越界必须明确否定。
+- 实现:`C_RD` 读 + `C_SE_NC` 两段写;地址 = prot_set `comm_addr`(**点表不另立地址表**);
+ `comm_addr = 0` 的本地项显式不可寻址(防 IOA=0 误命中)。
+- 判据:读回值 = 写入值(COT 正确);本地项读回 COT=14 + EVI;执行段写失败不影响旧值。
+
+### 5.14 SOE 与动作记录(FR-SOE)✅
+
+**FR-SOE-1 记录格式**
+- 需求:动作与状态变化必须带时标留痕,且**保护路径不得因写盘被拖慢**。
+- 实现:`App/log/soe_rec.c`——64 B 定长记录 = 类型 + 元件号 + IV 位 + `seq` + `CP56Time2a` + epoch + 值 + 校验和;
+ 六类边沿:元件动作 / 复归、软压板投 / 退、采样数据块 / 恢复。
+- 判据:`/log/soe.log` 经 FTP 下载后逐条解码通过(校验和、`seq` 严格 +1、CP56 与 epoch 交叉一致)。
+
+**FR-SOE-2 落盘与上送**
+- 需求:写盘单写者;104 变位与落盘记录同源同时基。
+- 实现:protectTask 投递 SPSC 环(深度 8,**禁 DBG**)→ `defaultTask` 排空落盘;
+ 104 自发单点换 `M_SP_TB_1`(带 CP56 时标),总召/周期保持 `M_SP_NA_1`。
+- 判据:动作路径零 NAND I/O(protectTask 静态链 872 B 改前后不变);104 时标 = 事件上送时刻,
+ 与落盘记录(事件发生时刻)差 ≤ 一拍 + 排空延迟(≤50 ms)。
+
+**FR-SOE-3 记录体系(🔶 展示层待补)**
+- 现状:内核只有 SOE 一类;UI 菜单的「事故 / 操作 / 保护告警 / 保护启动 / 遥控记录」5 页
+ **缺写入方**,运行报告缺上电次数与 104 统计只读计数(§9)。
+- 判据(补齐后):五类记录各有写入点、可翻最近 20 条、空记录明确显示"无记录"、共用 reader。
+
+### 5.15 IEC 60870-5-104 上行(FR-IEC104)✅
+
+本产品为**被控站(受控端)**:104 **TCP 服务器**,端口 `[comm]` 段 `port`(工厂默认 **2404**),主站主动连入。
+点表口径见 §6.8,设计细节见 [`docs/子系统设计/IEC104上行设计说明.md`](../子系统设计/IEC104上行设计说明.md)。
+
+**FR-IEC104-1 链路层**
+- 需求:APCI U/S/I 帧、STARTDT/STOPDT/TESTFR、k/w 窗、t1/t2/t3;TCP 流重组与坏帧自恢复。
+- 实现:`App/protocol/iec104/iec104_link.c`(纯逻辑:收=喂流、发=回调、时基注入);参数 k=12 / w=8 /
+ t1=15 s / t2=10 s / t3=20 s;序号 15 bit 回绕、超时一律差值法。
+- 判据:主机侧 174 断言全绿;台架主站往返 STARTDT → 总召四组 → actterm 全通过。
+
+**FR-IEC104-2 遥测上送**
+- 需求:遥测短浮点、系数 1、点号落在 `0x4001` 起的遥测段(段基址见 §2.5.3);支持背景/总召、
+ 周期(60 s)、死区与品质上送。
+- 实现:数据源 = L2 遥测快照(§5.11);品质直传,`CLIPPED` 映射为 `IV`;死区运行时副本(运行参数段可读写)。
+- 判据:总召读回值与 UI 同源一致;死区两拍确认、品质翻转直报;削顶五路恒 IV。
+
+**FR-IEC104-3 遥信上送**
+- 需求:双位置遥信上双点、其余单点;变位突发 + 背景扫描;**无效点也入表并置 IV**。
+- 实现:`iec104_pts.c` 点表(33 点)+ COV 判定;突发单点带 CP56 时标。
+- 判据:`YX15~18/23/31` 为活数据;`YX1~14/19~22/24~30/32~33` 恒 IV(缺行比置 IV 更糟)。
+
+**FR-IEC104-4 遥控**
+- 需求:双点命令两段式(选择 `82H` / 执行 `02H`),失配或越界否定确认。
+- 实现:`YK11` 信号复归 → 跨上下文复归请求;`YK12` 全局软压板 → 定值原子写;
+ `YK1~4` 开关、`YK13` 电池活化、`YK14` 解除闭锁 = 否定确认(无硬件)。
+- 判据:`YK11`/`YK12` 两段正答且行为可观测(压板退出态跨复位保持);否定确认带正确 COT + PN。
+
+**FR-IEC104-5 定值与运行参数读写**
+- 需求:`C_RD` 读、`C_SE_NC` 两段写;地址即定值表 `comm_addr`;写成功即持久化。
+- 实现:见 §5.13;路由顺序 = run_par 表先、未命中落 prot_set。
+- 判据:读回一致、越界否定、断电重启保持。
+
+**FR-IEC104-6 对时**
+- 需求:主站 `C_CS` 对时写入设备墙钟;时标无效如实置 IV。
+- 实现:CP56 → epoch ms → `sys_clock`(含 RTC 写回);epoch >2^32 显式拒绝回 PN。
+- 判据:对时后日志时间戳跟随主站;`C_CS` 后 SOE 时标同步。
+
+**FR-IEC104-7 响应时间(点表推荐值)**
+
+| 参数 | 要求 | 本产品实测 / 设计 |
+|---|---|---|
+| 终端启动时间 | ≤100 s | 开机到 `net init: OK` ≈0.6 s,到 104 监听 <2 s |
+| 104 连接 / 总召 | ≤3 s / ≤8 s | 连接 <1 s;总召分片 + 单轮 4 ASDU 预算,实测远小于 8 s |
+| SOE 上送 | ≤5 s | 变位到上送 ≤120 ms |
+| 遥控选择 / 撤销 / 执行 | ≤5 s | 同轮应答(ms 级) |
+| 读定值 / 改定值预置 / 执行 | ≤10 s / ≤5 s | 同轮应答(ms 级) |
+| 读文件目录 / 文件 | ≤30 s | ⬜ 未实现(文件传输未立项) |
+| 录波文件存储 | ≤15 s | ⬜ 未实现(录波未立项) |
+
+**FR-IEC104-8 单连接与自愈**
+- 需求:单连接语义(CH395F 单 socket);断链自动重听;网络重建(改 IP)后服务自愈;协议故障主动拆链。
+- 实现:监听与数据通道复用同一 socket(EOF 时 net 层 auto_relisten,应用层不关 fd);
+ `net_get_generation()` 变化即重建;坏帧 / N(R) 倒退 / t1 超时 / 发送 3 连败 → 本端拆链促主站重连。
+- 判据:断链后自动恢复监听;改 IP 后重建;**V0.1 为首到优先**(后连优先需 net 层支持,未实现)。
+
+**FR-IEC104-9 本期未实现项(如实登记,均为 §9.1 复刻进度条目)**
+
+| 项 | 原因 | 归属 |
+|---|---|---|
+| 多主站 / 双链路冗余 | 单连接 socket 语义;后连优先需 net 层扩展 | 规模型 |
+| 归一化值 / 标度化值上送 | 点表要求短浮点(系数 1),无需另做 | 不适用 |
+| 双点遥信带时标 | V0.1 双点恒 IV,无意义 | 随开入硬件(X4) |
+| 定值区切换 / 定值文件下装 | 产品未定义多定值区(参考有 4 区) | 规模型 |
+| 文件传输(目录 / 读文件 / 录波) | 录波子系统未开始 | 规模型 |
+| 固有参数 `8001H~800AH` | 字符串类无法短浮点上送 | 规模型 |
+| 主站 IP 白名单 | 单 socket 上"拒绝"= 断链重听,可被扫描打成 SPI 风暴且易锁死真主站 | 不适用 |
---
@@ -468,7 +964,7 @@ sequenceDiagram
| FTP | TCP **21** | 文件上传/下载(根目录 `/`,NAND 存储) | 登录后任意 FTP 客户端列目录/读写(鉴权见 §7.6) |
| 墙钟对时 | TCP **8888** | PC 主动推送时间到设备 | 对时后核对设备时间 / 日志时间戳 |
| 远程显示(RemoDispBus) | TCP **7003** | 远端看图(160×160 1bpp)+ 远端导航按键 | DTU-RemoteLCD 或任意 TCP 客户端连 7003 收帧 |
-| IEC 60870-5-104 上行 | TCP **2404** | 被控站接入:遥测/遥信上送、总召、遥控/定值下发(B4) | 任意 104 主站连 2404,STARTDT+总召往返(→ `docs/子系统设计/IEC104上行设计说明.md`) |
+| IEC 60870-5-104 上行 | TCP **2404** | 被控站接入:遥测/遥信上送、总召、遥控/定值下发(点表见 §6.8) | 任意 104 主站连 2404,STARTDT+总召往返(→ `docs/子系统设计/IEC104上行设计说明.md`) |
> **现场组网要求**:设备与客户端**同网段**(默认 .100/24、网关 .1);跨网段先改 IP 再上线。
@@ -570,7 +1066,66 @@ mac=00:00:00:00:00:00
| `ui_net_sink` | `ui_net_sink_start(port)` / `ui_net_sink_poll()` | 远程显示服务端 |
| `ui_content_page` | `ui_content_page_open/close/invalidate/is_open` | 内容页框架 |
| `task_watchdog` | `task_wd_beat/poll/start` + 观测接口 | 看门狗判定状态机 |
-| `sys_events` | `sys_evtHandle` + 7 个事件位 | 启动屏障 |
+| `sys_events` | `sys_evtHandle` + 9 个事件位 | 启动屏障 + 落盘请求 |
+| `adc_input` | `adc_input_init/poll/raw/desc` | L1 语义取数(8 电气量 + 温度) |
+| `adc_health` | `adc_health_init/report/flags` | L1 采样有效性判定(纯逻辑) |
+| `adc_cal` | `adc_cal_init/apply/flags/set/b_codes/prot_blocked` | L1.5 标定折算 + 三态可用性 |
+| `phasor` | `phasor_init/run/read` | L2 全周傅氏相量(双区) |
+| `freq` | `freq_run/get/valid` | L2.5 测频(自适应窗) |
+| `meas` | `meas_tick/snap` | L2.5 遥测快照(200 ms,双区) |
+| `prot_set` | `prot_set_init/load/selfcheck/set_sealed/get/locked` | L3 定值模型(原子写 + 封存) |
+| `prot_elm` | `prot_elm_init/run/eval/state/request_reset` | L3 保护元件框架(9 实例) |
+| `run_par` | `run_par_init/get/set_104_write/dirty_peek` | 运行参数段(死区 + 系数代理) |
+| `soe_rec` / `soe_store` | `soe_rec_encode/decode` · `soe_store_post/drain` | SOE 编解码 + 落盘投递 |
+| `iec104` | `iec104_link_*` / `iec104_pts_*` / `iec104_serv_*` | 104 链路 / 点表 / 板端胶水 |
+
+### 6.8 IEC 60870-5-104 点表摘要
+
+> **权威口径**:验收以《检测平台配电终端送检要求(点表)》为准;本表是 V0.1 实现摘要,
+> 逐点细节与未实现项见 [`docs/子系统设计/IEC104上行设计说明.md`](../子系统设计/IEC104上行设计说明.md) §3。
+> **段基址与参考产品逐字对齐**(8 段全表见 §2.5.3):遥信 `0x0001`、保护 `0x1001`、遥测 `0x4001`、
+> 参数 `0x5001`、遥控 `0x6001`、设定 `0x6201`、电能 `0x6401`、步位置 `0x6601`。
+> **点表规模是当前最大差距**:本产品 9 遥测 / 33 遥信 / 2 遥控,参考产品 31 遥测 / 138 开入 / 31 开出。
+
+**遥测(`0x4001` 段起,短浮点,系数 1)**
+
+| IOA | 点 | 来源 | V0.1 |
+|---|---|---|---|
+| `4011` / `4014` / `4015` | `1Ua` / `1U0` / `1Ia` | 遥测快照(TPAFE 侧,有效) | ✅ |
+| `4012` / `4013` / `4016~4018` | `1Ub`/`1Uc`/`1Ib`/`1Ic`/`1I0` | 快照(STM32 侧,削顶) | ❌ 恒 IV |
+| `4019~401C` | `1P`/`1Q`/`1S`/`1Pf` | 需跨转换器同刻 | ❌ 恒 IV(V0.2) |
+| `401D` | `1f` 频率 | 测频结果 | ✅(未收敛则 IV) |
+| `4010` / `401E` / `401F` | `UBA` 后备电源 / `V1`/`V2` 直流 | 无硬件通道 | ❌ 未入表(X4) |
+
+> **与参考的差额**:参考 `g_tYcIndexTab` 共 **31 点**——双回线各三相电流/电压(12)、双回线各三组
+> 线电压(6)、双回零序电流/电压(3)、频率(1)、直流 2 路(2)、有功/无功/视在/功率因数
+> 单相 3 + 三相 1(4)、电度 8 种另列。本产品 9 点,缺的是**第二回线、线电压、零序双回与
+> 功率四量**——前者等通道(X5),后两者等标定后的功率运算。
+
+**遥信(`0x0001` 段起,V0.1 定义 33 点)**:`1~4` 开关位置(双点,恒 IV)、`5~14` 预留(IV)、
+`15` 故障总、`16~18` 过流 Ⅰ/Ⅱ/Ⅲ 段、`19~20` 零序过流 Ⅰ/Ⅱ(IV)、`21~22` 接地故障/重载(IV)、
+`23` 过载、`24~30` 外部遥信(RS-485 冻结 → IV)、`31` 保护闭锁、`32~33` 预留(IV)。
+有效位图 `YX_VALID_MASK` = YX15~18 / 23 / 31(6 点)。
+
+> **与参考的差额**:参考 `g_tInputModelTab` 共 **138 点**(开关合/分位、未储能、就地远方、接地位置、
+> 隔离位置、停用重合闸、保护投入、检修压板、远方信号、手合手分、电源输入、活化状态、电池欠压…),
+> 另 `g_tOutputModelTab` **31 点**开出(保跳/保合/遥分/遥合/遥控备用/电池活化/电机保护/闭锁…)。
+> 两者都需要一次设备接口硬件(X4),属 §9.1 阻塞型。
+
+**遥控(`0x6001` 段起,双点两段式)**:`YK1~4` 开关(否定确认)、`YK11` 信号复归、`YK12` 遥控软压板、
+`YK13` 电池活化(否定)、`YK14` 解除闭锁(否定)。
+
+**定值与运行参数**:保护定值地址 = `prot_set.comm_addr`(基址 `0x8820`,过压/欠压沿用告警段
+`0x8027~0x802A`);运行参数段 `0x8030~0x8038`(死区 9 点)/ `0x8040~0x8047`(`k` 覆盖 8 路)/
+`0x8048~0x804F`(`b` 覆盖 8 路),共 25 项。
+**逐项地址为本仓自定,送检点表到位后以送检为准替换常量段。**
+
+> **与参考的差额**:参考 104 定值映射 **107 项**占 `0x8820~0x8891`(8 个空洞),
+> 底层定值表 **249 项 / 23 单元**。本产品 40 项,缺的是重合闸(16)、电压时间型自愈(17)、
+> 同期(13)、看门狗(63)、遥测越限(10)等整单元(§2.5.4)。
+
+**链路参数**:k=12 / w=8 / t1=15 s / t2=10 s / t3=20 s;IOA 3 字节、公共地址 2 字节、传送原因 2 字节;
+公共地址与端口可配(`[comm]` 段,工厂默认 1 / 2404,改后需重启生效)。
---
@@ -601,36 +1156,48 @@ mac=00:00:00:00:00:00
| 网络重建生效 | 2~5 s(含等链路 ≤3 s) | 配置设计 |
| UI 刷新 | 10 ms 循环 | `ui_task_func` |
| IWDG 停喂到复位 | ≤2.5 s | IWDG 设计 |
+| **采样节拍** | **1000 Hz**(每 10 s 帧号 +10000,零丢帧) | 台架 `@test` |
+| **单拍采集消费** | ≤10 µs(DMA 搬运后实测 8 µs) | `adc_task` 实测 |
+| **相量刷新** | 1 ms(每拍整窗重算 5 实例) | `phasor_run` |
+| **遥测快照周期** | 200 ms(经过时间分频) | `meas_tick` |
+| **测频精度** | 45~55 Hz 最坏 0.0101 Hz | 主机侧扫频用例 |
+| **保护判据节拍** | 20 ms(延时精度由 `now_ms` 差值保证) | `protectTask` |
+| **动作到 104 上送** | ≤120 ms(判据拍 + COV + 服务周期) | 台架主站往返 |
### 7.3 内存与资源预算
-> **权威来源**:`.map` 受管快照 + V5 30 min 运行时水位(2026-10-04)。详见
-> `docs/内存管理/RAM使用分析与优化方案.md`。
+> **权威来源**:`.map` 受管快照(`docs/内存管理/RAM使用分析与优化方案.md` §2.1,由
+> `scripts/check_mem_numbers.py --write` 生成)+ 2026-10-22 栈预算快照
+> (`docs/内存管理/data/stack_report_20261022.md`)。**本节数值随代码演进会过期,提交前以受管快照为准。**
-**静态区(产品构建)**:
+**静态区(产品构建,2026-10-24 `.map`)**:
| 区域 | 用量 | 容量 | 占比 |
|---|---|---|---|
-| Flash ER_IROM1 | 266,632 B | 1024 KB | 25.4% |
-| ROM 合计 | 267,372 B | — | — |
-| RW_IRAM1 | 84,960 B | 131,072 B | 64.8% |
-| RW_CCM | 49,184 B | 65,280 B | 75.3% |
+| Flash ER_IROM1 | 261,928 B | 1024 KB | 25.0% |
+| ROM 合计 | 263,500 B | 1024 KB | 25.1% |
+| RW_IRAM1 | 81,072 B | 131,072 B | 61.9% |
+| RW_CCM | 57,376 B | 65,280 B | 87.9% |
-**运行时(V5 30 min 真实负载)**:
+**运行时栈预算(9 任务,静态最坏链 × 真机水位取更坏者)**:
-| 项 | 值 | 判定 |
-|---|---|---|
-| 实测堆 | free=8,664 / min_ever=4,728 B | — |
-| `defaultTask` 栈峰值 | 3664 / 4096 B(余量 432 B ≈ **10%**) | ⚠️ **低于 30% 判据,需处理** |
-| `netTask` 栈峰值 | 1228 / 4096 B(余量 70%) | ✅ |
-| `ftpTask` 栈峰值 | 2516 / 4096 B(余量 38%) | ✅ |
-| `uiTask` 栈峰值 | 4060 / 16384 B(余量 75%) | ✅ |
-| `timeSyncTask` 栈峰值 | 792 / 2048 B(余量 61%) | ✅ |
-| `testTask` 栈峰值(产品态空转) | 496 / 8192 B(余量 93%) | ✅ |
+| 任务 | 配置 | 静态最坏链 | 真机峰值 | 余量 | 判定 |
+|---|---|---|---|---|---|
+| `defaultTask` | 5120 B | 3024 B | 2152 B | 40% | ✅ |
+| `netTask` | 3840 B | 1912 B | 1116 B | 50% | ✅ |
+| `ftpTask` | 4096 B | 1456 B | 740 B | 64% | ✅ |
+| `uiTask` | 16384 B | 1336 B | 4052 B | 75% | ✅ |
+| `testTask` | 8192 B | 736 B | — | 91% | ✅ |
+| `timeSyncTask` | 2560 B | 1264 B | 616 B | 50% | ✅ |
+| `adcTask` | 2560 B | 1320 B | 952 B | 48% | ✅ |
+| `iec104Task` | 2560 B | 1456 B | 580 B | 43% | ✅ |
+| `protectTask` | 2048 B | 872 B | 828 B | 57% | ✅ |
> **定栈规则**:改栈或加大栈内局部变量前后**必须**重跑 `scripts/stack_report.py`
-> (Keil 静态调用图 × 串口 `[STACK]` 水位,判定取两者更坏者)。
-> **LVGL 内存池** 16 KB(静态占用,2026-10-15 由 40 KB 收缩);**FreeRTOS 堆** 56 KB(CCM)。
+> (Keil 静态调用图 × 串口 `[STACK]` 水位,判定取两者更坏者;余量须 ≥ max(1024 B ISR, 30%))。
+> **LVGL 内存池** 16 KB(静态占用,2026-10-15 由 40 KB 收缩);**FreeRTOS 堆** 56 KB(CCM,水位 87.9% < 92% 门禁)。
+> **卡点已从主 SRAM 移到 CCM**(余 ~7.9 KB)——再加任务或抬栈前先看
+> `docs/内存管理/RAM使用分析与优化方案.md` §4。
### 7.4 可维护性(测试与门禁)
@@ -638,7 +1205,7 @@ mac=00:00:00:00:00:00
| 层 | 内容 | 运行位置 |
|---|---|---|
-| L0 | 静态门禁(pre-commit 18 钩子) | 本地 / CI |
+| L0 | 静态门禁(pre-commit 钩子族:格式 / 编码 / 静态分析 / 文档链接 / 体积 / 生成物新鲜度 / 编号) | 本地 / CI |
| L0.5 | 主机侧单元测试(MSVC 离线编译真实源码) | 本地 / CI |
| L1 / L2 | 板端套件 / 模拟器回归 | 本地(需硬件 / 模拟器) |
| L3 | 真机台架(`@test` 闭环 + 探针) | 本地(需真机 + ST-LINK) |
@@ -654,10 +1221,17 @@ mac=00:00:00:00:00:00
pre-commit run --all-files
```
-**pre-commit 18 钩子**:trailing-whitespace、end-of-file-fixer、check-added-large-files、
-check-merge-conflicts、check-yaml、cppcheck、test-cppcheck、no-mojibake、coding-standard、
-doc-links、task-table、mem-numbers、cubemx-survival、watchdog-unit-test、sys-clock-unit-test、
-cfg-file-unit-test、test-suite-switch、gitlint。
+**pre-commit 门禁族**(钩子数量随套件增长,以 `.pre-commit-config.yaml` 为准):
+
+| 族 | 代表钩子 | 作用 |
+|---|---|---|
+| 格式 / 仓库卫生 | `trailing-whitespace`、`end-of-file-fixer`、`check-added-large-files`、`check-merge-conflict`、`check-yaml`、`gitlint` | 行尾与空白、超大文件、冲突标记、提交信息规范 |
+| 编码与源码纪律 | `no-mojibake`、`coding-standard`、`nested-comment`、`bom-guard`、`layer-deps`、`bsp-err` | 乱码、命名与常量位置、注释嵌套、BOM 漂移、分层依赖、BSP 错误码契约 |
+| 静态分析 | `cppcheck`、`test-cppcheck` | 主机侧与测试代码静态检查 |
+| 文档一致性 | `doc-links`、`id-check`、`task-table`、`mem-numbers`、`mem-budget`、`size-gate` | 链接与章节引用、编号、任务表、内存数字、体积门禁 |
+| 生成物新鲜度 | `generated-fresh`、`font-charset`、`lv-conf-sync`、`ui-golden`、`setview-check`、`uinav-selftest` | 菜单/字体/像素黄金等生成物与源一致 |
+| 主机侧单测 | `watchdog` / `sys-clock` / `cfg-file` / `phasor` / `adc-input` / `adc-health` / `adc-cal` / `meas` / `freq` / `prot-set` / `prot-elm` / `run-par` / `iec104` / `soe` / `nand-port` / `ui-data` 等 `*-unit-test` | MSVC 离线编译真实源码跑断言 |
+| 结构与注册 | `registration-check`、`test-suite-switch`、`cubemx-survival` | 双端注册、套件互斥、CubeMX 保护区审计 |
**受管事实源(禁止手改,由脚本生成)**:
- 任务表(`README.md` / `AGENTS.md`)← `scripts/gen_task_table.py`
@@ -683,6 +1257,8 @@ cfg-file-unit-test、test-suite-switch、gitlint。
| FTP 鉴权 | **已鉴权**(2026-10-11):口令登录(`[ftp]` 段存 SHA-256 摘要,不存明文)+ 连续 5 次失败锁 60 s + `write=0` 可选只读;出厂默认 `admin`/`admin`,默认口令在用有启动告警。边界:FTP 明文传口令,挡未授权访问、不挡网络嗅探(详见 `docs/子系统设计/网络配置说明.md` §3.4) |
| UI 菜单权限 | 受保护叶子(行尾 `#P`)先经密码页;密码**仅编译期写入**(查看 `000` / 修改 `123`),不落 Flash、无运行期设置页 |
| 远程显示 | 无鉴权,单连接;现场同网段部署 |
+| 104 上行 | **无应用层鉴权**(标准 104 本身不带认证):安全边界 = 现场同网段部署 + 单连接语义 + 首到优先。主站 IP 白名单**不实现**(单 socket 上"拒绝"= close + 重听,可被端口扫描打成 SPI 风暴,且配错即锁死真主站;属协议语义决定,非范围裁剪,见 §9 卷首)→ 需冗余/白名单时随 net 层立项 |
+| 配置面 | 配置与定值只能经 FTP(需口令)或 104(同网段)改写;UI 侧修改需修改密码。**本地无串口配置命令通道** |
---
@@ -705,6 +1281,8 @@ cfg-file-unit-test、test-suite-switch、gitlint。

**规模**:菜单节点 **9** 个(含根)+ 叶子节点 **33** 个 = **42** 节点;最大深度 **4 级(L0~L3)**。
+**绑定现状**(2026-10-27 实测):**已绑内容页 22 叶 / 未绑 11 叶**(页面注册表 `UI_PAGE_MAP_COUNT` = 22,
+与已绑叶数一致);未绑 11 叶 = 记录 5 + 运行报告 1(当前执行)+ 无开入硬件 3 + 未立项 2。
**根页(主界面)7 个一级条目**:装置信息 / 实时数据 / 参数定值 / 三遥设置 / 装置维护 / 通讯参数 / 记录查询。
@@ -738,16 +1316,28 @@ cfg-file-unit-test、test-suite-switch、gitlint。
### 8.3 内容页
-| 页 | 节点 | 类型 | 规格 |
-|---|---|---|---|
-| 装置信息 | node 1 | 静态键值行 | 6 行不分页;副标题"馈线自动化终端" |
-| 交流量 | node 3 | 数据列表 | 24 行 / 每页 8(3 页) |
-| 直流量 | node 4 | 数据列表 | 3 行单页 |
-| 用户密钥 | 受保护叶子 | 表单/操作页 | 3 个 14×14 数字框 + 反显光标 |
+**已绑 22 页**(按分组;逐页形态见 [`docs/UI设计/页面补齐规划.md`](../UI设计/页面补齐规划.md)):
+
+| 分组 | 页面 | 形态 |
+|---|---|---|
+| 装置信息 | 装置信息 | 静态键值行 6 行不分页;副标题"馈线自动化终端" |
+| 实时数据 | 交流量 / 直流量 / 遥信量 | 数据列表(交流量 24 行 / 每页 8,共 3 页;直流量 3 行单页) |
+| 参数定值 | 查看 4 页(参数 / 定值 / 控制字 / 软压板) | 只读列表 |
+| 参数定值 | 整定 4 页(参数 / 定值 / 控制字 / 软压板) | 可编辑(写值 + 置脏 + 保存反馈) |
+| 三遥设置 | 遥测死区 / 遥测系数 | 可编辑(运行参数段,`0x8030~0x804F`) |
+| 装置维护 | 时钟设置 / 强制复归 / 清除记录 | 操作页(执行类必须出真反馈,不得"点了没效果") |
+| 通讯参数 | 通讯设置 / 网口设置 | 可编辑(`[comm]` / `[network]` 段,保存后按各自生效时机) |
+| 记录查询 | SOE 记录 / 自检记录 / 运行记录 | 记录列表(共用 reader) |
+
+**未绑 11 叶**:记录 5(事故 / 操作 / 保护告警 / 保护启动 / 遥控)+ 运行报告 = **当前执行 6 项**;
+遥信类型 / 遥信防抖 / 双点遥信 = 等开入硬件(§9.1.1「出口与开入」);手动录波 = 等录波子系统
+(§9.1.2「录波子系统」);SNTP 设置 = 等 SNTP 对时(§9.1.2「SNTP 对时」)。
- 内容页为**独立全屏屏**,由框架一次性自绘(**零 LVGL 子对象**),`ESC` 返回菜单屏。
- 菜单导航状态**不压层**,返回即原样还原;同一时刻至多一个内容页打开。
-- 节点→页映射在逻辑层 `menu_content_page_for(node)`;其余叶子暂无内容页(进空白终点框)。
+- 节点→页映射在逻辑层 `menu_content_page_for(node)`;未绑叶子进入空白终点框(不伪造数据)。
+- 数据供给走**注入通道**(rt / par / info / 遥测死区与系数第四表),页面不直接触算法层;
+ 像素黄金用例当前 **53 页**(菜单 8 状态另计)。
### 8.4 密码与权限
@@ -766,32 +1356,87 @@ cfg-file-unit-test、test-suite-switch、gitlint。
---
-## 9. 待实现项与路线图
+## 9. 复刻进度与路线图
-### 9.1 功能缺口(当前最大产品空洞)
+> **口径**:本章条目全部来自 §2.5.2 的 🔶 / ⬜ 行——即"参考源码有、本产品还没做或只做了一部分"。
+> **"不做"一词在本章不出现**:1:1 复刻口径下没有主动放弃的能力,只有尚未排期的能力。
+> 唯二例外是 §2.5.7 标为"不适用"的两条(归一化值上送、主站 IP 白名单),那是**协议语义决定**,
+> 不是范围裁剪。
+>
+> **命名**:本节条目一律用**语义短语**(编号规范 P-8 语义优先),不发字母+数字号——
+> 避免与其它文档的 `S`/`A`/`P` 编号族撞名。
-| 缺口 | 现状 | 影响 |
-|---|---|---|
-| **ADC 采集链路** | ✅ **采集链路已实现(B1 + L1,2026-10-10)**:采样节拍由 TIM6 更新中断(1 kHz)硬件触发;`adcTask` 经 L1 层 `adc_input_poll()` 消费(TPAFE 8 通道快照 + **STM32 ADC1 9 通道扫描**),台架 `@test` 闭环(1000 Hz、`adc1_rc=0`);取数按语义(「STM32 ADC1 启动与扫描」,双转换器无共同采样触发下逐通道独立监视) | 数据路径已通;剩余为上层保护/遥测算法与 104 上行 |
-| **RS-485 采集链路** | `rs485_task.c` 空桩;`App/protocol/` 仅 README | 无 RS-485 数据收发(B0 定:**对下 ModBus RTU 采集**) |
-| **DTU 核心转发职责** | **B0 已定(2026-10-10)**:上行 **IEC 60870-5-104**(以太网 TCP 2404,遥测短浮点系数 1);RS-485 对下 ModBus RTU 采集 | 转发目标已明确,待实现 |
+### 9.1 复刻缺口总表
-> **根因不是"缺陷难修",而是"功能没接"**——B1/B2 的规模取决于 B0 产品定义,**B0 已于 2026-10-10 确认**(见 `docs/算法/继电保护功能复现规划.md` §1.5)。
+按**缺口性质**分两类:**阻塞型**(缺外部资源或硬件,排期无用)与**规模型**(无外部依赖,只等排期)。
-### 9.2 阶段路线图
+#### 9.1.1 阻塞型(等外部条件,排期不能解决)
-> **顺序唯一权威 → [`../任务规划/README.md`](../任务规划/README.md) §2(统一推进顺序,波次见 §2.0;
-> RS-485/B2 整簇暂缓见其 §2.4,2026-10-12 用户决定)**。
-> 本节自 2026-10-11 起不再维护路线图(原阶段图删除,避免与登记簿漂移;原 C4"defaultTask 栈余量 10%"
-> 已于 2026-10-10 削链闭环销项,见 `../内存管理/RAM使用分析与优化方案.md`)。
-> 功能缺口口径见 §9.1;B0 产品定义结论见 `../算法/继电保护功能复现规划.md` §1.5。
+| 条目 | 对应 §2.5.2 | 现状 | 缺的是 | 解除条件 |
+|---|---|---|---|---|
+| **标定闭锁** | 1~3 | 9 个元件、定值、闭锁链、SOE、104 上送全部就绪,但 `ADC_CAL_F_VALID` 未置位 → 判据整体停走 | **外部资源**:子板/端子板变比 + 标准源 | 端子变比确认 → 8 通道两点标定 → VALID 置位(届时自动解卡,无需改代码) |
+| **出口与开入** | 7、8 | 无硬件;保护动作只体现为遥信 + SOE;遥控开关量否定确认 | **硬件 + 立项**:出口继电器、开入回路、回读自检 | 开入开出作为独立模块立项(不可移植项 X4 解除) |
+| **三相与同期** | 4、12 | 建接口不使能(B/C 相与 `IN` 削顶、跨转换器无同刻) | **V0.2 硬件** | 8 路电气量全接 TPAFE + 中点偏置 |
+| **电度计量** | 6 | 未实现(功率积分需跨转换器同刻) | **V0.2 硬件** | 同上(不可移植项 X5 解除) |
+| **对下采集** | 17(子站侧) | `rs485_task.c` 空桩、未建任务、协议族未实现;整簇冻结 | **决策 + 门禁**:用户已决定暂缓 | 先修「单缓冲包撕裂」「TX 超时拉 DE 未等 TC」→ 接消费者 |
+| **第三方送检** | 17 | 自有主站工具往返已通过 | **标定 + 第三方环境** | 标定闭锁解除后送检 |
+
+#### 9.1.2 规模型(无外部依赖,只等排期)
+
+| 条目 | 对应 §2.5.2 | 参考 | 现状 | 差额 |
+|---|---|---|---|---|
+| **定值铺开** | 1、2 | 249 项 / 23 单元 | 40 项 / 5 组 | +209 项 / +18 单元 |
+| **映射铺开** | 3 | 107 项 `0x8820~0x8891` | 40 项局部 | +67 项 |
+| **元件铺开** | 12 | 45 个模块 | 9 个元件 + 1 个记录模块 | +35 个(过流类 4 / 电压类 5 / 重合闸 5 / 方向功率 4 / 涌流故障 5 / 自动控制 5 / 记录 5 / 录波采样 2) |
+| **遥测铺开** | 4、5 | 31 点 + 模型 35 行 | 9 点 | +22 点 + 模型表 |
+| **录波子系统** | 10、15 | 3 类型 / 6 段 / 65 通道 / RAM 16 个 / COMTRADE 64·64·16 | 0 | 整子系统 |
+| **记录体系** | 9、13 | 13 类队列(128/256 条) | 8 通道 | +5 类(COS / 越限 / 启动 / 闭锁 / 顺控) |
+| **UI 记录页** | 9、13 | 参考有完整记录页与运行报告 | 菜单叶未绑页 | 5 页 + 运行报告 |
+| **多规约栈** | 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 面 |
+| **SNTP 对时** | 17 | 参考对时走 SNTP | 私有 TCP 8888 + 104 `C_CS` | SNTP 客户端 |
+| **固有参数** | 1 | `8001H~800AH` 字符串类参数 | 未实现(无法短浮点上送) | 随送检点表设计 |
+| **遥测增强** | 4、5 | k=1~9 谐波方和根 + 4 点平均 | 仅基波轨 | 谐波 / 等周波调频 / 零序自产外接切换 三条算法轨 |
+
+> **一句话**:**「标定闭锁」是唯一"再排期也没用"的缺口**(等标准源);「出口与开入」「三相与同期」
+> 「电度计量」等 V0.2 硬件;「对下采集」等用户决策;其余规模型条目**全部可在现有硬件上推进**,
+> 只取决于排期。
+> 这张表与 [`docs/任务规划/登记簿.md`](../任务规划/登记簿.md) 一一对应;状态只在登记簿维护,
+> 本节不另建状态。
+
+### 9.2 推进顺序
+
+> **顺序唯一权威 → [`docs/任务规划/README.md`](../任务规划/README.md) §2.0**(本表只是产品视角摘要,
+> 冲突时以该节为准)。
+
+| 顺序 | 工作 | 类别 | 当前状态 | 开始条件 |
+|---|---|---|---|---|
+| 1 | UI 补齐(记录 5 页 → 运行报告) | 规模型 | **当前执行** | 已开始 |
+| 2 | net 层跨上下文收口 | 平台 | 下一步 | UI 清单完成 |
+| 3 | 其余结构与可靠性评估 | 平台 | 排队 | net 收口后 |
+| 4 | 端子/子板变比确认 → 两点标定 | 阻塞型 | 等外部资源 | 子板实物/原理图、标准源到位可插入 |
+| 5 | 标准源送检与第三方 104 主站验收 | 阻塞型 | 等标定 | 保护 VALID 置位;送检窗口前 2 日冻结特性 |
+| 6 | 定值铺开 / 映射铺开 / 遥测铺开 / 软压板铺开 | 规模型 | 等排期 | 标定后(工程量才有意义) |
+| 7 | 元件铺开与遥测增强 | 规模型 | 等标准源/硬件 | 先解除未标定闭锁;三相类等 V0.2 |
+| 8 | 录波子系统 → 记录体系 → 多规约栈 | 规模型 | 不排 | 各自重启条件 |
+| 9 | 验证窗口事项(CI 远端、PC peer、负向注入) | 平台 | 逢条件顺带 | 条件到位即执行 |
+| 10 | 出口与开入 / 三相与同期 / 电度计量 / 对下采集 | 阻塞型 | 不排 | V0.2 硬件 / 用户决策 |
+
+> **不可颠倒的顺序(一)**:变比确认 → 两点标定 → 保护解卡 → 送检。未完成标定就送检,
+> 保护表现为**不动作**;保持该闭锁,不用非标准源走捷径(用户裁定,2026-10-25)。
+>
+> **不可颠倒的顺序(二)**:**点表铺开必须晚于标定**——否则铺出去的全是 IV 点,
+> 主站无法区分"没做"与"接线错",比不铺更糟。
### 9.3 未接线开关说明
| 开关 | 位置 | 现状 |
|---|---|---|
-| 功能裁剪开关 | `App/app/app_cfg.h`(当前无宏) | **没有任何生效的裁剪开关**:原三个 `APP_*_ENABLE` 占位宏因全库零消费点已于 2026-10-22 删除,各模块一律编译进产品——B0 已确认 ADC / RS-485 均为必需链路(ADC=遥测/保护来源,RS-485=对下 ModBus RTU 采集)。将来确需裁剪时在真实初始化点接入门控,并同步登记回该文件 |
+| 功能裁剪开关 | `App/app/app_cfg.h`(当前无宏) | **没有任何生效的裁剪开关**:原三个 `APP_*_ENABLE` 占位宏因全库零消费点已于 2026-10-22 删除,各模块一律编译进产品——ADC / RS-485 均为必需链路(ADC = 遥测/保护来源,RS-485 = 对下 ModBus RTU 采集)。将来确需裁剪时在真实初始化点接入门控,并同步登记回该文件 |
| `TEST_SUITE_*` | `test/board/test_config.h` | 测试套件**互斥**,一次构建只开一个;全注释 = 正常产品固件 |
+| `rs485_task.c` | `App/task/`(未建任务、白名单登记) | 唯一的结构白名单缺口:RS-485 整簇冻结期间**刻意不接线**,随该簇一并出白名单 |
+| `DTU_BENCH` | 构建宏(`protect_task.c` 等) | 台架构建下允许保护判据在未标定时动作(仅测试用);产品构建(`#ifndef DTU_BENCH`)下保护闭锁 |
---
@@ -802,18 +1447,24 @@ cfg-file-unit-test、test-suite-switch、gitlint。
| 项 | 判据 |
|---|---|
| 构建 | `@build` → `BUILD_OK: 0 errors, 0 warnings`(退出码 0) |
-| 静态门禁 | `pre-commit run --all-files` 全部通过(18 钩子) |
-| 主机侧单测 | 看门狗 39 用例 / 系统时钟 100 断言 / 配置文件 149 断言 全 PASS |
+| 静态门禁 | `pre-commit run --all-files` 全部通过(钩子族见 §7.4) |
+| 主机侧单测 | **全部套件全绿**(看门狗、时钟、配置、相量、采集层、标定、遥测、测频、定值、元件、运行参数、104、SOE 等;套件与断言数随代码演进,以 `.pre-commit-config.yaml` 与 `test/host/` 为准) |
+| 栈门禁 | `scripts/stack_report.py` 9/9 PASS(余量 ≥ max(1024 B, 30%)) |
+| 体积门禁 | `check_size_gate.py --ci` PASS(体积凭证与 git 索引一致) |
| 双端构建 | Keil 与 CMake 均 0 错 0 警 |
-| UI 回归 | `check_menu_rows.py` + `check_content_pages.py` PASS |
+| UI 回归 | 菜单行 + 内容页像素黄金 + 导航自检全 PASS |
### 10.2 上电自检(`@test`)
-| 项 | 判据 |
+| 层 | 判据 |
|---|---|
-| Required 标记 | `App init OK` / `Network Init` / `net init: OK` / `PHY: 100M FULL` |
-| Forbidden 标记 | 无 `FAIL` / `ERROR` / `HardFault` / `[ERR]` |
+| Required 标记(基础) | `App init OK` / `Network Init` / `net init: OK` / `PHY: 100M FULL` |
+| Required 标记(采集链,可选启用) | `ADC input layer init: OK` / `phasor(first)` / `freq(hb)`(顺序锚点 `App init OK>phasor(first)>phasor(hb)`) |
+| Required 标记(保护链,可选启用) | `protect task start` / `set=40 elm=9` 计数锚 |
+| Required 标记(104,可选启用) | `[I104]` 监听/接入行 |
+| Forbidden 标记 | 无 `FAIL` / `ERROR` / `HardFault` / `[ERR]`(四个 Fault 的崩溃日志都以 `[ERR]` 开头,出现即不通过) |
| 自检记录 | `selftest: no fault record` |
+| 固件身份 | `fw build` 身份戳匹配 + 烧录后回读 `No difference found` |
| 退出码 | `@test` → 0(PASS) |
### 10.3 现场验收清单
@@ -826,8 +1477,12 @@ cfg-file-unit-test、test-suite-switch、gitlint。
| 4 | FTP | FTP 客户端连 :21 | 列目录 / 读写 `/` 下文件 |
| 5 | UI 功能 | 远端操作 | 菜单 7 项导航、内容页、密码(查看 `000` / 修改 `123`)、网口设置保存后立即生效 |
| 6 | 对时 | PC 推送 8888 | 设备墙钟更新、日志时间戳正确 |
-| 7 | 掉电保持 | 写文件 / 改网口配置 → 重启 | 数据仍在(`/config.ini` 按新值生效) |
+| 7 | 掉电保持 | 写文件 / 改网口配置 / 改定值 → 重启 | 数据仍在(`/config.ini`、`/prot_set.bin` 按新值生效) |
| 8 | LED 状态 | 目检 | 6 路 LED 随系统状态变化(低电平点亮) |
+| 9 | 104 总召与变位 | PC 主站连 :2404 → STARTDT → 总召 | 四组数据回全、`actterm` 正常;制造变位后 COT=3 上送 |
+| 10 | 104 遥控与定值 | `YK12` 软压板投退、`C_SE` 写定值 | 两段式正答、压板行为可观测、定值跨复位保持 |
+| 11 | 保护闭锁态 | 未标定状态下观察 `YX31` 与日志 | 判据停走且**明确可见**(不得静默不动作) |
+| 12 | 记录可追溯 | FTP 下载 `/log/soe.log`、`/log/run.log`、`/log/selftest.log` | 记录连续、时标正确、解码校验通过 |
### 10.4 台架验收(已闭环)
@@ -838,6 +1493,11 @@ cfg-file-unit-test、test-suite-switch、gitlint。
| V5 | 30 min 真实负载长跑 | ✅ 120/120 FTP PASS,零 IWDG 复位 |
| 堆分配改造 | 配置引擎堆分配改造(真机) | ✅ `[CFG] load: OK`(经 FreeRTOS 堆);FTP 改 IP 复位即生效 |
| 存储/网络套件 | 16/16 PASS | ✅ |
+| **采样节拍与相量** | 帧号 1000 Hz、5 实例产出、双区刷新 | ✅ 2026-10-11 |
+| **ADC 前端注入** | 已知电压注入:零点 / 线性 / 斜率 / 映射 / 极性 | ✅ 2026-10-27 五项 PASS(斜率偏差 −0.14%,R²=0.9999997) |
+| **104 主站往返** | STARTDT / 总召四组 / 变位 / 遥控 / 定值读回 | ✅ 2026-10-12 18/18 PASS |
+| **定值与压板持久化** | `YK12` 投退 + 非默认定值跨复位 | ✅ 2026-10-12 21/21 + 13/13 + 4/4 + 4/4 PASS |
+| **SOE 落盘** | 自发 `M_SP_TB_1` 带时标 + FTP 下载解码 | ✅ 2026-10-12 56 条记录全 PASS |
---
@@ -861,6 +1521,17 @@ cfg-file-unit-test、test-suite-switch、gitlint。
| 菜单页面 | [`docs/UI设计/菜单页面设计.md`](../../docs/UI设计/菜单页面设计.md) |
| 内容页 | [`docs/UI设计/内容页架构.md`](../../docs/UI设计/内容页架构.md) |
| 远程显示协议 | [`docs/UI设计/RemoDispBus协议与接收设计说明.md`](../../docs/UI设计/RemoDispBus协议与接收设计说明.md) |
+| 采集与算法层(L1~L3) | [`docs/算法/采集与算法层设计说明.md`](../../docs/算法/采集与算法层设计说明.md) |
+| 保护功能复现规划(产品定义 / 定值 / 路线) | [`docs/算法/继电保护功能复现规划.md`](../../docs/算法/继电保护功能复现规划.md) |
+| 全周傅氏算法原理 | [`docs/算法/傅氏算法详解.md`](../../docs/算法/傅氏算法详解.md) |
+| 采样有效性校验 | [`docs/算法/采样有效性校验设计说明.md`](../../docs/算法/采样有效性校验设计说明.md) |
+| ADC 采样节拍与 DMA | [`docs/子系统设计/ADC采样节拍设计说明.md`](../../docs/子系统设计/ADC采样节拍设计说明.md) |
+| ADC 通道映射与实测 | [`docs/硬件平台/ADC通道映射说明.md`](../../docs/硬件平台/ADC通道映射说明.md) |
+| ADC 前端注入验证流程 | [`docs/测试说明/ADC前端注入验证流程.md`](../../docs/测试说明/ADC前端注入验证流程.md) |
+| IEC 60870-5-104 上行 | [`docs/子系统设计/IEC104上行设计说明.md`](../../docs/子系统设计/IEC104上行设计说明.md) |
+| 数据可信(标定 / 快照 / 运行参数) | [`docs/任务规划/数据可信.md`](../任务规划/数据可信.md) |
+| 页面补齐规划 | [`docs/UI设计/页面补齐规划.md`](../../docs/UI设计/页面补齐规划.md) |
+| 编号规范 | [`docs/编号规范.md`](../../docs/编号规范.md) |
| 部署环境 | [`docs/环境与部署/项目部署环境要求.md`](../../docs/环境与部署/项目部署环境要求.md) |
| 硬件网表 | [`docs/硬件平台/V0.1_网表详细分析报告.md`](../../docs/硬件平台/V0.1_网表详细分析报告.md) |
| 待办登记簿 | [`docs/任务规划/README.md`](../任务规划/README.md) |
@@ -878,3 +1549,5 @@ cfg-file-unit-test、test-suite-switch、gitlint。
|---|---|---|
| 2026-10-05 | 初版 | 基于项目全量内容(架构 / 子系统 / UI / 测试 / 硬件网表 / 待办)编写完整产品需求设计文档:产品定位、六层架构与任务模型、V0.1 硬件规格、10 类功能需求(含 2 项待实现)、接口规范、非功能需求、UI 规格、待实现项与路线图、验收判据 |
| 2026-10-10 | FR-CFG-4 旧档迁移**取消** | 删除旧固件 `/cfg/netcfg.bin`(NCFG 二进制)的首启自动迁移:旧档若存在则被忽略(不读、不删、不迁移),配置回落工厂默认。理由:该一次性路径把整条配置写链挂进启动期调用图,defaultTask 静态最坏栈链 +600 B,而本仓库不存在携带旧档的设备;`net_cfg_legacy.c/h` 与 `cfg_store_legacy_path()` 一并移除。§7.1「掉电不丢配置」同步 |
+| 2026-10-27 | **v1.1 全面刷新(以参考产品 CLS100 为横向基准)** | ① 新增 §2.5「与参考产品 CLS100 的能力对照」(12 个能力域逐域给出参考实现 / 本产品现状 / 结论),并据此重写 §2.1 现状口径与 §2.4 产品范围(分"已验收 / 已实现但受制约 / 非本期"三档);② 新增 §4.6「V0.1 硬件能力边界」(H1 双转换器无共同采样触发 / H2 无中点偏置 / H3 无出口开入 / H4 无本地屏 / H5 无 SDIO)作为范围裁剪的硬依据;③ 任务模型由 6 任务更正为 **9 任务**(补 `adcTask` / `iec104Task` / `protectTask`,栈配置改为 words/B 双列),事件位补至 bit8,启动时序补配置段注册与 `adc1_disable` 铁律,线程间通信补双区快照 / SPSC 环 / 脏位;④ **功能需求新增五节**:§5.9 ADC 采集与标定(FR-ADC,含标定折算与前端物理口径)、§5.11 遥测与相量(FR-MEAS)、§5.12 保护功能(FR-PROT,9 元件 + 四源闭锁)、§5.13 定值与运行参数(FR-SET)、§5.14 SOE 与动作记录(FR-SOE)、§5.15 IEC 104 上行(FR-IEC104,含点表推荐响应时间);⑤ 新增 §6.8 104 点表摘要,§6.7 对外 API 补 10 个模块;⑥ §7.2 补采样/相量/遥测/保护/上送七项实时指标,§7.3 内存与栈预算全部换为 2026-10-24 受管快照与 2026-10-22 栈快照,§7.4 门禁改为按族描述,§7.6 补 104 与配置面安全边界;⑦ §8 菜单绑定现状(22/33/42)与内容页分组重写;⑧ §9 改为「缺口总表(G1~G10)+ 推进顺序 + 未接线开关」,删除已闭环的 ADC/104 缺口;⑨ §10 验收补栈/体积门禁、采集与 104 锚点、六条现场项与五项台架闭环用例。**本次只改本文件** |
+| 2026-10-27 | **v1.2 改为 1:1 复刻口径(以参考工程源码为唯一清单)** | ① **范围口径反转**:产品范围由「按硬件裁剪」改为「参考源码能力全集」,差异只允许来自 5 项物理不可移植项(X1 双核分工 / X2 VxWorks / X3 本地屏 / X4 一次设备接口 / X5 计量通道,§2.4.1);② §2.5 由「12 域能力对照 + 取舍依据」重写为 **「1:1 复刻基线」**,判定依据从参考项目的分析文档改为 **参考工程源码的常量表与模块文件**(§2.5.1 三要素:点表即契约 / 地址即接口 / 模块即元件);③ 新增 **§2.5.2 19 项能力清单**(源码实测):定值 **249 项 / 23 单元**(`g_tSetModelTab`)、104 定值映射 **107 项 `0x8820~0x8891`**(`g_tCommSetParaTab`)、遥测 **31**、遥测模型 35、电度 **8**、开入 **138**、开出 **31**、动作事件 **33**、录波通道 **65**、软压板 **9**、保护元件 **45 模块**、记录队列 **13 类**、自检 3 类型、录波 3 类型 / 6 段、规约 **12 种**、加密 SM2/SM3/ECDSA;④ 新增 **§2.5.3 104 地址空间 8 段表**并 **更正段基址笔误**——参考 `Rly_IEC104.h` 为 1 起编,遥测 `0x4001`、遥控 `0x6001`(v1.1 及更早写 `4000H+` / `6000H+`),§5.15 与 §6.8 同步更正;⑤ 新增 **§2.5.4 定值 23 单元分布表**(WatchDog 63 / SYS3 45 / VolTimeRecv 17 / AutoReCls 16 …,并说明枚举 28 个中 4 个表内无项的原因)与 **§2.5.5 45 元件九类归集表**(含 `PRS_OverCurrent.c` 判据结构对照);⑥ 新增 **§2.5.6 规约全集 13 行表**(对上 9 种 / 对下 3 类 / 加密)与 **§2.5.7 差异归因表**,结论改为「差距全部是进度而非范围」;⑦ **§9 重写为「复刻进度与路线图」**:删除全部「不做」表述,缺口分 **阻塞型**(标定闭锁 / 出口与开入 / 三相与同期 / 电度计量 / 对下采集 / 第三方送检)与 **规模型**(定值 40→249、映射 40→107、元件 9→45、录波子系统、规约 1→12、国密等)两表,条目一律用**语义短语**命名以免与其它文档的 `S`/`A`/`P` 编号族撞名(编号规范 P-8),推进顺序补「点表铺开必须晚于标定」铁律;⑧ §2.1 产品定位补 1:1 复刻目标与三项差距量化(定值 40 vs 249 / 遥测 9 vs 31 / 开入开出 0 vs 138·31);⑨ §6.8 点表摘要逐段补「与参考的差额」说明(遥测缺第二回线与线电压、遥信缺 138 点开入、定值缺整单元)。**本次只改本文件** |