Files
STM32F4-Base/docs/算法/继电保护功能复现规划.md
T
wandering1 a275539c17 docs(全仓): 内容页黄金 47 → 53 的当前态同步——含钩子显示名,登记簿口径另笔
task-9 让内容页黄金从 47 涨到 53(通讯设置页六态),本笔只做**当前态陈述**的同步;真值全部本轮实测:
`simulator/tests/ref/*.bin` = **53**;`git diff 31ca4a1f..HEAD` 对该目录 = **
6 个新增、零修改** ⇒ 存量 47 张
逐字节未变(这条是关键:新增页不该让旧页重生成,否则回归基线就失去意义)。

**四类命中各走各路,这是本笔的全部难点**(分类比替换重要得多):
· 当前态 → 改,25 处页数,落在 16 只文件(AGENTS、钩子显示名、导航器 docstring、`lvgl-simulator` s
kill、
  门禁索引与 `ui-golden` 详解、UI 自动化流程、内容页架构、页面补齐规划与扩充方案、数据供给、自动化测
  试流程、覆盖率口径、测试开发标准流程、模拟器两份 README);
· 变更记录历史行 → **一条不动**,另在其下一行插入当日「47 → 53」新行 6 条(含判据与零漂移证据);
· **同数不同义 → 不动**:覆盖率口径里的「47 个 .c」「47 = 13+5+29」、ram_report 的表行号 47、`#47-D`
  诊断号、LSI 47kHz、47,360 栈字数、像素哈希 3476/3474 —— 一并替换就会毁掉六个不相干的事实;
· 带日期戳 / 自declare 冻结的快照 → 不臆改(数据供给篇那句上一笔已加「当时」,页面补齐规划里那张
  「2026-10-25 复核…剩 21 叶」的表自带「完成即冻结不回改」声明)。

复扫残留当前态 47 = **0**。⚠ 顺手纠一条**会教错方法**的陈旧:naive 计数 `grep -c '#page='` 上一笔写的是
22,现在真值是 **23**(文件头示例行也算一次)——旧文档里那个 22 **恰好等于新的正确 bound 数**,不改的话,
下一个人用错算法还能碰巧对上,比错更糟。

⚠ `AGENTS.md` 里本次有两件事同行相邻(本笔的内容页 53 页 + 批次三那句 `TC-*` 停发),**分两句说明**:
前者是计数同步,后者是昨天那条「批次三不坐」裁定的入口文案,二者不是同一件事。

钩子显示名改在 `.pre-commit-config.yaml`(47 → 53)。**这条必须与代码同批入库**:配置脏而未 stage 时
pre-commit 会直接报错挡住全仓任何提交(今天已实测两次),所以本笔先落它,把后面几笔的路清开。

自查:`check_doc_links --all` rc=0(203 篇)、`check_ids --strict` rc=0 且不可判定绝对
数 **979 未变**(新增
文本里的提交号与 `#page=comm` 没推高它)、`gen_task_table --check` 0、`check_bom_drift`
 0、18 只文件 noBOM /
LF / U+FFFD=0;行数变动 +49/−47 全部可归属(插 6、删 2、并 1),其余为 1:1 等行替换。登记簿销项与叶数
(`UI补齐.md` + `docs/任务规划/README.md`)**不在本笔** —— 那是口径变更不是计数同步。
2026-10-27 13:54:05 +08:00

