refactor(编号): 采集链分层 L1/L1.5/L2/L2.5/L3/L4/L5 → 语义名(批次 1)
用户裁定(2026-10-28):L1/L1.5/L2/L2.5/L3 这套层号「谁能看懂」,改用语义名。 映射(同一批定稿,含 L4/L5): L1 → 语义取数与有效性 L1.5 → 标定折算 L2 → 全周傅氏相量 L2.5 → 测频与遥测快照 L3 → 保护判据 L4 → 出口与记录 L5 → 动作留痕 实测规模:384 站点 / 62 文件(App/algo、App/task、test/host 六个套件、docs/算法、 产品需求、架构总览、启动顺序、ADC 采样节拍、IEC104 上行、采集短板评测、内存管理、 AGENTS.md、README.md、docs/README.md、.pre-commit-config.yaml 与 scripts 里的注释)。 改法(不是全局替换,逐模式有上下文规则): - 先吃同位语再落裸词:L1 有效性校验 → 语义取数与有效性校验、L2 相量层 → 全周傅氏 相量层、L3 保护 → 保护判据、L2.5 遥测快照 → 测频与遥测快照,避免「保护判据保护判据」 这类重复(第一版就是这么坏掉的,已整体回滚重做)。 - .c/.h 只改注释:先把字符串字面量切出去(引号数为奇数的跨行注释按整行处理), C 字符串里的 L2-in ring 之类原样保留——AGENTS 铁律「字符串字面量必须纯 ASCII」。 - 层内条目号(L1-3 / L2-3 这类)**本批不动**,属批次 2;另外三族(UI 菜单层级 L0~L3、链路延迟分段 L1~L8、CubeMX 防丢失三层)也不动,属批次 3。 - 顺手修的措辞:范围写法 L1~L3 → 「分层(语义取数与有效性 → 保护判据)」、 CI 段「不含 L1/L2/L3」→「不含采集链分层」、目录地图里同一处并列表述。 验证:@build 0 错 0 警(Code=236456,与改前逐字节同尺寸——纯注释改动); 内存布局配图已按新脚本重生成(自检通过);doc-links --all --sections-strict 通过 (195 文档);mojibake / bom-guard / coding-standard / 新编号门禁自查 全 rc=0; git diff --check 干净。
This commit is contained in:
@@ -271,7 +271,7 @@ repos:
|
||||
files: ^(App/cfg/cfg_file\.(c|h)|App/cfg/cfg_file_store\.h|App/log/sys_log\.h|test/host/cfg_file/.*|test/host/common/unit_test_harness\.py)$
|
||||
pass_filenames: false
|
||||
|
||||
# 7d) 相量层(L2)主机侧单元测试(2026-10-10 加)
|
||||
# 7d) 相量层(全周傅氏相量)主机侧单元测试(2026-10-10 加)
|
||||
# 背景:App/algo/ 为**纯算法**层(无寄存器、无 RTOS、无外设依赖),是本项目
|
||||
# 首个可完全离线验证的算法层。板端**无信号源**,无法注入已知幅值/相位/频率的
|
||||
# 标准波形,故"读数 = 设定值"这一核心判据在板上不可验;本钩子用 MSVC 离线编译
|
||||
@@ -285,7 +285,7 @@ repos:
|
||||
files: ^(App/algo/(phasor|sample_ring)\.(c|h)|test/host/phasor/.*|test/host/common/unit_test_harness\.py)$
|
||||
pass_filenames: false
|
||||
|
||||
# 7e) ADC 输入层(L1)主机侧单元测试(2026-10-10 加)
|
||||
# 7e) ADC 输入层(语义取数与有效性)主机侧单元测试(2026-10-10 加)
|
||||
# 背景:adc_input.c 的核心是"通道号 <-> Rank 顺序 <-> 语义"三者映射的正确性;
|
||||
# 板端无信号源,无法注入已知电压验证"读到的是哪只脚"(映射说明 §8)。本钩子用
|
||||
# MSVC 离线编译真实源文件(#include 纳入)+ HAL/TPAFE 可注入桩:给每个 Rank
|
||||
@@ -358,7 +358,7 @@ repos:
|
||||
files: ^(App/algo/adc_health\.(c|h)|App/task/adc_task\.c|test/host/adc_health/.*|test/host/common/unit_test_harness\.py)$
|
||||
pass_filenames: false
|
||||
|
||||
# 7h2) 通道标定层(L1.5,「数据可信」标定折算与落盘整定)主机侧单元测试(2026-10-25 加,道A)
|
||||
# 7h2) 通道标定层(标定折算,「数据可信」标定折算与落盘整定)主机侧单元测试(2026-10-25 加,道A)
|
||||
# 背景:标定折算是"码值→工程量"的唯一插入点,Q16 系数/零点两段落盘 +
|
||||
# 合法带哨兵回退 + 两点标定公式——板端无标准源、坏文件注入路径在真机
|
||||
# 上难以复现,只有离线端能逐系数钉死。钩子用 MSVC 编译真实源文件
|
||||
@@ -383,7 +383,7 @@ repos:
|
||||
files: ^(App/algo/(adc_cal|prot_elm|prot_set|phasor|sample_ring|freq)\.(c|h)|App/task/(adc_task|protect_task)\.c|test/host/prot_dim/.*|test/host/common/unit_test_harness\.py)$
|
||||
pass_filenames: false
|
||||
|
||||
# 7h4) 遥测快照层(L2 发布侧,「数据可信」遥测快照发布,道D)主机侧单元测试(2026-10-25 加)
|
||||
# 7h4) 遥测快照层(全周傅氏相量发布侧,「数据可信」遥测快照发布,道D)主机侧单元测试(2026-10-25 加)
|
||||
# 背景:遥测快照发布项的 DoD 一半是并发与结构类判据——双区切换无撕裂(撕裂窗
|
||||
# 200 ms 量级,台架人工比对观测不到)、seq 只增、§4.5 布局与字段偏移
|
||||
# (104 与 UI 直接按整体拷贝消费,破布局 = 破协议)、CLIPPED 品质汇总
|
||||
@@ -420,7 +420,7 @@ repos:
|
||||
files: ^(App/algo/prot_set\.(c|h)|test/host/prot_set/.*|test/host/common/unit_test_harness\.py)$
|
||||
pass_filenames: false
|
||||
|
||||
# 7j) 保护元件框架(L3 P1 子集)主机侧单元测试(2026-10-11 加)
|
||||
# 7j) 保护元件框架(保护判据 P1 子集)主机侧单元测试(2026-10-11 加)
|
||||
# 判据核(滞回/定时限/欠量方向/闭锁联动/时基回绕)是纯逻辑,
|
||||
# 板端复现需要标准源 + 故障注入,主机侧用合成测量序列即可穷举
|
||||
# 1.2×/0.9× 验收口径(规划 §8)。
|
||||
@@ -431,7 +431,7 @@ repos:
|
||||
files: ^(App/algo/prot_elm\.(c|h)|App/algo/prot_set\.(c|h)|App/algo/phasor\.(c|h)|App/algo/freq\.(c|h)|test/host/prot_elm/.*|test/host/common/unit_test_harness\.py)$
|
||||
pass_filenames: false
|
||||
|
||||
# 7j2) 频率测量层(L2.5,B8)主机侧单元测试(2026-10-12 加)
|
||||
# 7j2) 频率测量层(测频与遥测快照,B8)主机侧单元测试(2026-10-12 加)
|
||||
# 自适应窗测频(K_eff 对齐负序泄漏纹波周期)的 J1~J6 判据
|
||||
# (扫频/噪声/收敛/阶跃/浮空 valid=0/钳制恢复)是纯合成信号
|
||||
# 可穷举的精度契约;板端无标准源照不出来(规划 §3.3 过频 / 低频)。
|
||||
@@ -483,7 +483,7 @@ repos:
|
||||
# 64 B 定长记录(类型/seq/CP56Time2a/epoch/校验和)是磁盘上的
|
||||
# 字节级契约——编解码错了要 FTP 下载+解码才看得见;纯 codec
|
||||
# 零平台依赖(soe_store 胶水 SIM_EXEMPT),主机侧穷举往返/
|
||||
# 截断/坏校验/IV 位/seq 连续性(规划 §3.4 L4)。
|
||||
# 截断/坏校验/IV 位/seq 连续性(规划 §3.4 出口与记录)。
|
||||
- id: soe-unit-test
|
||||
name: SOE 动作记录编解码单测(主机侧)
|
||||
entry: python test/host/soe/run_unit_test.py
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
## 项目概况
|
||||
|
||||
**现状一句话**:平台能力(网络 / 存储 / 时间 / UI / 日志 / 看门狗 / FTP / 配置)**已实现并台架验收**;采集主线已闭环到业务消费者(L1→L2 相量→L2.5 遥测快照→L3 保护判据 protectTask→104 遥信/遥测+UI,B5/批 2);⚠ **保护判据现处于「未标定闭锁」态**——产品构建下 `adc_cal_flags()` 的 `ADC_CAL_F_VALID` 未置位,`protect_task.c:98` 直接停走判据,等两点标定写入 `[adc_cal] valid` 后自动解卡(用户裁定 2026-10-25:保持闭锁,不用万用表走捷径);**RS-485 采集尚未接线**(B2 按用户决策冻结,见 `docs/任务规划/暂缓-RS485.md`)——当前最大功能缺口,接线节奏受 **RS-485 接线门禁**约束(见「平台约束」)。
|
||||
**现状一句话**:平台能力(网络 / 存储 / 时间 / UI / 日志 / 看门狗 / FTP / 配置)**已实现并台架验收**;采集主线已闭环到业务消费者(语义取数与有效性→全周傅氏相量→测频与遥测快照→保护判据 protectTask→104 遥信/遥测+UI,B5/批 2);⚠ **保护判据现处于「未标定闭锁」态**——产品构建下 `adc_cal_flags()` 的 `ADC_CAL_F_VALID` 未置位,`protect_task.c:98` 直接停走判据,等两点标定写入 `[adc_cal] valid` 后自动解卡(用户裁定 2026-10-25:保持闭锁,不用万用表走捷径);**RS-485 采集尚未接线**(B2 按用户决策冻结,见 `docs/任务规划/暂缓-RS485.md`)——当前最大功能缺口,接线节奏受 **RS-485 接线门禁**约束(见「平台约束」)。
|
||||
|
||||
**数据主线**(能力视角;分层图与跨层依赖表 → `docs/架构设计/项目架构总览.md`):
|
||||
|
||||
- **采集**:TPAFE5160(计量级 8 路,并行总线)+ 片内 ADC1(9 路,DMA)→ TIM3 1 kHz 节拍 + 原子快照 → adcTask → L1 有效性校验 → L2 相量 → **L2.5 遥测快照(`meas` 200 ms 双区,104 与 UI 共用同一份上游,批 2)**+ L3 保护(protectTask 20 ms 判据节拍,B5)→ 104 遥信/遥测上送
|
||||
- **采集**:TPAFE5160(计量级 8 路,并行总线)+ 片内 ADC1(9 路,DMA)→ TIM3 1 kHz 节拍 + 原子快照 → adcTask → 语义取数与有效性校验 → 全周傅氏相量 → **测频与遥测快照(`meas` 200 ms 双区,104 与 UI 共用同一份上游,批 2)**+ 保护判据(protectTask 20 ms 判据节拍,B5)→ 104 遥信/遥测上送
|
||||
- **存储**:GD5F SPI NAND → dhara FTL → FatFs → `/log` 运行与自检记录、`/config.ini` 配置、FTP 根目录
|
||||
- **网络**:CH395F → netTask 串行 socket 栈 → FTP(21) / 对时(8888) / RemoDispBus 远程显示(7003) / IEC 60870-5-104 上行(2404)
|
||||
- **人机**:LVGL 160×160 单色菜单(uiTask),**与 PC 模拟器同一份 UI 源码**,远端可看图 + 注键
|
||||
@@ -24,7 +24,7 @@
|
||||
| 目录 | 职责 | 可改性 |
|
||||
|---|---|---|
|
||||
| `Src/` `Inc/` | CubeMX 生成(外设初始化 / 中断向量 / `freertos.c` 任务表) | **只写 `USER CODE` 区** |
|
||||
| `App/` | 应用层:`app/` 启动与就绪事件 · `task/` 任务编排 · `algo/` 采集与算法 L1~L3 · `cfg/` 配置引擎 · `log/` 日志 · `fs/` 卷锁 · `sync/` 对时 · `util/` 工具 | 手写 |
|
||||
| `App/` | 应用层:`app/` 启动与就绪事件 · `task/` 任务编排 · `algo/` 采集与算法分层(语义取数与有效性 → 保护判据) · `cfg/` 配置引擎 · `log/` 日志 · `fs/` 卷锁 · `sync/` 对时 · `util/` 工具 | 手写 |
|
||||
| `Drivers/BSP/` | 手写芯片驱动与服务:`TPAFE5160` `CH395F` `NET`(socket 栈+lftpd) `NETCFG` `GD5F2GQ5UE` `SD2506` `RS485` `UI`(LVGL 界面) | 手写 |
|
||||
| `Drivers/STM32F4xx_HAL_Driver/` `Drivers/CMSIS/` `Middlewares/` | ST HAL / CMSIS / FreeRTOS | 第三方,只读 |
|
||||
| `Lib/` | 第三方库:`lvgl` `FatFs` `dhara` + `lv_conf.h`(MCU 端) | 只读(本地补丁须有文档登记,如 LVGL I1 补丁) |
|
||||
@@ -41,12 +41,12 @@
|
||||
|
||||
`Src/main.c`(CubeMX 初始化)→ `app_main_init` → `osKernelStart` → 9 任务(`osKernelStart` 之前全是内核启动前代码:禁调任何内核 API,见「平台约束」)
|
||||
|
||||
- `app_main_init`(时间子系统优先,使后续日志带时间戳):`sd2506_init` → `sys_clock_init` → `rs485_init` → `gd5f2gq5ue_init` → `tpafe5160_init` → `adc_input_init`(L1 采集层)→ SD2506 诊断 → **启动 TIM3 1 kHz 采样节拍**
|
||||
- `app_main_init`(时间子系统优先,使后续日志带时间戳):`sd2506_init` → `sys_clock_init` → `rs485_init` → `gd5f2gq5ue_init` → `tpafe5160_init` → `adc_input_init`(语义取数与有效性层)→ SD2506 诊断 → **启动 TIM3 1 kHz 采样节拍**
|
||||
- **就绪屏障**(`App/app/sys_events.h` Event Flags,取代魔法延时):`SYS_EVT_NET_READY` / `STORAGE_READY` / `FTP_READY` / `TIMESYNC_READY`;消费者用 `osEventFlagsWait` 阻塞等待(就绪位 `osFlagsNoClear`)
|
||||
- netTask:`net_stack_bring_up`(配置已由 defaultTask 在屏障前加载,本任务只读 RAM 副本)→ 置 NET_READY → 循环 `net_poll` + `net_process_messages`;消费 `SYS_EVT_NET_RECONFIG` → 按网络代次号重建监听(新 IP 免重启生效)
|
||||
- defaultTask:`f_mount` forced(无卷自动 `f_mkfs`;挂载后卷健康探针,FAT 区陈旧时自愈重格式化)→ 加载网络配置 → STORAGE_READY → LED 闪烁;同时是 syslog(`/log/run.log`·`selftest.log`,定长 64B 记录)的**唯一写者**与**配置引擎属主**(netTask/uiTask 不得直接触碰配置引擎)
|
||||
- adcTask:**纯消费者**——每拍 `adc_input_poll()`(TPAFE 原子快照 + 消费一帧 STM32 ADC1 DMA 双缓冲),只取数不做保护运算;**节拍与唤醒同源**(TIM3 ISR 内触发 CONVST + 同一更新事件经 TRGO 触发 ADC1,并调 `adc_tick_irq_notify()` 置位,任务 `osThreadFlagsWait` 等唤醒)。⚠ ISR 侧**只能**走 `adc_tick_irq_notify()`(内含"消费者就绪"门,TIM3 比调度器早 ≈100 ms 启动);手写于 `Src/freertos.c` 的 `USER CODE` 区,纳入 IWDG `required_mask`(`TASK_WD_ADC`)
|
||||
- **采集与算法层(L1/L2/L3)落在 `App/algo/`**:`adc_input`/`adc_health` = L1,`sample_ring`/`phasor` = L2,`freq` = L2.5 测频(B8,自适应窗),`prot_set`/`prot_elm` = L3。板端消费者 = **protectTask**(B5,2026-10-12):20 ms 节拍 `prot_elm_run()` + 自检失败闭锁(采样故障闭锁)+ 定值校验和巡检;跨上下文复归(104 YK11)经 `prot_elm_request_reset()` 落请求。纳入 IWDG `required_mask`(`TASK_WD_PROTECT`,产品 `0x1F7`)。→ `docs/算法/采集与算法层设计说明.md`(设计与判据)、`App/algo/README.md`(目录索引)
|
||||
- **采集与算法层(语义取数与有效性/全周傅氏相量/保护判据)落在 `App/algo/`**:`adc_input`/`adc_health` = 语义取数与有效性,`sample_ring`/`phasor` = 全周傅氏相量,`freq` = 测频与遥测快照(B8,自适应窗),`prot_set`/`prot_elm` = 保护判据。板端消费者 = **protectTask**(B5,2026-10-12):20 ms 节拍 `prot_elm_run()` + 自检失败闭锁(采样故障闭锁)+ 定值校验和巡检;跨上下文复归(104 YK11)经 `prot_elm_request_reset()` 落请求。纳入 IWDG `required_mask`(`TASK_WD_PROTECT`,产品 `0x1F7`)。→ `docs/算法/采集与算法层设计说明.md`(设计与判据)、`App/algo/README.md`(目录索引)
|
||||
- 全景 → `docs/架构设计/项目架构总览.md`;启动时序与内核前模式 → `docs/架构设计/项目启动顺序管理.md`
|
||||
|
||||
<!-- TASK_TABLE:BEGIN generated by scripts/gen_task_table.py -->
|
||||
@@ -97,7 +97,7 @@
|
||||
- ⚠ **pre-commit 4.x 已移除 `always: true`**(实测对 `local` 钩子只告警 `Unexpected key(s)` 并跳过)→ 想"总是跑"的钩子**必须让 `files:` 覆盖到所有会触发它的文件**,没有兜底开关
|
||||
- **改写型钩子(`trailing-whitespace` + `end-of-file-fixer`)豁免 CubeMX/Keil 生成文件**(配置里 YAML 锚点 `&cubemx-generated`);⚠ **只读检查不受影响**:`cppcheck` / 乱码 / `cubemx-survival` / `task-table` / `mem-numbers` 仍覆盖 `Src/`、`Inc/`
|
||||
- 提交信息:标题 ≤100 字符、**正文每行 ≤80**(`.gitlint` + gitlint 默认)→ 长说明一律用**短标题 + `git commit -F <UTF-8 无 BOM 文件>` 多行正文**(中文长标题极易超限,且 `-m` 会被终端代码页转码破坏)
|
||||
- **CI**(`.gitea/workflows/ci.yml`)只跑 L0 静态门禁 + L0.5 主机侧单测,**刻意不跑 `@build`**(需 Keil 授权)、不含 L1/L2/L3(需真机)。**远程 CI 的全部资料(服务端开关 / runner 部署与保活 / workflow / 排障 / 实测坑)集中在 [`docs/CI/README.md`](docs/CI/README.md),不放本节**——它**只跑在本机一台 runner `win-stm32-ci` 上**,其他机器与项目都不涉及。日常改代码的等价自查是 `& '.venv\Scripts\python.exe' scripts/ci_local.py`(L0 + L0b + L0.5)——**runner 不在线也不影响本地门禁,不能因"已配 CI"放宽本地要求**
|
||||
- **CI**(`.gitea/workflows/ci.yml`)只跑 L0 静态门禁 + L0.5 主机侧单测,**刻意不跑 `@build`**(需 Keil 授权)、不含采集链分层(需真机)。**远程 CI 的全部资料(服务端开关 / runner 部署与保活 / workflow / 排障 / 实测坑)集中在 [`docs/CI/README.md`](docs/CI/README.md),不放本节**——它**只跑在本机一台 runner `win-stm32-ci` 上**,其他机器与项目都不涉及。日常改代码的等价自查是 `& '.venv\Scripts\python.exe' scripts/ci_local.py`(L0 + L0b + L0.5)——**runner 不在线也不影响本地门禁,不能因"已配 CI"放宽本地要求**
|
||||
|
||||
## 平台约束
|
||||
|
||||
|
||||
+21
-21
@@ -1,4 +1,4 @@
|
||||
# App/algo/ — 采集与算法层(L1 / L2 / L3)
|
||||
# App/algo/ — 采集与算法层(语义取数与有效性 / 全周傅氏相量 / 保护判据)
|
||||
|
||||
> 本目录的**索引**:文件清单、依赖、逐文件的"改代码必须知道"、构建与测试入口、新增模块动作。
|
||||
> **详细设计——机制、契约、判据、为什么这样设计 → `docs/算法/采集与算法层设计说明.md`**(本文不复制其内容)。
|
||||
@@ -9,21 +9,21 @@
|
||||
|
||||
| 文件 | 层 | 作用(一句话) | 主要对外入口 | 覆盖规划项 |
|
||||
|---|---|---|---|---|
|
||||
| `adc_input.h` / `.c` | L1 | 统一语义取数:两片转换器的码值按语义(`UA…IN` / 温度)暴露,并消费 STM32 ADC1 的 DMA 乒乓缓冲 | `adc_input_init()` `adc_input_poll()` `adc_input_raw()` | TPAFE 快照消费 / STM32 ADC1 启动与扫描 / 通道语义映射 |
|
||||
| `adc_health.h` / `.c` | L1 | 采样有效性判定:吃计数快照,产出静默 / 丢帧 / 单调性 / 错误增量故障位(判定与告警编排分离);「采样通道自检」残余的码值贴轨观察器同层 | `adc_health_check()` `adc_health_flags()` `adc_health_rail_watch()` | 「采样有效性校验」/「采样通道自检」(残余) |
|
||||
| `adc_cal.h` / `.c` | L1.5 | 通道标定折算(「数据可信」标定折算与落盘整定):工程量 =(code+b)×k,Q16 系数/零点两段落盘 + 三态 flags + 合法带哨兵 + 两点公式 | `adc_cal_apply()` `adc_cal_flags()` `adc_cal_set()` | 「通道标定(一次系数 + 零漂)」(M4 半边) |
|
||||
| `meas.h` / `.c` | L2 发布 | 遥测快照(「数据可信」遥测快照发布,M5 地基):200 ms 基波有效值 + 品质快照,双区无锁读,全仓唯一发布者 = adcTask | `meas_tick()` `meas_get()` `meas_seq()` | M5(104 改读快照与频率点绑定、UI 是读者) |
|
||||
| `sample_ring.h` / `.c` | L2 输入 | 按语义通道存最近 2 周波(40 点),供相量层"以当前时刻为终止"取窗 | `sample_ring_push_frame()` `sample_ring_window()` | L2 输入(为「每 1 ms 滑动窗刷新」供数) |
|
||||
| `phasor.h` / `.c` | L2 | 全周傅氏:一周波 20 点 DFT → 基波 / 谐波相量(有效值口径),双区原子切换供无锁读 | `phasor_run()` `phasor_get()` `phasor_calc()` | 全周傅氏系数表 / 基波相量实例 / 相量有效值输出 / 每 1 ms 滑动窗刷新 / 双区指针原子交换 |
|
||||
| `freq.h` / `.c` | L2 派生量 | 频率测量:相邻两拍基波相量共轭乘积取角 + 自适应窗滑动平均 + 假值钳制 + 幅值门(UA→IA 源回退) | `freq_run()` `freq_get()` `freq_valid()` | 「过频 / 低频」测量侧(测频范围 → `docs/算法/继电保护功能复现规划.md` §4.2) |
|
||||
| `prot_set.h` / `.c` | L3 输入 | 保护定值模型:Q10 定点 RAM 表 + 范围校验 + 校验和封存 / 自检 / 闭锁 + 持久化 blob 纯逻辑 | `prot_set_load_raw()` `prot_set_get_f()` `prot_set_selfcheck()` | 「定值校验和」载体 |
|
||||
| `prot_elm.h` / `.c` | L3 | 保护元件框架:通用"越限 + 返回系数滞回 + 定时限"核 + 数据驱动实例表(过流三段 / 过负荷 / 过压 / 欠压 / 零序过压 / 过频 / 低频) | `prot_elm_run()` `prot_elm_eval()` `prot_elm_active_mask()` | 「三段式相间过流」/「过负荷」/「过压 / 欠压」/「过频 / 低频」/「零序过压」(软件侧) |
|
||||
| `adc_input.h` / `.c` | 语义取数与有效性 | 统一语义取数:两片转换器的码值按语义(`UA…IN` / 温度)暴露,并消费 STM32 ADC1 的 DMA 乒乓缓冲 | `adc_input_init()` `adc_input_poll()` `adc_input_raw()` | TPAFE 快照消费 / STM32 ADC1 启动与扫描 / 通道语义映射 |
|
||||
| `adc_health.h` / `.c` | 语义取数与有效性 | 采样有效性判定:吃计数快照,产出静默 / 丢帧 / 单调性 / 错误增量故障位(判定与告警编排分离);「采样通道自检」残余的码值贴轨观察器同层 | `adc_health_check()` `adc_health_flags()` `adc_health_rail_watch()` | 「采样有效性校验」/「采样通道自检」(残余) |
|
||||
| `adc_cal.h` / `.c` | 标定折算 | 通道标定折算(「数据可信」标定折算与落盘整定):工程量 =(code+b)×k,Q16 系数/零点两段落盘 + 三态 flags + 合法带哨兵 + 两点公式 | `adc_cal_apply()` `adc_cal_flags()` `adc_cal_set()` | 「通道标定(一次系数 + 零漂)」(M4 半边) |
|
||||
| `meas.h` / `.c` | 全周傅氏相量发布 | 遥测快照(「数据可信」遥测快照发布,M5 地基):200 ms 基波有效值 + 品质快照,双区无锁读,全仓唯一发布者 = adcTask | `meas_tick()` `meas_get()` `meas_seq()` | M5(104 改读快照与频率点绑定、UI 是读者) |
|
||||
| `sample_ring.h` / `.c` | 全周傅氏相量输入 | 按语义通道存最近 2 周波(40 点),供相量层"以当前时刻为终止"取窗 | `sample_ring_push_frame()` `sample_ring_window()` | 全周傅氏相量输入(为「每 1 ms 滑动窗刷新」供数) |
|
||||
| `phasor.h` / `.c` | 全周傅氏相量 | 全周傅氏:一周波 20 点 DFT → 基波 / 谐波相量(有效值口径),双区原子切换供无锁读 | `phasor_run()` `phasor_get()` `phasor_calc()` | 全周傅氏系数表 / 基波相量实例 / 相量有效值输出 / 每 1 ms 滑动窗刷新 / 双区指针原子交换 |
|
||||
| `freq.h` / `.c` | 全周傅氏相量的派生量 | 频率测量:相邻两拍基波相量共轭乘积取角 + 自适应窗滑动平均 + 假值钳制 + 幅值门(UA→IA 源回退) | `freq_run()` `freq_get()` `freq_valid()` | 「过频 / 低频」测量侧(测频范围 → `docs/算法/继电保护功能复现规划.md` §4.2) |
|
||||
| `prot_set.h` / `.c` | 保护判据输入 | 保护定值模型:Q10 定点 RAM 表 + 范围校验 + 校验和封存 / 自检 / 闭锁 + 持久化 blob 纯逻辑 | `prot_set_load_raw()` `prot_set_get_f()` `prot_set_selfcheck()` | 「定值校验和」载体 |
|
||||
| `prot_elm.h` / `.c` | 保护判据 | 保护元件框架:通用"越限 + 返回系数滞回 + 定时限"核 + 数据驱动实例表(过流三段 / 过负荷 / 过压 / 欠压 / 零序过压 / 过频 / 低频) | `prot_elm_run()` `prot_elm_eval()` `prot_elm_active_mask()` | 「三段式相间过流」/「过负荷」/「过压 / 欠压」/「过频 / 低频」/「零序过压」(软件侧) |
|
||||
|
||||
依赖(自下而上、无环):`adc_input.h`(纯枚举 + 声明)← `adc_cal`(另依赖 `cfg_file.h` 接口,
|
||||
纯头文件级)← `sample_ring` ← `phasor` ← `freq`;`meas` ← `sample_ring` + `phasor`
|
||||
(仅 `phasor_calc` 纯核;频率/品质由调用方注入,**不链** `freq`/`adc_cal`);
|
||||
`prot_set` **独立**;`prot_elm` ← `prot_set` + `phasor` + `freq`。
|
||||
`adc_health` 只吃调用方喂进来的计数 / 码值,不反向依赖 L1 实现(「采样通道自检」贴轨门限由调用方
|
||||
`adc_health` 只吃调用方喂进来的计数 / 码值,不反向依赖 语义取数与有效性实现(「采样通道自检」贴轨门限由调用方
|
||||
从 `adc_cal_rail_ths()` 取,本层仍零算法依赖)。
|
||||
|
||||
**除 `adc_input.c` 外全部零平台依赖**(只用 `stdint.h` / `math.h` / `stddef.h` 与本目录头)
|
||||
@@ -32,40 +32,40 @@
|
||||
|
||||
## 2. 一拍的数据流(一眼版)
|
||||
|
||||
`adc_input_poll()` → `adc_input_raw()` ×9 → `adc_cal_apply()` ×9(L1.5 折算,现口径 =
|
||||
`adc_input_poll()` → `adc_input_raw()` ×9 → `adc_cal_apply()` ×9(标定折算折算,现口径 =
|
||||
ADC 引脚电压 V)+ `adc_health_rail_watch()` ×9(「采样通道自检」,码值域)→ `sample_ring_push_frame()`
|
||||
→ `phasor_run()` → `freq_run()` → 消费者(`adcTask` 心跳与 L1 健康判定;`protectTask` 每 20 ms 取相量 / 频率跑
|
||||
→ `phasor_run()` → `freq_run()` → 消费者(`adcTask` 心跳与 语义取数与有效性健康判定;`protectTask` 每 20 ms 取相量 / 频率跑
|
||||
`prot_elm_run()`;**每 200 ms** `meas_tick()` 发布遥测快照供 iec104Task / uiTask 读,即「数据可信」遥测快照发布)。节拍 = TIM3 1 kHz 更新事件,两片转换器同源触发。
|
||||
完整数据流图与初始化落点 → `docs/算法/采集与算法层设计说明.md` §2。
|
||||
|
||||
## 3. 逐文件要点(只留"改代码时必须知道"的;机制与理由见设计文档)
|
||||
|
||||
> **改本目录前先记五条红线**:① 取数只经 `adc_input_raw()`,不写死下标;② **禁止跨转换器**做
|
||||
> 相位 / 功率 / 矢量运算(双转换器无共同采样触发);③ 帧值已是 L1.5 工程量,但 **未标定(`adc_cal_flags()` 无
|
||||
> 相位 / 功率 / 矢量运算(双转换器无共同采样触发);③ 帧值已是 标定折算工程量,但 **未标定(`adc_cal_flags()` 无
|
||||
> VALID)时单位只是 ADC 引脚电压**,不是端子二次值——下游消费精度判据见「数据可信」§4.2 三态
|
||||
> 表;④ 工程量 → 帧的唯一折算点是 `adc_cal_apply()`,禁止旁路再乘系数;⑤ 本层不建任务、
|
||||
> 不等事件、不写日志(`adc_cal` 的 `[ERR]` 哨兵留痕是唯一例外,且每通道每开机一次),
|
||||
> `*_init()` 才可在内核前调。
|
||||
> 全文 → `docs/算法/采集与算法层设计说明.md` §10。
|
||||
|
||||
### 3.1 `adc_input.c` / `adc_input.h` — L1 语义取数
|
||||
### 3.1 `adc_input.c` / `adc_input.h` — 语义取数与有效性语义取数
|
||||
- 语义映射表 `k_adc_map[]` 的**内容**唯一权威是 `docs/硬件平台/ADC通道映射说明.md`;V0.2 改版只改表内容,API 不动。
|
||||
- `adc_input_poll()` **仅任务上下文**(TPAFE 快照是临界区);STM32 侧固定滞后 1 拍。
|
||||
- 四类 STM32 计数(`adc1_seq` / `adc1_gap` / `adc1_err` / `adc1_hw`)成因不同,**勿混读**。
|
||||
- 本目录**唯一**允许出现 HAL 调用的文件。→ `docs/算法/采集与算法层设计说明.md` §3。
|
||||
|
||||
### 3.2 `sample_ring.c` / `.h` — L2 输入采样环
|
||||
### 3.2 `sample_ring.c` / `.h` — 全周傅氏相量输入采样环
|
||||
- 整帧写入后才推进写指针 → 取到的窗永远落在整帧边界。
|
||||
- 本拍取数失败 → **整拍跳过入环**(`adc_task.c` 的 `skip`),**绝不补 0 点**。
|
||||
- 不做跨通道运算、不做丢帧判定(只出 `frames()` 计数)。→ `docs/算法/采集与算法层设计说明.md` §5。
|
||||
|
||||
### 3.3 `phasor.c` / `.h` — L2 相量计算
|
||||
### 3.3 `phasor.c` / `.h` — 全周傅氏相量计算
|
||||
- 系数表预乘 √2/N → `fAmSQ` **直接是有效值**(口径 `docs/算法/傅氏算法详解.md` §2.3)。
|
||||
- 实例表 `k_inst[]` 数据驱动:**新增实例只在表尾加一行**。
|
||||
- 任一实例不足一周波 → **本拍整体不产出**(不切使用区);每拍 20 点**全部重算**(不做增量递推)。
|
||||
- → `docs/算法/采集与算法层设计说明.md` §6。
|
||||
|
||||
### 3.4 `adc_health.c` / `.h` — L1 有效性判定
|
||||
### 3.4 `adc_health.c` / `.h` — 语义取数与有效性判定
|
||||
- 三类位**严格分开**:电平(可自愈)/ 锁存(必留痕)/ 边沿事件(仅当拍);**静默 ≠ 丢帧**。
|
||||
- **gap 不告警**(消费者超拍是已知现象);告警编排在 `adc_task.c`,不在本层。
|
||||
- 首拍 `check()` 只建基线。→ `docs/算法/采集与算法层设计说明.md` §4。
|
||||
@@ -76,7 +76,7 @@ ADC 引脚电压 V)+ `adc_health_rail_watch()` ×9(「采样通道自检」
|
||||
- 定值项 / 实例**只许尾部追加**(枚举序 = 数组序 = 校验和覆盖序)。
|
||||
- blob **换代(返回 2)≠ 损坏(返回负)**:前者打 INFO、不记自检。→ `docs/算法/采集与算法层设计说明.md` §8、§12.3。
|
||||
|
||||
### 3.6 `prot_elm.c` / `.h` — L3 保护元件框架
|
||||
### 3.6 `prot_elm.c` / `.h` — 保护判据元件框架
|
||||
- 数据缺失两种处理**刻意不同**:相量类任一未就绪 → 整拍跳过;频率类无有效读数 → 按方向填"必不启动"值,**不整拍跳过**。
|
||||
- `prot_set_locked()` 或投退 = 0 → 元件整体复位不判据;跨上下文复归走 `prot_elm_request_reset()`。
|
||||
- 零序过流(IN 走 STM32)**故意不在实例表**;OF / UF 无独立 104 遥信点,只经 YX15 总聚合可见。
|
||||
@@ -90,7 +90,7 @@ ADC 引脚电压 V)+ `adc_health_rail_watch()` ×9(「采样通道自检」
|
||||
- 源切换即废相位基准重建(UA / IA 无共同相位基准,即双转换器无共同采样触发)。
|
||||
- 判据 **J1~J6** 与实测口径 → `docs/算法/采集与算法层设计说明.md` §7.2(与 `test/host/freq/freq_test.c` 文件头同源)。
|
||||
|
||||
### 3.8 `adc_cal.c` / `.h` — L1.5 通道标定折算(「数据可信」标定折算与落盘整定)
|
||||
### 3.8 `adc_cal.c` / `.h` — 标定折算通道标定折算(「数据可信」标定折算与落盘整定)
|
||||
- 折算模型:工程量 = (code + b) × k;**k 落盘用 int32 Q16(µV/码 × 65536)**、b 用
|
||||
int32 码值(负零点靠 `CFG_VAL_INT`)——单位与定点格式的选型依据见
|
||||
`docs/任务规划/数据可信.md` §4.1,勿改回 V/码 直存(Q16 只剩 20 个刻度)。
|
||||
@@ -107,7 +107,7 @@ ADC 引脚电压 V)+ `adc_health_rail_watch()` ×9(「采样通道自检」
|
||||
- cfg 两段 `[adc_cal]` / `[adc_cal_ofs]` **不挂回调**(RAM 副本即生效值,引擎 load/poll
|
||||
原地改写,逐点现读);注册在 `app_main_init()` 内核前完成,必须先于 `cfg_file_load`。
|
||||
|
||||
### 3.9 `meas.c` / `.h` — 遥测快照发布(L2 发布侧,「数据可信」波次)
|
||||
### 3.9 `meas.c` / `.h` — 遥测快照发布(全周傅氏相量发布侧,「数据可信」波次)
|
||||
- **唯一发布者 = adcTask**:`phasor_run()`/`freq_run()` 同拍、200 ms **tick 经过**分频
|
||||
调 `meas_tick()`(非拍计数——idle/skip 拍拉长名义节拍)。docs/任务规划/数据可信.md §8
|
||||
风险表"快照双写"行 = 评审判据:全仓 `meas_tick` 调用点数须为 1;iec104Task /
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:通道标定与量纲折算(L1.5)——实现
|
||||
* 模块名称:通道标定与量纲折算(标定折算)——实现
|
||||
* 模块功能:见 adc_cal.h。折算模型(工程量 = (code + b) × k × 1e-6,k 为 Q16
|
||||
* µV/码)与两段 cfg 布局([adc_cal]:k_* + valid 位图;[adc_cal_ofs]:
|
||||
* b_*)照 docs/任务规划/数据可信.md §4.1 / §4.4 落地;系数口径
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:通道标定与量纲折算(L1.5,「数据可信」标定折算与落盘整定)
|
||||
* 模块名称:通道标定与量纲折算(标定折算,「数据可信」标定折算与落盘整定)
|
||||
* 模块功能:把 adc_input 的原始码值折算成工程量——模型与系数口径的唯一落点:
|
||||
* 工程量 = (code + b) × k_f,k_f = k[µV/码] × 1e-6
|
||||
* k 以 int32 **Q16**(µV/码 × 65536)落盘、b 以 int32 码值落盘,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:ADC 采样有效性校验(L1 采集与预处理)
|
||||
* 模块名称:ADC 采样有效性校验(语义取数与预处理)
|
||||
*(保护功能清单见 docs/算法/继电保护功能复现规划.md)
|
||||
* 模块功能:见 adc_health.h 文件头。本文件为**纯逻辑实现**:输入计数快照、
|
||||
* 输出故障位/事件位,零平台依赖(仅 stdint.h/string.h 标准 C)→
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:ADC 采样有效性校验(L1 采集与预处理)
|
||||
* 模块名称:ADC 采样有效性校验(语义取数与预处理)
|
||||
*(保护功能清单见 docs/算法/继电保护功能复现规划.md)
|
||||
* 模块功能:对两片转换器的"节拍是否还在喂数据"做**判定层**(观测计数由
|
||||
* `adc_input` / `tpafe5160` 驱动提供,本模块只做判定与告警位):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:ADC 输入层(L1 采集与预处理)
|
||||
* 模块名称:ADC 输入层(语义取数与预处理)
|
||||
* 模块功能:语义通道映射(通道语义映射)+ STM32 ADC1 采样消费(STM32 ADC1 启动与扫描,TIM3 TRGO 触发 +
|
||||
*(保护功能清单见 docs/算法/继电保护功能复现规划.md)
|
||||
* DMA 双缓冲)+ TPAFE 快照消费。
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:ADC 输入层(L1 采集与预处理)
|
||||
* 模块名称:ADC 输入层(语义取数与预处理)
|
||||
* 模块功能:把两片转换器的原始码值按**语义**(UA/UB/UC/UN/IA/IB/IC/IN/温度)统一
|
||||
* 暴露,使上层(UI / 自检 / 保护算法)**按语义取数,不写死下标**:
|
||||
* ① 语义通道映射表(通道语义映射)——权威口径 docs/硬件平台/ADC通道映射说明.md;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:频率测量层(L2 派生量)——实现
|
||||
* 模块名称:频率测量层(全周傅氏相量的派生量)——实现
|
||||
* 模块功能:见 freq.h。相邻两拍基波相量共轭乘积取角(= 每拍相位增量,免
|
||||
* 显式解缠绕)+ **自适应窗长滑动平均** + 瞬时值钳制 + 幅值门。
|
||||
* 输入 = phasor 使用区基波相量(UA 优先,UA 无幅值用 IA)。
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 模块名称:频率测量层(L2 派生量,过频 / 低频的测量输入)
|
||||
* 模块名称:频率测量层(全周傅氏相量的派生量,过频 / 低频的测量输入)
|
||||
*(保护功能清单见 docs/算法/继电保护功能复现规划.md)
|
||||
* 模块功能:由 L2 相量使用区的基波相量导出系统频率——相邻两拍基波相量取
|
||||
* 模块功能:由 全周傅氏相量使用区的基波相量导出系统频率——相邻两拍基波相量取
|
||||
* **共轭乘积** P = Z(m)·conj(Z(m-1))(其角 = 每拍相位增量,纯音 =
|
||||
* +2πf/Fs,免显式解缠绕),再对**自适应窗长**的相位增量做滑动平均:
|
||||
* K_eff = round(8·Fs/(2·f_hat)) ≈ 泄漏纹波周期 fs/(2f) 的整数倍
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:遥测快照发布层(L2 派生·发布侧,「数据可信」§4.5)
|
||||
* 模块名称:遥测快照发布层(全周傅氏相量派生·发布侧,「数据可信」§4.5)
|
||||
* 模块功能:实现见 meas.h——200 ms 基波有效值 + 品质快照,双区无锁读。
|
||||
* 本文件纯算法:输入 = sample_ring 取窗 + 调用方注入(频率/削顶位图),
|
||||
* 无 RTOS / 无寄存器 / 无日志(「数据可信」层内禁令:本目录不写日志)。
|
||||
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* 模块名称:遥测快照发布层(L2 派生·发布侧,「数据可信」§4.5)
|
||||
* 模块功能:每 **200 ms** 从 L2 层取一次基波有效值 + 品质,产出一份全仓唯一的
|
||||
* 模块名称:遥测快照发布层(全周傅氏相量派生·发布侧,「数据可信」§4.5)
|
||||
* 模块功能:每 **200 ms** 从 全周傅氏相量层取一次基波有效值 + 品质,产出一份全仓唯一的
|
||||
* 遥测快照(meas_snap_t,布局权威 = docs/任务规划/数据可信.md §4.5),
|
||||
* 让 104 与 UI **共用同一份上游**——"什么时候算新值、品质怎么判"只此
|
||||
* 一处决定(M5 遥测链的地基;104 侧消费见「数据可信」104 改读快照,UI 侧 ui_data_feed 属
|
||||
* 「UI 扩展」波次,两者都只是本快照的读者)。
|
||||
* 值口径(批 2「遥测快照发布」的 A-lite 裁决,2026-10-25):**基波有效值瞬时透传**
|
||||
* (同拍 phasor 使用区口径,系数已在 L1.5 折算进帧值——现单位 = ADC
|
||||
* (同拍 phasor 使用区口径,系数已在 标定折算折算进帧值——现单位 = ADC
|
||||
* 引脚电压 V,二次值语义等 adc_cal_flags() 出 VALID,见
|
||||
* docs/算法/采集与算法层设计说明.md §10 红线③);**不做** 4 点平均 /
|
||||
* 谐波方和根——docs/任务规划/数据可信.md §4.5 明示"200 ms 是上送节拍
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:相量计算层(L2 相量计算)
|
||||
* 模块名称:相量计算层(全周傅氏相量计算)
|
||||
* 模块功能:全周傅氏算法(单频 DFT)——系数表预乘 √2/N,fAmSQ 直接即有效值。
|
||||
* 覆盖 全周傅氏系数表 / 基波相量实例 / 相量有效值输出 / 每 1 ms 滑动窗刷新 / 双区指针原子交换。
|
||||
* 适用平台:STM32F407ZGTx(Cortex-M4F,硬件 FPU)
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:相量计算层(L2 相量计算)
|
||||
* 模块名称:相量计算层(全周傅氏相量计算)
|
||||
* 模块功能:全周傅氏(全周波傅里叶)算法——对一周波 20 点采样做单频 DFT,
|
||||
* 产出基波/谐波相量。系数表**预乘 √2/N**(口径见
|
||||
* `docs/算法/傅氏算法详解.md` §2.3),故 `fAmSQ = √(fRe²+fIm²)`
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:保护元件框架(L3,P1 子集)——实现
|
||||
* 模块名称:保护元件框架(保护判据,P1 子集)——实现
|
||||
* 模块功能:见 prot_elm.h。判据核 prot_elm_eval() 为纯逻辑(prot_set RAM +
|
||||
* 测量数组 → 状态机),prot_elm_run() 是 phasor→测量的薄适配层。
|
||||
*
|
||||
@@ -204,7 +204,7 @@ void prot_elm_eval(uint32_t now_ms, const float meas[PE_COUNT]) {
|
||||
* 函数功能:适配层——按实例表 src 组装测量数组后调判据核
|
||||
* 入口参数:now_ms - 单调时基(tick ms)
|
||||
* 返 回 值:无
|
||||
* 限定条件:仅保护消费者任务上下文;测量已是 L1.5 工程量(未标定域由
|
||||
* 限定条件:仅保护消费者任务上下文;测量已是 标定折算工程量(未标定域由
|
||||
* protectTask 未标定即闭锁挡在门外,本函数不感知标定态)
|
||||
* 函数说明:src=PHASOR 行任一相量未就绪(未满一周波)→ **整拍跳过**,
|
||||
* 不引入陈旧/半新测量(B5 口径)。src=FREQ 行:freq 有有效读数
|
||||
@@ -260,7 +260,7 @@ void prot_elm_state(prot_elm_id_t id, prot_elm_state_t *out) {
|
||||
/*
|
||||
* 函数功能:聚合动作位图
|
||||
* 入口参数:无
|
||||
* 返 回 值:bit i = 元件 i asserted(供 L4 出口 / 心跳日志)
|
||||
* 返 回 值:bit i = 元件 i asserted(供 出口与记录 / 心跳日志)
|
||||
*/
|
||||
uint32_t prot_elm_active_mask(void) {
|
||||
uint32_t mask = 0u;
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* 模块名称:保护元件框架(L3,P1 子集)
|
||||
* 模块名称:保护元件框架(保护判据,P1 子集)
|
||||
* 模块功能:通用"越限 + 返回系数滞回 + 定时限"元件核 + 实例表(数据驱动,
|
||||
* 同 phasor 实例表模式)。判据为**纯逻辑**(吃测量值 + 定值),
|
||||
* 主机侧可离线单测;出口/SOE(L4)与任务编排为后续。
|
||||
* 主机侧可离线单测;出口/SOE(出口与记录)与任务编排为后续。
|
||||
*
|
||||
* V0.1 有效实例(双转换器无共同采样触发 → 仅 TPAFE 三路):
|
||||
* OC1/OC2/OC3 三段式相间过流(A 相 IA)
|
||||
@@ -23,7 +23,7 @@
|
||||
* - 返回**即时**(参考 GRly_TimeRelay 带 10 ms 返回延时——V0.1 无出口硬件,
|
||||
* 抖动只影响日志,P4 接出口时再补返回延时);
|
||||
* - 复压/方向/无压无流闭锁(dwSetFyCtrl 类)随 P2/P3 元件扩展;
|
||||
* - 测量输入 = adc_task 经 adc_cal_apply() 折算后的工程量(L1.5,标定折算已落地):
|
||||
* - 测量输入 = adc_task 经 adc_cal_apply() 折算后的工程量(标定折算,标定折算已落地):
|
||||
* 未标定(VALID=0)时单位只是 ADC 引脚电压——该域下判据必然错配,由
|
||||
* protectTask 的「数据可信」未标定即闭锁停走整条判据链,元件核本身不掺和
|
||||
* 标定语义(保持纯逻辑);标定后单位 = 二次值,定值口径才名副其实。
|
||||
@@ -98,7 +98,7 @@ void prot_elm_run(uint32_t now_ms);
|
||||
/* 状态快照拷贝(NULL 安全;越界全零) */
|
||||
void prot_elm_state(prot_elm_id_t id, prot_elm_state_t *out);
|
||||
|
||||
/* 动作位图(bit i = 元件 i asserted),供 L4 出口 / 心跳日志 */
|
||||
/* 动作位图(bit i = 元件 i asserted),供 出口与记录 / 心跳日志 */
|
||||
uint32_t prot_elm_active_mask(void);
|
||||
|
||||
/* 启动位图(bit i = 元件 i picked),供「保护启动」记录边沿(task-10,2026-10-26):
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:运行参数段(L2/L3 整定层,「数据可信」这一项)——实现
|
||||
* 模块名称:运行参数段(全周傅氏相量/保护判据整定层,「数据可信」这一项)——实现
|
||||
* 模块功能:见 run_par.h。工厂默认 = 「数据可信」下游常数按工程量重定后的额定 0.5 % 档(电压 500
|
||||
* mV / 电流 5 mA / 频率 500 mHz,毫单位 int32 定点落盘);[run_par]
|
||||
* 段 9 键(db_ua…db_freq,均 ≤15 字符)≤ CFG_FILE_MAX_KEYS 不拆段
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:运行参数段(L2/L3 整定层,「数据可信」这一项)
|
||||
* 模块名称:运行参数段(全周傅氏相量/保护判据整定层,「数据可信」这一项)
|
||||
* 模块功能:遥测死区(9 点)与通道标定系数覆盖(k/b 各 8 路)的**单一真源**:
|
||||
* - 死区 = 本模块 int32 毫单位 RAM 副本(注册进 cfg 引擎 [run_par] 段,
|
||||
* 工厂默认 = 「数据可信」下游常数按工程量重定后的额定 0.5 % 档),104 消费侧
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* 模块名称:采样环缓冲(L2 相量计算的输入)
|
||||
* 模块功能:按语义通道保存最近 2 个周波(40 点)采样值,供 L2 相量计算按窗取数。
|
||||
* 模块名称:采样环缓冲(全周傅氏相量计算的输入)
|
||||
* 模块功能:按语义通道保存最近 2 个周波(40 点)采样值,供 全周傅氏相量计算按窗取数。
|
||||
* 适用平台:STM32F407ZGTx(纯算法,无寄存器/无 RTOS 依赖)
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-10-10
|
||||
* 修改记录:
|
||||
* v1.0 2026-10-10 王建锋 创建:L2 输入环缓冲(20 点/周波 × 2 周波)
|
||||
* v1.0 2026-10-10 王建锋 创建:全周傅氏相量输入环缓冲(20 点/周波 × 2 周波)
|
||||
*/
|
||||
|
||||
#include "sample_ring.h"
|
||||
@@ -48,7 +48,7 @@ void sample_ring_init(void) {
|
||||
* 入口参数:values - 按语义通道顺序排列的一帧采样值(长度须 = ADC_SEM_COUNT)
|
||||
* n - 实际长度(必须等于 ADC_SEM_COUNT)
|
||||
* 返 回 值:0 - 成功;-1 - 参数错
|
||||
* 限定条件:同一帧内各通道须同刻(同族量同刻性由上游 L1 负责)
|
||||
* 限定条件:同一帧内各通道须同刻(同族量同刻性由上游 语义取数与有效性负责)
|
||||
* 函数说明:整帧写入完毕后**统一**推进写指针——单帧内不存在"半新半旧",
|
||||
* 消费侧取到的窗永远落在整帧边界上(无帧内撕裂)。
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* 模块名称:采样环缓冲(L2 相量计算的输入)
|
||||
* 模块功能:按**语义通道**保存最近若干周波的采样值,供 L2 相量计算按窗取数。
|
||||
* 模块名称:采样环缓冲(全周傅氏相量计算的输入)
|
||||
* 模块功能:按**语义通道**保存最近若干周波的采样值,供 全周傅氏相量计算按窗取数。
|
||||
* V0.1 上 8 路电气量分属两片转换器(双转换器无共同采样触发),本层只做"按时序
|
||||
* 存/取",**不做任何跨通道运算**——同刻性由上游(L1)保证,本层不假设。
|
||||
* 存/取",**不做任何跨通道运算**——同刻性由上游(语义取数与有效性)保证,本层不假设。
|
||||
* 容量取 **2 个周波(40 点)**,与参考系统 `CN_BUFSAM_CYCLE = 2`
|
||||
* (规划 §10.1)一致,为后续加长数据窗(1.5~2 周波,抗衰减直流,
|
||||
* 见 `傅氏算法详解.md` §9 Q4)预留空间。
|
||||
@@ -10,7 +10,7 @@
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-10-10
|
||||
* 修改记录:
|
||||
* v1.0 2026-10-10 王建锋 创建:L2 输入环缓冲(20 点/周波 × 2 周波)
|
||||
* v1.0 2026-10-10 王建锋 创建:全周傅氏相量输入环缓冲(20 点/周波 × 2 周波)
|
||||
*/
|
||||
|
||||
#ifndef SAMPLE_RING_H
|
||||
@@ -45,7 +45,7 @@ void sample_ring_init(void);
|
||||
* 入口参数:values - 按语义通道顺序排列的一帧采样值(浮点工程量,长度须 = ADC_SEM_COUNT)
|
||||
* n - 实际长度(必须等于 ADC_SEM_COUNT,否则拒收)
|
||||
* 返 回 值:0 - 成功;-1 - 参数错(空指针或长度不符)
|
||||
* 限定条件:调用方保证同一帧内各通道**同刻**(同族量同刻性由上游 L1 负责)
|
||||
* 限定条件:调用方保证同一帧内各通道**同刻**(同族量同刻性由上游 语义取数与有效性负责)
|
||||
* 函数说明:整帧一次性写入,写完统一推进写指针——单帧内不可能出现"半新半旧",
|
||||
* 即天然无帧内撕裂。消费侧读到的窗永远是**整帧**边界。
|
||||
*/
|
||||
@@ -76,7 +76,7 @@ uint16_t sample_ring_filled(void);
|
||||
* 入口参数:无
|
||||
* 返 回 值:累计入环帧数(32 位,1 kHz 下约 49.7 天回绕)
|
||||
* 限定条件:无
|
||||
* 函数说明:与 L1 的 `tpafe5160_frame_seq()` 对照可判丢帧(采样有效性校验
|
||||
* 函数说明:与 语义取数与有效性的 `tpafe5160_frame_seq()` 对照可判丢帧(采样有效性校验
|
||||
*(保护功能清单见 docs/算法/继电保护功能复现规划.md)
|
||||
* 的判据之一,本层只提供计数,不做判定)。
|
||||
*/
|
||||
|
||||
+11
-11
@@ -24,14 +24,14 @@
|
||||
#include "sys_clock.h"
|
||||
#include "gd5f2gq5ue.h"
|
||||
#include "tpafe5160.h"
|
||||
#include "adc_input.h" /* L1 采集层:adc_input_init()(语义映射 + STM32 ADC1 扫描) */
|
||||
#include "adc_cal.h" /* L1.5 标定层:adc_cal_init()(ROM 系数 + cfg 两段注册,道A 标定折算与落盘整定) */
|
||||
#include "adc_input.h" /* 语义取数与有效性层:adc_input_init()(语义映射 + STM32 ADC1 扫描) */
|
||||
#include "adc_cal.h" /* 标定折算层:adc_cal_init()(ROM 系数 + cfg 两段注册,道A 标定折算与落盘整定) */
|
||||
#include "run_par.h" /* 运行参数段:run_par_init()([run_par] 注册 + 104 地址映射真源,道D 这一项) */
|
||||
#include "iec104_comm.h" /* [comm] 段:iec104_comm_init()(ca/端口注册,道G task-8) */
|
||||
#include "phasor.h" /* L2 相量层:phasor_init()(系数表 + 实例 + 双区交换) */
|
||||
#include "freq.h" /* L2 派生量:freq_init()(相位解缠绕测频,B8) */
|
||||
#include "prot_set.h" /* L3 定值模型:prot_set_init()(B5,内核前封存) */
|
||||
#include "prot_elm.h" /* L3 元件框架:prot_elm_init()(B5,解析相量索引) */
|
||||
#include "phasor.h" /* 全周傅氏相量层:phasor_init()(系数表 + 实例 + 双区交换) */
|
||||
#include "freq.h" /* 全周傅氏相量的派生量:freq_init()(相位解缠绕测频,B8) */
|
||||
#include "prot_set.h" /* 保护判据定值模型:prot_set_init()(B5,内核前封存) */
|
||||
#include "prot_elm.h" /* 保护判据元件框架:prot_elm_init()(B5,解析相量索引) */
|
||||
#include "sys_log.h"
|
||||
#include "task_watchdog.h" /* task_wd_seg_report():第 8 轮复位不丢"进段打点"上报 */
|
||||
#include "test_config.h" /* 套件开关:身份戳的构建变体串(FW_BUILD_VARIANT)依赖本头,
|
||||
@@ -108,7 +108,7 @@ static void reset_cause_str(uint32_t csr, char *buf, unsigned int len) {
|
||||
* 1) 时间子系统(SD2506 RTC → 墙钟基准)
|
||||
* 2) RS-485
|
||||
* 3) GD5F NAND
|
||||
* 4) TPAFE5160 ADC → ADC 输入层(L1,语义映射 + STM32 ADC1)
|
||||
* 4) TPAFE5160 ADC → ADC 输入层(语义取数与有效性,语义映射 + STM32 ADC1)
|
||||
* 5) SD2506 诊断信息
|
||||
* 6) 启动 TIM3 1 kHz 采样节拍(ISR 内脉冲 CONVST;同一更新事件经 TRGO 硬件触发 ADC1 + DMA)
|
||||
*/
|
||||
@@ -239,7 +239,7 @@ int app_main_init(void) {
|
||||
DBG_ERROR("ADC1 disable before DMA arm: TIMEOUT");
|
||||
}
|
||||
|
||||
/* 4b) ADC 输入层(L1)初始化:清原始码值缓冲与统计 + **语义映射表自洽性自检**
|
||||
/* 4b) ADC 输入层(语义取数与有效性)初始化:清原始码值缓冲与统计 + **语义映射表自洽性自检**
|
||||
* (映射指向了不会被扫描的通道 → 返回 -1,避免"读到恒为陈旧值"的静默错)
|
||||
* + 挂载一次 STM32 ADC1 的 DMA(失败返回 -2)。
|
||||
* ADC1 外设已由 MX_ADC1_Init()(main.c)配好 9 通道 / 144 cycles /
|
||||
@@ -259,20 +259,20 @@ int app_main_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* 4c) 相量层(L2)初始化:清双区结果与有效标志 + 复位采样环缓冲。
|
||||
/* 4c) 相量层(全周傅氏相量)初始化:清双区结果与有效标志 + 复位采样环缓冲。
|
||||
* 纯算法层(无外设 / 无 RTOS 依赖,见 docs/算法/继电保护功能复现规划.md
|
||||
* §3.2),须在启动采样节拍(步骤 6)之前。幂等、当前无失败路径
|
||||
* (返回值保留供后续自检扩展)。 */
|
||||
(void)phasor_init();
|
||||
DBG_INFO("phasor layer init: OK (inst=%u)", (unsigned)phasor_inst_count());
|
||||
|
||||
/* 4c-2) 测频层(L2 派生量,B8)初始化:清平均窗/相位基准/有效标志。
|
||||
/* 4c-2) 测频层(全周傅氏相量的派生量,B8)初始化:清平均窗/相位基准/有效标志。
|
||||
* 纯算法(输入 = phasor 使用区),消费在 adcTask(freq_run 每拍)
|
||||
* 与 protectTask(OF/UF 判据经 prot_elm_run 取数)。 */
|
||||
(void)freq_init();
|
||||
DBG_INFO("freq layer init: OK");
|
||||
|
||||
/* 4c-3) 通道标定层(L1.5,「数据可信」标定折算与落盘整定)初始化:RAM 系数副本置
|
||||
/* 4c-3) 通道标定层(标定折算,「数据可信」标定折算与落盘整定)初始化:RAM 系数副本置
|
||||
* ROM 默认(量程口径冻结定死的引脚侧 LSB,docs/硬件平台/ADC通道映射说明.md §7.1)
|
||||
* + 向配置引擎注册 [adc_cal] / [adc_cal_ofs] 两段。注册必须先于
|
||||
* defaultTask 的 cfg_file_load(「先注册后 load」契约)→ 只能落内核前;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 模块名称:IEC 60870-5-104 点表与数据源适配(实现)
|
||||
* 模块功能:实现 iec104_pts.h——YC/YX/YK/定值点表(ROM)、板端默认源
|
||||
* (**L2 遥测快照**(104 改读快照)/ prot_elm / prot_set)、COV 比对(遥信变位 +
|
||||
* (**测频与遥测快照**(104 改读快照)/ prot_elm / prot_set)、COV 比对(遥信变位 +
|
||||
* 遥测死区 2 点确认 + 品质变化)。点表口径见 iec104_pts.h 文件头与
|
||||
* 设计文档 §3。
|
||||
* 线程约定:init/bind 建服务前;其余仅 104 服务任务上下文(快照非原子)。
|
||||
@@ -12,7 +12,7 @@
|
||||
* k_yc 表头注释;数值随 104 改读快照迁运行参数,本表将退化为
|
||||
* ROM 默认载体。
|
||||
* 2026-10-25 DTU 项目组 104 改读快照与频率点绑定(「数据可信」,道D):YC 板端源改读
|
||||
* L2 遥测快照(App/algo/meas.h,meas_get 无锁双区);
|
||||
* 测频与遥测快照(App/algo/meas.h,meas_get 无锁双区);
|
||||
* 削顶五路由快照品质 CLIPPED 驱动线上 IV(不再绑死 -1,
|
||||
* V0.2 消除双转换器无共同采样触发后零改动自动启用);0x401d 绑频率源(频率点绑定);
|
||||
* 死区改运行时副本 + set/get 入口;COV 遥测腿 = 死区
|
||||
@@ -36,7 +36,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "iec104_asdu.h" /* QDS/DIQ 品质位常量 */
|
||||
#include "meas.h" /* 板端源:遥测 = L2 遥测快照(104 改读快照;品质域位同源) */
|
||||
#include "meas.h" /* 板端源:遥测 = 测频与遥测快照(104 改读快照;品质域位同源) */
|
||||
#include "run_par.h" /* 运行参数段:死区真源 + 104 读写路由 */
|
||||
#include "prot_elm.h" /* 板端源:遥信 = 元件状态 */
|
||||
#include "prot_set.h" /* 板端源:定值 + 闭锁 */
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
/* ---------------- YC 表(§1.5 点号 4011+;死区列 = ROM 默认值) ------------ */
|
||||
/* 源类型(「数据可信」频率点绑定:YC 表加 src 类型区分相量/频率) */
|
||||
#define PTS_SRC_MEAS 0u /* L2 快照槽 sem(电气量,yc/qds 直读) */
|
||||
#define PTS_SRC_MEAS 0u /* 全周傅氏相量快照槽 sem(电气量,yc/qds 直读) */
|
||||
#define PTS_SRC_FREQ 1u /* 快照频率(freq_valid 门 → IV) */
|
||||
|
||||
typedef struct {
|
||||
@@ -458,7 +458,7 @@ int iec104_pts_set_write(uint32_t addr, float v, uint8_t select) {
|
||||
/* ============================ 板端默认源 ================================= */
|
||||
|
||||
/*
|
||||
* 函数功能:板端默认源 - 遥测 = L2 遥测快照直读(「数据可信」104 改读快照与频率点绑定)
|
||||
* 函数功能:板端默认源 - 遥测 = 测频与遥测快照直读(「数据可信」104 改读快照与频率点绑定)
|
||||
* 入口参数:idx - YC 表下标 out/qds - 值 + uint16 域品质(MEAS_QDS_*)
|
||||
* 返 回 值:0 / -1 越界或频率未新鲜(IV)/ -2 快照从未发布(NT) int
|
||||
* 限定条件:iec104Task 上下文(meas_get 为双区无锁读,App/algo/meas.h)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* (asdu+pts+link)可离线跑(分层约束:协议解析与硬件 I/O 分离)。
|
||||
* 点表口径(docs/算法/继电保护功能复现规划.md §1.5,验收 = 省电科院点表):
|
||||
* - YC:IOA 0x4011~0x4018 + 0x401d(频率),短浮点、系数 1;数据源 =
|
||||
* L2 遥测快照(App/algo/meas.h,「数据可信」104 改读快照与频率点绑定):电气 8 路绑快照槽,
|
||||
* 测频与遥测快照(App/algo/meas.h,「数据可信」104 改读快照与频率点绑定):电气 8 路绑快照槽,
|
||||
* 有效性由快照品质驱动——V0.1 削顶路(docs/算法/继电保护功能复现规划.md
|
||||
* §1.6)快照置 CLIPPED → 本层映射为线上 IV(V0.2 后自动启用,绑定零
|
||||
* 改动,见 docs/任务规划/数据可信.md §10「双转换器无共同采样触发」行);0x401d 绑频率源,
|
||||
@@ -25,7 +25,7 @@
|
||||
* 线程约定:init/bind 内核启动前或建服务前;cov_check/read 仅 104 服务任务上下文。
|
||||
* 创建日期:2026-10-12(B4)
|
||||
* 修改记录:
|
||||
* 2026-10-25 DTU 项目组 104 改读快照与频率点绑定(「数据可信」,道D):YC 数据源 = L2 遥测
|
||||
* 2026-10-25 DTU 项目组 104 改读快照与频率点绑定(「数据可信」,道D):YC 数据源 = 全周傅氏相量遥测
|
||||
* 快照(削顶路由品质驱动 IV);死区改运行时副本 +
|
||||
* set/get 入口;COV 遥测腿 = 死区 2 点确认(seq 去重)
|
||||
* + 品质变化即报;0x401d 绑频率源(freq_valid → IV)。
|
||||
|
||||
+22
-22
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 模块名称:ADC Sampling Task
|
||||
* 模块功能:ADC 采集消费 + L2 相量计算——TPAFE5160 快照 + STM32 ADC1 DMA 乒乓帧消费
|
||||
* (经 L1 层 App/algo/adc_input.c 按语义取数)→ 压入采样环
|
||||
* 模块功能:ADC 采集消费 + 全周傅氏相量计算——TPAFE5160 快照 + STM32 ADC1 DMA 乒乓帧消费
|
||||
* (经 语义取数与有效性层 App/algo/adc_input.c 按语义取数)→ 压入采样环
|
||||
* (App/algo/sample_ring.c)→ 全周傅氏相量重算(App/algo/phasor.c)
|
||||
* + 帧统计(节拍由 TIM3 硬件定时器提供)
|
||||
* 状态说明:**B1 已落地(2026-10-10)**——本任务从空桩转为真实消费者:
|
||||
@@ -15,7 +15,7 @@
|
||||
* 消除 0~1 ms 的 tick 量化相位抖动与"超拍永久落后 → 空转"风险;本任务优先级
|
||||
* 同步由 Normal 提到 **AboveNormal**(唤醒即抢占)。详见
|
||||
* docs/子系统设计/ADC采样节拍设计说明.md §6。
|
||||
* **L1 采集层**:取数改走 App/algo/adc_input.c——
|
||||
* **语义取数与有效性层**:取数改走 App/algo/adc_input.c——
|
||||
* 本任务每拍调 adc_input_poll()(TPAFE 快照 + STM32 ADC1 9 通道扫描),
|
||||
* 经 adc_input_raw() **按语义**读通道(STM32 ADC1 启动与扫描 / 通道语义映射),不再直接触碰驱动缓冲。
|
||||
*(保护功能清单见 docs/算法/继电保护功能复现规划.md)
|
||||
@@ -41,7 +41,7 @@
|
||||
* v2.3 2026-10-10 王建锋 STM32 ADC1 启动与扫描 / 通道语义映射:取数改走 App/algo/adc_input.c(语义映射 +
|
||||
* STM32 ADC1 9 通道扫描);首帧日志补全 8 路电气量 + 温度,
|
||||
* 心跳日志增 adc1_rc / adc1_err 观测 STM32 侧健康度。
|
||||
* v2.4 2026-10-10 王建锋 L2:接入相量层——每拍把 9 路语义值压入采样环
|
||||
* v2.4 2026-10-10 王建锋 全周傅氏相量:接入相量层——每拍把 9 路语义值压入采样环
|
||||
* (sample_ring)并重算全部相量实例(phasor_run);
|
||||
* 攒满一周波后**首拍即落一次相量日志**(开机证据,不等
|
||||
* 10 s 心跳),心跳日志增 ring / skip 计数与各实例相量
|
||||
@@ -85,7 +85,7 @@
|
||||
* 者;该入口同时不再打日志——它落在本任务静态最坏链上,
|
||||
* 每条 DBG_* 约 216 B 栈,而这一行毫无诊断价值(本任务
|
||||
* 存活由首帧日志与 TASK_WD_ADC 心跳证明)
|
||||
* v3.1 2026-10-25 DTU 项目组 L1.5 折算 + 采样通道自检 贴轨观测(「数据可信」标定折算落地,道A):
|
||||
* v3.1 2026-10-25 DTU 项目组 标定折算折算 + 采样通道自检 贴轨观测(「数据可信」标定折算落地,道A):
|
||||
* frame[s] 由 (float)code 改 adc_cal_apply()——工程量 =
|
||||
* (code+b)×k,现口径 = ADC 引脚电压 V(eng=0,量程口径冻结的
|
||||
* ROM 系数,docs/硬件平台/ADC通道映射说明.md §7.1);同拍
|
||||
@@ -93,7 +93,7 @@
|
||||
* 门限 adc_cal_rail_ths,码值域与标定正交),锁存边沿 →
|
||||
* DBG_ERROR + 每开机一次 SYSLOG;心跳增 cal: 行(mV 定点
|
||||
* + valid/clipped 位图 + rail 锁存),台架注入口径见该行判读
|
||||
* v3.2 2026-10-25 DTU 项目组 L2 遥测快照发布(「数据可信」这一项,道D,M5):新模块
|
||||
* v3.2 2026-10-25 DTU 项目组 测频与遥测快照发布(「数据可信」这一项,道D,M5):新模块
|
||||
* App/algo/meas.c——本任务为唯一发布者,新帧拍内
|
||||
* freq_run() 之后按 200 ms **tick 经过**分频调
|
||||
* meas_tick()(全仓调用点 = 1,评审判据);品质注入源 =
|
||||
@@ -111,13 +111,13 @@
|
||||
#include "adc_task.h"
|
||||
#include "cmsis_os.h"
|
||||
#include "task_handles.h" /* adcTaskHandle(原为本文件局部 extern) */
|
||||
#include "adc_input.h" /* L1 采集层:adc_input_poll()/adc_input_raw()(按语义取数) */
|
||||
#include "sample_ring.h" /* L2 输入:sample_ring_push_frame()(采样环缓冲) */
|
||||
#include "phasor.h" /* L2 相量层:phasor_run()/phasor_get()(全周傅氏) */
|
||||
#include "freq.h" /* L2 派生量:freq_run()/freq_get()(测频,B8) */
|
||||
#include "adc_input.h" /* 语义取数与有效性层:adc_input_poll()/adc_input_raw()(按语义取数) */
|
||||
#include "sample_ring.h" /* 全周傅氏相量输入:sample_ring_push_frame()(采样环缓冲) */
|
||||
#include "phasor.h" /* 全周傅氏相量层:phasor_run()/phasor_get()(全周傅氏) */
|
||||
#include "freq.h" /* 全周傅氏相量的派生量:freq_run()/freq_get()(测频,B8) */
|
||||
#include "adc_health.h" /* 采样有效性校验(静默/丢帧/单调性/错误增量/贴轨) */
|
||||
#include "adc_cal.h" /* L1.5:通道标定折算(「数据可信」标定折算落地;flags 供 cal 心跳行) */
|
||||
#include "meas.h" /* L2 发布侧:遥测快照 meas_tick()(「数据可信」遥测快照发布,道D) */
|
||||
#include "adc_cal.h" /* 标定折算:通道标定折算(「数据可信」标定折算落地;flags 供 cal 心跳行) */
|
||||
#include "meas.h" /* 全周傅氏相量发布侧:遥测快照 meas_tick()(「数据可信」遥测快照发布,道D) */
|
||||
#include "tpafe5160.h"
|
||||
#include "task_watchdog.h"
|
||||
#include "console_log.h"
|
||||
@@ -133,7 +133,7 @@
|
||||
#define ADC_TASK_REPORT_MS 10000U
|
||||
|
||||
/* 统计:已消费帧数 / 无新帧次数(首拍必为无新帧,之后应稳定为 0 增量)。
|
||||
* 原始码值缓冲由 L1 层 App/algo/adc_input.c 持有(消费侧按语义取数,不写死下标) */
|
||||
* 原始码值缓冲由 语义取数与有效性层 App/algo/adc_input.c 持有(消费侧按语义取数,不写死下标) */
|
||||
static uint32_t s_frames_consumed;
|
||||
static uint32_t s_frames_idle;
|
||||
/* 因通道尚未首次成功而**整拍跳过入环**的次数(不向相量窗注入 0 点) */
|
||||
@@ -194,7 +194,7 @@ void adc_tick_irq_notify(void) {
|
||||
* 限定条件:仅任务上下文;调用方须保证 dbg_console_writer_ready() 为真
|
||||
* 函数说明:MicroLIB 的 snprintf **不支持 %f** → 以 ×0.1 定点整数打印
|
||||
* (打印值 = 实际值 × 10,分辨率 0.1)。逐实例数据驱动输出,
|
||||
* 实例表加行即自动覆盖。输入自 v3.1 起为 L1.5 折算后的工程量
|
||||
* 实例表加行即自动覆盖。输入自 v3.1 起为 标定折算折算后的工程量
|
||||
* (现口径 = ADC 引脚电压 V,见 cal: 心跳行与文件头 v3.1 记录);
|
||||
* 二次值语义仅在 adc_cal_flags() 出 VALID 后成立。
|
||||
*/
|
||||
@@ -329,7 +329,7 @@ void adc_task_func(void *arg) {
|
||||
* (osPriorityBelowNormal),是"UI 心跳缺席"的候选占用者之一 */
|
||||
task_prof_enter(TASK_PROF_ADC_BEAT);
|
||||
|
||||
/* 1) 采集一拍:L1 层 adc_input_poll() = TPAFE 原子快照 + 消费一帧 STM32 ADC1
|
||||
/* 1) 采集一拍:语义取数与有效性层 adc_input_poll() = TPAFE 原子快照 + 消费一帧 STM32 ADC1
|
||||
* DMA 双缓冲(仅任务上下文;TPAFE 侧 1=有新帧 0=无新帧 -1=参数错)。
|
||||
* 采样节拍由 TIM3 更新事件提供(ISR 内触发 CONVST + TRGO 触发 ADC1),
|
||||
* 本任务既不触发也不等待转换。
|
||||
@@ -347,7 +347,7 @@ void adc_task_func(void *arg) {
|
||||
/* r == -1:参数错。调用点 count 为常量,不可达;不计入 idle 以区分异常 */
|
||||
}
|
||||
|
||||
/* 2) L2 输入 + 相量重算:把本拍 9 路语义值转浮点帧压入采样环,再重算全部
|
||||
/* 2) 全周傅氏相量输入 + 相量重算:把本拍 9 路语义值转浮点帧压入采样环,再重算全部
|
||||
* 相量实例(每 1 ms 滑动窗刷新:每拍以"当前时刻为终止的前一周波"整窗重算)。
|
||||
*
|
||||
* ⚠ **仅在本拍确有新帧(r == 1)时**才压环。
|
||||
@@ -374,7 +374,7 @@ void adc_task_func(void *arg) {
|
||||
all_ok = 0u;
|
||||
break;
|
||||
}
|
||||
/* L1.5 折算(「数据可信」标定折算落地,§4.1 模型):工程量 = (code + b) × k。
|
||||
/* 标定折算折算(「数据可信」标定折算落地,§4.1 模型):工程量 = (code + b) × k。
|
||||
* 现口径 = **ADC 引脚电压 V**(eng=0,量程口径冻结的 ROM 系数,见
|
||||
* docs/硬件平台/ADC通道映射说明.md §7.1);端子变比确认与两点标定写入标定
|
||||
* 系数(adc_cal_flags() 出 VALID)后才按二次值消费。TEMP 透传码值
|
||||
@@ -394,11 +394,11 @@ void adc_task_func(void *arg) {
|
||||
if (all_ok != 0u) {
|
||||
(void)sample_ring_push_frame(frame, (uint8_t)ADC_SEM_COUNT);
|
||||
phasor_run();
|
||||
/* L2 派生量测频(B8):同拍紧随 phasor_run——本拍使用区已
|
||||
/* 全周傅氏相量的派生量测频(B8):同拍紧随 phasor_run——本拍使用区已
|
||||
* 切换,freq 读的就是本拍相量(1 ms 同上下文,无竞态) */
|
||||
freq_run();
|
||||
|
||||
/* L2 遥测快照发布(「数据可信」这一项,道D,M5):200 ms tick 经过分频。
|
||||
/* 测频与遥测快照发布(「数据可信」这一项,道D,M5):200 ms tick 经过分频。
|
||||
* 唯一发布者 = 本任务(全仓 meas_tick 调用点数 = 1 为评审判据,
|
||||
* 「数据可信」§8 风险表"快照双写"行);只在**压环成功的真新帧拍**发布
|
||||
* ——idle/skip 拍压环未推进,发布 = 重复旧窗。品质注入唯一源 =
|
||||
@@ -480,7 +480,7 @@ void adc_task_func(void *arg) {
|
||||
(long)ia, (long)ib, (long)ic, (long)in, (long)temp);
|
||||
}
|
||||
|
||||
/* 4) 首拍相量上报:攒满一周波(20 ms)后立即落一次,作为 L2 链路的开机证据。
|
||||
/* 4) 首拍相量上报:攒满一周波(20 ms)后立即落一次,作为 全周傅氏相量链路的开机证据。
|
||||
* 不依赖 10 s 心跳 → 台架 @test 的 settle 窗口内即可见(否则会被静默判据
|
||||
* 截断,见 docs/测试说明/自动化测试流程.md 的 settle 口径)。 */
|
||||
if ((first_phasor_logged == 0u) && (dbg_console_writer_ready() != 0u)) {
|
||||
@@ -495,7 +495,7 @@ void adc_task_func(void *arg) {
|
||||
/* 5) 看门狗心跳(本任务已纳入 required_mask) */
|
||||
task_wd_beat(TASK_WD_ADC);
|
||||
|
||||
/* 6) 周期心跳日志:帧统计 + 驱动侧 FRSTDATA 错误计数 + L2 相量。
|
||||
/* 6) 周期心跳日志:帧统计 + 驱动侧 FRSTDATA 错误计数 + 全周傅氏相量。
|
||||
* 写者就绪前抑制(同 3) 的交错理由);到点无论是否落日志都推进下个上报点 */
|
||||
{
|
||||
if ((int32_t)(now - report_at) >= 0) {
|
||||
@@ -552,7 +552,7 @@ void adc_task_func(void *arg) {
|
||||
(long)rc[ADC_SEM_TEMP]);
|
||||
}
|
||||
|
||||
/* L1.5/采样通道自检 台架观测面(×1000 mV 定点,MicroLIB 无 %f):
|
||||
/* 标定折算/采样通道自检 台架观测面(×1000 mV 定点,MicroLIB 无 %f):
|
||||
* ua/un/ia_mv = 三路 TPAFE 引脚电压毫伏(未标定域,**不是**
|
||||
* 二次值;两点标定注入验证的读数落点,偏差判据 ≤2 %)
|
||||
* vl = VALID 位图(默认构建应恒 0x00——未标定即未标定,
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
flowchart TB
|
||||
subgraph APP["应用层 (App/)"]
|
||||
direction LR
|
||||
A1["app/app_main.c"] ~~~ A2["task/net_task.c"] ~~~ A3["task/ui_task.c"] ~~~ A4["sync/time_sync.c"] ~~~ A5["algo/(L1~L3)"]
|
||||
A1["app/app_main.c"] ~~~ A2["task/net_task.c"] ~~~ A3["task/ui_task.c"] ~~~ A4["sync/time_sync.c"] ~~~ A5["algo/(语义取数与有效性~保护判据)"]
|
||||
end
|
||||
subgraph BSP["驱动层 (Drivers/BSP/)"]
|
||||
direction LR
|
||||
@@ -63,8 +63,8 @@ main.c
|
||||
│ ├─ rs485_init()
|
||||
│ ├─ gd5f2gq5ue_init() // 含 BBT 全片扫描
|
||||
│ ├─ tpafe5160_init()
|
||||
│ ├─ adc_input_init() // L1 采集层(语义映射 + STM32 ADC1 DMA)
|
||||
│ ├─ phasor_init() / freq_init() / prot_set_init() + prot_elm_init() // L2/L3 内核前就绪
|
||||
│ ├─ adc_input_init() // 语义取数与有效性层(语义映射 + STM32 ADC1 DMA)
|
||||
│ ├─ phasor_init() / freq_init() / prot_set_init() + prot_elm_init() // 全周傅氏相量/保护判据内核前就绪
|
||||
│ ├─ SD2506 诊断(ID/时间/温度/电池)
|
||||
│ └─ HAL_TIM_Base_Start_IT(&htim3) // 启动 TIM3 1kHz 采样节拍
|
||||
├─ osKernelInitialize()
|
||||
@@ -85,7 +85,7 @@ main.c
|
||||
| timeSyncTask | 640 words | Normal | 墙钟时间同步 |
|
||||
| adcTask | 640 words | AboveNormal | TPAFE5160 采样(TIM3 1kHz 事件驱动 + 原子快照 + STM32 ADC DMA,纯消费者) |
|
||||
| iec104Task | 640 words | Normal | IEC 60870-5-104 上行(:2404 监听,遥信/遥测/定值区) |
|
||||
| protectTask | 512 words | Normal | 保护判据 20ms 节拍(L3 元件 + 采样故障闭锁,B5) |
|
||||
| protectTask | 512 words | Normal | 保护判据 20ms 节拍(保护判据元件 + 采样故障闭锁,B5) |
|
||||
<!-- TASK_TABLE:END -->
|
||||
|
||||
> 上表与 `Src/freertos.c` 的 `osThreadAttr_t` 一致(2026-10-14 校准,9 任务);改动栈大小前先读
|
||||
@@ -119,7 +119,7 @@ STM32F4-Base/
|
||||
│ └── gpio.h / dma.h / spi.h / i2c.h / usart.h
|
||||
├── App/ # 应用层代码
|
||||
│ ├── app/ # 应用入口与全局(app_main / app_cfg / sys_events)
|
||||
│ ├── algo/ # 采集与算法层(L1 adc_input / L2 phasor+freq / L3 prot_set+prot_elm)
|
||||
│ ├── algo/ # 采集与算法层(语义取数与有效性 adc_input / 全周傅氏相量 phasor+freq / 保护判据 prot_set+prot_elm)
|
||||
│ ├── cfg/ # 配置引擎(cfg_file 解析/持久化/迁移 + 存储后端)
|
||||
│ ├── fs/ # 卷锁(vol_lock,syslog/cfg/lftpd 三条路径 try 语义)
|
||||
│ ├── sync/ # 时间同步(time_sync 任务)
|
||||
@@ -128,9 +128,9 @@ STM32F4-Base/
|
||||
│ │ ├── default_task.c/h # 存储挂载 + 配置引擎属主 + syslog 写者
|
||||
│ │ ├── net_task.c/h # 网络任务
|
||||
│ │ ├── ui_task.c/h # UI 任务
|
||||
│ │ ├── adc_task.c/h # ADC 任务(L1/L2 纯消费者,TIM3 1kHz 唤醒)
|
||||
│ │ ├── adc_task.c/h # ADC 任务(语义取数与有效性/全周傅氏相量纯消费者,TIM3 1kHz 唤醒)
|
||||
│ │ ├── iec104_serv.c/h # IEC 60870-5-104 上行服务
|
||||
│ │ ├── protect_task.c/h # 保护判据任务(L3 20ms 节拍)
|
||||
│ │ ├── protect_task.c/h # 保护判据任务(保护判据 20ms 节拍)
|
||||
│ │ └── rs485_task.c/h # RS-485 任务(已实现,未创建,B2 暂缓)
|
||||
│ ├── util/ # 工具函数(crc / ringbuf / sys_clock)
|
||||
│ └── protocol/ # 通信协议(预留)
|
||||
@@ -394,7 +394,7 @@ pre-commit run --all-files
|
||||
| `Drivers/BSP/NET/net_socket.c` | BSD Socket API |
|
||||
| `Drivers/BSP/NET/net_events.c` | 芯片边沿事件处理 + 周期对账 |
|
||||
| `Drivers/BSP/NET/net_listener.c` | 监听生命周期(单一重建所有者) |
|
||||
| `App/algo/prot_elm.h` | L3 保护元件框架(判据消费入口) |
|
||||
| `App/algo/prot_elm.h` | 保护判据元件框架(判据消费入口) |
|
||||
| `.dsh/skills/keil-build/scripts/keil_build.py` | 编译脚本(`@build`) |
|
||||
| `.dsh/skills/serial-boot-test/scripts/run_boot_test.py` | 自动化测试脚本 |
|
||||
|
||||
|
||||
+3
-3
@@ -57,7 +57,7 @@
|
||||
* CCM 末尾+1,PC 落在 HAL_UART_Transmit 的缓冲读取处)。
|
||||
* ⚠ 本辅助函数须定义在钩子**之前**:两个钩子本体已迁入 CubeMX 生成的
|
||||
* `USER CODE BEGIN 4 / 5` 区(位置在 `MX_FREERTOS_Init` 原型之后,比
|
||||
* `Application` 区靠前),故 helper 一并搬到此标准保护位(L2)。
|
||||
* `Application` 区靠前),故 helper 一并搬到此标准保护位(全周傅氏相量)。
|
||||
*/
|
||||
static int hook_ptr_ok(const void *p)
|
||||
{
|
||||
@@ -125,11 +125,11 @@ static int hook_ptr_ok(const void *p)
|
||||
* 784 B < 1024 B ISR 底线 → 抬至 **640 words**(2.5 KB),余 1296 B / 50%;
|
||||
* 堆开销 +512 B。
|
||||
* adcTask 640 words:本区下方手工定义(同上,不在 `.ioc` 里)。B1(2026-10-10)
|
||||
* ADC 采集消费者;L2 相量(2026-10-11)+ 采样有效性校验(同日)后链上为
|
||||
* ADC 采集消费者;全周傅氏相量(2026-10-11)+ 采样有效性校验(同日)后链上为
|
||||
* adc_input_poll + sample_ring/phasor + adc_health_report(DBG_ERROR +
|
||||
* syslog_post 回显尾)。静态最坏链 1080 B,512 words 时余 968 B < 1024 B
|
||||
* ISR 底线 → 抬至 640 words(2.5 KB,堆余量 min_ever 7152→≈6640 B,可承受)。
|
||||
* 2026-10-12 复测链 1320 B(L3 保护接线后),余 1240 B / 48% 仍 PASS。
|
||||
* 2026-10-12 复测链 1320 B(保护判据接线后),余 1240 B / 48% 仍 PASS。
|
||||
* 栈值以 `scripts/stack_report.py` 实测最坏链为准,改动前后各跑一次。
|
||||
* iec104Task 640 words:B4(2026-10-12)104 上行服务(2404 监听 + link 状态
|
||||
* 机)。link/pts 缓冲全静态;stack_report 实测静态最坏链 1456 B(拆链
|
||||
|
||||
+4
-4
@@ -46,7 +46,7 @@ docs/
|
||||
| 3 | [`项目启动顺序管理.md`](架构设计/项目启动顺序管理.md) | Event Flags 就绪屏障(取代魔法延时)的任务启动模型 |
|
||||
| 4 | [`项目部署环境要求.md`](环境与部署/项目部署环境要求.md) | 开发机/目标板/现场部署的完整环境核对清单 |
|
||||
| 5 | [`项目部署环境要求.md`](环境与部署/项目部署环境要求.md) → 构建 | 跑通 `@build` / `@test`(见根 `AGENTS.md`) |
|
||||
| 6 | [`测试开发标准流程.md`](测试说明/测试开发标准流程.md) | 测试分层 L0~L3 与门禁决策表 |
|
||||
| 6 | [`测试开发标准流程.md`](测试说明/测试开发标准流程.md) | 测试分层 L0~保护判据与门禁决策表 |
|
||||
| 7 | [`嵌入式C语言代码规范_V1.0.md`](代码规范/嵌入式C语言代码规范_V1.0.md) | 命名/格式/注释规范(提交门禁强制) |
|
||||
| 8 | [`项目架构总览.md`](架构设计/项目架构总览.md) → 按需 | 进入具体子系统设计文档 |
|
||||
|
||||
@@ -93,7 +93,7 @@ docs/
|
||||
| [`ADC采样节拍设计说明.md`](子系统设计/ADC采样节拍设计说明.md) | **ADC 采集链路采样节拍(现状说明)**:TIM3 1 kHz 更新事件同时触发 TPAFE CONVST 与(经 TRGO)STM32 ADC1 + DMA 乒乓缓冲;节拍源为什么是 TIM3、DMA 硬约束、事件驱动消费与就绪门、实现落点、观测计数、性能特征与设计边界 |
|
||||
| [`IEC104上行设计说明.md`](子系统设计/IEC104上行设计说明.md) | **B4 上行规约**:IEC 60870-5-104 被控站(TCP 2404)范围/点表(V0.1 有效子集)/链路流程(k/w/t1~t3、总召、COV、遥控两段式、定值)/netTask 接入决策/预算与测试方案;协议核心纯逻辑 + L0.5 全栈单测 |
|
||||
| [`网络/BSD_Socket_API_使用指南.md`](网络/BSD_Socket_API_使用指南.md) | **上层视图**:BSD Socket API 公开语义、示例、常见问题 |
|
||||
| [`网络/BSD_Socket_API_函数调用关系.md`](网络/BSD_Socket_API_函数调用关系.md) | **内部视图**:netTask / 消息队列 / L3 挂起 / 重试对账的调用关系与设计意图 |
|
||||
| [`网络/BSD_Socket_API_函数调用关系.md`](网络/BSD_Socket_API_函数调用关系.md) | **内部视图**:netTask / 消息队列 / 保护判据挂起 / 重试对账的调用关系与设计意图 |
|
||||
| [`网络/Net层阻塞模型架构设计.md`](网络/Net层阻塞模型架构设计.md) | **等待模型**:recv/send 挂起请求架构、数据结构与挂起槽状态机、recv 五路 + send 四路完成语义、模块接口契约(14 函数)、实现落点(20 集成点)、调用方契约、设计边界与性能特征 |
|
||||
| [`网络/网络自愈架构设计.md`](网络/网络自愈架构设计.md) | **网络自愈架构 + 监听生命周期**:现状权威描述——根因三层证据与 A′ 出局、ioLibrary 代码级对照、设计原则(不变量 I1~I8)、分层职责与三 tick、reconciler 形态①~⑤ + M3 门、驱动原语、读即清信源审计、FUN_PARA bit3 契约、recv 语义、KeepAlive、参数表与 E 锚点速查、红线、编号发现速查、代码级事实清点、决策记录、`net_listener.c` / `net_events.c` 模块化边界、延后项;审计与实施过程已归档 |
|
||||
|
||||
@@ -104,7 +104,7 @@ docs/
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
| [`傅氏算法详解.md`](算法/傅氏算法详解.md) | 全周波傅氏(单频 DFT)原理与工程实现:正交性、梳状带通、滑动窗、系数表折算有效值;保护/遥测双轨有效值的算法基础 |
|
||||
| [`采集与算法层设计说明.md`](算法/采集与算法层设计说明.md) | **`App/algo/` 的现状设计说明**:L1 语义取数与有效性判定、L2 采样环/相量/测频、L3 定值模型与元件框架的契约、关键机制(双区原子切换、乒乓半区、自适应测频窗、定值封存-自检-闭锁)、精度判据 J1~J6 与资源足迹 |
|
||||
| [`采集与算法层设计说明.md`](算法/采集与算法层设计说明.md) | **`App/algo/` 的现状设计说明**:语义取数与有效性语义取数与有效性判定、全周傅氏相量采样环/相量/测频、保护判据定值模型与元件框架的契约、关键机制(双区原子切换、乒乓半区、自适应测频窗、定值封存-自检-闭锁)、精度判据 J1~J6 与资源足迹 |
|
||||
| [`继电保护功能复现规划.md`](算法/继电保护功能复现规划.md) | **保护功能复现规划**:把参考系统(CLS100)保护链路映射到本项目(STM32F4)的分层功能/性能/参数清单、平台适配(「双转换器无共同采样触发」等)与分阶段路线图 |
|
||||
| [`采样有效性校验设计说明.md`](算法/采样有效性校验设计说明.md) | **`App/algo/adc_health.c` 单文件深设计**:四类判据(静默 / 丢帧 / 序号倒退 / 错误计数增量)的判据推导与 100 ms 门限依据、电平-锁存-事件三种位语义与位号对齐、闭锁与看门狗兜底的责任划分、观测盲区、主机侧验证分工与现场判读手册(含三张配图生成器) |
|
||||
|
||||
@@ -120,7 +120,7 @@ docs/
|
||||
| [`自动化测试流程.md`](测试说明/自动化测试流程.md) | `@test` 闭环细节:命令 / 串口标记 / 失败模式 |
|
||||
| [`测试文档模板规范.md`](测试说明/测试文档模板规范.md) | 测试文档模板与命名规则(TM / TC / DP) |
|
||||
| [`链路延迟测试说明.md`](测试说明/链路延迟测试说明.md) | 网络链路时延分段定义、判定基线、执行流程 |
|
||||
| [`模拟器差距清单.md`](测试说明/模拟器差距清单.md) | **PC 模拟器 vs 真机差距登记册**(L3 门禁可信度依据;改动涉及网络/日志/硬件层前必查 §3 决策规则) |
|
||||
| [`模拟器差距清单.md`](测试说明/模拟器差距清单.md) | **PC 模拟器 vs 真机差距登记册**(保护判据门禁可信度依据;改动涉及网络/日志/硬件层前必查 §3 决策规则) |
|
||||
| [`实机测试实施指南.md`](测试说明/实机测试实施指南.md) | **上板(真机)测试执行流程**(按顺序:环境预检 → `@test`+自检判定 → IWDG 注入/长跑 → 堆告警 → GD5F 错误通道 → 网络基线 → 工程卫生;每步含判据/命令/状态);已完成事项证据去向见 §10 |
|
||||
| [`ADC前端注入验证流程.md`](测试说明/ADC前端注入验证流程.md) | **ADC 前端与两片转换器的台架注入验证**(已知电压注入验证的执行侧,实测证据 → `docs/硬件平台/ADC通道映射说明.md` §8.1):注入点清单 / 期望码值表 / 零点·线性·映射·极性·节奏五步(每步自带现场记录表,边做边填);**不需示波器与信号源**,一块万用表即可 |
|
||||
|
||||
|
||||
+19
-19
@@ -50,7 +50,7 @@
|
||||
| **就绪屏障** | 用 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}`,实部 / 虚部 / 幅值 / 有效值 |
|
||||
| **双区交换** | 相量(及遥测快照)计算区 / 使用区索引单字节翻转,读者无锁取整份快照 |
|
||||
@@ -86,11 +86,11 @@
|
||||
|
||||
它的**产品目标是 1:1 复刻参考产品 CLS100**(配电保护测控装置)——按参考工程源码的
|
||||
常量表与模块文件逐项对齐点表、定值、保护元件与规约栈(§2.4、§2.5)。在此过程中沉淀出的
|
||||
分层底座(采集链 L1~L4、配置引擎、就绪屏障、双端测试)同时是可复用的平台能力。
|
||||
分层底座(采集链 语义取数与有效性~出口与记录、配置引擎、就绪屏障、双端测试)同时是可复用的平台能力。
|
||||
|
||||
> **产品现状一句话**:平台能力(网络 / 存储 / 时间 / UI / 日志 / 看门狗 / FTP / 配置)
|
||||
> **已实现并台架验收**;采集主线(L1 采集 → L1.5 标定 → L2 相量 → L2.5 遥测快照 → L3 保护判据
|
||||
> → L4 SOE → IEC 60870-5-104 上送)**软件链路已全线贯通并台架闭环**;与参考产品的差距
|
||||
> **已实现并台架验收**;采集主线(语义取数与有效性采集 → 标定折算 → 全周傅氏相量 → 测频与遥测快照 → 保护判据
|
||||
> → 出口与记录 SOE → IEC 60870-5-104 上送)**软件链路已全线贯通并台架闭环**;与参考产品的差距
|
||||
> 集中在三处:① 保护判据处于**未标定闭锁**态(等标准源两点标定)、② **点表规模**远小于参考
|
||||
> (定值 40 vs 249 项、遥测 9 vs 31 点、开入开出 0 vs 138/31 点)、③ **独立子系统未立项**
|
||||
> (故障录波、电度、多规约、SNTP)。即:**"数"与"判据"已可信到引脚电压口径,
|
||||
@@ -355,7 +355,7 @@ tTimer_NoUI 无压无流判据(CN_
|
||||
|---|---|---|---|
|
||||
| ① 业务层 | `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/*` `algo/*`(L1~L3)`protocol/iec104/*` `log/soe_store` `lftpd` `time_sync` |
|
||||
| ③ 基础服务层 | `App/`、`Drivers/BSP/NET/lftpd/` | 应用侧服务、采集算法与协议编排 | `app_main` `sys_events` `app_cfg` `task/*` `algo/*`(语义取数与有效性~保护判据)`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 |
|
||||
@@ -716,7 +716,7 @@ sequenceDiagram
|
||||
**映射自检**(STM32 映射通道必须落在扫描序列内,否则拒绝并自检留痕)。
|
||||
- 判据:`ADC input layer init: OK`;8 路 + 温度首帧全部读出、互异、非饱和。
|
||||
|
||||
**FR-ADC-3 标定与量纲折算(L1.5)**
|
||||
**FR-ADC-3 标定与量纲折算(标定折算)**
|
||||
- 需求:把码值折算为工程量 `(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/码);
|
||||
@@ -759,7 +759,7 @@ sequenceDiagram
|
||||
- **双轨有效值**:保护用**基波有效值**(抗衰减直流与谐波误动),计量/遥测要**真有效值**(谐波方和根)
|
||||
——两者不可混用;本产品当前只实现基波轨,谐波方和根轨未做(§9)。
|
||||
|
||||
**FR-MEAS-2 频率测量(L2.5)**
|
||||
**FR-MEAS-2 频率测量(测频与遥测快照)**
|
||||
- 需求:45~55 Hz 内测频,精度优先于响应速度。
|
||||
- 实现:`App/algo/freq.c`——共轭乘积相位增量 + 解缠绕 + **自适应窗长**(对齐纹波周期整数倍);
|
||||
假值钳制带与系统合理带分离;幅值门 <50 码判无效;`UA` → `IA` 优先级。
|
||||
@@ -908,7 +908,7 @@ sequenceDiagram
|
||||
**FR-IEC104-2 遥测上送**
|
||||
- 需求:遥测短浮点、系数 1、点号落在 `0x4001` 起的遥测段(段基址见 §2.5.3);支持背景/总召、
|
||||
周期(60 s)、死区与品质上送。
|
||||
- 实现:数据源 = L2 遥测快照(§5.11);品质直传,`CLIPPED` 映射为 `IV`;死区运行时副本(运行参数段可读写)。
|
||||
- 实现:数据源 = 测频与遥测快照(§5.11);品质直传,`CLIPPED` 映射为 `IV`;死区运行时副本(运行参数段可读写)。
|
||||
- 判据:总召读回值与 UI 同源一致;死区两拍确认、品质翻转直报;削顶五路恒 IV。
|
||||
|
||||
**FR-IEC104-3 遥信上送**
|
||||
@@ -1605,14 +1605,14 @@ mac=00:00:00:00:00:00
|
||||
| `ui_content_page` | `ui_content_page_open/close/invalidate/is_open` | 内容页框架 |
|
||||
| `task_watchdog` | `task_wd_beat/poll/start` + 观测接口 | 看门狗判定状态机 |
|
||||
| `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 实例) |
|
||||
| `adc_input` | `adc_input_init/poll/raw/desc` | 语义取数与有效性语义取数(8 电气量 + 温度) |
|
||||
| `adc_health` | `adc_health_init/report/flags` | 语义取数与有效性采样有效性判定(纯逻辑) |
|
||||
| `adc_cal` | `adc_cal_init/apply/flags/set/b_codes/prot_blocked` | 标定折算 + 三态可用性 |
|
||||
| `phasor` | `phasor_init/run/read` | 全周傅氏相量全周傅氏相量(双区) |
|
||||
| `freq` | `freq_run/get/valid` | 测频与遥测快照测频(自适应窗) |
|
||||
| `meas` | `meas_tick/snap` | 测频与遥测快照(200 ms,双区) |
|
||||
| `prot_set` | `prot_set_init/load/selfcheck/set_sealed/get/locked` | 保护判据定值模型(原子写 + 封存) |
|
||||
| `prot_elm` | `prot_elm_init/run/eval/state/request_reset` | 保护判据元件框架(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 链路 / 点表 / 板端胶水 |
|
||||
@@ -1745,8 +1745,8 @@ mac=00:00:00:00:00:00
|
||||
|---|---|---|
|
||||
| L0 | 静态门禁(pre-commit 钩子族:格式 / 编码 / 静态分析 / 文档链接 / 体积 / 生成物新鲜度 / 编号) | 本地 / CI |
|
||||
| L0.5 | 主机侧单元测试(MSVC 离线编译真实源码) | 本地 / CI |
|
||||
| L1 / L2 | 板端套件 / 模拟器回归 | 本地(需硬件 / 模拟器) |
|
||||
| L3 | 真机台架(`@test` 闭环 + 探针) | 本地(需真机 + ST-LINK) |
|
||||
| 语义取数与有效性 / 全周傅氏相量 | 板端套件 / 模拟器回归 | 本地(需硬件 / 模拟器) |
|
||||
| 保护判据 | 真机台架(`@test` 闭环 + 探针) | 本地(需真机 + ST-LINK) |
|
||||
|
||||
**构建 / 测试命令**:
|
||||
|
||||
@@ -2677,7 +2677,7 @@ docs/任务规划/UI补齐.md §5);原「当前执行 6 项」(记录 5
|
||||
| 菜单页面 | [`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) |
|
||||
| 采样有效性校验 | [`docs/算法/采样有效性校验设计说明.md`](../../docs/算法/采样有效性校验设计说明.md) |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 分工说明:采集链与上送链台架联调(2026-10-28)
|
||||
|
||||
**目标**:把 **L1→L2→L2.5** 取数链与 **L2.5→104/UI** 上送链在同一次台架烧录里对齐,提交门禁 **0 错误 0 警告**。
|
||||
**目标**:把 **语义取数与有效性→全周傅氏相量→测频与遥测快照** 取数链与 **测频与遥测快照→104/UI** 上送链在同一次台架烧录里对齐,提交门禁 **0 错误 0 警告**。
|
||||
**口径**:本文件只分工,不改行为;任何一条线单独验收通过后合并,**不交叉编辑**对方文件。
|
||||
|
||||
## A 线 · 采集链(负责人 A)
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
| 线 | 判据 | 证据 |
|
||||
|---|---|---|
|
||||
| A | L1 有效性→L2 相量 与 1 kHz 节拍一致,无半帧 | `test/host/adc_input` 全绿 + `docs/子系统设计/ADC采样节拍设计说明.md` |
|
||||
| A | 语义取数与有效性→全周傅氏相量与 1 kHz 节拍一致,无半帧 | `test/host/adc_input` 全绿 + `docs/子系统设计/ADC采样节拍设计说明.md` |
|
||||
| B | `meas` 双区 **104 与 UI 同源**,无撕裂 | `test/host/meas`、`test/host/ui_data` 全绿 + `docs/编号规范.md` 无新撞号 |
|
||||
| A+B | 台架一次烧录 **`-Rst -Run` + 回读校验**(`No difference found`),串口日志无 `[ERR]` | `@test` 报告 + `MDK-ARM/build_log.txt` |
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ dhara 失败类 +84;RO 另 +208,全是该失败类名表)→ `ER_IROM1`
|
||||
|---|---|---|
|
||||
| 主 SRAM (0x20000000) | 128 KB(RW_IRAM1 Max `0x20000`) | scatter `STM32F407-Demo.sct:22` |
|
||||
| CCM SRAM (0x10000000) | 64 KB;FreeRTOS 堆于 2026-09-21 迁入(§4.1.2) | scatter `STM32F407-Demo.sct:25`;RM0090 §3.1.1 |
|
||||
| FreeRTOS 堆 (heap_4) | **56 KB(57,344 B)**,**位于 RW_CCM**;2026-10-12(B5)由 48 KB 扩容(protectTask/iec104Task 栈入堆,CCM 水位 87.9% < 92% 门禁);旧 48KB 池实测 `free=8,784 / min_ever=4,848` B(2026-10-03),新池 min_ever 待上板复测 | `Inc/FreeRTOSConfig.h:71` `configTOTAL_HEAP_SIZE`(L1:`.ioc` `FREERTOS.configTOTAL_HEAP_SIZE`) |
|
||||
| FreeRTOS 堆 (heap_4) | **56 KB(57,344 B)**,**位于 RW_CCM**;2026-10-12(B5)由 48 KB 扩容(protectTask/iec104Task 栈入堆,CCM 水位 87.9% < 92% 门禁);旧 48KB 池实测 `free=8,784 / min_ever=4,848` B(2026-10-03),新池 min_ever 待上板复测 | `Inc/FreeRTOSConfig.h:71` `configTOTAL_HEAP_SIZE`(语义取数与有效性:`.ioc` `FREERTOS.configTOTAL_HEAP_SIZE`) |
|
||||
| C 库堆/栈 (startup) | 512 B / 1 KB,启动期 main() 用 | map `startup_stm32f407xx.o` HEAP/STACK 节 |
|
||||
|
||||
### 2.2 静态大项排行(2026-10-10 当前,完整台账 `data/ram_report_20261010.md`)
|
||||
@@ -104,7 +104,7 @@ dhara 失败类 +84;RO 另 +208,全是该失败类名表)→ `ER_IROM1`
|
||||
|
||||
> ✅ **本表已于 2026-10-10 重新基线**(产品构建 `suite=NONE`,开机 + 空闲采样,静态链取 `stack_report.py`)。
|
||||
> 同日**增列 `adcTask`**(B1:ADC 采集消费者,512 words,静态最坏链 504 B / 余 75%)。
|
||||
> **2026-10-11 L2 相量层接入后复测**:adcTask 静态 **832 B** / 台架实测峰值 **928 B / 2048(余 54%)**,
|
||||
> **2026-10-11 全周傅氏相量层接入后复测**:adcTask 静态 **832 B** / 台架实测峰值 **928 B / 2048(余 54%)**,
|
||||
> 增量为压环 + `phasor_run()`(`win[20]` 80 B)+ `log_phasors` 日志链;仍高于 1024 B 底线,7 任务全 PASS。
|
||||
> **同日采样有效性校验后抬栈 512→640 words**:`adc_health_report`→`syslog_post` 控制台回显尾把静态
|
||||
> 最坏链推到 **1080 B**(512 words 时余 968 B < 1024 B ISR 底线)→ 抬至 2.5 KB,余 **1480 B / 57%**;
|
||||
@@ -126,7 +126,7 @@ dhara 失败类 +84;RO 另 +208,全是该失败类名表)→ `ER_IROM1`
|
||||
| testTask | `2048*4` | 8KB | 测试套件(产品构建不创建;存储套件深链需要) | 未创建 / 静态 496 B |
|
||||
| defaultTask | `1280*4` | 5KB | FatFS 挂载/探针 + 配置引擎 + syslog + 栈水位探针 | 2152 B(余 41%)/ 静态 **3016 B**(栈余量收口时抬栈 1024→1280,2026-10-12) |
|
||||
| timeSyncTask | `640*4` | 2.5KB | TCP 时间同步 | 616 B(余 50%)/ 静态 **1264 B**(栈余量收口时抬栈 512→640,2026-10-12) |
|
||||
| adcTask | `640*4` | 2.5KB | TPAFE5160 采样消费 + L2 相量 + 有效性校验(TIM3 1 kHz 节拍,B1→L2→「采样有效性校验」 2026-10-11) | **952 / 2560**(余 1608 B / 62%,台架 `@test` 实测 2026-10-11);静态 **1320 B**(2026-10-12 复测,L3 接线后) |
|
||||
| adcTask | `640*4` | 2.5KB | TPAFE5160 采样消费 + 全周傅氏相量 + 有效性校验(TIM3 1 kHz 节拍,B1→全周傅氏相量→「采样有效性校验」 2026-10-11) | **952 / 2560**(余 1608 B / 62%,台架 `@test` 实测 2026-10-11);静态 **1320 B**(2026-10-12 复测,保护判据接线后) |
|
||||
| iec104Task | `640*4` | 2.5KB | IEC104 上行服务(2404 监听 + link 状态机,B4 2026-10-12) | 未上板 / 静态 **1456 B**(拆链→重建监听→net_bind→SPI 故障→日志尾,日志主导;512 words 时余 592 B < ISR 底线 → 抬至 640,余 1104 B / 43%) |
|
||||
| protectTask | `512*4` | 2KB | 保护判据节拍(prot_elm_run 消费者 + 「自检失败闭锁」采样闭锁,B5 2026-10-12) | 未上板 / 静态 **872 B**(float 判据 + phasor 快照 + 日志尾,余 1176 B / 57%) |
|
||||
| idle(内核) | `configMINIMAL_STACK_SIZE=128` | 0.5KB | 空闲 | 未观测(未取句柄) |
|
||||
|
||||
@@ -94,5 +94,5 @@ UI 16 KB / RTOS 堆 56 KB / 应用 8 KB**。归集口径(按 `.map` 对象名
|
||||
| 日期 | 变更 | 原因 / 出处 |
|
||||
|---|---|---|
|
||||
| 2026-10-12 | 建档:三件套落地(本台账 + `scripts/ram_baseline.py` + `scripts/ram_baseline.tsv` + pre-commit `mem-budget` 钩子) | 登记簿 N-27 前半 |
|
||||
| 2026-10-12 | **RTOS 堆配额 48 KB → 56 KB**(`QUOTAS` 同步) | B5 protectTask 立项:iec104Task(2.5KB)+protectTask(2KB)+TCB 入堆后 48KB 池 min_ever 预估跌破 3,072 B 告警线 → `.ioc` L1 参数 `configTOTAL_HEAP_SIZE` 49152→57344(CCM 水位 75.3%→87.9%,仍 <92% 门禁;CCM 空闲降至 ≈8 KB)。连带影响见 §3 迁 CCM 后半链注记 |
|
||||
| 2026-10-12 | **RTOS 堆配额 48 KB → 56 KB**(`QUOTAS` 同步) | B5 protectTask 立项:iec104Task(2.5KB)+protectTask(2KB)+TCB 入堆后 48KB 池 min_ever 预估跌破 3,072 B 告警线 → `.ioc` 语义取数与有效性参数 `configTOTAL_HEAP_SIZE` 49152→57344(CCM 水位 75.3%→87.9%,仍 <92% 门禁;CCM 空闲降至 ≈8 KB)。连带影响见 §3 迁 CCM 后半链注记 |
|
||||
| 2026-10-12 | **任务栈 +1536 B(堆内用量,配额 56 KB 不变)**:defaultTask 1024→1280 words(+1024 B)、timeSyncTask 512→640 words(+512 B);产品任务栈合计 37,632→39,168 B | 登记簿 N-33 栈收口:B7 定值持久化把 defaultTask 静态链推到 3016 B(余 1080 < 30% 线)、timeSyncTask 链 1264 B(余 784 < ISR 底线 1024);B6 台架背书 min_ever=10000 → 抬后实测 `heap free=16400 / min_ever=8464`(与预算 −1536 完全吻合,>3072 告警线);`stack_report` 9 任务 0 FAIL + `@test` PASS,见 `RAM使用分析与优化方案.md` §1.4 |
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
关键事实:
|
||||
|
||||
1. **CCM 对 CPU 是全速内存**。Cortex-M4 无 L1 cache,"CCM 是慢内存"的直觉只适用于带 cache 的核(M7/L4/H7 的非 cacheable 旁路),**在本芯片上不成立**——任何"按速度分配区域"的论证对本文档无效。
|
||||
1. **CCM 对 CPU 是全速内存**。Cortex-M4 无 语义取数与有效性 cache,"CCM 是慢内存"的直觉只适用于带 cache 的核(M7/出口与记录/H7 的非 cacheable 旁路),**在本芯片上不成立**——任何"按速度分配区域"的论证对本文档无效。
|
||||
2. **DMA 对 CCM 地址的传输静默不落地**。2026-09-21 首轮 CCM 实验实证:以 CCM 上栈缓冲(dhara meta 132B / is_free 64B)为 DMA 源/目的时传输不生效,引发 FTL 重格式化循环与幻影坏块。此后 DMA 阈值提至 1024B 消除。**工程规则按"DMA 不可达 CCM"执行,不论数据手册如何表述。**
|
||||
3. CCM 存在性已用 `ST-LINK_CLI -r32 0x10000000` 本机实测可读写;**克隆片可能缺 SRAM3,换料必须重测并回退布局**。
|
||||
4. 工程不进入 Stop/Standby 低功耗模式,两区域掉电保留行为无差异,不构成分配判据。
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
## 4. 内容分配规则
|
||||
|
||||
- **R1(CCM 驻留)**:CCM 只放"**CPU-only 且损坏即致命、无自愈**"的内存。当前唯一驻留者 = **FreeRTOS 堆**(`heap_4.o`,56KB——2026-10-12 B5 由 48KB 扩容,`.ioc` L1 参数 `configTOTAL_HEAP_SIZE=57344`;全部任务栈/队列/定时器)。scatter 的 RW_CCM 节**不得**再列其他对象;任何新增必须经 §5 式裁决并走 §7 完整验证阶梯。
|
||||
- **R1(CCM 驻留)**:CCM 只放"**CPU-only 且损坏即致命、无自愈**"的内存。当前唯一驻留者 = **FreeRTOS 堆**(`heap_4.o`,56KB——2026-10-12 B5 由 48KB 扩容,`.ioc` 语义取数与有效性参数 `configTOTAL_HEAP_SIZE=57344`;全部任务栈/队列/定时器)。scatter 的 RW_CCM 节**不得**再列其他对象;任何新增必须经 §5 式裁决并走 §7 完整验证阶梯。
|
||||
- **R2(DMA 缓冲)**:只允许文件作用域静态缓冲,必须落 SRAM。**三层防线缺一不可**:
|
||||
- **窗口防线(编译期)**:DMA 白名单窗口 `GD5F_DMA_RAM_BASE/END`(0x20000000~0x20020000,须与 scatter `RW_IRAM1` 一致)与 CCM 窗口**永不得重叠**,另锁死阈值契约 `132 ≤ GD5F_DMA_THRESHOLD < GD5F_PAGE_SIZE`——两条都用项目惯用的**负数组 typedef 断言**(AC5 不支持 C11 `_Static_assert`),有人改窗口常量或阈值当场编译失败(`gd5f2gq5ue.h`)。
|
||||
- **尺寸防线**:GD5F DMA 阈值 `GD5F_DMA_THRESHOLD=1024`(>1024B 才走 DMA;阈值以下一律 CPU 轮询)。取值须 ≥ 存储路径上可能出现在任务栈的最大缓冲(dhara meta 132B、`dhara_nand_is_free` 64B)、且 < 页大小(2048,保住页级热路径的 DMA)。
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# ADC 采样节拍设计说明(TIM3 1 kHz 同源硬件节拍)
|
||||
|
||||
> **模块名称**:ADC 采样节拍与消费链——TIM3 节拍源(`Src/tim.c`)、更新事件回调(`Src/main.c`)、
|
||||
> L1 采集层(`App/algo/adc_input.c`)、消费者 `adcTask`(`App/task/adc_task.c`)。
|
||||
> 语义取数与有效性层(`App/algo/adc_input.c`)、消费者 `adcTask`(`App/task/adc_task.c`)。
|
||||
> **文档定位**:**现状设计说明**——这条链当前由谁产生节拍、同一个硬件事件如何驱动两片转换器、
|
||||
> STM32 侧怎么搬运、消费者怎么取数、为什么这样配置、边界与代价在哪里。**历史演进、方案对比、
|
||||
> 门禁与台架复测记录、修订日志一律不写进本文**(需要时查 git 历史)。
|
||||
> **状态**:已落地并经真机验证;下游 = L2 相量 / 测频 → L3 保护判据(`docs/算法/采集与算法层设计说明.md`)。
|
||||
> **状态**:已落地并经真机验证;下游 = 全周傅氏相量 / 测频 → 保护判据(`docs/算法/采集与算法层设计说明.md`)。
|
||||
> **相关文档**:
|
||||
> `docs/硬件平台/ADC通道映射说明.md`(网名 ↔ 板级 `ADCn` ↔ 转换器通道号,唯一权威)
|
||||
> `docs/算法/继电保护功能复现规划.md` §3.1「周期 CONVST 重触发」
|
||||
@@ -54,10 +54,10 @@ flowchart TD
|
||||
DMA --> TAKE["stm32_take():取上一拍完成的半区"]
|
||||
TASK --> POLL
|
||||
TASK --> TAKE
|
||||
POLL --> L2["L2 相量 / 测频 → 采样环<br/>仅确有新帧时压环"]
|
||||
TAKE --> L2
|
||||
L2 --> OUT["下游:L3 保护判据(protectTask)"]
|
||||
L2 --> HB["task_wd_beat(TASK_WD_ADC) + 10 s 心跳"]
|
||||
POLL --> 全周傅氏相量["全周傅氏相量 / 测频 → 采样环<br/>仅确有新帧时压环"]
|
||||
TAKE --> 全周傅氏相量
|
||||
全周傅氏相量 --> OUT["下游:保护判据(protectTask)"]
|
||||
全周傅氏相量 --> HB["task_wd_beat(TASK_WD_ADC) + 10 s 心跳"]
|
||||
```
|
||||
|
||||
**关键性质**:
|
||||
@@ -85,10 +85,10 @@ flowchart TD
|
||||
| `App/app/app_main.c`(步骤 6) | 唯一的节拍启动点 `HAL_TIM_Base_Start_IT(&htim3)` | 手写;顺序约束见 §3.4 |
|
||||
| `Src/adc.c` | ADC1 触发与 DMA 参数 + `adc1_calibrate()` | 参数在生成区;自校准在 `USER CODE` 区(§4.2) |
|
||||
| `Src/dma.c` | DMA2_Stream4 参数与 NVIC 优先级 | 生成区;**改流后必回本页核对**(§4.3) |
|
||||
| `App/algo/adc_input.c` | L1:`adc_input_poll()` / `adc_input_raw()`、半区推导、DMA 完成回调、四类故障计数 | 手写 |
|
||||
| `App/algo/adc_input.c` | 语义取数与有效性:`adc_input_poll()` / `adc_input_raw()`、半区推导、DMA 完成回调、四类故障计数 | 手写 |
|
||||
| `App/task/adc_task.c` / `adc_task.h` | 消费者主循环、`adc_tick_irq_notify()` 与就绪门、10 s 心跳统计 | 手写 |
|
||||
| `Src/freertos.c` | `adcTask` 栈 640 words、优先级 `osPriorityAboveNormal` | 手写于 `USER CODE` 区(不在 `.ioc`);改栈前后各跑一次 `stack_report.py` |
|
||||
| `App/task/protect_task.c` | 下游消费者:20 ms 判据节拍取 L2 相量快照 | → `docs/算法/采集与算法层设计说明.md` §9 |
|
||||
| `App/task/protect_task.c` | 下游消费者:20 ms 判据节拍取 全周傅氏相量快照 | → `docs/算法/采集与算法层设计说明.md` §9 |
|
||||
|
||||
---
|
||||
## 3. 节拍源:TIM3 配置与启动
|
||||
|
||||
@@ -37,14 +37,14 @@
|
||||
|
||||
| IOA | 点 | 来源 | V0.1 状态 |
|
||||
|---|---|---|---|
|
||||
| 0x4011 | 1Ua | L2 遥测快照槽 `ADC_SEM_UA`(104 改读快照) | ✅ 有效 |
|
||||
| 0x4011 | 1Ua | 测频与遥测快照槽 `ADC_SEM_UA`(104 改读快照) | ✅ 有效 |
|
||||
| 0x4012/0x4013 | 1Ub/1Uc | 同表槽位;STM32 侧削顶(`docs/算法/继电保护功能复现规划.md` §1.6) | ❌ 发 IV——**品质驱动**(快照 CLIPPED 位映射,非点表绑死;V0.2 消除双转换器无共同采样触发后零改动自动启用) |
|
||||
| 0x4014 | 1U0 | 快照槽 `ADC_SEM_UN`(外部零序专用通道) | ✅ 有效 |
|
||||
| 0x4015 | 1Ia | 快照槽 `ADC_SEM_IA` | ✅ 有效 |
|
||||
| 0x4016~0x4018 | 1Ib/1Ic/1I0 | 同 Ub/Uc:绑槽 + 品质驱动 | ❌ 发 IV |
|
||||
| 0x401D | 1f 频率 | 快照 `freq_hz`(频率点绑定;B8 自适应窗测频 `freq_get()` 同源) | ✅ 随测频收敛生效;`freq_valid()==0` → IV(该点 DoD 原句) |
|
||||
|
||||
- **数据源 = L2 遥测快照**(`App/algo/meas.h`,「数据可信」遥测快照发布与 104 消费):200 ms 基波有效值
|
||||
- **数据源 = 测频与遥测快照**(`App/algo/meas.h`,「数据可信」遥测快照发布与 104 消费):200 ms 基波有效值
|
||||
+ 每点品质,104 与 UI 共用同一份上游;读数单位 = ADC 引脚电压(eng=0,`App/algo/adc_cal`
|
||||
折算层 2026-10-25 落地;二次值等两点标定置 VALID)。槽位值/品质整体透传,本层
|
||||
**不再自行判新旧**(快照 `seq` 仅供 COV 去重)。
|
||||
@@ -266,6 +266,6 @@
|
||||
| 2026-10-12 | **B7 台架腿闭环**(§7 台架行回填):主站工具加 `--b7-pre/--b7-post/--b7-mark/--b7-check` 四模式(中间 ST-LINK 复位);pre 21/21(YK12 OFF→低定值不动作 / ON→YX15·16 即动作)、post 13/13(**压板退出态跨复位保持** + 重启后联动在位)、mark/check 4/4+4/4(**非默认定值 7.5 跨复位保持**);开机日志 `[CFG] prot set loaded (/prot_set.bin)`;证据 `../测试说明/boot_log_data/20261012_B7_*` |
|
||||
| 2026-10-25 | **标定折算落地联动(下游常数按工程量重定)**:遥测读数由原始码值改工程量(§3.1 注已重写);死区按额定 0.5% 逐点重定(0.5 V / 0.005 A / 0.5 Hz),§8 第 4 条改「已落地,8020H 段仍归运行参数段」 |
|
||||
| 2026-10-25 | **运行参数段(道D,「数据可信」M6-①)**:新增 `App/algo/run_par.c/h`——遥测死区 9 点真源收编([run_par] 段 9 键 int32 毫单位落盘,工厂默认 = 下游常数按工程量重定的档位;pts 层 s_yc_db 副本删除、set/get 转转发壳并保留清确认计数语义);104 **0x8020~0x8058 读写映射**(§3.4 新表:逐项地址本仓自定、送检点表到位后替换常量段;0x8027~0x802A 永不覆盖,路由 run_par 先 prot_set 后);**k/b 系数覆盖 = adc_cal_set 代理**(合法带/越带留痕复用,run_par 不存系数);持久化走新事件位 `SYS_EVT_RUN_PAR_SAVE`(1<<8) 整档外科 save;单测 test/host/run_par 新建(TC-RUNPAR-001~008,67 断言)+ iec104 套 +TC-IEC104-029 路由钉(141 断言);台架/送检腿待排窗 |
|
||||
| 2026-10-25 | **104 改读快照与频率点绑定(道D,「数据可信」M5/M6)**:YC 板端源改读 L2 遥测快照(削顶五路从点表绑死 -1 改为**槽位绑定 + 快照品质 CLIPPED→IV**,V0.2/N-18 零改动启用);`0x401D` 绑频率源(`freq_valid()==0` → IV);死区改运行时副本 + `iec104_pts_yc_set_deadband()`(运行参数段接线点);COV 遥测腿 = 死区连续 2 点确认(快照 `seq` 去重)+ 品质翻转直报;`iec104_pts_src_t` 表尾追加 `yc_read_ex`(旧源退路语义不变);单测 97→127(TC-IEC104-025~028 走真实 L2 链);台架腿(总召读回一致 / 频率 ±0.01 Hz)待排窗——主站工具已记 val+qds,无需改工具 |
|
||||
| 2026-10-25 | **104 改读快照与频率点绑定(道D,「数据可信」M5/M6)**:YC 板端源改读 测频与遥测快照(削顶五路从点表绑死 -1 改为**槽位绑定 + 快照品质 CLIPPED→IV**,V0.2/N-18 零改动启用);`0x401D` 绑频率源(`freq_valid()==0` → IV);死区改运行时副本 + `iec104_pts_yc_set_deadband()`(运行参数段接线点);COV 遥测腿 = 死区连续 2 点确认(快照 `seq` 去重)+ 品质翻转直报;`iec104_pts_src_t` 表尾追加 `yc_read_ex`(旧源退路语义不变);单测 97→127(TC-IEC104-025~028 走真实 全周傅氏相量链);台架腿(总召读回一致 / 频率 ±0.01 Hz)待排窗——主站工具已记 val+qds,无需改工具 |
|
||||
| 2026-10-12 | **B9 时标 SOE**:自发单点 YX 换 **M_SP_TB_1(30)**(SIQ+CP56,§3.2 注;总召/周期保持 NA 型);link cfg 增 `epoch_ms` 时标源(NULL/无效 → IV 如实);serv 绑 `sys_clock`(秒域 → ms 域=秒×1000);主站工具解析 type 30/1 双型;单测 iec104 94→97(TB 时标 + IV 路径,两种类型都断言);台架腿见 §7 B9 行;落盘侧见 `App/log/README.md` soe 节 |
|
||||
| 2026-10-26 | **道G task-8:`[comm]` 段落地(「UI 补齐」波次里的非 UI 前置项)**——ca/端口从写死改 `[comm]` 可配(getter 合法带自愈,键表 → `docs/子系统设计/网络配置说明.md` §3.6);`iec104_comm_init()` 内核前注册于 `app_main_init`(先注册后 load 契约,同 [adc_cal]/[run_par]);生效 = 改后重启(ca 任务启动读一次;port 下次重 bind 自然生效),不挂回调不新增事件位;§5/§8 同步销项,**主站地址不做**的理由登记 §8 第 8 条;死 define `IEC104_PORT` 删除(零 .c 消费);`IEC104_SERV_PORT` 降为快照兼容出口(真源 getter,task-9 切 ui_data_feed);单测 = `test/host/iec104` TC-IEC104-031~033(套件 174/174 PASS)+ `test/host/iec104_serv` TC-I104SRV-001b/c(37/37 PASS)+ `test/host/cfg_file` TC-CONFIG-056/057(207/207 PASS)|
|
||||
|
||||
@@ -23,8 +23,8 @@ HAL_Init → SystemClock_Config → MX_GPIO/DMA/USART1/SPI2/SPI1/I2C1/UART4/IWDG
|
||||
├─ sd2506_init() → sys_clock_init() // 时间子系统优先(墙钟基准)
|
||||
├─ rs485_init()
|
||||
├─ gd5f2gq5ue_init() // NAND 底层驱动(含 BBT 全片扫描 + ECC 使能)
|
||||
├─ tpafe5160_init() → adc_input_init() // TPAFE + L1 采集层(语义映射 + ADC1 DMA)
|
||||
├─ phasor_init() / freq_init() / prot_set_init() + prot_elm_init() // L2/L3 内核前就绪
|
||||
├─ tpafe5160_init() → adc_input_init() // TPAFE + 语义取数与有效性层(语义映射 + ADC1 DMA)
|
||||
├─ phasor_init() / freq_init() / prot_set_init() + prot_elm_init() // 全周傅氏相量/保护判据内核前就绪
|
||||
├─ SD2506 诊断(ID/时间/温度/电池)
|
||||
└─ HAL_TIM_Base_Start_IT(&htim3) // 启动 TIM3 1kHz 采样节拍
|
||||
→ osKernelInitialize() → MX_FREERTOS_Init() → osKernelStart() // FreeRTOS 启动
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
| `timeSyncTask` | 墙钟时间同步 | `osEventFlagsWait(SYS_EVT_NET_READY, … \| osFlagsNoClear)` 后开始同步 |
|
||||
| `uiTask` | LVGL UI(`ui_port_init` → `ui_menu_init` → `ui_net_sink` :7003 → 10ms 刷新) | `osEventFlagsWait(SYS_EVT_NET_READY, osFlagsWaitAny \| osFlagsNoClear, osWaitForever)` |
|
||||
| `iec104Task` | IEC 60870-5-104 上行(:2404 监听 + link 状态机,B4) | `osEventFlagsWait(SYS_EVT_NET_READY, … \| osFlagsNoClear)` |
|
||||
| `adcTask` | TIM3 1kHz 采样节拍**纯消费者**(`adc_input_poll()`,L1/L2 取数,不做保护运算) | **无事件位依赖**:TIM3 ISR 内 `adc_tick_irq_notify()` 直接唤醒(TIM3 比调度器早 ≈100ms 启动,ISR 侧只能走该通知函数) |
|
||||
| `protectTask` | 保护判据 20ms 节拍(`prot_elm_run()`,L3,B5) | 无(节拍自持,不依赖网络) |
|
||||
| `adcTask` | TIM3 1kHz 采样节拍**纯消费者**(`adc_input_poll()`,语义取数与有效性/全周傅氏相量取数,不做保护运算) | **无事件位依赖**:TIM3 ISR 内 `adc_tick_irq_notify()` 直接唤醒(TIM3 比调度器早 ≈100ms 启动,ISR 侧只能走该通知函数) |
|
||||
| `protectTask` | 保护判据 20ms 节拍(`prot_elm_run()`,保护判据,B5) | 无(节拍自持,不依赖网络) |
|
||||
| `rs485_task` | RS-485 通信(任务体已实现) | **未在 `freertos.c` 创建**(B2 暂缓,见 `docs/任务规划/暂缓-RS485.md`) |
|
||||
|
||||
### 1.2 改造前(已废弃)的依赖管理手段
|
||||
@@ -235,7 +235,7 @@ if (sys_evtHandle != NULL) {
|
||||
| 6 | `RS485 init: OK (UART4, DE=PA15)` | `rs485_init()` | UART4 / DE 引脚配置 |
|
||||
| 7 | `NAND init: OK/...` | `gd5f2gq5ue_init()` | **BBT 全片扫描**——启动段最耗时的一步,卡住多为此处(SPI2 与片选) |
|
||||
| 8 | `ADC init: OK/TIMEOUT` | `tpafe5160_init()` | TPAFE5160 SPI 通信 |
|
||||
| 9 | `ADC input layer init: OK` | `adc_input_init()`(L1 语义映射 + ADC1 DMA 武装) | 映射自检 FAILED / DMA arm FAILED(两条 `DBG_ERROR` 即此步;失败时无 OK 行) |
|
||||
| 9 | `ADC input layer init: OK` | `adc_input_init()`(语义取数与有效性层的语义映射 + ADC1 DMA 武装) | 映射自检 FAILED / DMA arm FAILED(两条 `DBG_ERROR` 即此步;失败时无 OK 行) |
|
||||
| 10 | `phasor layer init: OK (inst=N)` | `phasor_init()` | 纯 RAM(不会卡;实例数不符 = 相量层配置问题) |
|
||||
| 11 | `freq layer init: OK` | `freq_init()` | 纯 RAM(不会卡) |
|
||||
| 12 | `protection init: OK (set=N elm=N)` | `prot_set_init()` + `prot_elm_init()` | 纯 RAM(不会卡) |
|
||||
|
||||
+7
-7
@@ -23,7 +23,7 @@
|
||||
|---|---|---|---|
|
||||
| ① 业务层 | `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/*` `algo/*`(L1~L3) `lftpd` `time_sync` |
|
||||
| ③ 基础服务层 | `App/`、`Drivers/BSP/NET/lftpd/` | 应用侧服务与编排 | `app_main` `sys_events` `app_cfg` `task/*` `algo/*`(语义取数与有效性~保护判据) `lftpd` `time_sync` |
|
||||
| ④ 中间件层 | `Drivers/BSP/NET/`、`Lib/`、`App/util/` | 通用库 / 协议栈 | `net_socket` `net_select` `net_events` `net_pending` `net_listener` `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 |
|
||||
@@ -36,7 +36,7 @@
|
||||
| `ui_page_net_cfg` → `net_cfg` | 网口设置页显示/编辑 RAM 副本(不直接触 CH395F SPI) |
|
||||
| `netTask` → `net_cfg` → `net_socket` | 上电只读 RAM 副本(defaultTask 已在屏障前 `net_cfg_load`)→ `net_init(ip,mask,gw,mac)`;配置保存后经 `SYS_EVT_NET_RECONFIG` 按**网络代次号**重建(新 IP 免重启生效) |
|
||||
| `net_socket` → `net_events` / `net_listener` / `net_pending` | socket 宿主调三个内部模块:芯片边沿事件 + 100ms 周期对账 / 监听生命周期(重建请求登记 + 唯一执行)/ 阻塞 recv·send 挂起请求表 |
|
||||
| `App/algo/*`(L1→L2→L3) → `adc_task` / `protect_task` | 采集与算法层为纯计算:adcTask 消费 L1/L2(TIM3 1kHz 节拍)、protectTask 消费 L3(20ms 判据节拍) |
|
||||
| `App/algo/*`(语义取数与有效性→全周傅氏相量→保护判据) → `adc_task` / `protect_task` | 采集与算法层为纯计算:adcTask 消费 语义取数与有效性/全周傅氏相量(TIM3 1kHz 节拍)、protectTask 消费 保护判据(20ms 判据节拍) |
|
||||
| `lftpd` / `net_cfg` / 测试 → `FatFs` → `nand_ftl` → `gd5f2gq5ue` | 文件与配置落 NAND |
|
||||
| `ui_net_sink` / `time_sync` → `net_socket` | 远程显示 :7003 / 对时 :8888 共用同一 TCP 栈 |
|
||||
| `ui_menu` → `ui_content_page` → `ui_page_*` | 框架 + 页面插件(描述符解耦) |
|
||||
@@ -59,7 +59,7 @@
|
||||
| `testTask` | 8192 | BelowNormal | 测试套件入口(`test/board/test_config.h` 选择)。**产品构建不创建**:CubeMX 生成区无条件建后,`MX_FREERTOS_Init()` 在未选套件时(`!TEST_SUITE_SELECTED`)立即 `vTaskDelete` 回收其 8KB CCM 栈(2026-10-04) | `start_test_task` |
|
||||
| `uiTask` | 16384 | BelowNormal | 等网络 → `ui_port_init`/`ui_menu_init`/`ui_standby_init`(空闲 60s 切待机屏)/`ui_net_sink` → 10ms 刷新 | `ui_task_func` |
|
||||
| `timeSyncTask` | 2560 | Normal | 等网络 → TCP :8888 收 PC 推送时间 → 写 RTC | `time_sync_task` |
|
||||
| `adcTask` | 2560 | AboveNormal | 纯消费者:`osThreadFlagsWait` 等 TIM3 1kHz 唤醒(ISR 内 `adc_tick_irq_notify` 置位)→ `adc_input_poll()`(TPAFE 原子快照 + STM32 ADC1 DMA 双缓冲)→ L1/L2 消费,不取数不做保护运算 | `adc_task_func` |
|
||||
| `adcTask` | 2560 | AboveNormal | 纯消费者:`osThreadFlagsWait` 等 TIM3 1kHz 唤醒(ISR 内 `adc_tick_irq_notify` 置位)→ `adc_input_poll()`(TPAFE 原子快照 + STM32 ADC1 DMA 双缓冲)→ 语义取数与有效性/全周傅氏相量消费,不取数不做保护运算 | `adc_task_func` |
|
||||
| `iec104Task` | 2560 | Normal | 等网络 → IEC 60870-5-104 上行(:2404 监听 + link 状态机,遥信/遥测/定值区,B4) | `iec104_serv_task` |
|
||||
| `protectTask` | 2048 | Normal | 保护判据 20ms 节拍:`prot_elm_run()` + 「自检失败闭锁」采样故障闭锁 + 定值校验和巡检(B5);不依赖网络,纳入 IWDG `required_mask` | `protect_task` |
|
||||
|
||||
@@ -119,7 +119,7 @@ sequenceDiagram
|
||||
Note over A: 时间子系统优先,使后续日志带时间戳
|
||||
A->>A: sd2506_init() → sys_clock_init()(墙钟基准)
|
||||
A->>A: rs485_init() → gd5f2gq5ue_init()(BBT 扫描)→ tpafe5160_init()
|
||||
A->>A: adc_input_init()(L1 语义映射 + ADC1 DMA)→ phasor_init() → freq_init()<br/>→ prot_set_init() + prot_elm_init()(L3 内核前封存)
|
||||
A->>A: adc_input_init()(语义取数与有效性层的语义映射 + ADC1 DMA)→ phasor_init() → freq_init()<br/>→ prot_set_init() + prot_elm_init()(保护判据内核前封存)
|
||||
A->>A: SD2506 诊断(ID/时间/温度/电池)→ HAL_TIM_Base_Start_IT(&htim3)(1kHz 节拍)
|
||||
A-->>M: "App init OK"
|
||||
M->>K: osKernelStart()
|
||||
@@ -269,7 +269,7 @@ STM32F4-Base/
|
||||
│ └── main.c 入口 → app_main_init → osKernelStart
|
||||
├── App/ 应用层(业务编排,非 CubeMX)
|
||||
│ ├── app/ 启动编排与全局契约:app_main.c(时间子系统优先)、app_cfg.h、sys_events.h
|
||||
│ ├── algo/ 采集与算法层 L1~L3:adc_input / phasor / freq / prot_set / prot_elm
|
||||
│ ├── algo/ 采集与算法层 语义取数与有效性~保护判据:adc_input / phasor / freq / prot_set / prot_elm
|
||||
│ ├── task/ default_task / net_task / ui_task / adc_task / iec104_serv / protect_task / rs485_task*(*未创建,B2 暂缓)
|
||||
│ ├── log/ sys_log 记录引擎(定长 64B;MCU 后端落盘 /log/*.log)
|
||||
│ ├── cfg/ 配置引擎:cfg_file(静态态单任务收敛于 defaultTask)、store(MCU=FreeRTOS 堆)
|
||||
@@ -329,7 +329,7 @@ flowchart LR
|
||||
| 存储架构(NAND/FTL/FatFs) | `docs/架构设计/STM32F4-Base存储架构说明.md` |
|
||||
| NET 阻塞模型(挂起请求表五路语义) | `docs/网络/Net层阻塞模型架构设计.md` |
|
||||
| 网络自愈(监听重建 / 沉降隔离 / 周期对账) | `docs/网络/网络自愈架构设计.md` |
|
||||
| 采集与算法层 L1~L3(**设计与判据**) | `docs/算法/采集与算法层设计说明.md` |
|
||||
| 采集与算法层 语义取数与有效性~保护判据(**设计与判据**) | `docs/算法/采集与算法层设计说明.md` |
|
||||
| 采集与算法层目录索引(文件清单 / 构建测试) | `App/algo/README.md` |
|
||||
| ADC 采样节拍(TIM3 1kHz 同源驱动) | `docs/子系统设计/ADC采样节拍设计说明.md` |
|
||||
| IEC 60870-5-104 上行(:2404) | `docs/子系统设计/IEC104上行设计说明.md` |
|
||||
@@ -368,5 +368,5 @@ flowchart LR
|
||||
| 2026-09-24 → 09-25 | **控制台单写者日志**(09-24 实证驱动:多任务并发日志字符级交错 + HardFault 脏指针直达 UART):4KB 环形缓冲 + defaultTask 唯一发送(行级原子 + 指针可控)+ 内核前/ISR/异常钩子有界直发回退 + `fputc` 收敛到单写者路径;09-24 初版实施于 `Src/usart.c` USER CODE 区,09-25 迁出至 `App/log/console_log.{h,c}`(HAL 生成文件不含应用代码),`dbg_log.h` 改 `#include "console_log.h"`(调用点零改动),`Src/usart.c` 恢复纯 CubeMX 形态;`@build` 0/0 + `@test` PASS;详见 `docs/子系统设计/控制台单写者日志设计说明.md` |
|
||||
| 2026-09-25 | **defaultTask 任务体文件拆分**:`Src/freertos.c` 的 `StartDefaultTask` 任务体(存储 bring-up / 配置引擎属主 / 控制台单写者 attach+drain / syslog 落盘 / LED / 栈水位探针 `stack_probe_poll`)整体迁至 `App/task/default_task.c`(`default_task_func()`,与其余任务文件同址);`freertos.c` 恢复"CubeMX 接线 + 崩溃钩子"形态(719→361 行),`@build` 0/0 复验;栈配置属性仍定义于 `freertos.c`(`stack_report` 数据源不变) |
|
||||
| 2026-10-10 | **删除旧档 NCFG 迁移(栈整改)**:`Drivers/BSP/NETCFG/net_cfg_legacy.{c,h}` 整体移除、`cfg_store_legacy_path()` 撤销,`net_cfg_load` 不再调用 `net_cfg_legacy_migrate()`;旧档 `/cfg/netcfg.bin` 若存在则被忽略(不读、不删、不迁移),配置回落工厂默认。理由:该一次性路径把整条配置写链挂进启动期调用图,defaultTask 静态最坏栈链 +600 B,本仓库无携带旧档的设备。同轮栈整改(未抬栈):defaultTask 静态最坏链 5312 → 2776 B / 实测峰值 3392 → 2152 B、timeSyncTask 1736 → 1024 B,6 任务全 PASS;代价静态 BSS +4,128 B |
|
||||
| 2026-10-14 | **任务面与 NET 内部模块同步现状**:§1.1 补 ④ 中间件层 `net_events`/`net_pending`/`net_listener` 与 ③ 层 `algo/*`(L1~L3)、⑦ 硬件行去重(原两行重复编号且 UART5/TIM7 过期 → UART4/TIM3/ADC1);§1.2 增 NET 三内部模块与 algo→adcTask/protectTask 两条跨层依赖;§2.1 任务表 6 → 9 行(补 adcTask/iec104Task/protectTask,栈值按 `freertos.c` 校准:defaultTask 5120、netTask 3840、 timeSyncTask 2560、adcTask 2560、iec104Task 2560、protectTask 2048 B),栈实测更新至 2026-10-10~14 并注明堆已迁 CCM 扩容 56KB;§3 时序图补 adc_input/phasor/freq/prot_set/prot_elm 内核前初始化与 TIM3 节拍启动、新增 iec104Task/protectTask/adcTask 参与者;§5 网络栈图补三个 NET 内部模块与 iec104_serv 消费者,单客户端恢复窗更新为实测 p50 208 ms,登记 SEND pending 二期与 2026-10-14 FTP 实测;§7 目录树补 `algo/`/`fs/`、iec104_serv/protect_task、NET 三新文件;§9 补 Net 阻塞模型/网络自愈/algo/ADC 节拍/IEC104 五条专项文档索引 |
|
||||
| 2026-10-14 | **任务面与 NET 内部模块同步现状**:§1.1 补 ④ 中间件层 `net_events`/`net_pending`/`net_listener` 与 ③ 层 `algo/*`(语义取数与有效性~保护判据)、⑦ 硬件行去重(原两行重复编号且 UART5/TIM7 过期 → UART4/TIM3/ADC1);§1.2 增 NET 三内部模块与 algo→adcTask/protectTask 两条跨层依赖;§2.1 任务表 6 → 9 行(补 adcTask/iec104Task/protectTask,栈值按 `freertos.c` 校准:defaultTask 5120、netTask 3840、 timeSyncTask 2560、adcTask 2560、iec104Task 2560、protectTask 2048 B),栈实测更新至 2026-10-10~14 并注明堆已迁 CCM 扩容 56KB;§3 时序图补 adc_input/phasor/freq/prot_set/prot_elm 内核前初始化与 TIM3 节拍启动、新增 iec104Task/protectTask/adcTask 参与者;§5 网络栈图补三个 NET 内部模块与 iec104_serv 消费者,单客户端恢复窗更新为实测 p50 208 ms,登记 SEND pending 二期与 2026-10-14 FTP 实测;§7 目录树补 `algo/`/`fs/`、iec104_serv/protect_task、NET 三新文件;§9 补 Net 阻塞模型/网络自愈/algo/ADC 节拍/IEC104 五条专项文档索引 |
|
||||
| 2026-10-28 | **UI 现状补同步(§3 图形/字体节)**:记录 5 页与运行报告页落地绑页,中文字体当前态 122 字/217 字形 → **218 字/313 字形**(本页上一版只同步到 UI 设计文档,架构总览这行漏了);页面数与字数的权威口径仍分别见 docs/UI设计/页面补齐规划.md §2.3 与 docs/UI设计/UI_中文字体生成与配置.md §7 |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# ADC 输入层单元测试说明(主机侧)
|
||||
|
||||
> **模块**:ADC Input Layer(L1 采集与预处理,`App/algo/adc_input.c`)
|
||||
> **模块**:ADC Input Layer(语义取数与预处理,`App/algo/adc_input.c`)
|
||||
> **测试类型**:**主机侧纯逻辑单元测试**(L0.5 层)——在 PC 上离线验证语义通道映射、
|
||||
> STM32 ADC1 的 DMA 乒乓帧消费(含半区选择)、TPAFE 快照消费与取数守卫,零硬件、零烧录、
|
||||
> 毫秒级、不占 MCU 的 RAM。
|
||||
@@ -10,7 +10,7 @@
|
||||
> [`../../AGENTS.md`](../../AGENTS.md)(平台约束 · CubeMX 生成区铁律)、
|
||||
> [`测试开发标准流程.md`](测试开发标准流程.md)(测试分层与门禁总览)、
|
||||
> [`配置文件单元测试说明.md`](配置文件单元测试说明.md)(同层"强符号桩"范本)、
|
||||
> [`相量层单元测试说明.md`](相量层单元测试说明.md)(同批落地的 L2 姊妹篇)、
|
||||
> [`相量层单元测试说明.md`](相量层单元测试说明.md)(同批落地的 全周傅氏相量姊妹篇)、
|
||||
> [`../硬件平台/ADC通道映射说明.md`](../硬件平台/ADC通道映射说明.md)(**语义映射权威口径**)、
|
||||
> [`../算法/继电保护功能复现规划.md`](../算法/继电保护功能复现规划.md)(「STM32 ADC1 启动与扫描」/「通道语义映射」设计依据)、
|
||||
> 快照语义约定的历史审计(属主文档已于 2026-10-15 删除)
|
||||
@@ -97,7 +97,7 @@ test/host/adc_input/adc_input_test.c
|
||||
| 项 | 说明 |
|
||||
|---|---|
|
||||
| **触发范围** | `App/algo/adc_input.c` / `adc_input.h`,或 `test/host/adc_input/**`、`test/host/common/unit_test_harness.py` 变动 |
|
||||
| **门禁层级** | **L0.5 层**(介于 L0 静态门禁与 L1 板端套件之间):主机侧、秒级、纯逻辑 |
|
||||
| **门禁层级** | **L0.5 层**(介于 L0 静态门禁与 语义取数与有效性板端套件之间):主机侧、秒级、纯逻辑 |
|
||||
| **pre-commit 钩子** | `adc-input-unit-test`(本地钩子,`.pre-commit-config.yaml` §7e) |
|
||||
| **汇总行** | `=== ADC Input Tests: 70/70 PASSED (failed=0) ===` |
|
||||
| **与板端测试的关系** | 互补:本单测保证**映射 / 契约 / 故障路径**正确;板端保证 **HAL 配置(Rank 顺序、采样时间、引脚)** 与真机一致 |
|
||||
@@ -263,7 +263,7 @@ test/host/adc_input/adc_input_test.c
|
||||
### 4.3 不覆盖 V0.1 的硬件缺陷(双转换器无共同采样触发)
|
||||
|
||||
V0.1 上 8 路电气量分属两片转换器且**无共同采样触发**(登记簿条目「双转换器无共同采样触发」),本层只做**逐通道独立监视**。
|
||||
"跨转换器相量合成"(线 / 负序 / 零序)不得在本层或 L2 上做——属「线/负序/零序合成」且 V0.1 受限
|
||||
"跨转换器相量合成"(线 / 负序 / 零序)不得在本层或 全周傅氏相量上做——属「线/负序/零序合成」且 V0.1 受限
|
||||
(见 `docs/算法/继电保护功能复现规划.md` §1.6)。
|
||||
|
||||
---
|
||||
|
||||
@@ -61,8 +61,8 @@ git add -f docs/测试说明/boot_log_data/20261012_B9_soe_after_post.bin
|
||||
| 日期 | 构建 / 负载 | 关键 `[STACK]` 水位 | 文件 |
|
||||
|---|---|---|---|
|
||||
| 2026-10-10 | `prod_adc_tim6` / 开机 + 30 s 空载 | `adc` 528/2048(74%);`default` 2164/4096(47%);heap free=15088 min_ever=7152 | `20261010_prod_adc_tim6_boot_log.txt` |
|
||||
| 2026-10-10 | `prod_adc_l1` / 开机 + 30 s 空载 | `adc` **584/2048(71%)**(+56 B,L1 层 adc_input_poll/raw 上链);`default` 2164/4096(47%);heap free=15088 min_ever=7152 | `20261010_prod_adc_l1_boot_log.txt` |
|
||||
| 2026-10-11 | `prod_phasor` / 开机 + 30 s 空载(L2 台架闭环) | `adc` **928/2048(54%)**(+344 B,压环 + `phasor_run` + `log_phasors` 上链);`default` 2152/4096(47%);heap free=15088 min_ever=7152 | `20261011_prod_phasor_boot_log.txt` |
|
||||
| 2026-10-10 | `prod_adc_l1` / 开机 + 30 s 空载 | `adc` **584/2048(71%)**(+56 B,语义取数与有效性层 adc_input_poll/raw 上链);`default` 2164/4096(47%);heap free=15088 min_ever=7152 | `20261010_prod_adc_l1_boot_log.txt` |
|
||||
| 2026-10-11 | `prod_phasor` / 开机 + 30 s 空载(全周傅氏相量台架闭环) | `adc` **928/2048(54%)**(+344 B,压环 + `phasor_run` + `log_phasors` 上链);`default` 2152/4096(47%);heap free=15088 min_ever=7152 | `20261011_prod_phasor_boot_log.txt` |
|
||||
| 2026-10-11 | `prod_adc_health` / 开机 + 30 s 空载(L1-6 + 抬栈 640 words) | `adc` **952/2560(62%)**(静态最坏链 1080 B,`adc_health_report`→`syslog_post` 回显尾);`default` 2152/4096(47%);heap free=14576 **min_ever=6640**(抬栈 -512 B,符合预算) | `20261011_prod_adc_health_boot_log.txt` |
|
||||
| 2026-10-12 | `prod`(HEAD d3107f3,B4/B5 验收窗口 B6)/ 开机 + 30 s 空载 | **首采**:`iec104` 424/2560(83%);`protect` 828/2048(59%,free_min 1220);新 56 KB 堆 heap free=17936 **min_ever=10000**(>3072 告警线,无 `[HEAP]` 告警);⚠ **@test FAIL(缺陷证据快照)**:`protect task start` 锚点行字节级交错损坏(`st[art: cycle=220ms elm=70`,两次开机同形复现)= protectTask 违反控制台写者注册前门控纪律(`控制台单写者日志设计说明.md` §3.4),其余 8 Required / 零 `[ERR]` / 锚点×1 / 回读一致全过;**缺陷已修**(启动行改 writer-ready 首拍补打),修复后 PASS 见下行 | `20261012_B6_prod_boot_log_PROTECT_MISS.txt` |
|
||||
| 2026-10-12 | `prod`(B7 `1fe163b` + B6 门控修复)/ 开机 + 30 s 空载(**B6 复测 PASS**) | `protect` 828/2048(59%,free_min 1220);`iec104` 424/2560(83%);heap free=17936 **min_ever=10000**(**N-33 抬栈 min_ever 背书就绪**);锚点行完好 `cycle=20ms elm=7`(+577 ms,写者 attach 后首拍);零 `[ERR]`、采样闭锁不误报 | `20261012_B6_prod_boot_log.txt` |
|
||||
|
||||
+12
-12
@@ -1,6 +1,6 @@
|
||||
# 相量层单元测试说明(主机侧)
|
||||
|
||||
> **模块**:Phasor Layer(L2 相量计算,`App/algo/phasor.c` + `App/algo/sample_ring.c`)
|
||||
> **模块**:Phasor Layer(全周傅氏相量计算,`App/algo/phasor.c` + `App/algo/sample_ring.c`)
|
||||
> **测试类型**:**主机侧纯逻辑单元测试**(L0.5 层)——在 PC 上离线验证全周傅氏相量计算与
|
||||
> 采样环缓冲,零硬件、零烧录、毫秒级、不占 MCU 的 RAM。
|
||||
> **状态**:✅ 已落地(57 用例,`/W4` 0 告警,已挂 pre-commit 钩子)
|
||||
@@ -8,10 +8,10 @@
|
||||
> **关联文档**:
|
||||
> [`../../AGENTS.md`](../../AGENTS.md)(平台约束)、
|
||||
> [`测试开发标准流程.md`](测试开发标准流程.md)(测试分层与门禁总览)、
|
||||
> [`ADC输入层单元测试说明.md`](ADC输入层单元测试说明.md)(同批落地的 L1 姊妹篇)、
|
||||
> [`ADC输入层单元测试说明.md`](ADC输入层单元测试说明.md)(同批落地的 语义取数与有效性姊妹篇)、
|
||||
> [`../算法/傅氏算法详解.md`](../算法/傅氏算法详解.md)(**系数约定权威口径** §2.3)、
|
||||
> [`../算法/继电保护功能复现规划.md`](../算法/继电保护功能复现规划.md)(§3.2 L2 设计点 / §10.2 术语表)、
|
||||
> [`../硬件平台/ADC通道映射说明.md`](../硬件平台/ADC通道映射说明.md)(L1 输入口径 / 「双转换器无共同采样触发」约束)
|
||||
> [`../算法/继电保护功能复现规划.md`](../算法/继电保护功能复现规划.md)(§3.2 全周傅氏相量设计点 / §10.2 术语表)、
|
||||
> [`../硬件平台/ADC通道映射说明.md`](../硬件平台/ADC通道映射说明.md)(语义取数与有效性输入口径 / 「双转换器无共同采样触发」约束)
|
||||
|
||||
---
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
### 1.1 为什么单独做主机侧单测
|
||||
|
||||
`App/algo/` 是本项目**首个纯算法层**(L1/L2 落点)——**无寄存器、无 RTOS、无文件 / 外设依赖**,
|
||||
`App/algo/` 是本项目**首个纯算法层**(语义取数与有效性/全周傅氏相量落点)——**无寄存器、无 RTOS、无文件 / 外设依赖**,
|
||||
因此天然适合离线穷举。板端套件(`test/board/`)**无法验证本层的核心判据**:
|
||||
|
||||
- 板端**无信号源**,无法注入已知**幅值 / 相位 / 频率**的标准波形,因而无法验证
|
||||
@@ -35,8 +35,8 @@
|
||||
|
||||
```
|
||||
test/host/phasor/phasor_test.c
|
||||
├── #include "sample_ring.c" ← 生产源文件(App/algo/),原样纳入(采样环,L2 输入)
|
||||
└── #include "phasor.c" ← 生产源文件(App/algo/),原样纳入(相量计算,L2 核心)
|
||||
├── #include "sample_ring.c" ← 生产源文件(App/algo/),原样纳入(采样环,全周傅氏相量输入)
|
||||
└── #include "phasor.c" ← 生产源文件(App/algo/),原样纳入(相量计算,全周傅氏相量核心)
|
||||
```
|
||||
|
||||
`include_dirs` 只需 `App/algo` + 本目录。源文件被纳入同一编译单元,故**静态量亦可直接观测**
|
||||
@@ -54,7 +54,7 @@ test/host/phasor/phasor_test.c
|
||||
术语权威见 `docs/算法/继电保护功能复现规划.md` §10.2:
|
||||
`{fRe, fIm, fAm, fAmSQ}` = 实部 / 虚部 / **幅值** / **有效值**。
|
||||
|
||||
> 采样参数:N = 20 点/周波 @ 50 Hz → 1000 Hz,保护节拍 1 ms(与 L1 采样节拍同源)。
|
||||
> 采样参数:N = 20 点/周波 @ 50 Hz → 1000 Hz,保护节拍 1 ms(与 语义取数与有效性采样节拍同源)。
|
||||
> 系数表为**离线生成的 float 常量**(运行期不调 `sinf` / `cosf`),故主机侧与 MCU 侧
|
||||
> 使用**逐位相同**的系数——这是本单测结论能外推到真机的前提。
|
||||
|
||||
@@ -84,7 +84,7 @@ test/host/phasor/phasor_test.c
|
||||
| 项 | 说明 |
|
||||
|---|---|
|
||||
| **触发范围** | `App/algo/phasor.c` / `phasor.h`、`App/algo/sample_ring.c` / `sample_ring.h`,或 `test/host/phasor/**`、`test/host/common/unit_test_harness.py` 变动 |
|
||||
| **门禁层级** | **L0.5 层**(介于 L0 静态门禁与 L1 板端套件之间):主机侧、秒级、纯逻辑 |
|
||||
| **门禁层级** | **L0.5 层**(介于 L0 静态门禁与 语义取数与有效性板端套件之间):主机侧、秒级、纯逻辑 |
|
||||
| **pre-commit 钩子** | `phasor-unit-test`(本地钩子,`.pre-commit-config.yaml` §7d) |
|
||||
| **汇总行** | `=== Phasor Tests: 57/57 PASSED (failed=0) ===` |
|
||||
| **与板端测试的关系** | 互补:本单测保证**算法正确性**;板端保证 **1 kHz 采样节拍与 TPAFE 快照链路**(「周期 CONVST 重触发」/「TPAFE 快照消费」)正常 |
|
||||
@@ -123,11 +123,11 @@ test/host/phasor/phasor_test.c
|
||||
|---|---|---|
|
||||
| **TC-PHASOR-007** | 幅值误差:50 Hz ≤ 0.1%、±1 Hz ≤ 1.5%、±2 Hz ≤ 3%(**最坏相位**) | 「相量有效值输出」/「等周波采样(软件测频 + 调频闭环)」依据 |
|
||||
|
||||
### 2.5 L2 输入采样环(`sample_ring.c`)
|
||||
### 2.5 全周傅氏相量输入采样环(`sample_ring.c`)
|
||||
|
||||
| 用例 | 断言 | 设计点 |
|
||||
|---|---|---|
|
||||
| **TC-PHASOR-010** | `init` 清填充与帧计数;未攒满取窗 → -2;入环后取窗**按时序**(老 → 新);通道之间**互相独立**;填充量饱和于 `DEPTH` 但帧计数**不**饱和;回绕后取窗 == 最后 N 个值(有序);参数守卫:`n=0` / `n>DEPTH` / 越界通道 / `NULL out` / `NULL frame` / 错帧长 均拒绝 | L2 输入 |
|
||||
| **TC-PHASOR-010** | `init` 清填充与帧计数;未攒满取窗 → -2;入环后取窗**按时序**(老 → 新);通道之间**互相独立**;填充量饱和于 `DEPTH` 但帧计数**不**饱和;回绕后取窗 == 最后 N 个值(有序);参数守卫:`n=0` / `n>DEPTH` / 越界通道 / `NULL out` / `NULL frame` / 错帧长 均拒绝 | 全周傅氏相量输入 |
|
||||
|
||||
### 2.6 「基波相量实例」实例层
|
||||
|
||||
@@ -183,7 +183,7 @@ test/host/phasor/phasor_test.c
|
||||
|
||||
### 4.2 主机侧合成波形**不代表真实硬件**
|
||||
|
||||
`frame_at()` 给 9 路语义通道灌的是**同值**波形,仅为驱动 L2 本身。V0.1 上各通道**不同刻**
|
||||
`frame_at()` 给 9 路语义通道灌的是**同值**波形,仅为驱动 全周傅氏相量本身。V0.1 上各通道**不同刻**
|
||||
(V0.1 硬件缺陷:TPAFE 与 STM32 无共同采样触发),跨通道相量运算在本平台上不成立——本单测**不**做
|
||||
任何跨通道合成断言(「线/负序/零序合成」受限,见 `docs/算法/继电保护功能复现规划.md` §1.6)。
|
||||
|
||||
|
||||
+25
-25
@@ -4,7 +4,7 @@
|
||||
> **参考来源**:`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)。
|
||||
> **状态**:**P0 采样与相量底座已台架闭环(2026-10-11)**——语义取数与有效性采集链路(B1,2026-10-10)、 采样有效性校验与 全周傅氏相量层(`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,含台架腿验证)**;**出口记录(出口与记录)与标准源注入验收为下一步**(见 §7)。
|
||||
|
||||
---
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
| 已实现子系统 | 网络(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) |
|
||||
| 保护算法层 | **全周傅氏相量层已实现并台架闭环**(`App/algo/sample_ring.c` + `phasor.c`:全周傅氏 5 实例、双区交换、每 1 ms 刷新,2026-10-11 `@test`);**保护判据元件框架 + 过流/过负荷/过压/欠压/零序过压 + 定值模型软件侧完成**(`prot_elm.c` + `prot_set.c`,2026-10-11,57 项主机单测);**出口 / SOE 记录仍缺失**(P4) |
|
||||
| 已知硬件缺陷 | 登记簿条目「双转换器无共同采样触发」:8 路电气量分属两片转换器 → V0.1 上禁止跨转换器做相位/功率/矢量运算 |
|
||||
|
||||
### 1.3 复现范围界定
|
||||
@@ -183,13 +183,13 @@
|
||||
| 层 | 职责 | 参考对应 | 本项目落点(拟) |
|
||||
| --- | --- | --- | --- |
|
||||
| **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/` |
|
||||
| **语义取数与预处理** | 快照取数、语义映射、标定、有效性校验、等周波调频、零序接入 | `DataPreRecv` / `RealDataMerge` / `CalSoftFr` / `GetZoreSamData` | `adc_task` + `App/algo/`(拟) |
|
||||
| **全周傅氏相量计算** | 全周傅氏基波/谐波、线/负序/零序合成、双区交换 | `CalFFTVecFull` / `CalfLineVec` / `CalfNegVec` | `App/algo/`(拟) |
|
||||
| **保护判据元件** | 各保护判据(过流/零序/过压/频率/…) | `RelayUnit/PRS_*.c` | `App/protect/`(拟) |
|
||||
| **出口与记录与信号** | 跳闸/告警出口、信号灯 | `TripKO` / KO | `App/protect/` + BSP 出口驱动 |
|
||||
| **动作留痕记录与上送** | SOE/动作记录、UI 显示、遥测上送 | 记录模块 + 通信 | `App/log/` + `Drivers/BSP/UI/` + `App/protocol/` |
|
||||
|
||||
> **分层原则**:L1 只做"数"(码值→工程量),L2 只做"相量"(工程量→复相量),L3 只做"判据"(相量 + 定值→布尔),L4/L5 只做"动作与留痕"。**算法与 I/O 分离**,使 L2/L3 成为主机侧单元测试(L0.5)的天然适格对象(落实 `docs/任务规划/测试与架构专项.md`「采集链路测试可验证性约束」)。
|
||||
> **分层原则**:语义取数与有效性只做"数"(码值→工程量),全周傅氏相量只做"相量"(工程量→复相量),保护判据只做"判据"(相量 + 定值→布尔),出口与记录/动作留痕只做"动作与留痕"。**算法与 I/O 分离**,使 全周傅氏相量/保护判据成为主机侧单元测试(L0.5)的天然适格对象(落实 `docs/任务规划/测试与架构专项.md`「采集链路测试可验证性约束」)。
|
||||
|
||||
### 2.2 任务与中断模型(映射到 STM32F4 + FreeRTOS)
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
|
||||
> 每项给出:**功能点 / 关键参数 / 完成判据**。状态列 ⬜ 未实现。
|
||||
|
||||
### 3.1 L1 采集与预处理
|
||||
### 3.1 语义取数与预处理
|
||||
|
||||
| 功能名 | 关键参数 | 完成判据 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -248,9 +248,9 @@
|
||||
| 零序通道接入(外部专用 / 自产切换) | 外部 `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` 无共同采样触发)。
|
||||
> ⚠️ **「双转换器无共同采样触发」约束**:「通道语义映射」中 `UA/UN/IA` 在 TPAFE、`UB/UC/IB/IC/IN` 在 STM32 ADC。V0.1 上 语义取数与有效性只做**逐通道独立监视**,不得假设同族量同刻(`UA` 与 `UB` 无共同采样触发)。
|
||||
|
||||
### 3.2 L2 相量计算
|
||||
### 3.2 全周傅氏相量计算
|
||||
|
||||
| 功能名 | 关键参数 | 完成判据 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -260,7 +260,7 @@
|
||||
| 相位输出 | `φ = 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 任务预留无锁读 |
|
||||
| 双区指针原子交换 | 计算区/使用区切换 | 保护元件读使用区,无撕裂 | ✅ 2026-10-11:`s_zone[2][5]` + 单字节 `volatile` 切换(Cortex-M 原子);单测覆盖双区交换;为独立 保护判据任务预留无锁读 |
|
||||
| 遥测谐波轨(可选) | k=1~9,方和根 `√(ΣHk²)` | 与基波轨并行,供 UI/上送 | ⬜ |
|
||||
|
||||
> **双轨有效值**:保护要"基波有效值 + 相位"(抗衰减直流、抗谐波误动);计量/遥测要"真有效值"(谐波方和根)。两者**不可混用**——这是参考系统 `CN_ANA_VEC_SQRT=FALSE` 与遥测谐波轨并存的根本原因。
|
||||
@@ -269,7 +269,7 @@
|
||||
|
||||
> **本表状态列口径**(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 保护元件
|
||||
### 3.3 保护判据元件
|
||||
|
||||
采用参考系统的**统一接口模式**:每元件一个 `tagPRS_XXX` 配置结构(定值号、模拟通道号、KI/KO、标志位、校验和)+ `Init` / `Main`(判据)/ 出口函数。
|
||||
|
||||
@@ -277,7 +277,7 @@
|
||||
|
||||
| 元件 | 判据要点 | 关键定值 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| 三段式相间过流 | 相电流基波 > 定值,经延时出口;返回系数滞回 | Ⅰ/Ⅱ/Ⅲ 段电流 + 延时 | 🔶 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)待做 |
|
||||
| 三段式相间过流 | 相电流基波 > 定值,经延时出口;返回系数滞回 | Ⅰ/Ⅱ/Ⅲ 段电流 + 延时 | 🔶 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 上送)**;出口(出口与记录)待做 |
|
||||
| 三段式零序过流 | 零序电流 > 定值,经延时出口 | Ⅰ/Ⅱ/Ⅲ 段零序电流 + 延时 | ⬜(双转换器无共同采样触发:`IN` 走 STM32,V0.2 使能;框架已就绪,加实例表一行即可) |
|
||||
| 过负荷 | 相电流 > 定值,告警/跳闸可整定 | 过负荷电流 + 延时 | 🔶 同「三段式相间过流」(`OL-IA` 实例,默认告警不跳闸;板端接线随 B5 落地,YX23 上送) |
|
||||
| 过压 / 欠压 | 相/线电压越限,经延时出口 | 过压定值、失压定值 + 延时 | 🔶 同「三段式相间过流」(`OV-UA`/`UV-UA`,欠量方向单测覆盖;沿用参考告警段 0x8027/0x8029) |
|
||||
@@ -305,7 +305,7 @@
|
||||
|
||||
> **V0.1 可行性**:上表按元件类型分组,但**V0.1 上能否闭环**取决于通道(见 **§1.6**)——核心集中 `IA`/`UA`/`UN` 可做(A 相过流、过负荷、过压/欠压、零序过压),**三段式零序过流与 B/C 相过流本期不可做**(`IN`/`IB`/`IC` 削顶);扩展集「涌流制动」~「无压/无流闭锁」多依赖三相,本期**建接口不使能**。
|
||||
|
||||
### 3.4 L4 出口与记录
|
||||
### 3.4 出口与记录
|
||||
|
||||
| 功能名 | 说明 | 状态 |
|
||||
| --- | --- | --- |
|
||||
@@ -316,7 +316,7 @@
|
||||
| 动作记录 | 保护动作/返回记录,落 `/log/soe.log` | ✅(B9,2026-10-12:六类边沿全覆盖——元件动作/复归、软压板投/退、采样数据块/恢复;protectTask 只投递(SPSC 环,post 禁 DBG),defaultTask `syslog_drain()` 落盘,动作路径无 NAND I/O) |
|
||||
| 故障录波(可选) | 4000 Hz 内部节拍预留 | ⬜ |
|
||||
|
||||
### 3.5 L5 自检与闭锁
|
||||
### 3.5 动作留痕自检与闭锁
|
||||
|
||||
| 功能名 | 说明 | 状态 |
|
||||
| --- | --- | --- |
|
||||
@@ -470,11 +470,11 @@
|
||||
|
||||
| 阶段 | 名称 | 内容 | 前置 | 里程碑 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| **P0** | 采样与相量底座 | B1(周期 CONVST + `adcTask` 消费 + 建任务 + 栈预算)+ L1 + L2 | B0 + B1 ✅ | 每 1 ms 产出正确的基波相量 —— **✅ 2026-10-11 台架闭环**(「采样有效性校验」同日落地 ✅;「通道标定(一次系数 + 零漂)」标定 / 「等周波采样(软件测频 + 调频闭环)」等周波为 P0 遗留项,精度复核依赖标准源) |
|
||||
| **P0** | 采样与相量底座 | B1(周期 CONVST + `adcTask` 消费 + 建任务 + 栈预算)+ 语义取数与有效性 + 全周傅氏相量 | 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 口径) |
|
||||
| **P3** | 异常检测与闭锁 | 动作留痕自检闭锁、采样通道自检;三相类(涌流/PT·CT 断线/母线接地)**建接口不使能** | P1/P2 | 自检失败闭锁;未使能元件不误动 |
|
||||
| **P4** | 出口、记录与定值集成 | 出口与记录、§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 硬件(修复「双转换器无共同采样触发」+ 中点偏置),本期**建接口不使能**。
|
||||
@@ -513,8 +513,8 @@ B0 产品定义 ✅(2026-10-10 已确认,见 §1.5)
|
||||
| --- | --- | --- |
|
||||
| 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) |
|
||||
| 语义取数与有效性板端套件 | 采样/相量/保护元件 | `test/run_all_suites.py` 板端套件 |
|
||||
| 全周傅氏相量/保护判据台架 | 标准源注入、动作出口、时序 | 台架闭环(COM6 @115200) |
|
||||
|
||||
### 8.2 `docs/任务规划/测试与架构专项.md`「采集链路测试可验证性约束」落实
|
||||
|
||||
@@ -603,14 +603,14 @@ B0 产品定义 ✅(2026-10-10 已确认,见 §1.5)
|
||||
| 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-3/L1-4 落地:STM32 ADC1 扫描 + 语义映射** | 新增 `App/algo/adc_input.c/h`(语义取数与有效性层):① `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-2 实例数口径对齐** | 新增 `App/algo/sample_ring.c/h`(全周傅氏相量输入:按语义通道保存 2 周波 = 40 点环缓冲,整帧写后统一推进写指针)与 `App/algo/phasor.c/h`(全周傅氏相量核心:全周傅氏单频 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 的 全周傅氏相量各点状态**仍标 ⬜**——实现与主机单测已完成,但**台架 `@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 | **全周傅氏相量台架闭环: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 | **B8 频率测量层 + 过频/低频保护(L3-5,W1 任务卡)** | 新增 `App/algo/freq.c/h`(测频与遥测快照测频:共轭乘积相位增量 + 解缠绕 + **自适应窗长** 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 否定确认口径不变) |
|
||||
|
||||
+15
-15
@@ -5,7 +5,7 @@
|
||||
> **阅读前提**:采样节拍与乒乓双缓冲 → `docs/子系统设计/ADC采样节拍设计说明.md`;
|
||||
> 8 路电气量为何分属两片转换器 → `docs/硬件平台/ADC通道映射说明.md`。
|
||||
> **不在本文范围**:接口签名与全层约定速览在 `docs/算法/采集与算法层设计说明.md`,本文不重复其接口表;
|
||||
> 需求与验收口径登记在 `docs/算法/继电保护功能复现规划.md` §3.1(功能项「采样有效性校验」)与同文档 §3.5(L5 自检与闭锁)。
|
||||
> 需求与验收口径登记在 `docs/算法/继电保护功能复现规划.md` §3.1(功能项「采样有效性校验」)与同文档 §3.5(动作留痕自检与闭锁)。
|
||||
> **配图**:三张 SVG 的生成器在 `tools/arch_diagram/`(改图 = 改脚本顶部数据后重跑,勿手改 `.svg`)。
|
||||
|
||||
## 目录
|
||||
@@ -67,10 +67,10 @@
|
||||
| 节拍源/转换器静默 | 相量停在最后一帧的数值上,看着完全合理 | 只能靠人盯 10 s 一条的心跳日志 | 100 ms 内置电平位 → 保护直接闭锁 |
|
||||
| 消费者超拍丢帧 | 相量窗出现时间空洞,幅值/相位带系统性偏差 | 同上(`adc1_gap` / `tgap` 在心跳里) | 计数 + 当拍事件,**不告警**(§6.2) |
|
||||
| 帧序号倒退 | 序号与数据的对应关系失效,快照可能是两帧混合 | 无 | 锁存位 + 永久闭锁(§6.3) |
|
||||
| 错误计数增量 | 个别帧不可信(FRSTDATA 无跳变、HAL 报错、L1 停摆) | 无(驱动只累计不上报) | 事件 + 锁存,供事后归因(§6.4) |
|
||||
| 错误计数增量 | 个别帧不可信(FRSTDATA 无跳变、HAL 报错、语义取数与有效性停摆) | 无(驱动只累计不上报) | 事件 + 锁存,供事后归因(§6.4) |
|
||||
|
||||
最关键的是第一行。**节拍停而任务照跑时,上层拿到的是旧数据而不是空数据**:`App/task/adc_task.c`
|
||||
只在 `adc_input_poll()` 返回 1 时才压环重算,于是 L2 相量**保持最后一帧**;`App/task/protect_task.c`
|
||||
只在 `adc_input_poll()` 返回 1 时才压环重算,于是 全周傅氏相量**保持最后一帧**;`App/task/protect_task.c`
|
||||
每 20 ms 读到的 rms 数值合理、`phasor_get()` 返回 0(成功),定时限判据却在这条冻住的 rms 上继续
|
||||
累计延时——这比「没有数据」危险得多。**本层的全部价值就是把「数据是否新鲜」变成一个可以被
|
||||
保护的消费者直接消费的电平量**。
|
||||
@@ -84,7 +84,7 @@
|
||||
| 层 | 落点 | 在本机制里只负责什么 |
|
||||
|---|---|---|
|
||||
| 驱动 ISR | `Drivers/BSP/TPAFE5160/tpafe5160.c` | BUSY EXTI 每读完一帧 `s_frame_seq++`;无跳变帧只累计 `s_frstdata_err` |
|
||||
| L1 采集 | `App/algo/adc_input.c` | DMA 半区/整区完成计数 + 自算丢帧(次数)/停摆(连续 >=2 拍无新帧)/HAL 错误四类计数 |
|
||||
| 语义取数与有效性采集 | `App/algo/adc_input.c` | DMA 半区/整区完成计数 + 自算丢帧(次数)/停摆(连续 >=2 拍无新帧)/HAL 错误四类计数 |
|
||||
| 快照装配 | `App/task/adc_task.c` | **本拍 poll 之后**把 6 个计数 + 一份 `now_ms` 填进 `adc_health_in_t` |
|
||||
| 判定 | `App/algo/adc_health.c` | 只做判定与位图维护;不知道寄存器、不知道日志 |
|
||||
| 编排 | `App/task/adc_task.c` | 按位分级:`DBG_ERROR` / `SYSLOG_SELFTEST` / `DBG_INFO`(恢复) |
|
||||
@@ -195,7 +195,7 @@ flowchart TD
|
||||
|---|---|---|---|
|
||||
| 1 建基线 | `s_primed == 0` | 记 6 个计数与 `now_ms`,两侧前进时刻都设为本拍 | **不判定、不产生事件**——开机首拍没有参照系(此刻 `tpafe5160_frame_seq()` 已非 0,因为 TIM3 比调度器早约 100 ms 就在生产帧) |
|
||||
| 2 TPAFE 差值 | `d < 0` / `d > 1` / `d >= 1` | 见图中三个分支 | 倒退分支**只重新对齐序号**,不动错误计数基线,避免一次倒退顺手抹掉别的证据 |
|
||||
| 3 STM32 差值 | 同一口径,但不在此累计丢帧 | 前进/倒退两态 | **不重算 gap**:L1 已有细账 `adc_input_stm32_gaps()`,两处各算一套就会打架(§6.2) |
|
||||
| 3 STM32 差值 | 同一口径,但不在此累计丢帧 | 前进/倒退两态 | **不重算 gap**:语义取数与有效性已有细账 `adc_input_stm32_gaps()`,两处各算一套就会打架(§6.2) |
|
||||
| 4 静默判定 | `elapsed >= 100` | 置电平位并进 sticky;否则**清**电平位 | 判定排在前进更新之后 → 同一拍内「前进」与「静默」互斥,不会出现刚推进又报静默 |
|
||||
| 5 错误增量 | 四个计数各自 `!=` 基线 | 事件位 + 锁存位,并更新基线 | 用 `!=` 不用 `>`:见 §6.4 |
|
||||
| 6 出参 | `out != 0` | 写 4 个字段 + `tpafe_stall_ms`(非静默态给 0) | 事件位只在本次出参里出现,绝不写进 `flags`/`sticky` |
|
||||
@@ -246,7 +246,7 @@ else { 清电平位 } /* 只有 stall 类有 else 分支,SEQ_BACKWARD 没有
|
||||
| 车道 | 丢帧证据来源 | 单位 | 为什么这样分 |
|
||||
|---|---|---|---|
|
||||
| TPAFE | 判定层自算(驱动只暴露 `tpafe5160_frame_seq()`) | **帧点数**:按 `d - 1` 加权 | 驱动侧除帧序号外没有别的观测点,判定层手里的 seq 是唯一线索 |
|
||||
| STM32 | L1 的 `adc_input_stm32_gaps()`,判定层只看它的增量 | **帧点数**:按 `d - 1` 加权 | L1 在消费点上直接看得到 DMA 完成计数,细账归它;判定层再算一套就是两处判据打架 |
|
||||
| STM32 | 语义取数与有效性的 `adc_input_stm32_gaps()`,判定层只看它的增量 | **帧点数**:按 `d - 1` 加权 | 语义取数与有效性在消费点上直接看得到 DMA 完成计数,细账归它;判定层再算一套就是两处判据打架 |
|
||||
|
||||
两条车道**同单位(帧点数)**,心跳里 `tgap` 与 `adc1_gap` 可以直接对比(2026-10-21 之前
|
||||
固件的 `adc1_gap` 是"次数"口径,跨版本对比要留意:单拍超一帧时两者数值相同,只有
|
||||
@@ -284,8 +284,8 @@ else { 清电平位 } /* 只有 stall 类有 else 分支,SEQ_BACKWARD 没有
|
||||
| 计数(快照字段) | 生产者 | 正常增量 | 出现增量意味着 | 事件位 | 锁存位 | 闭锁 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| `tpafe_frst_err` | TPAFE BUSY EXTI | 0 | 该帧 8 个通道不可信(FRSTDATA 无跳变) | `ADC_HE_FRSTDATA` | `ADC_HF_FRSTDATA` | 否 |
|
||||
| `stm32_errs` | L1 消费侧 | 0 | 连续 >=2 拍无新帧,或 DMA 挂载失败 | `ADC_HE_STM32_ERR` | `ADC_HF_STM32_ERR` | 否 |
|
||||
| `stm32_gaps` | L1 消费侧 | 少量 | 超拍丢帧(§6.2) | `ADC_HE_STM32_GAP` | 不入锁存 | 否 |
|
||||
| `stm32_errs` | 语义取数与有效性消费侧 | 0 | 连续 >=2 拍无新帧,或 DMA 挂载失败 | `ADC_HE_STM32_ERR` | `ADC_HF_STM32_ERR` | 否 |
|
||||
| `stm32_gaps` | 语义取数与有效性消费侧 | 少量 | 超拍丢帧(§6.2) | `ADC_HE_STM32_GAP` | 不入锁存 | 否 |
|
||||
| `stm32_hw_errs` | HAL ADC/DMA 错误回调 | 0 | 硬件层面报过错 | `ADC_HE_HW_ERR` | `ADC_HF_HW_ERR` | 否 |
|
||||
|
||||
- **用 `!=` 而不是 `>`**:① 驱动侧一次 `+N` 的跳变不会因为「已经大于基线」被吞掉;
|
||||
@@ -371,9 +371,9 @@ if (((serious | rise) & ~s_health_logged) != 0u) { /* 位图当去重键 */
|
||||
|---|---|---|---|
|
||||
| TIM3 节拍源停 | 本层**看不见**(`adcTask` 永久阻塞,没人跑判定)→ 由 §15 兜底门判老 | §15:120 ms;看门狗:100 ms 抽样 + 连续 800 ms 停喂 | §15 闭锁保护(≤140 ms);IWDG 溢出复位(标称 2498 ms,LSI 偏快约 1701 ms) |
|
||||
| TPAFE BUSY EXTI 停 | 本层 `ADC_HF_TPAFE_STALL` | 100 ms | 闭锁保护(任务仍活着,不复位) |
|
||||
| ADC1 / DMA 停 | 本层 `ADC_HF_STM32_STALL`,L1 的 `stm32_errs` 增量同时给出事件 | 100 ms | 闭锁 + 留痕 |
|
||||
| HAL 报错 | L1 计数 → 本层 `HE_HW_ERR` | 下一拍 | 事件 + 锁存,不闭锁 |
|
||||
| `adcTask` 超拍 | 本层 `HE_TPAFE_GAP` + L1 `adc1_gap` | 当拍 | 只计数 |
|
||||
| ADC1 / DMA 停 | 本层 `ADC_HF_STM32_STALL`,语义取数与有效性的 `stm32_errs` 增量同时给出事件 | 100 ms | 闭锁 + 留痕 |
|
||||
| HAL 报错 | 语义取数与有效性计数 → 本层 `HE_HW_ERR` | 下一拍 | 事件 + 锁存,不闭锁 |
|
||||
| `adcTask` 超拍 | 本层 `HE_TPAFE_GAP` + 语义取数与有效性 `adc1_gap` | 当拍 | 只计数 |
|
||||
| 帧序号倒退 | 本层 `SEQ_BACKWARD` | 当拍 | 闭锁且不自愈,直到复位 |
|
||||
|
||||
一句话概括本层的**能力边界**:它判的是「生产者相对消费者是否前进」,因此**判不了消费者自己**
|
||||
@@ -543,7 +543,7 @@ stateDiagram-v2
|
||||
| 剧本 | 判定路径 | 结论 |
|
||||
|---|---|---|
|
||||
| 现场报「保护退出」 | 查 `[PROT] sampling FAULT` 的 `hf` → 回到 `flags` 上升沿行看 `stall_ms` | `hf=0x4` → 计数器被动过,查软件;`hf=0x1/0x2` → 采样侧真停,查节拍与转换器供电 |
|
||||
| 心跳里 `idle` / `skip` 在涨但无 `health` 行 | 那不是本层的判据(本层只看序号) | 属 L1 相位伪影或通道首次未就绪,见 `docs/子系统设计/ADC采样节拍设计说明.md` §8 |
|
||||
| 心跳里 `idle` / `skip` 在涨但无 `health` 行 | 那不是本层的判据(本层只看序号) | 属 语义取数与有效性相位伪影或通道首次未就绪,见 `docs/子系统设计/ADC采样节拍设计说明.md` §8 |
|
||||
| 偶发一条 `health` + 一条 `recovered` | 一次瞬态静默(几十 ms 到几百 ms) | 查同窗口的日志突发、NAND 擦写、FTP 传输等长耗时窗口(`docs/子系统设计/看门狗设计说明.md` §4.3) |
|
||||
|
||||
---
|
||||
@@ -645,8 +645,8 @@ stateDiagram-v2
|
||||
- `docs/子系统设计/看门狗设计说明.md` §4.3 —— 长耗时窗口的三类处置(瞬态静默的候选来源)
|
||||
- `docs/子系统设计/看门狗设计说明.md` §11.4 —— `[PROF]` 探针字段与耗时基线(判「超拍」要看它)
|
||||
- `docs/硬件平台/ADC通道映射说明.md` —— 语义映射唯一权威口径(与「哪一侧静默」直接相关)
|
||||
- `docs/算法/继电保护功能复现规划.md` §3.1 —— L1 功能项与验收口径(本层 = 「采样有效性校验」行)
|
||||
- `docs/算法/继电保护功能复现规划.md` §3.5 —— L5 自检与闭锁(本层供数的「自检失败闭锁」在此登记)
|
||||
- `docs/算法/继电保护功能复现规划.md` §3.1 —— 语义取数与有效性功能项与验收口径(本层 = 「采样有效性校验」行)
|
||||
- `docs/算法/继电保护功能复现规划.md` §3.5 —— 动作留痕自检与闭锁(本层供数的「自检失败闭锁」在此登记)
|
||||
- `docs/内存管理/RAM使用分析与优化方案.md` §2.3 与 §4.0.6 —— `adcTask` 栈配置、最坏链与余量台账
|
||||
- `App/algo/README.md` —— 目录级文件清单与构建测试入口
|
||||
- `docs/子系统设计/ADC采样节拍设计说明.md` §3.4 —— TIM3 启动位置与顺序(兜底门开机不误锁的前提)
|
||||
@@ -658,6 +658,6 @@ stateDiagram-v2
|
||||
| 日期 | 变更 | 说明 |
|
||||
|---|---|---|
|
||||
| 2026-10-21 | 新建 | 首版单文件深设计:判据推导、四种位语义、闭锁与兜底责任矩阵、验证分工与现场判读手册;新增三张配图生成器(`tools/arch_diagram/gen_adc_health_flow_svg.py`、`gen_adc_health_bitmap_svg.py`、`gen_adc_health_timeline_svg.py`)与产物 SVG |
|
||||
| 2026-10-21 | §6.2 / §10 | 丢帧口径统一:L1 的 `adc1_gap` 由「次数」改为「帧点数」,与 `tgap` 同单位;§10 盲区第 4 条改写、§11.2 台架证据标注历史日志为旧口径 |
|
||||
| 2026-10-21 | §6.2 / §10 | 丢帧口径统一:语义取数与有效性的 `adc1_gap` 由「次数」改为「帧点数」,与 `tgap` 同单位;§10 盲区第 4 条改写、§11.2 台架证据标注历史日志为旧口径 |
|
||||
| 2026-10-21 | 新增 §15 | 兜底新鲜度门:`adc_health_age_stale()` 无状态纯判据 + `ADC_HF_STALE`(bit8)+ `protectTask` 独立观测;§7 位表、§8 责任矩阵与「已知窗口」段、§10 盲区、§11 用例表、§12 判读、§14 清单与位图配图全部同步 |
|
||||
| 2026-10-21 | §14 更新 | 初始化入口已接线:`adc_task_func()` 进循环前调 `adc_task_init()`(该入口不再打日志);同时删除 `App/task/net_task.c` 里的空壳 `net_task_init()` |
|
||||
|
||||
+23
-23
@@ -1,14 +1,14 @@
|
||||
# 采集与算法层设计说明(`App/algo/`:L1 → L2 → L3)
|
||||
# 采集与算法层设计说明(`App/algo/`:语义取数与有效性 → 全周傅氏相量 → 保护判据)
|
||||
|
||||
> **模块名称**:自研采集与算法层,代码在 `App/algo/`(七个 `.c`,全部登记进 Keil 工程)。
|
||||
> **文档定位**:**现状设计说明**——本层当前如何组织、每个模块的契约与关键机制、为什么这样设计、
|
||||
> 边界与代价。**目录级索引(文件清单、构建与测试命令、新增模块动作)在 `App/algo/README.md`**,
|
||||
> 本文不重复其内容;本文不写历史演进、门禁复测记录与修订日志(需要时查 git 历史)。
|
||||
> **状态**:L1 → L2 → L3 主线已闭环到板端消费者(`protectTask`,20 ms 判据节拍);
|
||||
> **状态**:语义取数与有效性 → 全周傅氏相量 → 保护判据主线已闭环到板端消费者(`protectTask`,20 ms 判据节拍);
|
||||
> 标定折算层 `App/algo/adc_cal` 已于 2026-10-25 落地(标定折算与落盘整定,`docs/任务规划/数据可信.md` §4.1,
|
||||
> 引脚电压量纲 + 系数落盘 + 未标定闭锁);**幅值精度判据**仍待标准源两点注入复核(两点标定,`docs/任务规划/数据可信.md` §5)。
|
||||
> **相关文档**:
|
||||
> 分层与功能项(L1~L5)的唯一属主登记处:`docs/算法/继电保护功能复现规划.md` §2.1(分层)、§3(功能清单)、§4.2(精度)、§7(路线图)
|
||||
> 分层与功能项(语义取数与有效性~动作留痕)的唯一属主登记处:`docs/算法/继电保护功能复现规划.md` §2.1(分层)、§3(功能清单)、§4.2(精度)、§7(路线图)
|
||||
> `docs/硬件平台/ADC通道映射说明.md`(**语义映射唯一权威口径**)
|
||||
> `docs/子系统设计/ADC采样节拍设计说明.md`(TIM3 1 kHz 同源节拍、ADC1+DMA 乒乓缓冲、`adcTask` 唤醒)
|
||||
> `docs/算法/傅氏算法详解.md` §2.3(有效值口径怎么来的)
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
- [1. 定位与边界](#1-定位与边界)
|
||||
- [2. 一拍的数据流与初始化落点](#2-一拍的数据流与初始化落点)
|
||||
- [3. L1 语义取数 `adc_input.c`](#3-l1-语义取数-adcinputc)
|
||||
- [4. L1 有效性判定 `adc_health.c`](#4-l1-有效性判定-adchealthc)
|
||||
- [5. L2 输入 `sample_ring.c`](#5-l2-输入-sampleringc)
|
||||
- [6. L2 `phasor.c` 相量计算](#6-l2-phasorc-相量计算)
|
||||
- [7. L2 派生量:频率测量 `freq.c`](#7-l2-派生量频率测量-freqc)
|
||||
- [8. L3 输入:保护定值模型 `prot_set.c`](#8-l3-输入保护定值模型-protsetc)
|
||||
- [9. L3 保护元件框架 `prot_elm.c`](#9-l3-保护元件框架-protelmc)
|
||||
- [3. 语义取数与有效性语义取数 `adc_input.c`](#3-l1-语义取数-adcinputc)
|
||||
- [4. 语义取数与有效性判定 `adc_health.c`](#4-l1-有效性判定-adchealthc)
|
||||
- [5. 全周傅氏相量输入 `sample_ring.c`](#5-l2-输入-sampleringc)
|
||||
- [6. 全周傅氏相量 `phasor.c` 相量计算](#6-l2-phasorc-相量计算)
|
||||
- [7. 全周傅氏相量的派生量:频率测量 `freq.c`](#7-l2-派生量频率测量-freqc)
|
||||
- [8. 保护判据输入:保护定值模型 `prot_set.c`](#8-l3-输入保护定值模型-protsetc)
|
||||
- [9. 保护判据元件框架 `prot_elm.c`](#9-l3-保护元件框架-protelmc)
|
||||
- [10. 关键约定与禁令](#10-关键约定与禁令)
|
||||
- [11. 资源足迹(改容量前先看这里)](#11-资源足迹改容量前先看这里)
|
||||
- [12. 验证与判读](#12-验证与判读)
|
||||
@@ -83,7 +83,7 @@ flowchart TD
|
||||
|
||||
---
|
||||
|
||||
## 3. L1 语义取数 `adc_input.c`
|
||||
## 3. 语义取数与有效性语义取数 `adc_input.c`
|
||||
|
||||
**解决的问题**:V0.1 上 8 路电气量被两片转换器分片(硬件缺陷**双转换器无共同采样触发**),且网名 `AINn`
|
||||
≠ 板级 `ADCn` ≠ 转换器通道号(17 路里 13 路置换)。消费侧若直接索引驱动缓冲,改版即全线错位。
|
||||
@@ -111,9 +111,9 @@ flowchart TD
|
||||
`phasor` 那种零依赖形态,才能免桩单测。
|
||||
|
||||
---
|
||||
## 4. L1 有效性判定 `adc_health.c`
|
||||
## 4. 语义取数与有效性判定 `adc_health.c`
|
||||
|
||||
**解决的问题**:驱动侧与 L1 只有"观测计数"(`tpafe5160_frame_seq()` /
|
||||
**解决的问题**:驱动侧与 语义取数与有效性只有"观测计数"(`tpafe5160_frame_seq()` /
|
||||
`tpafe5160_frstdata_err()`、`adc_input_stm32_*()`),**没有判定**——芯片静默、消费者超拍丢帧、
|
||||
序号倒退这些故障原本只能靠人读心跳日志发现。本层把判定收进纯逻辑,**告警编排留在消费者**
|
||||
(`adc_task.c` 的 `adc_health_report()`)→ 判定可主机免桩单测。
|
||||
@@ -144,9 +144,9 @@ flowchart TD
|
||||
|
||||
---
|
||||
|
||||
## 5. L2 输入 `sample_ring.c`
|
||||
## 5. 全周傅氏相量输入 `sample_ring.c`
|
||||
|
||||
**解决的问题**:相量计算要"以当前时刻为终止的一周波",而 L1 每次只给最新一帧。本层按**语义通道**
|
||||
**解决的问题**:相量计算要"以当前时刻为终止的一周波",而 语义取数与有效性每次只给最新一帧。本层按**语义通道**
|
||||
存最近 `SAMPLE_RING_CYCLES = 2` 个周波(`SAMPLE_RING_DEPTH = 40` 点),与参考系统
|
||||
`CN_BUFSAM_CYCLE = 2` 一致,并为后续加长数据窗(1.5~2 周波抗衰减直流)预留空间。
|
||||
|
||||
@@ -160,14 +160,14 @@ flowchart TD
|
||||
**要点**
|
||||
|
||||
- **整帧写入后才统一推进写指针** → 单帧内不可能"半新半旧",消费侧取到的窗永远落在整帧边界。
|
||||
- 本层**只做按时序存 / 取,不做任何跨通道运算**:同刻性由上游 L1 负责,本层既不保证也不假设。
|
||||
- 本层**只做按时序存 / 取,不做任何跨通道运算**:同刻性由上游 语义取数与有效性负责,本层既不保证也不假设。
|
||||
判定也不在本层(本层只出计数)。
|
||||
- 某通道本拍取数失败 → **整拍跳过入环**(现 `adc_task.c` 的 `s_frames_skip` 即此),
|
||||
**切勿补 0 点**——单个 0 点会显著污染 20 点 DFT 窗。
|
||||
|
||||
---
|
||||
|
||||
## 6. L2 `phasor.c` 相量计算
|
||||
## 6. 全周傅氏相量 `phasor.c` 相量计算
|
||||
|
||||
**算法**:全周傅氏(单频 DFT),`N = PHASOR_N = 20`(1 kHz @ 50 Hz)。系数表
|
||||
`k_fft_sin` / `k_fft_cos` **离线生成**并**预乘 √2/N**(口径推导见
|
||||
@@ -198,10 +198,10 @@ flowchart TD
|
||||
- **相位(「相位输出」)不常驻结构体**:需要时自行 `atan2f(fIm, fRe)`(`φ` 约定 = 窗首初相,见 §7)。
|
||||
|
||||
---
|
||||
## 7. L2 派生量:频率测量 `freq.c`
|
||||
## 7. 全周傅氏相量的派生量:频率测量 `freq.c`
|
||||
|
||||
**解决的问题**:过频 / 低频(`docs/算法/继电保护功能复现规划.md` §3.3 「过频 / 低频」)需要系统频率读数,
|
||||
而 L2 只出相量。本层把"相邻两拍基波相量的相位差"变成"频率",并解决**非整周波窗长的 DFT 泄漏纹波**
|
||||
而 全周傅氏相量只出相量。本层把"相邻两拍基波相量的相位差"变成"频率",并解决**非整周波窗长的 DFT 泄漏纹波**
|
||||
——这是决定精度的关键问题。
|
||||
|
||||
| API | 契约 |
|
||||
@@ -256,7 +256,7 @@ UA 无幅值落 IA → 0.0020 Hz。
|
||||
|
||||
---
|
||||
|
||||
## 8. L3 输入:保护定值模型 `prot_set.c`
|
||||
## 8. 保护判据输入:保护定值模型 `prot_set.c`
|
||||
|
||||
**解决的问题**:保护判据的"输入宪法"。参考系统把定值放 EEPROM + 常量表做校验和自检;本层做
|
||||
**RAM 模型 + 持久化纯逻辑**(blob 序列化 / 解析,文件胶住在 `App/cfg/prot_set_store.c`),
|
||||
@@ -296,7 +296,7 @@ UA 无幅值落 IA → 0.0020 Hz。
|
||||
|
||||
---
|
||||
|
||||
## 9. L3 保护元件框架 `prot_elm.c`
|
||||
## 9. 保护判据元件框架 `prot_elm.c`
|
||||
|
||||
**解决的问题**:参考系统 89 个 `PRS_*.c` 各自实现"滞回 + 定时限"——本框架把这段公共核收敛成
|
||||
**一个通用核 + 数据驱动实例表**(与 `phasor` 的 `k_inst` 同一模式):新增元件 = 表加一行 +
|
||||
@@ -307,7 +307,7 @@ UA 无幅值落 IA → 0.0020 Hz。
|
||||
| `prot_elm_init()` | 复位状态 + 按名前缀(`C01/C02/C03`)解析相量实例索引;须在 `phasor_init()` 之后;`src = FREQ` 行无相量绑定(`pidx = 0xFF`) |
|
||||
| `prot_elm_eval(now_ms, meas)` | **纯判据**:定值 RAM + 测量数组 → 全元件状态机;主机单测入口;`NULL` 测量按 0 |
|
||||
| `prot_elm_run(now_ms)` | 适配层:按实例表 `src` 组测量(`0` 取 `phasor_get()` rms,`1` 取 `freq_get()`)再 eval |
|
||||
| `prot_elm_state()` / `prot_elm_active_mask()` | 状态快照 / 动作位图,供 L4 出口与心跳日志 |
|
||||
| `prot_elm_state()` / `prot_elm_active_mask()` | 状态快照 / 动作位图,供 出口与记录与心跳日志 |
|
||||
| `prot_elm_request_reset()` | 跨上下文复归入口(104 YK11 落请求,`eval` 头部消费) |
|
||||
|
||||
**要点**
|
||||
@@ -447,7 +447,7 @@ adcTask 静态最坏链与余量的**台账在** `docs/内存管理/RAM使用分
|
||||
|
||||
- 目录索引与构建 / 测试入口:`App/algo/README.md`
|
||||
- 「采样有效性校验」判定层深设计(判据推导 / 盲区 / 验证分工):`docs/算法/采样有效性校验设计说明.md`
|
||||
- 分层与功能项清单(L1~L5 的属主登记处):`docs/算法/继电保护功能复现规划.md`
|
||||
- 分层与功能项清单(语义取数与有效性~动作留痕的属主登记处):`docs/算法/继电保护功能复现规划.md`
|
||||
- 通道映射权威口径:`docs/硬件平台/ADC通道映射说明.md`
|
||||
- 采样节拍与 DMA 搬运:`docs/子系统设计/ADC采样节拍设计说明.md`
|
||||
- 傅氏算法与有效值口径:`docs/算法/傅氏算法详解.md` §2.3
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
| `nand-port-unit-test` | dhara NAND 移植层 `Drivers/BSP/GD5F2GQ5UE/nand_ftl.c` |
|
||||
| `adc-cal-unit-test` | 通道标定层 `App/algo/adc_cal.c`(2026-10-25 挂闸,下同) |
|
||||
| `prot-dim-unit-test` | 量纲回归:标定 → 相量 → 定值 → 判据链的单位与倍率一致性 |
|
||||
| `meas-unit-test` | L2.5 遥测快照层 `App/algo/meas.c`(200 ms 双区,104 与 UI 共用上游) |
|
||||
| `meas-unit-test` | 测频与遥测快照层 `App/algo/meas.c`(200 ms 双区,104 与 UI 共用上游) |
|
||||
| `run-par-unit-test` | 运行参数段 `App/algo/run_par.c`(遥测死区与系数) |
|
||||
| `vol-idle-sync-unit-test` | 卷空闲同步 `App/fs/vol_idle_sync.c`(空闲窗口内的 f_sync 语义) |
|
||||
| `ui-data-unit-test` | UI 数据快照层 `Drivers/BSP/UI/ui_data.c` 与各页写入方 |
|
||||
|
||||
+10
-10
@@ -2,7 +2,7 @@
|
||||
|
||||
> **定位**:以参考项目 CLS100(`Scatter_P_HV03.01_SV01.01`)的"采样 → 预处理 → 相量 → 遥测 → 录波 → 上送"全链路为对照,评测本项目在**电力采集与数据处理**上的完成度,指出下一步该补的短板与顺序。
|
||||
> **不是待办登记簿**:排序权威仍是 `docs/任务规划/README.md` §2;本文只出评测结论与建议,条目落地时按语义标识登记进 `docs/任务规划/登记簿.md`。
|
||||
> **对照口径**:项目内以 `docs/算法/继电保护功能复现规划.md` §3 的 L1~L5 清单为准;参考侧以参考项目 `项目分析文档/04-算法与采样专题/` 三篇(《ADC采集至数据使用全流程详解》《项目详细分析-交流采样与有效值计算》《傅氏算法详解》)与源码为准。
|
||||
> **对照口径**:项目内以 `docs/算法/继电保护功能复现规划.md` §3 的 语义取数与有效性~动作留痕清单为准;参考侧以参考项目 `项目分析文档/04-算法与采样专题/` 三篇(《ADC采集至数据使用全流程详解》《项目详细分析-交流采样与有效值计算》《傅氏算法详解》)与源码为准。
|
||||
> **硬件前提**:结论只针对 **V0.1 现板**;受「双转换器无共同采样触发」(8 路电气量分属两片转换器)制约的项单独标注,V0.2 改版后解禁。
|
||||
|
||||
---
|
||||
@@ -57,14 +57,14 @@
|
||||
|
||||
| 层 | 项 | 证据 |
|
||||
|---|---|---|
|
||||
| L1 | 1 kHz 硬件节拍、TPAFE 快照、ADC1 DMA 乒乓、语义映射 | `docs/算法/继电保护功能复现规划.md` §3.1 的「周期 CONVST 重触发」~「通道语义映射」 |
|
||||
| L1 | 采样有效性(静默/丢帧/倒退/错误增量) | 复现规划 §3.1(「采样有效性校验」);`docs/算法/采样有效性校验设计说明.md` |
|
||||
| L1 | 谐波相量入口(IA 的 2/5 次) | 复现规划 §3.1(「二次谐波/五次谐波提取入口」) |
|
||||
| L2 | 全周傅氏 5 实例、双区原子切换、每拍重算 | 复现规划 §3.2(「全周傅氏系数表」~「相位输出」) |
|
||||
| L2.5 | 测频(自适应窗,45~55 Hz 最坏 0.0101 Hz) | 复现规划 §3.3(「过频 / 低频」) |
|
||||
| L3 | 9 元件(三段过流/过负荷/过压/欠压/零序过压/过频/低频) | 复现规划 §3.3(「三段式相间过流」~「零序过压」) |
|
||||
| L4 | SOE + 动作记录(64 B 定长、CP56 时标、SPSC 环异步落盘) | 复现规划 §3.4(「SOE 记录」) |
|
||||
| L5 | 定值校验和 + 持久化 + 全局软压板 + 采样故障闭锁 | 复现规划 §3.5(「定值校验和」) |
|
||||
| 语义取数与有效性 | 1 kHz 硬件节拍、TPAFE 快照、ADC1 DMA 乒乓、语义映射 | `docs/算法/继电保护功能复现规划.md` §3.1 的「周期 CONVST 重触发」~「通道语义映射」 |
|
||||
| 语义取数与有效性 | 采样有效性(静默/丢帧/倒退/错误增量) | 复现规划 §3.1(「采样有效性校验」);`docs/算法/采样有效性校验设计说明.md` |
|
||||
| 语义取数与有效性 | 谐波相量入口(IA 的 2/5 次) | 复现规划 §3.1(「二次谐波/五次谐波提取入口」) |
|
||||
| 全周傅氏相量 | 全周傅氏 5 实例、双区原子切换、每拍重算 | 复现规划 §3.2(「全周傅氏系数表」~「相位输出」) |
|
||||
| 测频与遥测快照 | 测频(自适应窗,45~55 Hz 最坏 0.0101 Hz) | 复现规划 §3.3(「过频 / 低频」) |
|
||||
| 保护判据 | 9 元件(三段过流/过负荷/过压/欠压/零序过压/过频/低频) | 复现规划 §3.3(「三段式相间过流」~「零序过压」) |
|
||||
| 出口与记录 | SOE + 动作记录(64 B 定长、CP56 时标、SPSC 环异步落盘) | 复现规划 §3.4(「SOE 记录」) |
|
||||
| 动作留痕 | 定值校验和 + 持久化 + 全局软压板 + 采样故障闭锁 | 复现规划 §3.5(「定值校验和」) |
|
||||
| 上行 | 104 总召/变位/遥控/定值读写/时钟同步 | `docs/子系统设计/IEC104上行设计说明.md` |
|
||||
|
||||
### 3.2 部分闭环
|
||||
@@ -106,7 +106,7 @@
|
||||
|
||||
**建议动作**
|
||||
|
||||
- 新增 L1 后置标定层(建议 `App/algo/adc_cal.c/h`,零平台依赖便于主机单测):每通道 `k`/`b`(Q10 定点),对外只暴露"语义通道 → 工程量"。
|
||||
- 新增 语义取数与有效性后置标定层(建议 `App/algo/adc_cal.c/h`,零平台依赖便于主机单测):每通道 `k`/`b`(Q10 定点),对外只暴露"语义通道 → 工程量"。
|
||||
- 落点放在 `adc_input_raw()` 与 `sample_ring_push_frame()` 之间,**上层一行不改**——相量、元件、遥测、UI 自动拿到工程量。
|
||||
- 系数载体沿用 `prot_set_store` 的 blob 范式(magic + 版本 + 校验和 + 原子写),文件独立于定值档,避免标定与定值互相干扰。
|
||||
- PT/CT 变比(`PS_PT_PRI`/`PS_CT_PRI` 等 4 项已在册但零消费)在此层接上,输出"二次值"与"一次值"两套口径。
|
||||
|
||||
@@ -84,19 +84,19 @@ SIM_EXEMPT = [
|
||||
("*_mcu.c", "MCU 平台后端,模拟器另有 *_sim.c 替身"),
|
||||
|
||||
# --- App/:固件任务 / MCU 依赖 / 纯算法(模拟器无消费路径)---
|
||||
("App/algo/adc_health.c", "L1 有效性校验纯算法,模拟器无消费路径"),
|
||||
("App/algo/adc_health.c", "语义取数与有效性校验纯算法,模拟器无消费路径"),
|
||||
("App/algo/adc_input.c", "依赖 HAL/TPAFE 取数,MCU 专属"),
|
||||
("App/algo/phasor.c", "L2 相量纯算法,模拟器无消费路径"),
|
||||
("App/algo/prot_elm.c", "L3 保护元件纯算法,模拟器无消费路径"),
|
||||
("App/algo/phasor.c", "全周傅氏相量纯算法,模拟器无消费路径"),
|
||||
("App/algo/prot_elm.c", "保护判据元件纯算法,模拟器无消费路径"),
|
||||
("App/util/boot_stats.c", "开机账本(SD2506 用户 SRAM + RCC_CSR 快照,依赖 I2C/HAL 位掩码),MCU 专属;L0.5 覆盖于 test/host/boot_stats"),
|
||||
("App/algo/prot_set.c", "L5 保护定值纯算法,模拟器无消费路径"),
|
||||
("App/algo/freq.c", "L2 派生测频纯算法(输入=phasor 使用区),模拟器无消费路径"),
|
||||
("App/algo/prot_set.c", "动作留痕保护定值纯算法,模拟器无消费路径"),
|
||||
("App/algo/freq.c", "全周傅氏相量派生测频纯算法(输入=phasor 使用区),模拟器无消费路径"),
|
||||
("App/cfg/prot_set_store.c", "定值持久化 MCU 胶水(依赖 prot_set 纯算法),模拟器无消费路径"),
|
||||
("App/log/soe_rec.c", "SOE 记录编解码纯逻辑(B9),L0.5 主机单测覆盖,模拟器无消费路径"),
|
||||
("App/log/soe_store.c", "SOE 落盘 MCU 胶水(队列+FatFs 单写者,B9),模拟器无消费路径"),
|
||||
("App/algo/sample_ring.c", "L2 环形缓冲纯算法,模拟器无消费路径"),
|
||||
("App/algo/adc_cal.c", "L1.5 标定折算纯算法 + cfg 段注册(消费者 = MCU 侧 adcTask 每拍;模拟器不跑采样任务),模拟器无消费路径"),
|
||||
("App/algo/meas.c", "L2 遥测快照发布纯算法(唯一发布者 = MCU 侧 adcTask 200 ms 分频;104 改读快照与 UI 侧消费属另一波次另行接线,模拟器无消费路径;L0.5 单测 test/host/meas 覆盖),模拟器无消费路径"),
|
||||
("App/algo/sample_ring.c", "全周傅氏相量环形缓冲纯算法,模拟器无消费路径"),
|
||||
("App/algo/adc_cal.c", "标定折算纯算法 + cfg 段注册(消费者 = MCU 侧 adcTask 每拍;模拟器不跑采样任务),模拟器无消费路径"),
|
||||
("App/algo/meas.c", "测频与遥测快照发布纯算法(唯一发布者 = MCU 侧 adcTask 200 ms 分频;104 改读快照与 UI 侧消费属另一波次另行接线,模拟器无消费路径;L0.5 单测 test/host/meas 覆盖),模拟器无消费路径"),
|
||||
("App/algo/run_par.c", "运行参数段纯算法 + [run_par] cfg 段注册 + 104 地址映射(写者 = iec104Task 直通、属主落盘 defaultTask;模拟器不跑 104 协议,模拟器无消费路径;L0.5 单测 test/host/run_par 覆盖),模拟器无消费路径"),
|
||||
("App/app/app_main.c", "固件启动/就绪屏障,MCU 专属"),
|
||||
("App/app/ui_data_feed.c", "UI 快照装配器(依赖 phasor/prot_set/iec104 端口常量等固件侧数据源);模拟器不跑装配链,快照由 simulator/main.c 直接发布固定帧,模拟器无消费路径"),
|
||||
|
||||
@@ -77,7 +77,7 @@ ROLE = {
|
||||
"timeSyncTask": "墙钟时间同步",
|
||||
"adcTask": "TPAFE5160 采样(TIM3 1kHz 事件驱动 + 原子快照 + STM32 ADC DMA,纯消费者)",
|
||||
"iec104Task": "IEC 60870-5-104 上行(:2404 监听,遥信/遥测/定值区)",
|
||||
"protectTask": "保护判据 20ms 节拍(L3 元件 + 采样故障闭锁,B5)",
|
||||
"protectTask": "保护判据 20ms 节拍(保护判据元件 + 采样故障闭锁,B5)",
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:通道标定层(L1.5,adc_cal)主机侧单元测试
|
||||
* 模块名称:通道标定层(标定折算,adc_cal)主机侧单元测试
|
||||
* 被测对象:真实源文件 App/algo/adc_cal.c + App/cfg/cfg_file.c(均 #include
|
||||
* 原样纳入——标定落盘与整定入口的持久化契约必须用真引擎测,不造轮子替身)。
|
||||
* 平台依赖桩:dbg_log.h(stub/ 计数宏)、cfg_store_*(本文件内存
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""通道标定层(L1.5,adc_cal)主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
"""通道标定层(标定折算,adc_cal)主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
|
||||
做什么:
|
||||
用本机 MSVC 编译 test/host/adc_cal/adc_cal_test.c(它以 #include 纳入
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:ADC 输入层(L1)主机侧单元测试
|
||||
* 模块名称:ADC 输入层(语义取数与有效性)主机侧单元测试
|
||||
* 模块功能:在 PC 上对 App/algo/adc_input.c 做离线验证(8 个公开函数 + 2 个静态函数)。
|
||||
*
|
||||
* 被测对象:真实源文件 ../../../App/algo/adc_input.c(以 #include 原样纳入,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""ADC 输入层(L1,adc_input)的主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
"""ADC 输入层(语义取数与有效性,adc_input)的主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
|
||||
做什么:
|
||||
用本机 MSVC 编译 test/host/adc_input/adc_input_test.c(它以 #include 纳入
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:频率测量层(L2 派生量,B8)主机侧单元测试
|
||||
* 模块名称:频率测量层(全周傅氏相量的派生量,B8)主机侧单元测试
|
||||
* 模块功能:在 PC 上对 App/algo/freq.c + phasor.c + sample_ring.c 做离线验证。
|
||||
*
|
||||
* 被测对象:真实源文件(#include 原样纳入,纯算法无需桩):
|
||||
@@ -72,7 +72,7 @@ static double s_noise_unit(void) { /* [-0.5, 0.5) */
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:合成一拍整帧并跑一遍 L2+测频链
|
||||
* 函数功能:合成一拍整帧并跑一遍 全周傅氏相量+测频链
|
||||
* 入口参数:f - 信号频率(Hz)
|
||||
* amp - 基波峰值(码值)
|
||||
* dc - 直流偏置(码值)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""频率测量层(L2 派生量,B8)主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
"""频率测量层(全周傅氏相量的派生量,B8)主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
|
||||
做什么:用本机 MSVC 离线编译 test/host/freq/freq_test.c(#include 纳入生产
|
||||
源文件 App/algo/freq.c + phasor.c + sample_ring.c),验证相位解缠绕
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:遥测快照发布层(L2 派生·发布侧)主机侧单元测试
|
||||
* 模块名称:遥测快照发布层(全周傅氏相量派生·发布侧)主机侧单元测试
|
||||
* 被测对象:真实源文件(#include 原样纳入,测生产代码而非副本):
|
||||
* App/algo/meas.c + App/algo/phasor.c + App/algo/sample_ring.c
|
||||
* 三源均为纯算法(无寄存器/RTOS/文件依赖)→ **无需任何桩**。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""遥测快照层(L2 发布侧,meas)主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
"""遥测快照层(全周傅氏相量发布侧,meas)主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
|
||||
做什么:
|
||||
用本机 MSVC 编译 test/host/meas/meas_test.c(它以 #include 纳入
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 模块名称:相量层(L2)主机侧单元测试
|
||||
* 模块名称:相量层(全周傅氏相量)主机侧单元测试
|
||||
* 模块功能:在 PC 上对 App/algo/phasor.c + App/algo/sample_ring.c 做离线验证。
|
||||
*
|
||||
* 被测对象:真实源文件(以 #include 原样纳入,保证测的是生产代码而非副本):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""相量层(L2)的主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
"""相量层(全周傅氏相量)的主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
|
||||
做什么:
|
||||
用本机 MSVC 编译 test/host/phasor/phasor_test.c(它以 #include 纳入**生产源文件**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 模块名称:量纲回归主机侧单测(「数据可信」量纲回归用例 · 道A)
|
||||
* 被测对象:真实源文件(#include 原样纳入,全链路 L1.5→L2→L3):
|
||||
* 被测对象:真实源文件(#include 原样纳入,全链路 标定折算→全周傅氏相量→保护判据):
|
||||
* adc_cal.c + prot_set.c + sample_ring.c + phasor.c + freq.c +
|
||||
* prot_elm.c
|
||||
* 平台依赖桩:dbg_log.h(stub/)、cfg_file_register(捕获计数)、
|
||||
@@ -122,7 +122,7 @@ static int32_t dim_code(double eng, double b_codes) {
|
||||
}
|
||||
|
||||
/* 一拍:三相量按 50 Hz 正弦(峰值 = rms×√2),其余电气量通道给 0 码值,
|
||||
* TEMP 透传 0;随后跑真实 L2 链。 */
|
||||
* TEMP 透传 0;随后跑真实 全周傅氏相量链。 */
|
||||
static void dim_beat(double ia_rms, double ua_rms, double un_rms) {
|
||||
float frame[ADC_SEM_COUNT];
|
||||
double s50 = sin(2.0 * 3.14159265358979 * 50.0 * (double)s_t / 1000.0);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* 模块名称:保护元件框架(L3,P1 子集)主机侧单元测试
|
||||
* 模块名称:保护元件框架(保护判据,P1 子集)主机侧单元测试
|
||||
* 模块功能:在 PC 上对 App/algo/prot_elm.c 的判据核做离线验证。
|
||||
*
|
||||
* 被测对象:真实源文件(#include 原样纳入):
|
||||
* prot_elm.c + prot_set.c(判据吃定值 RAM)
|
||||
* phasor.c + sample_ring.c + freq.c(prot_elm.c 链接依赖;
|
||||
* TC-PROTELEM-001~010 走 prot_elm_eval 纯判据路径,TC-PROTELEM-013 走
|
||||
* run() 适配层 = 合成波形跑真实 L2+测频链)
|
||||
* run() 适配层 = 合成波形跑真实 全周傅氏相量+测频链)
|
||||
*
|
||||
* 覆盖点(docs/算法/继电保护功能复现规划.md §3.3 三段式相间过流 等、§8 验收):
|
||||
* TC-PROTELEM-001 init:全状态清零、动作位图 0
|
||||
@@ -391,7 +391,7 @@ static void tc_uf_direction(void) {
|
||||
CHECK(st.picked == 0u, "TC-PROTELEM-012 UF NOT picked at 52 (direction isolation)");
|
||||
}
|
||||
|
||||
/* ---- run() 适配层驱动:合成波形跑真实 L2+测频链(同 freq_test 口径) ---- */
|
||||
/* ---- run() 适配层驱动:合成波形跑真实 全周傅氏相量+测频链(同 freq_test 口径) ---- */
|
||||
static uint32_t s_t = 0u;
|
||||
|
||||
static void drive_beat(double f, double amp) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""保护元件框架(L3,P1 子集)主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
"""保护元件框架(保护判据,P1 子集)主机侧单元测试运行器(L0.5,纯标准库)。
|
||||
|
||||
做什么:用本机 MSVC 离线编译 test/host/prot_elm/prot_elm_test.c(#include 纳入
|
||||
生产源文件 prot_elm.c + prot_set.c + phasor.c + sample_ring.c),验证
|
||||
|
||||
@@ -87,7 +87,7 @@ TASK_STACKS = [
|
||||
("uiTask", 16384, "BelowNormal", 4052, 4052, 12332, 75, "PASS", "LVGL UI 主循环 + 远程显示推流"),
|
||||
("testTask", 8192, "BelowNormal", 736, 736, 7456, 91, "PASS", "测试套件(产品构建不创建,取静态最坏链)"),
|
||||
("timeSyncTask", 2560, "Normal", 1264, 648, 1296, 50, "PASS", "TCP 时间同步(8888)"),
|
||||
("adcTask", 2560, "AboveNormal", 1320, 952, 1240, 48, "PASS", "1 kHz 节拍消费者(L1 采集,纯取数)"),
|
||||
("adcTask", 2560, "AboveNormal", 1320, 952, 1240, 48, "PASS", "1 kHz 节拍消费者(语义取数与有效性采集,纯取数)"),
|
||||
("iec104Task", 2560, "Normal", 1456, 540, 1104, 43, "PASS", "IEC 60870-5-104 上行(2404)"),
|
||||
("protectTask", 2048, "Normal", 872, 828, 1176, 57, "PASS", "20 ms 保护判据 + 闭锁 + 定值校验和巡检"),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user