docs(algo): L2 相量层台架闭环收尾,P0 里程碑达成(证据+栈复测)

- @test 新增 Required 标记 phasor(first)/phasor(hb) 并校验顺序
  App init OK>phasor(first)>phasor(hb) → PASS(net init: OK 不在序内:
  adcTask 与 netTask 并行,phasor(first)≈+500ms 早于 net init 属正常)
- 证据归档 boot_log_data/20261011_prod_phasor_boot_log.txt:5 实例相量
  开机即产出、frames 每 10s +10000(1000.0 Hz)、idle=0、零 [ERR]、
  fw build 身份戳匹配、回读一致、锚点 ×1
- 栈复测:adcTask 静态 832 B / 实测峰值 928/2048(余 54%),7 任务
  全 PASS;RAM 方案 §2.3 基线同步
- 规划 §3.1 L1-9、§3.2 L2-1~L2-4/L2-6/L2-7 置 ✅(精度判据保留
  "待标准源"注);L2-5 更正为"V0.1 不适用、随 V0.2"(N-18 + 外部
  零序专用通道,原表下注系误记);§7.1 P0 里程碑置 ✅
- 自动化测试流程登记 phasor 常开标记(hb 需采集窗口 ≥10s)
This commit is contained in:
2026-10-11 00:56:23 +08:00
parent 54d6d2d5d5
commit 6c8f82ec54
4 changed files with 135 additions and 14 deletions
@@ -93,6 +93,8 @@
> ✅ **本表已于 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%)**,
> 增量为压环 + `phasor_run()`(`win[20]` 80 B)+ `log_phasors` 日志链;仍高于 1024 B 底线,7 任务全 PASS。
> 此前 2026-10-04 的 V5 30 min 重采曾把 defaultTask 推到 **3664B/4096(余量 432B ≈ 10%,登记 S-1)**;
> 2026-10-10 的栈整改(**未抬栈**,见 §4 阶段 0 的"2026-10-10 复测")把它压回 **2152B/4096**,S-1 已销项。
@@ -104,7 +106,7 @@
| testTask | `2048*4` | 8KB | 测试套件(产品构建不创建;存储套件深链需要) | 未创建 / 静态 496 B |
| defaultTask | `1024*4` | 4KB | FatFS 挂载/探针 + 配置引擎 + syslog + 栈水位探针 | 2152 B(余 47%)/ 静态 2776 B |
| timeSyncTask | `512*4` | 2KB | TCP 时间同步 | 616 B(余 69%)/ 静态 **1024 B**(= ISR 底线,无再加深空间) |
| adcTask | `512*4` | 2KB | TPAFE5160 采样(1 ms 采样节拍触发 CONVST + 原子快照消费,B1 2026-10-10) | **496 / 2048**(余 1552 B / 75%,台架 `@test` 实测);静态 504 B |
| adcTask | `512*4` | 2KB | TPAFE5160 采样消费 + L2 相量(TIM3 1 kHz 节拍 + 快照 + 压环 + 全周傅氏,B1→L2 2026-10-11) | **928 / 2048**(余 1120 B / 54%,台架 `@test` 实测 2026-10-11);静态 832 B |
| idle(内核) | `configMINIMAL_STACK_SIZE=128` | 0.5KB | 空闲 | 未观测(未取句柄) |
| timer(内核) | `configTIMER_TASK_STACK_DEPTH=256` | 1KB | 软定时器 | 未观测 |
@@ -0,0 +1,117 @@
[+0ms] A-F5: Re=0 Im=1 rms=1 (x0.1)
[+8522ms] [----/--/-- --:--:--][APP] boot: syslog init OK
[+8522ms] [----/--/-- --:--:--][APP] fw build: Oct 11 2026 00:38:20
[+8532ms] [----/--/-- --:--:--][APP] reset cause: software (NVIC_SystemReset) (CSR=0x14000000)
[+8532ms] PREVRUN seg=2 seq=1914584053 t=10556
[+8543ms] TICKRUN uw=10569 n=10569 duw=13
[+8543ms] [----/--/-- --:--:--][RTC] sd2506_init: OK
[+8543ms] [----/--/-- --:--:--][APP] SD2506 init: OK (ret=0)
[+8553ms] [2026-10-10 16:51:42][CLK] sys_clock_init: RTC initial time 2026-10-10 16:51:42
[+8564ms] [2026-10-10 16:51:42][CLK] sys_clock_init: wall clock base = unix 1791651102, base_tick=137
[+8564ms] [2026-10-10 16:51:42][APP] RS485 init: OK (UART4, DE=PA15)
[+8585ms] [2026-10-10 16:51:42][NAND] Resetting NAND...
[+8606ms] [2026-10-10 16:51:42][NAND] Reading NAND ID...
[+8606ms] [2026-10-10 16:51:42][NAND] NAND ID: MID=0xC8, DID=0x52
[+8606ms] [2026-10-10 16:51:42][NAND] Scanning bad blocks...
[+8748ms] [2026-10-10 16:51:42][NAND] BBT scan: 0 bad blocks found
[+8748ms] [2026-10-10 16:51:42][NAND] Enabling ECC...
[+8758ms] [2026-10-10 16:51:42][NAND] Unlocking block protection...
[+8758ms] [2026-10-10 16:51:42][NAND] Locating BBT pool...
[+8758ms] [2026-10-10 16:51:42][NAND] Loading persisted BBT...
[+8769ms] [2026-10-10 16:51:42][NAND] NAND init OK
[+8769ms] [2026-10-10 16:51:42][APP] NAND init: OK
[+8779ms] [2026-10-10 16:51:42][ADC] Init OK
[+8779ms] [2026-10-10 16:51:42][APP] ADC init: OK
[+8790ms] [2026-10-10 16:51:42][APP] ADC input layer init: OK
[+8790ms] [2026-10-10 16:51:42][APP] phasor layer init: OK (inst=5)
[+8800ms] [2026-10-10 16:51:42][APP] SD2506 ID: 2512153425482405
[+8800ms] [2026-10-10 16:51:42][APP] SD2506 time: 2026-10-10 16:51:42 (week 2)
[+8813ms] [2026-10-10 16:51:42][APP] SD2506 temp: 28 C
[+8813ms] [2026-10-10 16:51:42][APP] SD2506 battery: 3.11 V
[+8823ms] [2026-10-10 16:51:42][APP] App init OK
[+8823ms] [2026-10-10 16:51:42][NAND_FTL] Initializing NAND FTL...
[+8854ms] [2026-10-10 16:51:42][NAND_FTL] Map resumed: 14094/97504 sectors used
[+8854ms] [2026-10-10 16:51:42][NAND_FTL] Map head=116992 tail=99819 epoch=1
[+8865ms] [2026-10-10 16:51:42][NAND_FTL] NAND FTL ready (capacity: 97504 pages = 190 MB)
[+8936ms] [2026-10-10 16:51:42] [FS] FATFS mounted
[+8988ms] [2026-10-10 16:51:42][SYSLOG] runlog boot entry: reboot
[+8988ms] [2026-10-10 16:51:42][CFG] register: section 'network' (4 keys)
[+8999ms] [2026-10-10 16:51:42][CFG] load: OK (523B, heap free 15240B)
[+9009ms] [2026-10-10 16:51:42][NET_CFG] load: OK ip=192.168.1.100
[+9030ms] [2026-10-10 16:51:42][ADC_TASK] first: UA=11429 UB=975 UC=840 UN=11454 IA=11451 IB=930 IC=1004 IN=889 T=904
[+9040ms] [2026-10-10 16:51:42][ADC_TASK] phasor(first) C01-IA-F1: Re=0 Im=-3 rms=3 (x0.1)
[+9051ms] [2026-10-10 16:51:42][ADC_TASK] phasor(first) C02-UA-F1: Re=1 Im=0 rms=1 (x0.1)
[+9062ms] [2026-10-10 16:51:42][ADC_TASK] phasor(first) C03-UN-F1: Re=-1 Im=-1 rms=1 (x0.1)
[+9062ms] [2026-10-10 16:51:42][ADC_TASK] phasor(first) C04-IA-F2: Re=1 Im=2 rms=2 (x0.1)
[+9072ms] [2026-10-10 16:51:42][ADC_TASK] phasor(first) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[+9083ms] [2026-10-10 16:51:42][NET_TASK] === Network Init ===
[+9083ms] [2026-10-10 16:51:42][NET_TASK] net init: OK
[+9094ms] [2026-10-10 16:51:42][NET_TASK] MAC: 3C:AB:72:53:2B:12
[+9094ms] [2026-10-10 16:51:42][NET_TASK] IP_INF: IP=192.168.1.100 GW=192.168.1.1 MASK=255.255.255.0
[+9104ms] MISS start snap=0x00000067 req=0x00000077 t=686
[+9104ms] [2026-10-10 16:51:42][WD] [WD] armed: timeout ~2498ms (worst ~1701ms), miss_tol=800ms
[+9115ms] [2026-10-10 16:51:42][UI_TASK] UI task: started, wait net ready
[+11071ms] [2026-10-10 16:51:44][NET_TASK] PHY: 100M FULL
[+11071ms] [2026-10-10 16:51:44][NET_TASK] netTask: started (single-socket mode)
[+11112ms] [2026-10-10 16:51:44] [FTP] waiting for connection...
[+11154ms] [2026-10-10 16:51:44][TIME_SYNC] time_sync: TCP listen on :8888 (sock=1)
[+11154ms] [2026-10-10 16:51:44][UI_TASK] UI task: net ready, init port
[+11164ms] [2026-10-10 16:51:44][UI_TASK] UI task: ui_port_init enter
[+11175ms] [2026-10-10 16:51:44][UI_PORT] theme: mono dark_bg=true applied
[+11175ms] [2026-10-10 16:51:44][UI_TASK] UI port init: OK
[+11185ms] [2026-10-10 16:51:44][UI_TASK] UI task: ui_menu_init enter
[+11185ms] [2026-10-10 16:51:44][UI_MENU] menu build start: total=39408 free=36572 big=36572
[+11195ms] [2026-10-10 16:51:44][UI_MENU_VIEW] view init: root frame w=66 h=107
[+11206ms] [2026-10-10 16:51:44][UI_MENU] menu build done: total=39292 free=35708 big=35696 used=3584
[+11206ms] [2026-10-10 16:51:44][UI_TASK] UI menu init: OK
[+11216ms] [2026-10-10 16:51:44][UI_STANDBY] standby: ready (idle=60000ms)
[+11227ms] [2026-10-10 16:51:44][UI_TASK] UI standby: ready (idle=60s)
[+11268ms] [2026-10-10 16:51:44][UI_TASK] UI net sink: started (port 7003)
[+11279ms] MISS start snap=0x00000067 req=0x00000077 t=2861
[+11279ms] [PROF] t=2865 uic=0 uip=0 uipn=0 uil=0 uiw=0 uis=0 uisn=0 adc=2458 adcm=2067 adcn=0 gl=0
[+11289ms] [PROF2] t=2865 defd=11937 defs=7 netp=0 netn=0 adcp=8 adcq=0 gl=0
[+13444ms] [PROF] t=5028 uic=213 uip=20263 uipn=8995 uil=9999 uiw=10317 uis=1 uisn=0 adc=4621 adcm=2067 adcn=0 gl=0
[+13455ms] [PROF2] t=5028 defd=11937 defs=7 netp=0 netn=0 adcp=8 adcq=0 gl=0
[+13858ms] [2026-10-10 16:51:47] [STACK] default peak_used=2152/4096 free_min=1944 (47%)
[+13868ms] [2026-10-10 16:51:47] [STACK] net peak_used=940/3840 free_min=2900 (75%)
[+13868ms] [2026-10-10 16:51:47] [STACK] ftp peak_used=740/4096 free_min=3356 (81%)
[+13879ms] [2026-10-10 16:51:47] [STACK] ui peak_used=4052/16384 free_min=12332 (75%)
[+13889ms] [2026-10-10 16:51:47] [STACK] timesync peak_used=616/2048 free_min=1432 (69%)
[+13889ms] [2026-10-10 16:51:47] [STACK] adc peak_used=928/2048 free_min=1120 (54%)
[+13900ms] [2026-10-10 16:51:47] [STACK] heap free=15088 min_ever=7152
[+15454ms] [PROF] t=7041 uic=408 uip=58799 uipn=9995 uil=9999 uiw=10317 uis=1 uisn=0 adc=6634 adcm=2067 adcn=0 gl=0
[+15465ms] [PROF2] t=7041 defd=11937 defs=7 netp=0 netn=0 adcp=8 adcq=0 gl=0
[+17476ms] [PROF] t=9057 uic=608 uip=58799 uipn=9995 uil=9999 uiw=10317 uis=1 uisn=0 adc=8650 adcm=2067 adcn=0 gl=0
[+17486ms] [PROF2] t=9057 defd=11937 defs=7 netp=0 netn=0 adcp=8 adcq=0 gl=0
[+18829ms] [2026-10-10 16:51:52][ADC_TASK] frames=10001 idle=0 skip=24 seq=10006 frst_err=0 ring=9977 adc1_rc=0 adc1_err=0 adc1_seq=10004 adc1_gap=24 adc1_hw=0
[+18840ms] [2026-10-10 16:51:52][ADC_TASK] phasor(hb) C01-IA-F1: Re=-1 Im=3 rms=3 (x0.1)
[+18850ms] [2026-10-10 16:51:52][ADC_TASK] phasor(hb) C02-UA-F1: Re=-2 Im=-1 rms=3 (x0.1)
[+18850ms] [2026-10-10 16:51:52][ADC_TASK] phasor(hb) C03-UN-F1: Re=-2 Im=0 rms=2 (x0.1)
[+18860ms] [2026-10-10 16:51:52][ADC_TASK] phasor(hb) C04-IA-F2: Re=2 Im=1 rms=3 (x0.1)
[+18860ms] [2026-10-10 16:51:52][ADC_TASK] phasor(hb) C05-IA-F5: Re=2 Im=0 rms=2 (x0.1)
[+19523ms] [PROF] t=11106 uic=807 uip=58799 uipn=9995 uil=9999 uiw=10317 uis=1 uisn=0 adc=10699 adcm=2067 adcn=0 gl=0
[+19533ms] [PROF2] t=11106 defd=47235 defs=7 netp=0 netn=0 adcp=11 adcq=0 gl=0
[+21545ms] [PROF] t=13123 uic=1007 uip=58799 uipn=9995 uil=9999 uiw=10317 uis=1 uisn=0 adc=12716 adcm=2067 adcn=0 gl=0
[+21545ms] [PROF2] t=13123 defd=47235 defs=7 netp=0 netn=0 adcp=11 adcq=0 gl=0
[+23553ms] [PROF] t=15140 uic=1207 uip=58799 uipn=9995 uil=9999 uiw=10317 uis=1 uisn=0 adc=14733 adcm=2067 adcn=0 gl=0
[+23563ms] [PROF2] t=15140 defd=47235 defs=7 netp=0 netn=0 adcp=11 adcq=0 gl=0
[+25575ms] [PROF] t=17157 uic=1407 uip=58799 uipn=9995 uil=9999 uiw=10317 uis=1 uisn=0 adc=16750 adcm=2067 adcn=0 gl=0
[+25586ms] [PROF2] t=17157 defd=47235 defs=7 netp=0 netn=0 adcp=11 adcq=0 gl=0
[+27596ms] [PROF] t=19174 uic=1607 uip=58799 uipn=9995 uil=9979 uiw=10317 uis=1 uisn=0 adc=18767 adcm=2067 adcn=0 gl=0
[+27596ms] [PROF2] t=19174 defd=47235 defs=7 netp=0 netn=0 adcp=11 adcq=0 gl=0
[+28829ms] [2026-10-10 16:52:02][ADC_TASK] frames=20000 idle=1 skip=26 seq=20006 frst_err=0 ring=19974 adc1_rc=0 adc1_err=0 adc1_seq=20004 adc1_gap=26 adc1_hw=0
[+28840ms] [2026-10-10 16:52:02][ADC_TASK] phasor(hb) C01-IA-F1: Re=5 Im=1 rms=5 (x0.1)
[+28840ms] [2026-10-10 16:52:02][ADC_TASK] phasor(hb) C02-UA-F1: Re=-1 Im=-1 rms=2 (x0.1)
[+28850ms] [2026-10-10 16:52:02][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=-2 rms=2 (x0.1)
[+28861ms] [2026-10-10 16:52:02][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=1 rms=1 (x0.1)
[+28861ms] [2026-10-10 16:52:02][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[+29622ms] [PROF] t=21206 uic=1804 uip=58799 uipn=9995 uil=9999 uiw=10317 uis=1 uisn=0 adc=20799 adcm=2067 adcn=0 gl=0
[+29632ms] [PROF2] t=21206 defd=47236 defs=7 netp=0 netn=0 adcp=11 adcq=0 gl=0
[+31642ms] [PROF] t=23223 uic=2004 uip=58799 uipn=9995 uil=9999 uiw=10317 uis=1 uisn=0 adc=22816 adcm=2067 adcn=0 gl=0
[+31652ms] [PROF2] t=23223 defd=47236 defs=7 netp=0 netn=0 adcp=11 adcq=0 gl=0
[+33653ms] [PROF] t=25240 uic=2204 uip=58799 uipn=9995 uil=9999 uiw=10317 uis=1 uisn=0 adc=24833 adcm=2067 adcn=0 gl=0
[+33663ms] [PROF2] t=25240 defd=47236 defs=7 netp=0 netn=0 adcp=11 adcq=0 gl=0
[+35670ms] [PROF] t=27257 uic=2404 uip=58799 uipn=9995 uil=9999 uiw=10317 uis=1 uisn=0 adc=26850 adcm=2067 adcn=0 gl=0
[+35681ms] [PROF2] t=27257 defd=47236 defs=7 netp=0 netn=0 adcp=11 adcq=0 gl=0
[+37692ms] [PROF] t=29274 uic=2604 uip=58799 uipn=9995 uil=9979 uiw=10317 uis=61 uisn=0 adc=28867 adcm=2067 adcn=0 gl=0
[+37702ms] [PROF2] t=29274 defd=47236 defs=7 netp=0 netn=0 adcp=11 adcq=0 gl=0
@@ -65,6 +65,7 @@
| `ADC init:` | `App/app/app_main.c` |
| `SD2506 ID:` / `time:` / `temp:` / `battery:` | `App/app/app_main.c` |
| `Network Init` / `net init: OK` / `MAC:` / `PHY:` | `App/task/net_task.c` |
| `phasor(first)` / `phasor(hb)` | `App/task/adc_task.c`(L2 相量层,2026-10-11 起常开;`hb` 每 10 s 一次,采集窗口需 ≥10 s——默认 `max_wait 30 s` 覆盖) |
**默认 Forbidden 模式**:`FAIL;ERROR;HardFault;[ERR]`
+14 -13
View File
@@ -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/待处理内容.md`、`docs/内存管理/RAM使用分析与优化方案.md`。
> **状态**:规划稿——保护链路本体尚未实现;其前置的 **ADC 采集链路(`adc_task`)已于 2026-10-10 实现并 `@test` 实机闭环**(B1:周期 CONVST + 原子快照消费 + 建任务 + 栈预算 + 台架 1000 Hz 确认)。
> **状态**:**P0 采样与相量底座已台架闭环(2026-10-11)**——L1 采集链路(B1,2026-10-10)与 L2 相量层(`sample_ring` + `phasor`,57 项主机单测 + 台架 `@test` 含 `phasor(first)/phasor(hb)` 标记闭环)均已落地;**L3 保护元件 / L4 出口记录 / L5 自检闭锁与定值模型尚未实现**(下一步 = P1,见 §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 乒乓帧消费(L1-3/L1-4,v2.0)**,`HAL_ADC_Start_DMA` 已出现 |
| 保护算法层 | **完全缺失**(无傅氏、无保护元件、无出口、无定值模型) |
| 保护算法层 | **L2 相量层已实现并台架闭环**(`App/algo/sample_ring.c` + `phasor.c`:全周傅氏 5 实例、双区交换、每 1 ms 刷新,2026-10-11 `@test`);**保护元件 / 出口 / 定值模型仍缺失**(P1 起) |
| 已知硬件缺陷 | **N-18**:8 路电气量分属两片转换器 → V0.1 上禁止跨转换器做相位/功率/矢量运算 |
### 1.3 复现范围界定
@@ -67,7 +67,7 @@
| **B0 产品定义** | 采集是否持续 / 采样率与通道 / 转发目标 / 保护元件清单——决定 B1 与保护层的**规模** | ✅ 已确认(2026-10-10,见 §1.5) |
| **B1 ADC 采集链路** | 周期 CONVST + `adc_task` 消费 `tpafe5160_snapshot()` + 建任务 + 栈预算 | ✅ 已实现并 `@test` 实机闭环(2026-10-10;`adcTask` 512 words,台架 1000 Hz) |
| **N-18 硬件缺陷** | V0.1 跨转换器无同一时刻性 → 限定 V0.1 可实现的保护范围 | ⚠️ 硬件改版项(V0.2) |
| **栈预算** | 保护任务栈需入 `Src/freertos.c` 并经 `scripts/stack_report.py` 核算 | 🔶 `adcTask` 已核算(静态 504 B / 余 75%;台架实测峰值 496/2048);保护任务为后续 |
| **栈预算** | 保护任务栈需入 `Src/freertos.c` 并经 `scripts/stack_report.py` 核算 | 🔶 `adcTask` 已核算(**L2 接入后复测 2026-10-11:静态 832 B / 台架实测峰值 928/2048 / 余 54%**);`protectTask` 为后续 |
### 1.5 B0 产品定义(2026-10-10 确认)
@@ -246,7 +246,7 @@
| L1-6 | 采样有效性校验 | FRSTDATA 跳变、帧序号单调、丢帧计数 | 芯片静默/丢帧被检出并置告警 | ⬜ |
| L1-7 | 等周波采样(软件测频 + 调频闭环) | 20 点/周波;测频范围建议 **45~55 Hz**(参考 40.5~60.5) | 频率偏移 ±2 Hz 时幅值误差 ≤ 1% | ⬜ |
| L1-8 | 零序通道接入(外部专用 / 自产切换) | 外部 `UN`/`IN`;自产 `3I0 = Ia+Ib+Ic`(V0.2 起) | 零序通道可切换来源,值正确 | ⬜ |
| L1-9 | 二次谐波/五次谐波提取入口 | k=2(涌流)、k=5(选线) | 相量层可产出对应谐波相量 | ⬜ |
| L1-9 | 二次谐波/五次谐波提取入口 | 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/`) |
> ⚠️ **N-18 约束**:L1-4 中 `UA/UN/IA` 在 TPAFE、`UB/UC/IB/IC/IN` 在 STM32 ADC。V0.1 上 L1 只做**逐通道独立监视**,不得假设同族量同刻(`UA` 与 `UB` 无共同采样触发)。
@@ -254,20 +254,20 @@
| # | 功能点 | 关键参数 | 完成判据 | 状态 |
| --- | --- | --- | --- | --- |
| L2-1 | 全周傅氏系数表 | `sin(2πk/N)·(√2/N)`、`cos(2πk/N)·(√2/N)`,N=20 | 系数表与 `docs/算法/傅氏算法详解.md` §2.3 一致 | ⬜ |
| L2-2 | 基波相量实例 | **5 个实例**(参考项目 4 个,见下方注):`C01-IA-F1` / `C02-UA-F1` / `C03-UN-F1` / `C04-IA-F2` / `C05-IA-F5` | 每实例输出 `{fRe, fIm, fAm, fAmSQ}` | ⬜ |
| L2-3 | 相量有效值输出 | `fAmSQ = √(fRe²+fIm²)` 直接为**有效值**(系数已折算) | 标准源读数 = 设定有效值 | ⬜ |
| L2-4 | 相位输出 | `φ = atan2(fIm, fRe)` | 相位误差 ≤ 目标值 | ⬜ |
| L2-5 | 线/负序/零序合成 | 线电压 `Uab=Ua−Ub` 等;负序 `3U2`/`3I2`;零序 `3U0`/`3I0` | 合成相量可复用于保护元件(**V0.1 仅同转换器内可合成**,见 §1.6) | ⬜ |
| L2-6 | 每 1 ms 滑动窗刷新 | 每来新点,窗滑动一格、20 点重算(暴力法) | 相量每拍更新 | ⬜ |
| L2-7 | 双区指针原子交换 | 计算区/使用区切换 | 保护元件读使用区,无撕裂 | ⬜ |
| L2-1 | 全周傅氏系数表 | `sin(2πk/N)·(√2/N)`、`cos(2πk/N)·(√2/N)`,N=20 | 系数表与 `docs/算法/傅氏算法详解.md` §2.3 一致 | ✅ 2026-10-11:`phasor.c` 离线系数表**预乘 √2/N**;主机单测逐项复核(`test/host/phasor/` 系数表用例) |
| L2-2 | 基波相量实例 | **5 个实例**(参考项目 4 个,见下方注):`C01-IA-F1` / `C02-UA-F1` / `C03-UN-F1` / `C04-IA-F2` / `C05-IA-F5` | 每实例输出 `{fRe, fIm, fAm, fAmSQ}` | ✅ 2026-10-11:`k_inst[]` 数据驱动 5 实例;台架开机即产出 `phasor(first)` 5 行(`boot_log_data/20261011_prod_phasor_boot_log.txt`) |
| L2-3 | 相量有效值输出 | `fAmSQ = √(fRe²+fIm²)` 直接为**有效值**(系数已折算) | 标准源读数 = 设定有效值 | ✅ 2026-10-11(链路级):`fAmSQ` 口径实现 + 单测合成正弦幅值误差 ≤1%;**"标准源读数"判据在无信号源台架不可达**(同 §7.1),待 L1-5 标定后复核 |
| L2-4 | 相位输出 | `φ = atan2(fIm, fRe)` | 相位误差 ≤ 目标值 | ✅ 2026-10-11(链路级):`fRe/fIm` 常驻双区、每拍产出,φ 由消费侧 `atan2f` 现算(不常驻结构体,见 `App/algo/README.md` §3.3);单测覆盖相位;**目标值待产品定义 + 标准源复核** |
| L2-5 | 线/负序/零序合成 | 线电压 `Uab=Ua−Ub` 等;负序 `3U2`/`3I2`;零序 `3U0`/`3I0` | 合成相量可复用于保护元件(**V0.1 仅同转换器内可合成**,见 §1.6) | ⬜ **V0.1 不适用**:跨转换器合成被 N-18 禁止;零序走**外部专用通道** `UN`/`IN`(§6.4),无需自产 → 随 V0.2 启用 |
| L2-6 | 每 1 ms 滑动窗刷新 | 每来新点,窗滑动一格、20 点重算(暴力法) | 相量每拍更新 | ✅ 2026-10-11:`sample_ring` 40 点环 + `phasor_run()` 每拍整窗重算(仅 `r==1` 新帧压环,P0 修复);台架 `ring` 随 `frames` 同步递增、`idle=0` |
| L2-7 | 双区指针原子交换 | 计算区/使用区切换 | 保护元件读使用区,无撕裂 | ✅ 2026-10-11:`s_zone[2][5]` + 单字节 `volatile` 切换(Cortex-M 原子);单测覆盖双区交换;为独立 L3 任务预留无锁读 |
| L2-8 | 遥测谐波轨(可选) | k=1~9,方和根 `√(ΣHk²)` | 与基波轨并行,供 UI/上送 | ⬜ |
> **双轨有效值**:保护要"基波有效值 + 相位"(抗衰减直流、抗谐波误动);计量/遥测要"真有效值"(谐波方和根)。两者**不可混用**——这是参考系统 `CN_ANA_VEC_SQRT=FALSE` 与遥测谐波轨并存的根本原因。
> **L2-2 实例数 4 → 5 的来历**:参考项目(`APP/CLS100_Dsp/InstCalCell.c`)为 **4 个实例**——C01 基波 I/U、C02 零序基波、C03 二次谐波、C04 五次谐波。本项目按 V0.1 **有效通道**(`UA`/`UN`/`IA`,见 §1.6:`UB/UC/IB/IC/IN` 无中点偏置 → 削顶不可用)展开:C01 的"I/U"拆为两行(`C01-IA-F1` 电流 / `C02-UA-F1` 电压),其余顺延为 `C03-UN-F1` 零序、`C04-IA-F2` 二次、`C05-IA-F5` 五次。实现见 `App/algo/phasor.c` 的 `k_inst[]`;判据按 **5** 个实例断言(见 `docs/测试说明/相量层单元测试说明.md` §2.6)。
> **本表状态列口径**:L2-1~L2-7 的**实现与主机单测已完成**(`App/algo/phasor.c` + `App/algo/sample_ring.c`;`test/host/phasor/` 57 用例全绿),但状态**仍标 ⬜**——**台架 `@test` 闭环未做**,且 L2-3 的完成判据"标准源读数 = 设定有效值"在无信号源台架上不可达(同 §7.1 无示波器口径)。待台架闭环后统一置 ✅。
> **本表状态列口径**(2026-10-11 更新):L2-1~L2-4 / L2-6 / L2-7 已**实现 + 主机单测(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 无示波器口径),且 L1-5 标定未实现 → 现读数为**原始码值**,只证明链路通;精度复核排在标定之后。L2-5 随 V0.2(N-18),L2-8 可选项未做。
### 3.3 L3 保护元件
@@ -463,7 +463,7 @@
| 阶段 | 名称 | 内容 | 前置 | 里程碑 |
| --- | --- | --- | --- | --- |
| **P0** | 采样与相量底座 | B1(周期 CONVST + `adcTask` 消费 + 建任务 + 栈预算)+ L1 + L2 | B0 + B1 ✅ | 每 1 ms 产出正确的基波相量 |
| **P0** | 采样与相量底座 | B1(周期 CONVST + `adcTask` 消费 + 建任务 + 栈预算)+ L1 + L2 | B0 + B1 ✅ | 每 1 ms 产出正确的基波相量 —— **✅ 2026-10-11 台架闭环**(L1-5 标定 / L1-6 有效性 / L1-7 等周波为 P0 遗留项,精度复核依赖标准源) |
| **P1** | 基础保护元件 | **V0.1 有效子集**:过流(A 相,`IA`)、过负荷(A 相)+ 定值模型;B/C 相过流**建接口不使能** | P0 | 标准源注入 A 相可正确动作 |
| **P2** | 电压/频率类保护 | 过压/欠压(`UA`)、过频/低频、零序过压(`UN`) | P0 | 电压/频率越限正确动作 |
| **P3** | 异常检测与闭锁 | L5 自检闭锁、采样通道自检;三相类(涌流/PT·CT 断线/母线接地)**建接口不使能** | P1/P2 | 自检失败闭锁;未使能元件不误动 |
@@ -601,3 +601,4 @@ B0 产品定义 ✅(2026-10-10 已确认,见 §1.5)
| 2026-10-10 | **L1-3/L1-4 落地:STM32 ADC1 扫描 + 语义映射** | 新增 `App/algo/adc_input.c/h`(L1 采集层):① `k_adc_map[]` **语义通道表**(`UA/UN/IA`→TPAFE `buf[6]/[5]/[2]`,`UB/UC/IB/IC/IN/TEMP`→ADC1 `CH14/3/6/1/2/5`)+ `adc_input_desc()`/`adc_input_raw()` **按语义取数**;② `stm32_scan()` STM32 ADC1 9 通道软件触发顺序扫描(`HAL_ADC_Start` + 逐通道 `PollForConversion`/`GetValue`);③ `adc_input_poll()` 统一"TPAFE 快照 + STM32 扫描"。`adc_task.c` 取数改走本层(首帧日志补全 8 路 + 温度、心跳增 `adc1_rc`/`adc1_err`);`app_main.c` 在 `tpafe5160_init()` 后调 `adc_input_init()`(含**映射自检**:STM32 映射通道必落在扫描序列内,失败记 `SYSLOG_SELFTEST`);Keil 工程挂 `adc_input.c` 并加 `../App/algo` 包含路径。§1.2 采样软件行、§3.1 L1-3/L1-4 同步。`@build` 0 错 0 警;台架 `@test` PASS(`ADC input layer init: OK`、`adc1_rc=0`/`adc1_err=0`、`seq` 仍 1000.0 Hz、`adc` 栈峰值 528→584 B、回读一致、零 `[ERR]`/HardFault),证据 `测试说明/boot_log_data/20261010_prod_adc_l1_boot_log.txt` |
| 2026-10-10 | **L2 相量层落地 + L2-2 实例数口径对齐** | 新增 `App/algo/sample_ring.c/h`(L2 输入:按语义通道保存 2 周波 = 40 点环缓冲,整帧写后统一推进写指针)与 `App/algo/phasor.c/h`(L2 核心:全周傅氏单频 DFT,N = 20;系数表**离线预乘 √2/N** → `fAmSQ` 直接为**有效值**;计算区/使用区**双区原子切换**;实例表 `k_inst[]` 数据驱动);主机侧单测 `test/host/phasor/` **57 用例全绿**(`phasor-unit-test` 钩子)。**§3.2 L2-2 行口径对齐**:参考项目为 **4 个实例**,本项目按 V0.1 有效通道展开为 **5 个**(`C01-IA-F1`/`C02-UA-F1`/`C03-UN-F1`/`C04-IA-F2`/`C05-IA-F5`),已加注说明 4 → 5 的来历;§4.3 相量区 RAM 行同步为 5 实例。⚠ §3.2 的 L2 各点状态**仍标 ⬜**——实现与主机单测已完成,但**台架 `@test` 闭环未做**,且 L2-3 的完成判据(标准源读数 = 设定有效值)在无信号源台架上不可达,故不置 ✅(口径见 §3.2 表下注) |
| 2026-10-10 | **L1-1/L1-3 节拍源与搬运方式升级(v2.8)** | 节拍源 **TIM6 → TIM3**(更正硬事实:F4 上 ADC1 的外部触发清单里没有 TIM6/TIM7 TRGO,只接 DAC),TIM3 更新事件同时触发 TPAFE CONVST 与(经 TRGO)ADC1 一轮 9 通道;L1-3 由"软件触发 + 逐通道轮询"改为 **DMA2_Stream4 循环搬运 + 乒乓双缓冲**,`stm32_scan()` → `stm32_take()`,单拍 `adcp` **122 µs → 8 µs**。§1.4 采样软件行、§3.2 L1-1/L1-3/L1-4 同步。完整设计与实测见 `docs/子系统设计/ADC采样节拍设计说明.md` §11 |
| 2026-10-11 | **L2 台架闭环:P0 收尾** | `@build` 0 错 0 警 → `@test` 闭环把 `phasor(first)`/`phasor(hb)` 列为 Required 并校验顺序 `App init OK>phasor(first)>phasor(hb)`(⚠ `net init: OK` **不在**该序内——adcTask 与 netTask 并行,`phasor(first)` ≈+500 ms 早于 `net init: OK` ≈+574 ms 属正常)→ **PASS**:5 实例相量开机即产出、心跳 5 实例持续刷新、`frames` 每 10 s +10000(1000.0 Hz)、`idle=0`、`frst_err=0`、`adc1_err=0`、`adc1_hw=0`、`fw build` 身份戳匹配、回读一致、锚点 ×1、零 `[ERR]`/HardFault;证据 `boot_log_data/20261011_prod_phasor_boot_log.txt`。栈复测:adcTask 静态 832 B / 实测峰值 **928/2048(余 54%)**,7 任务全 PASS(RAM 方案 §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 采样有效性校验** |