617 lines
72 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 继电保护功能复现规划
> **定位**:把参考系统(CLS100 DTU 保护测控装置)的**继电保护链路**在本项目(STM32F4-Base DTU 平台)上分层复现的**总规划**——给出要实现的功能、性能指标、定值参数、平台适配口径与分阶段路线图。
> **参考来源**:`D:\Code\DTU\参考资料\huaiyuan\huaiyuan\Scatter_P_HV03.01_SV01.01\项目分析文档\04-算法与采样专题\ADC采集至数据使用全流程详解`(同专题另有《项目详细分析-交流采样与有效值计算》《傅氏算法详解》《项目详细分析-阶段6-继电器保护单元分析》)。
> **阅读前提**:先读 `docs/算法/傅氏算法详解.md`(算法原理)与 `docs/硬件平台/ADC通道映射说明.md`(采样通道权威口径)。
> **相关文档**:`docs/产品需求/产品需求设计文档.md`、`docs/任务规划/README.md`、`docs/内存管理/RAM使用分析与优化方案.md`。
> **状态**:**P0 采样与相量底座已台架闭环(2026-10-11)**——L1 采集链路(B1,2026-10-10)、 采样有效性校验与 L2 相量层(`sample_ring` + `phasor`,57 项主机单测 + 台架 `@test` 含 `phasor(first)/phasor(hb)` 标记闭环)均已落地;**P1/P2 保护元件与定值模型软件侧完成(2026-10-11,`prot_set` + `prot_elm`,57 项主机单测)**;**B5 板端接线完成(2026-10-12)**——`protectTask`(20 ms 判据节拍 + 「自检失败闭锁」采样故障闭锁 + 定值校验和巡检,IWDG `TASK_WD_PROTECT` bit8,栈 512 words 静态链 872 B / 余 57%),判据结果经 B4 IEC104 遥信(YX15~23/31)上送;**B7 定值持久化 + 全局软压板 + 竞态收口完成(2026-10-12,含台架腿验证)**;**出口记录(L4)与标准源注入验收为下一步**(见 §7)。
---
## 1. 背景、目标与范围
### 1.1 参考系统(CLS100)保护实现概览
| 维度 | 参考实现 |
| --- | --- |
| 硬件平台 | TI OMAP-L138(ARM926EJ-S + C674x DSP **双核**),无 FPGA |
| 操作系统 | VxWorks |
| 核心分工 | **DSP 核**跑保护算法(1 ms 中断节拍),**ARM 核**跑管理 / 通信 / 人机 |
| 采样率 | 50 Hz 系统,每周波 **20 点** → 保护采样率 **1000 Hz**(`CN_SAM_HERTZ=50`、`CN_SAM_RATE=20`) |
| 内部总线节拍 | **4000 Hz**(80 点/周波,为保护采样率的 4 倍,`CN_WAVE_RATIO=4`),供录波/高频量使用 |
| 保护相量 | **全周傅氏**(全周 DFT),每次刷新 15 个基波相量 + 3 个二次谐波相量 + 1 个五次谐波相量,**每 1 ms 重算** |
| 遥测有效值 | 每 **200 ms** 对 k=1~9 次谐波做 DFT 再**方和根**(`CN_NUM_YCHUMWAVE=9`),得"真有效值"轨 |
| 保护元件 | **89 个模块**(`RelayUnit/PRS_*.c`),统一 `tagPRS_XXX` 接口(Init / Main / 执行函数) |
| 并发机制 | 采样**双缓冲**(2 周波 = 40 点)+ 相量**双区指针原子交换** + 遥测 **0x55/0xaa 计算/拷贝标志协议** |
| 调度 | **时间片表**(单点 / 2 点 / 4 点 / 8 点)按 `g_dwSchedulerCnt` 位掩码分发 |
| 定值 | EEPROM 存定值 + 折算系数(`wCoeEEP` / `wCoeCal` / `wCoeRet`),TLV 通道;遥测微调 TLV10(±10%,0.1% 步长) |
| 有效值口径 | 保护用**基波有效值**(`CN_ANA_VEC_SQRT=FALSE`),计量/遥测用**谐波方和根** |
> 数据全链路(采样 → 内部总线 → 缓冲 → 预处理 → 算法 → 存储 → 使用)见参考文档《ADC采集至数据使用全流程详解》§5~§7;傅氏原理与系数折算见 `docs/算法/傅氏算法详解.md`。
### 1.2 本项目现状
| 维度 | 现状 |
| --- | --- |
| 硬件平台 | STM32F407ZGTx(Cortex-M4F,168 MHz,**单核**,硬件 FPU) |
| 操作系统 | FreeRTOS V10.3.1(CMSIS-RTOS v2) |
| 已实现子系统 | 网络(CH395F)、存储(GD5F2GQ5UE SPI NAND + dhara FTL + FatFs)、时间(SD2506 RTC + `sys_clock`)、配置(cfg_file)、日志、UI(远端显示)、看门狗(IWDG)、FTP |
| 采样硬件 | TPAFE5160(16 位、8 通道**同步**、±5 V 双极性、并行 `GPIOG[15:0]`)+ STM32 内部 ADC1(12 位、9 通道**顺序**扫描、0~3.3 V 单极性) |
| 采样软件 | `Drivers/BSP/TPAFE5160/tpafe5160.h` 驱动就绪(原子快照 API);`App/task/adc_task.c` **已实现真实消费者(B1,2026-10-10)**——`tpafe5160_snapshot()` 取数 + 帧统计;**采样节拍由 TIM3 更新事件(1 kHz)硬件触发**(2026-10-10;同一事件经 TRGO 触发 ADC1 + DMA);STM32 侧 **`App/algo/adc_input.c` 已实现语义映射 + ADC1 DMA 乒乓帧消费(「STM32 ADC1 启动与扫描」,v2.0)**,`HAL_ADC_Start_DMA` 已出现 |
| 保护算法层 | **L2 相量层已实现并台架闭环**(`App/algo/sample_ring.c` + `phasor.c`:全周傅氏 5 实例、双区交换、每 1 ms 刷新,2026-10-11 `@test`);**L3 元件框架 + 过流/过负荷/过压/欠压/零序过压 + 定值模型软件侧完成**(`prot_elm.c` + `prot_set.c`,2026-10-11,57 项主机单测);**出口 / SOE 记录仍缺失**(P4) |
| 已知硬件缺陷 | 登记簿条目「双转换器无共同采样触发」:8 路电气量分属两片转换器 → V0.1 上禁止跨转换器做相位/功率/矢量运算 |
### 1.3 复现范围界定
**本期做(保护链路最小可用集)**
1. 采样与预处理:周期采样触发、通道语义映射、标定、有效性校验、等周波调频、零序通道接入。
2. 相量计算:全周傅氏基波/谐波相量、线/负序/零序合成、双区交换、每 1 ms 刷新。
3. 保护元件:**V0.1 测量有效子集**——过压/欠压(`UA`)、零序过压(`UN`)、过流(A 相,`IA`)、过负荷(A 相)、过频/低频;三相完整过流、零序过流、涌流制动、PT/CT 断线等**建接口不使能**,待 V0.2(见 §1.6)。
4. 出口与记录:跳闸/告警出口、SOE/动作记录、定值模型与 cfg_file 集成、自检闭锁。
> ⚠️ **V0.1 硬件裁剪**(2026-10-10 定性):本清单受「双转换器无共同采样触发」(跨转换器无同一时刻性)与**"STM32 侧无中点偏置"**两条约束,实际可闭环的保护元件见 **§1.6**——V0.1 上只有 TPAFE 三路(`UA`/`UN`/`IA`)测量有效。
**本期不做(延后或依赖条件)**
- 方向元件 / 功率 / 功率因数 / 对称分量类运算——受「双转换器无共同采样触发」制约,V0.1 上取子板计量结果,或待 V0.2 硬件改版后实现。
- 三相完整过流、零序过流、依赖三相的 PT/CT 断线——需 V0.2 硬件(8 路电气量全上 TPAFE + 中点偏置)后启用。
- 重合闸、馈线自动化(FA)等 FTU 专有功能——视产品定义(B0)。
- 双核 / DSP 拆分、VxWorks 特有机制、IEC 61850、完整故障录波——与单核 FreeRTOS 平台不匹配。
- 参考系统 89 个模块的**全量**移植——按需裁剪,只复现本产品定义的元件集。
### 1.4 前置依赖与阻塞项
| 依赖 | 说明 | 状态 |
| --- | --- | --- |
| **B0 产品定义** | 采集是否持续 / 采样率与通道 / 转发目标 / 保护元件清单——决定 B1 与保护层的**规模** | ✅ 已确认(2026-10-10,见 §1.5) |
| **B1 ADC 采集链路** | 周期 CONVST + `adc_task` 消费 `tpafe5160_snapshot()` + 建任务 + 栈预算 | ✅ 已实现并 `@test` 实机闭环(2026-10-10;`adcTask` 512 words,台架 1000 Hz) |
| **双转换器无共同采样触发(硬件缺陷)** | V0.1 跨转换器无同一时刻性 → 限定 V0.1 可实现的保护范围 | ⚠️ 硬件改版项(V0.2) |
| **栈预算** | 保护任务栈需入 `Src/freertos.c` 并经 `scripts/stack_report.py` 核算 | ✅ 两任务均已核算:`adcTask`(**「采样有效性校验」后:栈抬至 640 words,静态 1080 B / 台架实测峰值 952/2560 / 余 57%**);`protectTask`(B5,2026-10-12:**512 words,静态链 872 B / 余 1176 B / 57%**,台架水位待 `@test`) |
### 1.5 B0 产品定义(2026-10-10 确认)
> **来源**:两份合并——①《检测平台配电终端送检要求(点表)》(省电科院送检要求,**验收口径**);② 参考项目 `APP/EquipCfg/Const_CommPara.c`(**DTU410 / F30(Z)** 的 IEC 104 信息体地址点表,**实现细节**)。
> **口径**:点表定"上送什么、什么格式、什么地址";`Const_CommPara.c` 定"怎么编号、哪些定值"。
**(1)确认结论**
| 项 | 确认结论 |
| --- | --- |
| 定义基准 | 两份合并(点表为验收口径 + 参考项目 104 点表为实现细节) |
| 上行规约(转发目标) | **IEC 60870-5-104**(DL/T 634.5104-2009),以太网 TCP **2404**(**非** ModBus RTU 上行) |
| 主站 / 终端地址 | 主站 `192.168.1.199:2404`;终端 `192.168.1.101~106`(可设);链路地址与 ASDU 公共体地址 2 字节、传送原因 2 字节、**IOA 3 字节**(101 为 2 字节) |
| 采集持续性 | **持续采集**(中断驱动 + 遥测周期上送 + 死区上送 + SOE) |
| 采样率 | **1000 Hz**(20 点/周波 @50 Hz),1 ms 保护节拍 |
| 遥测 | 上送**短浮点**,采集上传**系数 = 1**;点号 `4000H+` |
| 遥信 | 双位置遥信上**双点**,其余**单点**;点号 `0+` |
| 遥控 | **双点命令**,合闸选择 `82H`、执行 `02H`;点号 `6000H+` |
| **RS-485** | **对下 ModBus RTU 采集**(下行采集口,非上行口) |
| 对时 | 点表要求 **SNTP `192.168.1.121:5105`**;本项目**保留自定义 TCP 8888**,SNTP 本期不实现(B0-b) |
| 固有参数 | `8001H~800AH`:终端类型/操作系统/制造商/硬件版本/软件版本/校验码/规约类型/型号/ID/MAC |
| 运行参数 | `8020H~8058H`:死区(电流/交流电压/直流电压/功率/频率/功率因数)、PT/CT 变比、负荷越限/重载/过载报警、录波投退与定值、功率置负 |
| 定值 | `8820H~8882H`:过流 I/II/III 段、零序过流 I/II 段、重合闸、低压/低频、励磁涌流闭锁、小电流接地等 |
**(2)遥测点号 → 本项目通道映射**
| 点号 | 点表语义 | 本项目来源(V0.1) |
| --- | --- | --- |
| `4010` | UBA 后备电源电压 | ⚠️ 无对应硬件通道 → **本期不做**(B0-a) |
| `4011~4013` | `1Ua/Uab`、`1Ub/Uca`、`1Uc/Ubc` | `UA`/`UB`/`UC`(映射见 `docs/硬件平台/ADC通道映射说明.md`) |
| `4014` | `1U0` 零序电压 | `UN`(外部专用零序电压通道) |
| `4015~4017` | `1Ia`、`1Ib`、`1Ic` | `IA`/`IB`/`IC` |
| `4018` | `1I0` 零序电流 | `IN`(外部专用零序电流通道) |
| `4019~401c` | `1P`/`1Q`/`1S`/`1Pf` | 计算量(受「双转换器无共同采样触发」制约,V0.1 不可做) |
| `401d` | `1f` 频率 | 软件测频 |
| `401e/f` | `V1`/`V2` 直流量(点表注"FTU 无") | ⚠️ 无对应硬件通道 → **本期不做**(B0-a) |
**(3)遥信 / 遥控点号**
- **遥信**(`0+`,33 点):`YX15` 故障总、`YX16` 过流 I 段/短路、`YX17` 过流 II 段、`YX18` 过流 III 段、`YX19` 零序过流 I 段、`YX20` 零序过流 II 段、`YX21` 接地故障、`YX22` 重载、`YX23` 过载、`YX24~30` 外部遥信、`YX31~33` 闭锁状态。
- **遥控**(`6000H+`):`YK1~YK4` 开关 1~4、`YK11` 信号复归、`YK12` 遥控软压板、`YK13` 电池活化、`YK14` 解除闭锁。
**(4)响应时间要求(点表推荐值)**
| 参数 | 推荐值 |
| --- | --- |
| 终端启动时间 | ≤ 100000 ms |
| 104 连接 / 总召 | ≤ 3000 ms / ≤ 8000 ms |
| 104 SOE 上送 | ≤ 5000 ms |
| 104 遥控选择/撤销/执行 | ≤ 5000 ms |
| 104 读定值 / 修改定值预置/执行 | ≤ 10000 ms / ≤ 5000 ms |
| 104 读文件目录/文件 | ≤ 30000 ms |
| 录波文件存储 | ≤ 15000 ms |
**(5)B0 残留项处置(2026-10-10 确认)**
| # | 事项 | 处置 |
| --- | --- | --- |
| B0-a | `UBA` 后备电源电压、`V1/V2` 直流量三路遥测的硬件来源 | **本期不做**——V0.1 无对应硬件通道,不加子板/通道;点表此三项本期空缺 |
| B0-b | 对时 | **保留自定义 TCP 8888**;点表要求的 **SNTP 5105 本期不实现** |
| B0-c | 保护/控制范围 | **本期 = 骨架全做 + 有效通道子集闭环**(2026-10-10 用户确认),评估见 §1.6 |
> **B0 至此全部闭环**:上行 IEC 60870-5-104 / 持续采集 / 1000 Hz 已定(§1.5 表 1~4);B0-a / B0-b 本期不做或维持现状;B0-c 的范围裁剪见 §1.6。
### 1.6 B0-c 本期保护范围评估(2026-10-10 确认)
**(1)V0.1 硬件约束(两条叠加)**
| # | 约束 | 出处 | 后果 |
| --- | --- | --- | --- |
| 双转换器无共同采样触发 | 8 路电气量分属 TPAFE5160 与 STM32 ADC1 **两片**,两片**无共同采样触发** | `ADC通道映射说明.md` §1、登记簿条目「双转换器无共同采样触发」 | 跨转换器的相位 / 矢量 / 功率 / 功率因数 / 负序运算**不成立** |
| R5 | STM32 侧**无中点偏置**(1k 串联 + 1k 到 `*_GND`),0~3.3 V 单极性 | `ADC通道映射说明.md` §7、本文 §9 R5 | STM32 侧交流量负半周**削顶** → 该侧**算不出有效值 / 相量** |
**(2)净效果:V0.1 只有 TPAFE 三路"测量有效"**
| 通道 | 转换器 | 有效值 + 相位 |
| --- | --- | --- |
| `UA` / `UN` / `IA` | TPAFE5160(16 位、±5 V 双极性、同步) | ✅ **有效** |
| `UB` / `UC` / `IB` / `IC` / `IN` | STM32 ADC1(12 位、0~3.3 V 单极性、顺序) | ❌ 削顶 → 仅可读码值**监视** |
**(3)保护元件可行性(V0.1)**
| 元件 | 依赖通道 | 转换器 | V0.1 | 原因 |
| --- | --- | --- | --- | --- |
| 过压 / 欠压 | `UA` | TPAFE | ✅ | 测量有效 |
| 零序过压 | `UN` | TPAFE | ✅ | 测量有效 |
| 过流(A 相) | `IA` | TPAFE | ✅ | 测量有效 |
| 过负荷(A 相) | `IA` | TPAFE | ✅ | 测量有效 |
| 过频 / 低频 | `UA` / `IA` | TPAFE | ✅ | 单通道测频,有效 |
| 过流(B / C 相) | `IB` / `IC` | STM32 | ❌ | 削顶,无有效值 |
| 零序过流 | `IN`(外部)/ 自产 `Ia+Ib+Ic` | STM32 / 跨转换器 | ❌ | 削顶 / 跨转换器(双转换器无共同采样触发) |
| 方向 / 功率 / 功率因数 / 负序 | 多路 | 跨转换器 | ❌ | 双转换器无共同采样触发 |
| PT / CT 断线 | 三相判据 | 跨转换器 | ❌ | 需三相同时刻 |
| 母线接地告警 | `3U0`(UN) + `3I0`(IN) | UN 可 / IN 不可 | ⚠️ 部分 | 仅电压侧可判 |
**(4)本期范围(定论,2026-10-10)**
采用**"骨架全做 + 有效通道子集闭环"**:
- **与通道无关的骨架**(采集触发、`adcTask`、语义映射、标定、全周傅氏、双区交换、统一保护元件接口、定值模型 + cfg_file、出口驱动、SOE / 记录、自检闭锁)——**本期全做**;这是 V0.2 改版后**不需要重构**的核心资产(§6.2 的接口设计启示)。
- **保护元件**——本期只让**测量有效的通道**闭环动作:`UA`(过压/欠压、测频)、`UN`(零序过压)、`IA`(过流 A 相、过负荷)。其余元件**建接口 + 预置定值但不使能**,待 **V0.2**(修复「双转换器无共同采样触发」+ 补中点偏置,8 路电气量全上 TPAFE)。
- **控制类 / FTU 专有功能**(重合闸、小电流接地选线、后加速、检合环同期):均依赖三相 / 零序测量或出口硬件,**本期不做**,随 V0.2。
- 即:**本期交付"整条保护链路的软件实现" + "单相/中性线保护闭环验证"**;三相完整过流、零序过流、方向/功率类随 V0.2 硬件启用。
---
## 2. 总体架构设计
### 2.1 数据全链路(分层)
复现后的保护链路分为 6 层,自下而上:
| 层 | 职责 | 参考对应 | 本项目落点(拟) |
| --- | --- | --- | --- |
| **L0 采样驱动** | 触发转换、读出原始码值 | AD 芯片 + 总线 | `Drivers/BSP/TPAFE5160/` + STM32 ADC1 HAL |
| **L1 采集与预处理** | 快照取数、语义映射、标定、有效性校验、等周波调频、零序接入 | `DataPreRecv` / `RealDataMerge` / `CalSoftFr` / `GetZoreSamData` | `adc_task` + `App/algo/`(拟) |
| **L2 相量计算** | 全周傅氏基波/谐波、线/负序/零序合成、双区交换 | `CalFFTVecFull` / `CalfLineVec` / `CalfNegVec` | `App/algo/`(拟) |
| **L3 保护元件** | 各保护判据(过流/零序/过压/频率/…) | `RelayUnit/PRS_*.c` | `App/protect/`(拟) |
| **L4 出口与信号** | 跳闸/告警出口、信号灯 | `TripKO` / KO | `App/protect/` + BSP 出口驱动 |
| **L5 记录与上送** | SOE/动作记录、UI 显示、遥测上送 | 记录模块 + 通信 | `App/log/` + `Drivers/BSP/UI/` + `App/protocol/` |
> **分层原则**:L1 只做"数"(码值→工程量),L2 只做"相量"(工程量→复相量),L3 只做"判据"(相量 + 定值→布尔),L4/L5 只做"动作与留痕"。**算法与 I/O 分离**,使 L2/L3 成为主机侧单元测试(L0.5)的天然适格对象(落实 `docs/任务规划/测试与架构专项.md`「采集链路测试可验证性约束」)。
### 2.2 任务与中断模型(映射到 STM32F4 + FreeRTOS)
参考系统用 DSP 的 1 ms 中断串起整条保护链。本项目为单核 FreeRTOS,采用"**中断触发 + 任务计算**"模型:
| 角色 | 载体 | 周期 | 优先级(拟) | 说明 |
| --- | --- | --- | --- | --- |
| 采样节拍 | 定时器中断(TIMx) | **1 ms** | 最高(ISR) | 产生 CONVST 脉冲;ISR 内只置事件/计数,不做重运算 |
| 采集与预处理 | `adcTask` | 1 ms | 高 | `tpafe5160_snapshot()` 取数 → 标定 → 存入采样环 |
| 相量计算 | `adcTask` 内联 或 `algoTask` | 1 ms | 高 | 全周傅氏 → 相量双区交换 |
| 保护判据 | `protectTask` | 1 ms | 高 | 各保护元件 Init/Main → 出口。**✅ B5 已落地(2026-10-12):V0.1 实为 20 ms / Normal**——元件吃 50 Hz 基波 rms(phasor 每工频周更新),延时精度由 `prot_elm` 的 now_ms 差值法保证、与节拍无关;1 ms/高是参考系统瞬时值元件口径,随 P2 瞬时值元件再评 |
| 遥测与显示 | 复用 `uiTask` / 新增 `measTask` | 200 ms | 中 | 谐波方和根、死区/平滑、UI 与上送 |
| 记录 | `defaultTask`(已有) | 事件驱动 | 低 | SOE/动作记录落 `sys_log` |
> **铁律**:`adcTask` / `protectTask` 的 FS 路径若触碰存储,必须沿用卷锁 try 语义(`vol_lock_wait(0)`),且每任务纳入看门狗 `required_mask` 心跳(见 `docs/子系统设计/看门狗设计说明.md`)。**保护节拍任务不得阻塞在存储 I/O 上**——记录走队列异步落盘。
### 2.3 并发与数据一致性
参考系统用三重机制保证"采样—相量—保护"三段并发无锁:**采样双缓冲 + 相量双区指针交换 + 遥测标志协议**。本项目沿用同一思想,并复用已有的原子快照范式:
| 机制 | 参考做法 | 本项目做法 |
| --- | --- | --- |
| 采样缓冲 | 双缓冲(2 周波 = 40 点),写/读分属两区 | 环形缓冲 + **序号**(`tpafe5160_frame_seq()` 已有)+ 临界区快照,防撕裂 |
| 相量区 | `tVectorRly[2][N]`,算完**原子交换**计算区/使用区指针 | 双区结构体 + 指针/索引原子切换(单核下用临界区或 `__atomic`) |
| 遥测拷贝 | 0x55/0xaa 计算/拷贝握手标志 | 快照 + 序号,或 FreeRTOS 事件标志握手 |
| 取数契约 | —— | **只能用 `tpafe5160_snapshot()`**(`AGENTS.md` 铁律),不用已删除的 `get_buf` / `data_ready` |
### 2.4 与现有子系统的接口
| 保护层需求 | 复用现有能力 | 落点 |
| --- | --- | --- |
| 定值存取 | **cfg_file 配置引擎**(替代参考的 EEPROM 定值文件) | `App/cfg/cfg_file.c` + 新增定值段 |
| 动作/SOE 记录 | `sys_log`(`/log/run.log`)与运行记录 | `App/log/` |
| 保护定值/测量显示 | 远端显示 UI(`ui_page_ac` 已有 24 行占位) | `Drivers/BSP/UI/ui_page_ac.h` |
| 遥测/事件上送 | 网络栈 + `App/protocol/`(协议预留) | `App/protocol/` + `Drivers/BSP/NET/` |
| 时间戳 | `sys_clock`(RTC 基准) | `App/util/sys_clock.c` |
| 自检留痕 | `selftest.log` / 自检框架 | `App/log/` |
---
## 3. 功能规划(分层清单)
> 每项给出:**功能点 / 关键参数 / 完成判据**。状态列 ⬜ 未实现。
### 3.1 L1 采集与预处理
| 功能名 | 关键参数 | 完成判据 | 状态 |
| --- | --- | --- | --- |
| 周期 CONVST 重触发 | 1000 Hz(与保护节拍同源) | 示波器见 U3 `BUSY` 连续脉冲;`tpafe5160_frame_seq()` 持续递增 | ✅ 2026-10-10:**TIM3 更新事件(1 kHz)硬件触发**(ISR 内 `tpafe5160_start_conv_irq()`;方案 A,零引脚/零驱动改动。⚠ 节拍源**不能**是 TIM6/TIM7——F4 上 ADC1 收不到它们的 TRGO,见 `docs/子系统设计/ADC采样节拍设计说明.md` §3.2);台架 `@test` PASS——`seq` 每 10 s 精确 +10000 = 1000.0 Hz、`frst_err=0`(早期证据 `boot_log_data/20261010_prod_adc_tim6_boot_log.txt`,节拍源当时为 TIM6) |
| TPAFE 快照消费 | 8 通道 / 帧 | `adc_task` 每拍调 `tpafe5160_snapshot()`,返回 1/0/-1 有处理 | ✅ B1 已实现并 `@test` 闭环(`adc_task.c`;台架 `idle=0`、`frst_err=0`) |
| STM32 ADC1 启动与扫描 | 9 通道、144 cycles、**TIM3 TRGO 硬件触发 + DMA** | 全库出现 `HAL_ADC_Start_DMA`;9 通道码值随注入变化 | ✅ 2026-10-10(v2.0):`App/algo/adc_input.c` 的 `stm32_take()`——ADC1 由 TIM3 更新事件经 TRGO 触发一轮 9 通道,`HAL_ADC_Start_DMA(&hadc1, buf, 18)` + DMA2_Stream4 循环模式把码值自动搬进**乒乓双缓冲**,任务侧只消费刚完成的半区(**零忙等**,实测单拍 `adcp` 122 µs → **8 µs**);台架 `@test` PASS——`adc1_seq` 每拍 +1、`adc1_err=0`、`adc1_hw=0`。⚠ 判据"随注入变化"以"逐通道独立读数 + 零停摆 + 跨次开机读数不同"替代(台架无信号源,同 §7.1 无示波器口径);**引脚级注入验证(`ADC通道映射说明.md` §8 步骤 2)仍为待做项** |
| 通道语义映射 | 见 `docs/硬件平台/ADC通道映射说明.md`(**按语义取数,不写死下标**) | `UA→buf[6]`、`UN→buf[5]`、`IA→buf[2]`;STM32 侧 `UB→ADC_CHANNEL_14` | ✅ 2026-10-10:`App/algo/adc_input.c` 的 `k_adc_map[]` 语义表(`UA/UN/IA`→TPAFE `buf[6]/[5]/[2]`,`UB/UC/IB/IC/IN/TEMP`→ADC1 `CH14/3/6/1/2/5`)+ `adc_input_raw()` 按语义取数;开机**映射自检**(`adc_input_init()` 校验 STM32 映射通道必落在扫描序列内 → 挡住"映射到不扫描的通道"静默错)通过(`ADC input layer init: OK`)。台架首帧日志 8 路 + 温度全部读出:`UA=11429 UN=11454 IA=11452`(与 TIM3 轮次一致)、`UB=1018 UC=1044 IB=943 IC=1069 IN=1052 T=850`(互异、非饱和;**两次开机读数不同** → 确为实时转换而非常量) |
| 通道标定(一次系数 + 零漂) | 每通道 `k`、`b`;系数定点 `2^10` | 注入标准源,读数误差 ≤ 目标精度 | ⬜ |
| 采样有效性校验 | FRSTDATA 跳变、帧序号单调、丢帧计数 | 芯片静默/丢帧被检出并置告警 | ✅ 2026-10-11:新增 `App/algo/adc_health.c/h`(纯逻辑判定层:静默 100 ms 门限 / 丢帧边沿 / 序号倒退锁存 / FRSTDATA·HAL 错误·STM32 停摆计数增量)+ `adc_task.c` 告警编排(严重事件与故障上升沿 `DBG_ERROR` + 每类每次开机一次 `SYSLOG_SELFTEST`,恢复 `DBG_INFO`;gap 不告警只计数,心跳增 `tgap`);主机单测 `test/host/adc_health/` **31 用例全绿**(`adc-health-unit-test` 钩子);台架 `@test` PASS 零 `[ERR]`(健康不误报,`boot_log_data/20261011_prod_adc_health_boot_log.txt`)。⚠ 抬栈:判定链 `adc_health_report`→`syslog_post` 回显尾使 adcTask 静态最坏链 832→**1080 B** → 栈 512→**640 words**(余 1480 B / 57%) |
| 等周波采样(软件测频 + 调频闭环) | 20 点/周波;测频范围建议 **45~55 Hz**(参考 40.5~60.5) | 频率偏移 ±2 Hz 时幅值误差 ≤ 1% | ⬜ |
| 零序通道接入(外部专用 / 自产切换) | 外部 `UN`/`IN`;自产 `3I0 = Ia+Ib+Ic`(V0.2 起) | 零序通道可切换来源,值正确 | ⬜ |
| 二次谐波/五次谐波提取入口 | k=2(涌流)、k=5(选线) | 相量层可产出对应谐波相量 | ✅ 2026-10-11:`phasor.c` 实例表 `C04-IA-F2`(k=2)/ `C05-IA-F5`(k=5)随每拍重算产出,台架心跳日志 `phasor(hb) C04/C05` 行可见(`boot_log_data/20261011_prod_phasor_boot_log.txt`);谐波**抑制/提取正确性**已由主机单测覆盖(`test/host/phasor/`) |
> ⚠️ **「双转换器无共同采样触发」约束**:「通道语义映射」中 `UA/UN/IA` 在 TPAFE、`UB/UC/IB/IC/IN` 在 STM32 ADC。V0.1 上 L1 只做**逐通道独立监视**,不得假设同族量同刻(`UA` 与 `UB` 无共同采样触发)。
### 3.2 L2 相量计算
| 功能名 | 关键参数 | 完成判据 | 状态 |
| --- | --- | --- | --- |
| 全周傅氏系数表 | `sin(2πk/N)·(√2/N)`、`cos(2πk/N)·(√2/N)`,N=20 | 系数表与 `docs/算法/傅氏算法详解.md` §2.3 一致 | ✅ 2026-10-11:`phasor.c` 离线系数表**预乘 √2/N**;主机单测逐项复核(`test/host/phasor/` 系数表用例) |
| 基波相量实例 | **5 个实例**(参考项目 4 个,见下方注):`C01-IA-F1` / `C02-UA-F1` / `C03-UN-F1` / `C04-IA-F2` / `C05-IA-F5` | 每实例输出 `{fRe, fIm, fAm, fAmSQ}` | ✅ 2026-10-11:`k_inst[]` 数据驱动 5 实例;台架开机即产出 `phasor(first)` 5 行(`boot_log_data/20261011_prod_phasor_boot_log.txt`) |
| 相量有效值输出 | `fAmSQ = √(fRe²+fIm²)` 直接为**有效值**(系数已折算) | 标准源读数 = 设定有效值 | ✅ 2026-10-11(链路级):`fAmSQ` 口径实现 + 单测合成正弦幅值误差 ≤1%;**"标准源读数"判据在无信号源台架不可达**(同 §7.1),待「通道标定(一次系数 + 零漂)」标定后复核 |
| 相位输出 | `φ = atan2(fIm, fRe)` | 相位误差 ≤ 目标值 | ✅ 2026-10-11(链路级):`fRe/fIm` 常驻双区、每拍产出,φ 由消费侧 `atan2f` 现算(不常驻结构体,见 `docs/算法/采集与算法层设计说明.md` §6);单测覆盖相位;**目标值待产品定义 + 标准源复核** |
| 线/负序/零序合成 | 线电压 `Uab=Ua−Ub` 等;负序 `3U2`/`3I2`;零序 `3U0`/`3I0` | 合成相量可复用于保护元件(**V0.1 仅同转换器内可合成**,见 §1.6) | ⬜ **V0.1 不适用**:跨转换器合成被「双转换器无共同采样触发」禁止;零序走**外部专用通道** `UN`/`IN`(§6.4),无需自产 → 随 V0.2 启用 |
| 每 1 ms 滑动窗刷新 | 每来新点,窗滑动一格、20 点重算(暴力法) | 相量每拍更新 | ✅ 2026-10-11:`sample_ring` 40 点环 + `phasor_run()` 每拍整窗重算(仅 `r==1` 新帧压环,P0 修复);台架 `ring` 随 `frames` 同步递增、`idle=0` |
| 双区指针原子交换 | 计算区/使用区切换 | 保护元件读使用区,无撕裂 | ✅ 2026-10-11:`s_zone[2][5]` + 单字节 `volatile` 切换(Cortex-M 原子);单测覆盖双区交换;为独立 L3 任务预留无锁读 |
| 遥测谐波轨(可选) | k=1~9,方和根 `√(ΣHk²)` | 与基波轨并行,供 UI/上送 | ⬜ |
> **双轨有效值**:保护要"基波有效值 + 相位"(抗衰减直流、抗谐波误动);计量/遥测要"真有效值"(谐波方和根)。两者**不可混用**——这是参考系统 `CN_ANA_VEC_SQRT=FALSE` 与遥测谐波轨并存的根本原因。
> **「基波相量实例」实例数 4 → 5 的来历**:参考项目(`APP/CLS100_Dsp/InstCalCell.c`)为 **4 个实例**——C01 基波 I/U、C02 零序基波、C03 二次谐波、C04 五次谐波。本项目按 V0.1 **有效通道**(`UA`/`UN`/`IA`,见 §1.6:`UB/UC/IB/IC/IN` 无中点偏置 → 削顶不可用)展开:C01 的"I/U"拆为两行(`C01-IA-F1` 电流 / `C02-UA-F1` 电压),其余顺延为 `C03-UN-F1` 零序、`C04-IA-F2` 二次、`C05-IA-F5` 五次。实现见 `App/algo/phasor.c` 的 `k_inst[]`;判据按 **5** 个实例断言(见 `docs/测试说明/相量层单元测试说明.md` §2.6)。
> **本表状态列口径**(2026-10-11 更新):「全周傅氏系数表」~「相位输出」/「每 1 ms 滑动窗刷新」/「双区指针原子交换」已**实现 + 主机单测(57 用例)+ 台架 `@test` 闭环**——闭环命令 `run_boot_test.py --required "...;phasor(first);phasor(hb)" --require-order "App init OK>phasor(first)>phasor(hb)"`,证据 `boot_log_data/20261011_prod_phasor_boot_log.txt`(`fw build` 身份戳匹配、回读一致、锚点 ×1、零 `[ERR]`)。⚠ **幅值/相位精度判据(标准源)在无信号源台架上不可达**(同 §7.1 无示波器口径),且「通道标定(一次系数 + 零漂)」标定未实现 → 现读数为**原始码值**,只证明链路通;精度复核排在标定之后。「线/负序/零序合成」随 V0.2(双转换器无共同采样触发),「遥测谐波轨(可选)」可选项未做。
### 3.3 L3 保护元件
采用参考系统的**统一接口模式**:每元件一个 `tagPRS_XXX` 配置结构(定值号、模拟通道号、KI/KO、标志位、校验和)+ `Init` / `Main`(判据)/ 出口函数。
**核心集(P0/P1)**
| 元件 | 判据要点 | 关键定值 | 状态 |
| --- | --- | --- | --- |
| 三段式相间过流 | 相电流基波 > 定值,经延时出口;返回系数滞回 | Ⅰ/Ⅱ/Ⅲ 段电流 + 延时 | 🔶 2026-10-11 主机实现:`App/algo/prot_elm.c` 通用"滞回+定时限"核 + `prot_set.c` 定值(Ⅰ/Ⅱ/Ⅲ 段,A 相 `IA`),单测 27 用例含 1.01× 启动/100 ms 到点/滞回保持/返回释放;**板端接线已落地(B5,2026-10-12:protectTask 20 ms 节拍,动作经 104 YX16~18 上送)**;出口(L4)待做 |
| 三段式零序过流 | 零序电流 > 定值,经延时出口 | Ⅰ/Ⅱ/Ⅲ 段零序电流 + 延时 | ⬜(双转换器无共同采样触发:`IN` 走 STM32,V0.2 使能;框架已就绪,加实例表一行即可) |
| 过负荷 | 相电流 > 定值,告警/跳闸可整定 | 过负荷电流 + 延时 | 🔶 同「三段式相间过流」(`OL-IA` 实例,默认告警不跳闸;板端接线随 B5 落地,YX23 上送) |
| 过压 / 欠压 | 相/线电压越限,经延时出口 | 过压定值、失压定值 + 延时 | 🔶 同「三段式相间过流」(`OV-UA`/`UV-UA`,欠量方向单测覆盖;沿用参考告警段 0x8027/0x8029) |
| 过频 / 低频 | 频率越限,经延时出口 | 过频、低频定值 + 延时 | ✅ 软件侧完成(B8,2026-10-12):`freq` 层测频(自适应窗,45~55 Hz 扫频最坏 **0.0101 Hz** / 1% 噪声 0.0160 Hz)+ `OF/UF` 实例(51.0/49.0 Hz、dly 1000 ms、返回系数 0.99/1.01,本地定值 8 项);OF/UF 暂无独立遥信点,动作仅经 YX15 总聚合可见(独立分点 + 注入验收 = B10) |
| 零序过压 | 零序电压 > 定值 | 零序过压定值 + 延时 | 🔶 同「三段式相间过流」(`3U0-UN` 实例,外部零序电压通道,不受双转换器无共同采样触发限制) |
**扩展集(P2/P3)**
| 元件 | 判据要点 | 状态 |
| --- | --- | --- |
| 涌流制动 | 二次谐波占比 > 制动系数,闭锁差动/过流 | ⬜ |
| PT 断线 | 电压突变/负序判据,闭锁电压类保护 | ⬜ |
| CT 断线 | 电流不平衡判据,闭锁 | ⬜ |
| 母线接地告警 | 零序电压 + 零序电流组合 | ⬜ |
| 故障启动(波形启动) | 突变量启动,触发录波/启动元件 | ⬜ |
| 无压/无流闭锁 | 低电压或低电流时闭锁过流 | ⬜ |
**延后集(受双转换器无共同采样触发 / 产品定义制约)**
| 元件 | 制约 |
| --- | --- |
| 方向元件 / 功率方向 | 需跨转换器相位一致 → V0.1 不可做 |
| 重合闸 | FTU 专有,视 B0 产品定义 |
| 手动跳闸 / 遥控 | 依赖出口硬件与协议定义 |
> **V0.1 可行性**:上表按元件类型分组,但**V0.1 上能否闭环**取决于通道(见 **§1.6**)——核心集中 `IA`/`UA`/`UN` 可做(A 相过流、过负荷、过压/欠压、零序过压),**三段式零序过流与 B/C 相过流本期不可做**(`IN`/`IB`/`IC` 削顶);扩展集「涌流制动」~「无压/无流闭锁」多依赖三相,本期**建接口不使能**。
### 3.4 L4 出口与记录
| 功能名 | 说明 | 状态 |
| --- | --- | --- |
| 跳闸出口(KO) | 判据满足 → 驱动出口继电器,带保持/脉冲 | ⬜ |
| 告警出口 / 信号 | 告警类动作驱动信号灯/继电器 | ⬜ |
| 出口自检 | 出口回路检测(若有回读) | ⬜ |
| SOE 记录 | 带时标的事件顺序记录 | ✅(B9,2026-10-12:`/log/soe.log` 64 B 定长记录 = 类型 + 元件号 + seq(u32) + CP56Time2a + epoch + 校验和;台架 FTP 下载解码 PASS,时标与 104 CP56 交叉一致) |
| 动作记录 | 保护动作/返回记录,落 `/log/soe.log` | ✅(B9,2026-10-12:六类边沿全覆盖——元件动作/复归、软压板投/退、采样数据块/恢复;protectTask 只投递(SPSC 环,post 禁 DBG),defaultTask `syslog_drain()` 落盘,动作路径无 NAND I/O) |
| 故障录波(可选) | 4000 Hz 内部节拍预留 | ⬜ |
### 3.5 L5 自检与闭锁
| 功能名 | 说明 | 状态 |
| --- | --- | --- |
| 定值校验和 | `tagPRS_XXX` 的 `dwTagSum` 自检,定值非法闭锁 | 🔶 2026-10-11:`prot_set.c` 已实现 sum32 正/反码封存 + selfcheck 失配置闭锁(参考 `dwTagSum/dwTagSumN` 模式);**B7(2026-10-12)竞态收口**:104 定值写改 `prot_set_set_sealed`(影子区写+封存后单字交换)+ selfcheck seqlock 式复核(提交撞见 = 本轮跳过),B5 登记的 µs 级误锁窗口消除;定值持久化 `/prot_set.bin`(blob 带 sum32 正/反码对,整表原子装载);元件级 tagPRS 常量表校验仍待补 |
| 采样通道自检 | 通道码值越界/静默检出 | 🔶 静默/丢帧/序号倒退/错误增量已由「采样有效性校验」 `adc_health` 检出(2026-10-11);码值越界待做 |
| 硬件自检 | 出口回路、电源、时钟 | ⬜ |
| 自检失败闭锁 | 任一项失败 → 闭锁相关保护并告警 | 🔶 定值闭锁 → 全元件复位已联动(`prot_elm_eval` 读 `prot_set_locked()`,单测覆盖);**采样故障闭锁已落地(B5,2026-10-12)**:protectTask 每拍读 `adc_health_flags()` 电平位(TPAFE/STM32 stall + 序号倒退)→ 命中即 `prot_elm_init()` 复位 + 本拍不判据,自愈后自动恢复;锁存类事件位(FRSTDATA/HW_ERR)不构成"当前测量不可信"→ 不闭锁,如实登记 |
---
## 4. 性能指标
### 4.1 实时性
| 指标 | 目标值 | 依据 |
| --- | --- | --- |
| 保护节拍 | **1 ms** | 参考 `CN_PROTECT_PERIOD=1000 µs` |
| 保护采样率 | **1000 Hz**(20 点/周波 @ 50 Hz) | 全周傅氏窗长 |
| 相量刷新周期 | **1 ms** | 每来一点重算 |
| 遥测刷新周期 | **200 ms** | 参考遥测链周期 |
| 出口动作时间 | ≥ 1 周波(20 ms)算法窗 + 定值延时 | 全周波算法固有延时 |
| 内部总线节拍 | 4000 Hz(80 点/周波) | 参考 `CN_WAVE_RATIO=4`(本项目按需裁剪) |
### 4.2 精度
| 指标 | 目标值 | 说明 |
| --- | --- | --- |
| 基波幅值误差 | ≤ 1%(频偏 ±2 Hz 内) | 依赖等周波采样 |
| 相位误差 | ≤ 目标角误差(依产品定义) | 依赖调频闭环 |
| 测频范围 | 建议 45~55 Hz(参考 40.5~60.5) | `CN_HERTZ_SOFTFR_MIN/MAX` |
| 定值折算 | 定点系数 `2^10` | 与参考一致 |
| 遥测微调 | ±10%,0.1% 步长(TLV10) | 参考口径 |
> **误差来源与预算**(参考《ADC采集至数据使用全流程详解》[计划] §12):采样量化(TPAFE LSB ≈ 152.6 µV)、通道标定残差、窗长偏离整周波(频偏)、系数定点舍入。前三项决定可达精度,最后一项可忽略。
### 4.3 算力与内存预算
| 项 | 估算 | 说明 |
| --- | --- | --- |
| 傅氏乘加 | 20 点 × 2(sin/cos)× 相量数 / 拍 | 参考用暴力法(CPU 余量足够);本项目 168 MHz + FPU 需实测 |
| 相量区 RAM | `tVectorRly[2][N] × sizeof(相量)` | 双区 + **5 实例**(本项目;参考项目 4 实例) |
| 采样缓冲 RAM | 40 点/通道 × 通道数 × 字宽 | 双缓冲 2 周波 |
| 定值区 RAM | 元件数 × 定值项 × 字宽 | 可由 cfg_file 载入 |
| 任务栈 | `adcTask` ✅ / `protectTask` ✅(B5:512 words,静态链 872 B / 余 57%) | 建任务前后各跑 `scripts/stack_report.py` |
> ⚠️ **改内存相关代码后必须刷新快照**:`@build` 出 `.map` 后跑 `scripts/check_mem_numbers.py --write`,同步 `docs/内存管理/RAM使用分析与优化方案.md` §2.1(`mem-numbers` 钩子会因体积变化 FAIL)。
### 4.4 频率跟踪
- **原理**:软件测频(对电压/电流信号过零点或相角差测频)→ 调整采样定时器周期 → 使窗长恒等于实际周波(严格 20 点/周波)。
- **闭环**:测频 → 周期修正 → 采样 → 再测频;参考用片内 EHRPWM 调频,本项目用 TIM 重装载值调整。
- **必要性**:窗长偏离整周波会破坏正交性,直流与二次谐波漏入测量(见 `docs/算法/傅氏算法详解.md` §3)。
---
## 5. 定值参数模型
定值分三类:**固有参数**(只读)、**运行参数**(可整定)、**保护定值**(可整定);地址口径来自 B0(§1.5 表 1,源参考项目 `APP/EquipCfg/Const_CommPara.c`)。
### 5.1 定值分类与地址
| 类 | 地址范围 | 内容 | 属性 |
| --- | --- | --- | --- |
| 固有参数 | `8001H~800AH` | 终端类型/操作系统/制造商/硬件版本/软件版本/校验码/规约类型/型号/ID/MAC | 只读 |
| 运行参数 | `8020H~8058H` | 死区(电流/交流电压/直流电压/功率/频率/功率因数)、PT/CT 变比、负荷越限/重载/过载报警、录波投退与定值、功率置负 | 可整定 |
| 保护定值 | `8820H~8882H` | 过流 I/II/III 段、零序过流 I/II 段、重合闸、低压/低频、励磁涌流闭锁、小电流接地等 | 可整定 |
### 5.2 定值项模型(`tagPRS_XXX`)
每元件一个配置结构:**定值号 / 模拟通道号 / KI·KO 标志 / 校验和** + `Init` / `Main` / 出口函数。定值项与元件一一绑定,便于逐元件自检(「定值校验和」)。
### 5.3 折算与存储
| 维度 | 参考 | 本项目 |
| --- | --- | --- |
| 折算 | `wCoeEEP` / `wCoeCal` / `wCoeRet`,定点系数 `2^10` | 同模型(工程量 ↔ 码值) |
| 载体 | EEPROM 定值文件 | cfg_file(`/config.ini`,NAND + FatFs),新增定值段 |
| 微调 | TLV10 ±10%,0.1% 步长 | cfg_file 微调段(按需) |
### 5.4 定值项清单(按元件)
| 元件 | 定值项(拟) | 单位 |
| --- | --- | --- |
| 过流(A 相) | I 段/II 段/III 段电流定值 + 各段延时 | A / s |
| 过负荷 | 过负荷电流定值 + 延时 + 投退 | A / s |
| 过压 / 欠压 | 过压定值、欠压定值 + 延时 | V / s |
| 零序过压 | 零序过压定值 + 延时 | V / s |
| 过频 / 低频 | 过频定值、低频定值 + 延时 | Hz / s |
| 公共 | 返回系数、PT/CT 变比、通道标定系数 | — |
> ⚠️ **待补**:逐项**取值范围 / 步长 / 默认值**取自参考项目 `APP/EquipCfg/Const_CommPara.c` 的 `CommPara_ConfigTable`(`0x8020~0x8882`);本表在实现各保护元件时逐项落实(见 §10.3)。
>
> **2026-10-25 运行参数段落实进度**:卡 10 已落 `App/algo/run_par.c`——本仓自定逐项地址
> 0x8030~0x8038(死区 9 点)/ 0x8040~0x804F(k/b 覆盖直通 adc_cal),表与理由见
> `docs/子系统设计/IEC104上行设计说明.md` §3.4;**送检点表到位后以送检为准替换常量段**。
> 变比/报警/录波/功率置负等其余运行参数类项目前无消费者,留白不预埋。
>
> **2026-10-11 落实进度**:`App/algo/prot_set.c` 已建 RAM 模型(Q10 定点,31 项),**通讯地址逐项对照参考 `Comm/Pub/Const_CommSetPara.c` `g_tCommSetParaTab`**(基址 0x8820:过流 Ⅰ/Ⅱ/Ⅲ = 0x8856~0x8861、过负荷 = 0x8871~0x8874、零序过压 = 0x888E~0x8890;过压/欠压沿用告警段 0x8027~0x802A)。⚠ **默认值/范围为拟定值**(参考 EEPROM 出厂默认表不在本仓库,按 DTU 馈线典型量级拟定),待对照参考出厂表逐项修订。
---
## 6. 平台适配与差异处理
### 6.1 采样源差异
| 维度 | 参考系统 | 本项目 | 适配要点 |
| --- | --- | --- | --- |
| AD 器件 | 专用同步采样 AD | TPAFE5160(16 位、8 通道同步、±5 V)+ STM32 ADC1(12 位、顺序、0~3.3 V) | 统一到"工程量"层,屏蔽码值差异 |
| 通道数 | 8 实通道(4U+4I,自产零序) | 8 路电气量(4U+4I)+ 温度 | 语义映射见 `docs/硬件平台/ADC通道映射说明.md` |
| 同一时刻性 | 单芯片同步 | **跨转换器无共同触发**(登记簿条目「双转换器无共同采样触发」) | V0.1 只做逐通道独立监视 |
| 量程/精度 | 一致 | TPAFE LSB ≈ 152.6 µV vs STM32 LSB ≈ 806 µV | 同族量不可统一算法处理 |
### 6.2 双转换器无共同采样触发:影响与降级口径
- **V0.1 现板**:主板侧只做**逐通道独立监视**(有效值/越限/温度);**禁止**跨转换器的同周期相位、功率、功率因数、矢量类运算。
- **受影响功能**:方向元件、功率方向、差动类——延后(「方向元件 / 功率方向」)。
- **V0.2 改版后**:8 路电气量全部接 TPAFE(与 5 路备用路对调串联电阻目的地,BOM 不变),上层语义与代码**不动**,只改映射表内容 → 保护层无需重构。
- **接口设计启示**:**按语义取数、不写死下标**,是 V0.2 平滑升级的前提。
### 6.3 单核 vs 双核
| 维度 | 参考(ARM+DSP) | 本项目(单核) | 适配 |
| --- | --- | --- | --- |
| 保护计算 | DSP 核独占 | 与 FreeRTOS 任务共享 CPU | 保护任务优先级最高;避免长临界区 |
| 管理/通信 | ARM 核 | 同核分任务 | 依赖现有任务优先级体系 |
| 隔离 | 核间隔离 | 无 | 靠任务优先级 + 栈预算 + 看门狗保证实时性 |
### 6.4 零序:外部专用通道 vs 自产
- 参考:TLV13 选择映射表——外部零序(专用通道)或**自产零序**(`3I0 = Ia+Ib+Ic`)。
- 本项目 V0.1 实况(**2026-10-10 更正**,此前"V0.1 无专用零序通道"的表述作废):
- **有外部零序专用通道**——`UN`(零序电压,TPAFE)与 `IN`(零序电流,STM32 ADC),对应点表 `4014` / `4018`;
- **自产零序在 V0.1 不可行**:`Ia` 在 TPAFE、`Ib`/`Ic` 在 STM32,求和属**跨转换器**(双转换器无共同采样触发)。
- 于是本期:**零序过压**(`UN`,TPAFE,测量有效)可做;**零序过流**(`IN`,STM32 削顶 → 无有效值)不可做。
- V0.2(8 路电气量全上 TPAFE)后可自产,外部/自产可切换(恢复 TLV13 语义)。
- 落点:「零序通道接入(外部专用 / 自产切换)」。
### 6.5 定值存储
| 维度 | 参考 | 本项目 |
| --- | --- | --- |
| 载体 | EEPROM 定值文件 | cfg_file(`/config.ini`,NAND + FatFs) |
| 折算 | `wCoeEEP` 定点 | 同模型(工程量 ↔ 码值) |
| 微调 | TLV10 ±10% | cfg_file 微调段(按需) |
---
## 7. 分阶段实施路线图
### 7.1 阶段划分与里程碑
| 阶段 | 名称 | 内容 | 前置 | 里程碑 |
| --- | --- | --- | --- | --- |
| **P0** | 采样与相量底座 | B1(周期 CONVST + `adcTask` 消费 + 建任务 + 栈预算)+ L1 + L2 | B0 + B1 ✅ | 每 1 ms 产出正确的基波相量 —— **✅ 2026-10-11 台架闭环**(「采样有效性校验」同日落地 ✅;「通道标定(一次系数 + 零漂)」标定 / 「等周波采样(软件测频 + 调频闭环)」等周波为 P0 遗留项,精度复核依赖标准源) |
| **P1** | 基础保护元件 | **V0.1 有效子集**:过流(A 相,`IA`)、过负荷(A 相)+ 定值模型;B/C 相过流**建接口不使能** | P0 | 标准源注入 A 相可正确动作 —— 🔶 **软件侧 2026-10-11 完成**(`prot_set` 定值模型 30 用例 + `prot_elm` 元件框架/过流三段/过负荷 27 用例,主机全绿);**板端接线已落地(B5,2026-10-12:protectTask + IWDG bit8 + 栈核算 + 104 YX 上送)**;标准源注入验收待做 |
| **P2** | 电压/频率类保护 | 过压/欠压(`UA`)、过频/低频、零序过压(`UN`) | P0 | 电压/频率越限正确动作 —— 🔶 过压/欠压/零序过压随 P1 同批主机完成(同框架实例);过频/低频 ✅ **B8 已落地(2026-10-12)**:freq 层(自适应窗,扫频最坏 0.0101 Hz)+ OF/UF 实例;出口独立遥信点与注入验收归 B10 |
| **P3** | 异常检测与闭锁 | L5 自检闭锁、采样通道自检;三相类(涌流/PT·CT 断线/母线接地)**建接口不使能** | P1/P2 | 自检失败闭锁;未使能元件不误动 |
| **P4** | 出口、记录与定值集成 | L4 出口与记录、§5 定值模型落 cfg_file、UI 显示、上送 | P1 | 动作出口 + SOE 记录 + UI 显示闭环(**定值持久化 + 软压板 + 竞态收口 = B7 完成 2026-10-12,台架腿已验 ✅**;**SOE/动作记录 = B9 完成 2026-10-12 ✅**:protectTask 边沿→SPSC 环→defaultTask 落盘 `/log/soe.log`,protectTask 静态链 872 B 不变,自发 YX 上送 M_SP_TB_1 带时标;出口继电器「跳闸出口(KO)」~「出口自检」仍 ⬜——V0.1 无出口硬件,跳闸维持否定确认 R7 口径) |
| **P5** | 方向/功率类(延后) | 「方向元件 / 功率方向」方向元件等 | V0.2 硬件 / 子板计量 | 跨转换器相位一致后实现 |
> ⚠️ **V0.1 硬件裁剪**(2026-10-10,详见 §1.6):V0.1 上只有 TPAFE 三路(`UA`/`UN`/`IA`)测量有效。故 **P0 骨架全做**(与通道无关),**P1/P2 只做有效通道子集**——A 相过流、A 相过负荷、过压/欠压、零序过压、过频/低频;**三相过流(B/C 相)、零序过流、方向/功率类、PT/CT 断线**依赖 V0.2 硬件(修复「双转换器无共同采样触发」+ 中点偏置),本期**建接口不使能**。
### 7.2 每阶段交付物与验收判据
| 阶段 | 交付物 | 验收判据 |
| --- | --- | --- |
| P0 | `adcTask`/`algo` 模块(采集触发 + 语义映射 + 标定 + 全周傅氏 + 双区交换)+ 设计文档 + L0.5 单测 | TPAFE 三路(`UA`/`UN`/`IA`)标准源读数误差 ≤ 目标;相量每 1 ms 刷新;`@test` 通过 |
| P1 | A 相过流 + A 相过负荷元件 + 定值模型 | 注入 1.2×/0.9× 定值,A 相正确动作/返回;返回系数正确 |
| P2 | 过压/欠压 + 过频/低频 + 零序过压元件 | 越限动作时间符合定值延时 |
| P3 | 自检闭锁 + 采样通道自检;三相类元件建接口 | 自检失败闭锁;未使能元件不误动 |
| P4 | 出口 + 记录 + 定值 UI | 动作驱动出口;SOE 带正确时标;UI 显示实时值 |
| P5 | 方向元件 | 需 V0.2 前置条件满足 |
### 7.3 依赖关系图
```text
B0 产品定义 ✅(2026-10-10 已确认,见 §1.5)
└─ B1 ADC 采集链路(周期 CONVST + adcTask + 建任务 + 栈预算)
└─ P0 采样与相量底座
├─ P1 基础保护(A 相过流/过负荷)
│ └─ P4 出口/记录/定值
├─ P2 电压/频率保护(UA/UN)
└─ P3 异常检测与闭锁(自检;三相类不使能)
└─ P5 方向/功率类(依赖 V0.2 硬件 / 子板计量)
```
---
## 8. 测试与验证
### 8.1 测试分层
| 层 | 对象 | 方式 |
| --- | --- | --- |
| L0 静态 | 代码规范、文档链接、体积 | pre-commit 钩子(`cppcheck` / `doc-links` / `mem-numbers`) |
| L0.5 主机单测 | 傅氏相量、定值解析、保护判据(**算法与 I/O 分离**后天然适格) | `test/host/<模块>/run_unit_test.py`(MSVC 离线编译真实源文件,参考 `test/host/cfg_file/run_unit_test.py`) |
| L1 板端套件 | 采样/相量/保护元件 | `test/run_all_suites.py` 板端套件 |
| L2/L3 台架 | 标准源注入、动作出口、时序 | 台架闭环(COM6 @115200) |
### 8.2 `docs/任务规划/测试与架构专项.md`「采集链路测试可验证性约束」落实
`docs/任务规划/测试与架构专项.md`「采集链路测试可验证性约束」对采集链路提出三条设计约束,保护层须一并满足:
1. **协议解析与硬件 I/O 分离**——保护判据函数只吃相量 + 定值,可单测;
2. **采集缓冲双缓冲 + 序号**——防撕裂(单测测不出时序撕裂,须设计上消除);
3. **DE 收尾超时路径**(RS-485,若保护涉及 485 通信)。
### 8.3 验收判据(保护层)
- 标准源注入:幅值/相位/频率读数误差在目标内(**V0.1 限 TPAFE 三路**);
- 定值动作:1.2× 定值可靠动作、0.9× 定值可靠返回,返回系数符合 `wCoeRet`;
- 时序:动作时间 = 算法窗(≥20 ms)+ 定值延时,误差在允许范围;
- 闭锁:自检失败工况下相关保护可靠闭锁(V0.1 的 PT/CT 断线、涌流闭锁待 V0.2);
- 记录:SOE/动作记录时标正确(注意板载 RTC 比墙钟慢约 8 h)。
---
## 9. 风险与开放问题
| # | 风险 / 开放问题 | 影响 | 处置方向 |
| --- | --- | --- | --- |
| R1 | **V0.1 硬件裁剪保护范围**(双转换器无共同采样触发 + 无中点偏置 → 仅 TPAFE 三路 `UA`/`UN`/`IA` 测量有效) | 三相过流 / 零序过流 / 方向功率类本期无法闭环 | 本期做有效通道子集(§1.6);其余随 V0.2 硬件启用 |
| R2 | **双转换器无共同采样触发(硬件缺陷)** | 方向/功率/矢量类无法在 V0.1 实现 | V0.2 硬件改版;V0.1 取子板计量 |
| R3 | **单核算力** | 1 ms 节拍内完成傅氏 + 全部保护元件 | 实测 CPU 余量;必要时裁剪遥测谐波轨或降低元件扫描频率 |
| R4 | **等周波调频实现** | 频偏时精度不达标 | TIM 重装载调频;先固定 1000 Hz 跑通再上闭环 |
| R5 | **STM32 侧无中点偏置** | 交流量负半周削顶,无法算 RMS | V0.1 只做监视;V0.2 补偏置 |
| R6 | **栈预算** | 新任务栈溢出 | 建任务前后跑 `scripts/stack_report.py`;纳入看门狗 |
| R7 | **出口硬件未确认** | 跳闸出口无法验证 | 确认出口继电器/回读电路;无硬件时先做逻辑级验证 |
---
## 10. 附录
### 10.1 参考系统关键常量
| 常量 | 值 | 含义 |
| --- | --- | --- |
| `CN_PROTECT_PERIOD` | 1000 µs | 保护中断周期 |
| `CN_SAM_HERTZ` | 50 | 系统频率(Hz) |
| `CN_SAM_RATE` | 20 | 每周波采样点数 |
| `CN_SAM_RATIO` | 1 | 保护采样倍率 |
| `CN_YCSAM_RATIO` | 2 | 遥测采样倍率 |
| `CN_WAVE_RATIO` | 4 | 录波倍率(4000 Hz) |
| `CN_BUFSAM_CYCLE` | 2 | 采样缓冲周波数 |
| `CN_BUFSAM_LEN` | 40 | 采样缓冲长度(点) |
| `CN_ANA_VEC_SQRT` | FALSE | 保护用基波有效值(非方和根) |
| `CN_ANA_DIF` | FALSE | 半周波/差分组件关闭 |
| `CN_HERTZ_SOFTFR_MIN/MAX` | 40.5 / 60.5 Hz | 软测频范围 |
| `CN_NUM_YCHUMWAVE` | 9 | 遥测谐波次数上限(`(20>>1)−1`) |
| `CN_NUM_YCAVER` | 4 | 遥测平均点数 |
| 系数定点 | `2^10` | 标定系数定标 |
### 10.2 术语表
| 术语 | 含义 |
| --- | --- |
| 全周傅氏 | 全周波傅里叶算法,单频 DFT,得基波相量 |
| 相量 | `{fRe, fIm, fAm, fAmSQ}`,实部/虚部/幅值/有效值 |
| 等周波采样 | 软件测频 + 调频,保持严格 20 点/周波 |
| 外部零序 | 专用 `UN`/`IN` 通道直接取零序量 |
| 自产零序 | `3I0 = Ia+Ib+Ic` 软件合成(V0.2 起可用) |
| 双区交换 | 相量计算区/使用区指针原子切换 |
| 时间片表 | 单点/2点/4点/8点调度表 |
| TLV | 参考系统的参数通道(定值/微调/映射) |
| 返回系数 | 动作值/返回值之比(滞回) |
### 10.3 待确认清单
1. 定值逐项取值范围/步长/单位/默认值——源参考项目 `Const_CommPara.c`,实现各元件时落实(见 §5.4)。
2. 出口硬件形态(继电器/回读)——依硬件(R7)。
3. 等周波调频范围与精度目标——依产品定义(R4)。
4. 是否保留遥测谐波轨(k=1~9)——依 UI/上送需求。
---
## 变更记录
| 日期 | 变更 | 说明 |
| --- | --- | --- |
| 2026-10-10 | 建立本文档 | 依据参考项目《ADC采集至数据使用全流程详解》等专题文档,规划 CLS100 保护链路在本项目(STM32F4-Base)的分层复现:功能/性能/参数/平台适配/路线图;登记至 `docs/README.md` |
| 2026-10-10 | 增补 §1.5 B0 产品定义 | 从参考项目 `APP/EquipCfg/Const_CommPara.c`(DTU410/F30(Z) 的 104 信息体地址点表)与《检测平台配电终端送检要求(点表)》挖出并确认 B0:上行 **IEC 60870-5-104**(以太网 2404)、持续采集、**1000 Hz**(20 点/周波)、遥测短浮点系数 1、**RS-485 对下 ModBus RTU 采集**;§1.4 的 B0 状态改"已确认" |
| 2026-10-10 | 同步 B0 确认到下游章节 | §7.3 依赖图 B0 由"阻塞"改"已确认";§9 R1 由"B0 未定"改为"B0 残留待确认项(B0-a/b/c)" |
| 2026-10-10 | B0 残留项闭环 + 新增 §1.6 范围评估 | B0-a **本期不做**(`UBA`/`V1`/`V2` 无硬件通道)、B0-b **保留 TCP 8888**(SNTP 5105 不做);B0-c **定为"骨架全做 + 有效通道子集闭环"**;新增 **§1.6** 由 V0.1 硬件(N-18 + 无中点偏置)推导本期可做保护范围 = TPAFE 三路(`UA`/`UN`/`IA`)有效子集;同步 §1.3、§3.3、§6.4(零序口径更正)、§7.1/§7.2、§9 R1 |
| 2026-10-10 | 恢复被外部工具回写的旧稿 | 文件曾被外部格式化工具回写为旧稿:**§1.5/§1.6/§5 丢失、§10 混入 66 组下划线(u)标签、表格被填充对齐**。本次按权威来源重建 §1.5/§1.6、补齐 **§5 定值参数模型**,清除全部下划线标签并把表格压回仓库紧凑风格;内容与 §1.3/§3.3/§6.4/§7/§9 的定稿一致 |
| 2026-10-10 | **B1 落地:ADC 采集链路实现** | `App/task/adc_task.c` 由空桩转为真实消费者——每 1 ms 触发 `tpafe5160_start_conv_irq()` + `tpafe5160_snapshot()` 原子取数 + 帧统计 + 每 10 s 心跳日志;`Src/freertos.c` 手工创建 `adcTask`(512 words / Normal,落 `USER CODE` 保护区)+ 纳入 IWDG 必需掩码(`TASK_WD_ADC`,`0x37`→`0x77`)。§1.4 采样软件行、§1.4 依赖表 B1 行、§3.2 任务表(L1-1/L1-2)、§4 栈预算行、§7.1 P0 行同步更新。⚠ 本阶段为**任务周期软触发**(`osDelayUntil`);硬件定时器 1 kHz 触发为后续。同日 `@test` 实机闭环 PASS(`frame_seq` 严格 1000 Hz 递增、`idle=0`、`frst_err=0`、栈峰值 496/2048) |
| 2026-10-10 | **1 kHz 硬件定时器触发(TIM6)** | 采样节拍由任务周期软触发改为 **TIM6 更新中断(1 kHz)**:`Src/main.c` 的 `HAL_TIM_PeriodElapsedCallback` 加 TIM6 分支触发 `tpafe5160_start_conv_irq()`(`USER CODE` 区);`app_main.c` 用 `HAL_TIM_Base_Start_IT(&htim6)` 替换单次触发(在 `tpafe5160_init()` 之后);`adc_task.c` 退化为**纯消费者**(1 ms 轮询仅作消费节奏)。§1.2 采样软件行、§3.2 L1-1 同步。详见 `docs/子系统设计/ADC采样节拍设计说明.md` |
| 2026-10-10 | **L1-3/L1-4 落地:STM32 ADC1 扫描 + 语义映射** | 新增 `App/algo/adc_input.c/h`(L1 采集层):① `k_adc_map[]` **语义通道表**(`UA/UN/IA`→TPAFE `buf[6]/[5]/[2]`,`UB/UC/IB/IC/IN/TEMP`→ADC1 `CH14/3/6/1/2/5`)+ `adc_input_desc()`/`adc_input_raw()` **按语义取数**;② `stm32_scan()` STM32 ADC1 9 通道软件触发顺序扫描(`HAL_ADC_Start` + 逐通道 `PollForConversion`/`GetValue`);③ `adc_input_poll()` 统一"TPAFE 快照 + STM32 扫描"。`adc_task.c` 取数改走本层(首帧日志补全 8 路 + 温度、心跳增 `adc1_rc`/`adc1_err`);`app_main.c` 在 `tpafe5160_init()` 后调 `adc_input_init()`(含**映射自检**:STM32 映射通道必落在扫描序列内,失败记 `SYSLOG_SELFTEST`);Keil 工程挂 `adc_input.c` 并加 `../App/algo` 包含路径。§1.2 采样软件行、§3.1 L1-3/L1-4 同步。`@build` 0 错 0 警;台架 `@test` PASS(`ADC input layer init: OK`、`adc1_rc=0`/`adc1_err=0`、`seq` 仍 1000.0 Hz、`adc` 栈峰值 528→584 B、回读一致、零 `[ERR]`/HardFault),证据 `测试说明/boot_log_data/20261010_prod_adc_l1_boot_log.txt` |
| 2026-10-10 | **L2 相量层落地 + L2-2 实例数口径对齐** | 新增 `App/algo/sample_ring.c/h`(L2 输入:按语义通道保存 2 周波 = 40 点环缓冲,整帧写后统一推进写指针)与 `App/algo/phasor.c/h`(L2 核心:全周傅氏单频 DFT,N = 20;系数表**离线预乘 √2/N** → `fAmSQ` 直接为**有效值**;计算区/使用区**双区原子切换**;实例表 `k_inst[]` 数据驱动);主机侧单测 `test/host/phasor/` **57 用例全绿**(`phasor-unit-test` 钩子)。**§3.2 L2-2 行口径对齐**:参考项目为 **4 个实例**,本项目按 V0.1 有效通道展开为 **5 个**(`C01-IA-F1`/`C02-UA-F1`/`C03-UN-F1`/`C04-IA-F2`/`C05-IA-F5`),已加注说明 4 → 5 的来历;§4.3 相量区 RAM 行同步为 5 实例。⚠ §3.2 的 L2 各点状态**仍标 ⬜**——实现与主机单测已完成,但**台架 `@test` 闭环未做**,且 L2-3 的完成判据(标准源读数 = 设定有效值)在无信号源台架上不可达,故不置 ✅(口径见 §3.2 表下注) |
| 2026-10-10 | **L1-1/L1-3 节拍源与搬运方式升级(v2.8)** | 节拍源 **TIM6 → TIM3**(更正硬事实:F4 上 ADC1 的外部触发清单里没有 TIM6/TIM7 TRGO,只接 DAC),TIM3 更新事件同时触发 TPAFE CONVST 与(经 TRGO)ADC1 一轮 9 通道;L1-3 由"软件触发 + 逐通道轮询"改为 **DMA2_Stream4 循环搬运 + 乒乓双缓冲**,`stm32_scan()` → `stm32_take()`,单拍 `adcp` **122 µs → 8 µs**。§1.4 采样软件行、§3.2 L1-1/L1-3/L1-4 同步。完整设计与实测见 `docs/子系统设计/ADC采样节拍设计说明.md` §11 |
| 2026-10-11 | **L2 台架闭环:P0 收尾** | `@build` 0 错 0 警 → `@test` 闭环把 `phasor(first)`/`phasor(hb)` 列为 Required 并校验顺序 `App init OK>phasor(first)>phasor(hb)`(⚠ `net init: OK` **不在**该序内——adcTask 与 netTask 并行,`phasor(first)` ≈+500 ms 早于 `net init: OK` ≈+574 ms 属正常)→ **PASS**:5 实例相量开机即产出、心跳 5 实例持续刷新、`frames` 每 10 s +10000(1000.0 Hz)、`idle=0`、`frst_err=0`、`adc1_err=0`、`adc1_hw=0`、`fw build` 身份戳匹配、回读一致、锚点 ×1、零 `[ERR]`/HardFault;证据 `boot_log_data/20261011_prod_phasor_boot_log.txt`。栈复测:adcTask 静态 832 B / 实测峰值 **928/2048(余 54%)**,7 任务全 PASS(`docs/内存管理/RAM使用分析与优化方案.md` §2.3 已同步)。§3.1 L1-9 置 ✅(`C04-IA-F2`/`C05-IA-F5` 台架产出);§3.2 L2-1~L2-4/L2-6/L2-7 置 ✅(精度判据保留"待标准源"注),**L2-5 更正为"V0.1 不适用、随 V0.2"**(跨转换器合成被 N-18 禁止、零序走外部专用通道——原表下注"L2-1~L2-7 实现完成"对 L2-5 系误记);§7.1 P0 里程碑置 ✅(遗留 L1-5/L1-6/L1-7)。下一步 = **P1**(A 相过流/过负荷 + 定值模型)与 **L1-6 采样有效性校验** |
| 2026-10-11 | **L1-6 采样有效性校验落地** | 新增 `App/algo/adc_health.c/h`(**纯逻辑判定层**,零平台依赖免桩单测):① 静默——两侧帧序号连续 ≥100 ms 无前进(电平位,可自愈;`adc_health_flags()` 为 L5-4 闭锁预留);② 丢帧——TPAFE 序号一次前进 >1 计 `tgap`(与 STM32 侧 `adc1_gap` 对称,边沿事件不告警——消费者超拍是已知现象,告警会淹没真故障);③ 单调性——序号倒退锁存位;④ 错误增量——FRSTDATA / HAL 错误回调 / STM32 停摆计数增量(事件位与锁存位**编号对齐**,消费者按位图"每类每次开机留痕一次")。`adc_task.c` 只做告警编排:严重事件/上升沿 `DBG_ERROR` + `SYSLOG_SELFTEST`("adc sampling fault"),下降沿 `DBG_INFO`,心跳行增 `tgap`。主机单测 `test/host/adc_health/` **31 用例全绿**(100 ms 门限两侧、tick 回绕、边沿语义、NULL 守卫、init 幂等;`adc-health-unit-test` 钩子登记)。台架 `@test` PASS:零 `[ERR]`(健康不误报)、`tgap=1→2` 与 `adc1_gap` 同步可见、`frames` 1000.0 Hz;证据 `boot_log_data/20261011_prod_adc_health_boot_log.txt`。⚠ **抬栈**:`adc_health_report`→`syslog_post` 控制台回显尾使 adcTask 静态最坏链 832→**1080 B**(512 words 余 968 B < 1024 B 底线)→ **512→640 words**,复测余 **1480 B / 57%**、堆 min_ever 7152→6640 B(AGENTS 任务表 / `docs/内存管理/RAM使用分析与优化方案.md` §2.3 已同步)。§3.1 L1-6 置 ✅ |
| 2026-10-11 | **P1/P2 软件侧:定值模型 + 保护元件框架** | 新增 `App/algo/prot_set.c/h`(**定值模型**:Q10 定点与参考 2^10 口径一致;31 项元数据表**通讯地址逐项对照参考 `Comm/Pub/Const_CommSetPara.c`**——过流 Ⅰ/Ⅱ/Ⅲ = 0x8856~0x8861、过负荷 = 0x8871~0x8874、零序过压 = 0x888E~0x8890、过压/欠压沿用告警段 0x8027~0x802A;范围校验 + 整表装载 all-or-nothing + **sum32 正/反码封存自检闭锁**(参考 `dwTagSum/dwTagSumN` 模式,L5-1);⚠ 默认值/范围为**拟定**,参考 EEPROM 出厂表不在本仓库,待对照修订)+ `App/algo/prot_elm.c/h`(**元件框架**:通用"越限 + 返回系数滞回 + 定时限"核,数据驱动实例表 7 行 = OC1/OC2/OC3/OL(IA)+ OV/UV(UA)+ 3U0(UN);`prot_elm_eval()` 纯判据可主机单测,`prot_elm_run()` 为 phasor→测量薄适配(相量未就绪整拍跳过);定值闭锁 → 全元件复位)。主机单测 `test/host/prot_set/`(30 用例)+ `test/host/prot_elm/`(27 用例:1.01× 启动 / 100 ms 到点 / 滞回保持与释放 / 欠量方向 / 投退 / 闭锁联动 / 时基回绕)全绿,钩子 `prot-set-unit-test` / `prot-elm-unit-test` 登记。`@build` 0 错 0 警(**未接线 → 链接器整对象移除,零 Flash/RAM 足迹**);板端接线随 protectTask 立项(栈预算 + IWDG 门禁),标准源注入验收随其后。§3.3 L3-1/3/4/6 置 🔶、L3-2/5 注明框架就绪待通道/频率算法;§3.5 L5-1/2/4 置 🔶;§5.4 落实进度注 |
| 2026-10-12 | **B5 板端接线:protectTask 立项落地** | 新增 `App/task/protect_task.c/h`(**纯编排**,判据仍在 `App/algo/`):20 ms 节拍三件事——① **L5-4 采样故障闭锁**:`adc_health_flags()` 电平位(TPAFE/STM32 stall + 序号倒退)命中 → `prot_elm_init()` 复位 + 本拍不 eval(stall 自愈自动恢复;锁存类事件位不闭锁——非"当前测量不可信");② **L5-1 定值校验和巡检**(每拍 `prot_set_selfcheck()`,31 项 sum32 开销可忽略;⚠ 与 104 定值写的竞态窗口 µs 级、同次写 seal 即清锁,如实登记,P4 定值持久化收口);③ `prot_elm_run()` + 动作位图边沿日志(`[PROT]`,V0.1 无出口 → 动作 = 遥信 + 日志)。**线程契约收口**:`prot_elm_request_reset()`(单字标志,任意上下文)——104 YK11 在 iec104Task 落请求、下一拍 eval 头部消费,杜绝与 protectTask eval 竞态(`iec104_pts.c` 改走此口);定值/元件初始化移入 `app_main_init`(内核前,phasor_init 之后)。**门禁(E-59 同款)**:`TASK_WD_PROTECT = 8` 入 `wd_required_mask()` 两分支(产品 `0xF7`→`0x1F7`、HW 层 `0xF5`→`0x1F5`,看门狗单测 39 断言同步);栈 **512 words**,`stack_report.py` 实测静态最坏链 **872 B / 余 1176 B / 57%**;**FreeRTOS 堆 48→56 KB**(`.ioc` L1 参数 + `FreeRTOSConfig.h` 同步,CCM 75.3%→87.9% < 92% 门禁,`RAM预算台账.md` §6 登记配额 48→56 KB)。任务手写于 `Src/freertos.c` USER CODE 区(Normal,V0.1 无出口不需 AboveNormal;§2.2 表已注"1 ms/高"为 P2 瞬时值口径)。单测 +1(TC-PE-010 复归请求:不当拍生效、下一拍消费,滞回保持区可区分复位与否)→ prot_elm 28 用例全绿。`@build` 0 错 0 警(Code=204348,ZI +8,196 = 堆 +8 KB);台架 `@test`(PROT 锚点 + `[STACK] protect` 水位 + 104 YX 联动)待做。§3.3 L3-1/3 注板端落地、§3.5 L5-4 置 ✅、§7 P1 里程碑更新 |
| 2026-10-12 | **B7 定值持久化 + 全局软压板 + 竞态收口(采集保护收尾任务卡)** | **定值模型增项** `PS_GLOBAL_EN`(全局软压板,枚举尾追加,编号不回收);**原子写**:`prot_set_set_sealed()` 影子区拷贝→改→重封→**单字交换活跃区**(双缓冲 +124 B 静态),`prot_set_selfcheck()` 改 seqlock 式复核(封存和两读不一致 = 提交撞见 → 本轮跳过)——B5 登记的"104 写 vs 巡检"µs 级误锁窗口就此消除(§3.5 L5-1 注收口)。**持久化**:新增 `App/cfg/prot_set_store.c/h`(双端注册 + 模拟器豁免点名)——blob = magic`PSET`+版本+计数+值区+sum32 正/反码对(144 B),`/prot_set.bin` 走 `cfg_store_write_atomic`(临时文件+rename,掉电安全);**写路径** = C_SE/YK12 执行段置脏 → iec104Task `dirty_peek` 投递 `SYS_EVT_PROT_SET_SAVE`(事件位 bit7)→ defaultTask(配置引擎属主)落盘,写失败脏回置 = 下轮重试;**装载** = storage_bring_up 在 STORAGE_READY 前整表原子 parse(损坏/越界/版本换代 → 拒绝保出厂默认 + 自检留痕 `prot set corrupt`;文件缺失 = 首启正常静默)。**YK12 转真**:`iec104_pts.c` 两段式(选择段校验 DPC、执行段 set_sealed),protectTask 下一拍读退出态 → 复位元件 + 停判据(`global plate OUT/IN` 边沿日志);本地定值项 `comm_addr=0` 显式不可寻址(防 IOA=0 误命中)。单测:prot_set 63 断言(+33:软压板/原子写/脏握手/blob 往返/坏 magic/截断/坏版本/**伪造自洽越界**对抗样本)、iec104 94 断言(+7:YK12 两段转真/置脏/本地项 C_RD EVI)。`@build` 0 错 0 警(Code=205500 +1152 B,ZI +280 = 双缓冲+blob 缓冲,`ram_baseline` 已刷)。**台架腿完成(2026-10-12)**:`@test` PASS + PC 主站 `test/host/iec104_master.py --b7-pre` **21/21**(YK12 两段 OFF→0.05 A 低定值不动作 / ON→YX15·16 即动作,C_SE→C_RD 回读)、`--b7-post` **13/13**(**压板退出态跨复位保持**:开机日志 `global plate OUT -> protection disabled` + 低定值仍不动作、重启后 YK12 ON 联动在位)、`--b7-mark/--b7-check` **4/4+4/4**(**非默认定值 7.5 跨复位保持**,C_RD=7.500,与出厂默认可区分);开机日志两次 `[CFG] prot set loaded (/prot_set.bin)`;证据 `docs/测试说明/boot_log_data/`(20261012_B7_* 两份) |
| 2026-10-12 | **B6 台架 `@test` 闭环复测(B4/B5 验收窗口,采集保护收尾任务卡)** | 首跑(HEAD `d3107f3`)**FAIL**:`protect task start` 锚点行字节级交错损坏(`st[art: cycle=220ms elm=70`,两次开机同形复现)= protectTask 启动行违反控制台写者注册前门控纪律(B5 台架腿未跑故未暴露,机理与实证见 `docs/子系统设计/控制台单写者日志设计说明.md` §11 2026-10-12 行);其余 8 Required / 零 `[ERR]` / 锚点×1 / 回读一致全过。**修复** = 启动锚点行改 `dbg_console_writer_ready()` 首拍补打(adcTask 首帧门控同款,+16 B)。**复测 PASS**(B7 `1fe163b`+fix):锚点行完好(+577 ms,attach 后);**首采水位** `protect` 828/2048(free_min 1220,59%)、`iec104` 424/2560(83%)、新 56 KB 堆 free=17936 **min_ever=10000**(>3072 告警线零告警,**N-33 抬栈 min_ever 背书就绪**);采样闭锁不误报。**PC 主站往返**:新增 `test/host/iec104_master.py`(纯标准库主站客户端)STARTDT→总召四组+actterm→C_SE 两段写临时压低 OC1 定值**确定性**触发 YX15·16 变位(COT=3)→恢复复归→YK11 两段正答→C_RD 读回 10.000,**18/18 PASS**(`d3107f3` 与 B7+fix 两版固件各一轮),串口侧 `[I104] accepted`/`[PROT] elm OC1-IA` 边沿/YK11 复位→UV-UA +10 s 重返联一致。证据 `docs/测试说明/boot_log_data/20261012_B6_*`(含缺陷复现 MISS 快照)。B5 行"台架 `@test` 待做"遗留**闭环**;B7 台架腿的 C_SE 写路径已随本窗验证(断电重启保持 + YK12→YX 仍待窗) |
| 2026-10-12 | **B8 频率测量层 + 过频/低频保护(L3-5,W1 任务卡)** | 新增 `App/algo/freq.c/h`(L2.5 测频:共轭乘积相位增量 + 解缠绕 + **自适应窗长** K_eff=round(8·Fs/(2·f̂))——定长窗受 20 点矩形窗**负序泄漏纹波**限制(实测最坏 0.317 Hz)、60 拍 Kay 复数和 0.197 Hz(交叉项和角不按 1/K² 衰减),自适应窗把窗长对齐纹波周期 fs/(2f) 整数倍 → **0.0101 Hz**;假值钳制带 35~65 Hz 与系统合理带分离(贴边钳制会非对称丢纹波半周 → 45 Hz 点 +0.16 Hz 偏置);幅值门 <50 码 → valid=0 保持;UA→IA 优先级;`freq_run()` 挂 adcTask `phasor_run()` 后,心跳 `freq(hb)` 行)。**定值 32→40**:尾追加 OF/UF 8 项(51.0/49.0 Hz、dly 1000 ms、返回系数 0.99/1.01;全部本地项 `comm_addr=0`,参考逐项地址不在本仓库待对照);`bad_mask`→`uint64_t`(TC-PS-011 断言 bit39 可指认);**blob VER 1→2**(144→176 B;升级语义换代/损坏分流:旧档 → `prot_set_store_load()` **rc=2 换代** INFO ≠ **rc<0 真损坏** ERROR+自检,defaultTask 不误报)。**prot_elm 7→9**:`PE_OF`/`PE_UF` + `pe_cfg_t.src`(0=相量有效值 / 1=freq 测频;freq 无读数按方向填"必不启动"值,不整拍跳过);OF/UF 暂无独立 YX 点,动作仅经 YX15 总聚合可见(独立分点 = B10 送检点表);YC `0x401D` 频率点仍 QDS=IV(接真值 + 独立分点归 B10)。单测:`test/host/freq/` **46 断言**(J1 扫频 45~55 Hz ≤0.02 实测 0.0101 / J2 噪声 1% ≤0.10 实测 0.0160 / J3 启动收敛 ≤40 ms 实测 20 / J4 阶跃 50→51 ≤120 ms 实测 98——**精度优先于响应**显式取舍:98 ms ≪ OF/UF 动作延时定值默认 1000 ms / J5 浮空 valid=0 漂移 0.13 / J6 双跳变 60 ms 回 ±0.05;三代弯路推导写 `freq.c` 文件头防重蹈)+ prot_set **90**(+27:40 项/VER 2/64 位 bad_mask/旧档拒绝)+ prot_elm **47**(+OF/UF 滞回·方向隔离·测频接线);回归 phasor 57 / iec104 94 无退化。`@build` 0 错 0 警(Code=207468);RW_IRAM1 +632 B(73.3%→73.8%)、CCM 不变、Flash +2,244 B(21.6%);**adcTask/protectTask 栈链不变**(freq_run 帧未进最坏链,无需抬栈)。§3.3 L3-5 置 ✅(软件侧)、§7 P2 更新;`freq-unit-test` 钩子登记(31→32) |
| 2026-10-12 | **B9 动作记录 + 时标 SOE(L4-4/L4-5,W1 任务卡)** | 新增 `App/log/soe_rec.c/h`(64 B 定长 SOE 记录纯编解码:类型 1~6 = 元件动作/复归、软压板投/退、采样数据块/恢复 + 元件号 + IV 位 + seq(u32) + CP56Time2a + epoch_s + value + sum8)与 `App/log/soe_store.c/h`(板端胶水:SPSC 无锁环 8 深惰性创建 + `soe_store_drain()` 挂 `syslog_drain()` 尾,defaultTask 唯一落盘写者)。**动作路径零 NAND I/O**:protectTask 只投递(post **禁 DBG**——曾把静态链从 872 垫到 1192 FAIL,丢弃计数留痕挪 drain 侧),**protectTask 静态链 872 B / 57% 改前后逐字节不变**(DoD 硬约束)。**104 自发单点改 M_SP_TB_1(type 30,带 CP56 时标)**——idx≥4 且时标有效;总召/周期上送保持 M_SP_NA_1 不变;主站工具 `iec104_master.py` 同步解析 type 1/30。单测 `test/host/soe/` **32 断言**(往返/截断/坏校验和/IV 位/seq 连续性)+ iec104 **94→97**(TB 编解码 + pts 自发选型 + IV);`soe-unit-test` 钩子登记(32→33)。**台架腿**(sync 追平 B8/N33 后重跑,覆盖将被合并的代码):`@test` PASS(锚点 `set=40 elm=9`、无 `[ERR]`)+ **顺带兜住 B8 板端面**(`freq(hb): f=0 valid=0` 浮空不发散、`prot set blob version change (ver=1 cnt=32), defaults in use` = 换代 INFO ≠ CORRUPT 实证)+ `--b7-pre` 21/21 / `--b7-post` 13/13 不回归 + 自发 YX M_SP_TB_1 带 ts(动作/复归/重启后联动三段)+ FTP 下载 `SOE.LOG` **56 条** `decode_soe.py` PASS(boot 段内 seq 严格 +1、CP56↔epoch UTC 交叉一致)。RAM:RW_IRAM1 +1,088 B(SPSC 环 512 + 静态 FIL 528 + 计数器,74.7%);Flash +1,856 B。§3.4 L4-4/L4-5 置 ✅、§7 P4 更新;出口 L4-1~L4-3 仍 ⬜(V0.1 无出口硬件,R7 否定确认口径不变) |