test(b7): 定值持久化+软压板台架腿闭环(跨复位保持 42+8 判据)+ B6/B7 销项
- @test PASS(B6 门控修复生效,protect 锚点行完好) - 主站工具 iec104_master.py 增 --b7-pre/--b7-post/--b7-mark/--b7-check 四模式(纯标准库、ASCII 输出可归档,中间 ST-LINK 复位) - pre 21/21:YK12 两段 OFF → 0.05 A 低定值不动作(保护退出); ON → YX15/16 立即动作(COT=3);C_SE→C_RD 回读 - post 13/13:压板退出态跨复位保持(开机日志 global plate OUT + 低定值仍不动作)、重启后 YK12 ON 联动在位 - mark/check 4/4+4/4:非默认定值 7.5 跨复位保持(C_RD=7.500, 排除"回落出厂默认"假阳性);台架留干净态(定值/压板回默认) - 开机日志两次 [CFG] prot set loaded (/prot_set.bin) - 证据:boot_log_data 20261012_B7_* 两份 + 清单行 - 文档:IEC104 §7 台架行/变更记录、保护规划状态行/§7 P4/B7 行尾巴、 W1 卡 B6+B7 销项(删行 + §1 指针/§2 判据/§3 图/写范围注)、 任务规划 README §2.0/§2.1、test/host/README - 验证:doc-links 全绿(141 文档)、9 个文件字节卫生干净
This commit is contained in:
+3
-3
@@ -90,7 +90,7 @@
|
||||
|
||||
| 波次 | 内容 | 为什么在这 |
|
||||
|---|---|---|
|
||||
| **W1 采集+保护收尾** | **里程碑制 + 并行道**:M1 台架闭环(台架道 B6→N-33)∥ M2 功能面(代码道 B7→{B8∥B9})→ M3 送检(B10,Fixed Date)——任务卡/判据/写范围见 `W1-采集保护收尾.md` | **用户决定(2026-10-12):先把 ADC 采集、保护等相关功能完成**。B4/B5 代码已落地但未台架闭环、功能面不完整(定值不落盘 / 无频率保护 / 无动作记录 / 栈两处 FAIL)——本波收口到"可用 + 可验收";真约束只有**台架**与**送检窗口**两个稀缺资源,其余任务按写范围切分并行 |
|
||||
| **W1 采集+保护收尾** | **里程碑制 + 并行道**:M1 台架闭环(台架道 B6 ✅→N-33)∥ M2 功能面(代码道 B7 ✅→{B8∥B9})→ M3 送检(B10,Fixed Date)——任务卡/判据/写范围见 `W1-采集保护收尾.md` | **用户决定(2026-10-12):先把 ADC 采集、保护等相关功能完成**。B4/B5 代码已落地但未台架闭环、功能面不完整(定值不落盘 / 无频率保护 / 无动作记录 / 栈两处 FAIL)——本波收口到"可用 + 可验收";真约束只有**台架**与**送检窗口**两个稀缺资源,其余任务按写范围切分并行 |
|
||||
| **W2 数据正确性** | **N-21** dhara `is_free`/`copy`(报告 N-12/13) | 低概率、后果重(数据丢失);修复须配主机侧移植层测试,一并补报告"覆盖率"缺口 |
|
||||
| **W3 预算与内存** | **N-27 后半**:R-9 池 40→16 KB → R-2 后半(54 KB→CCM)→ R-3~R-6 逐项评估 | 依赖 W1 三件套产出的台账数据;**B5 堆扩容后 CCM 只剩 ≈8 KB**(56 KB 堆),R-2 后半更被堵死(解锁链见 `docs/内存管理/RAM预算台账.md` §3) |
|
||||
| **W4 结构债** | **N-20 → C6(S-3)→ C3(N-2+N-24)→ C1 pending 二期 → C5(含 N-23 残余)→ N-22/N-25/N-26/N-28**(详表 `排期详述.md` §1) | 无紧急,按性价比排:C6 灭 IWDG 误复位机制根源;C1 体量大、验证重,放后(N-23 钩子已落地 2026-10-12,残余并入 C5) |
|
||||
@@ -103,8 +103,8 @@
|
||||
### 2.1 顺序一图
|
||||
|
||||
```
|
||||
W1 收尾 台架道: B6→N-33(M1) ∥ 代码道: B7→{B8∥B9}(M2) → B10 送检(M3, Fixed Date) 详表 W1-采集保护收尾.md
|
||||
(B4 IEC104 ✅ / B5 protectTask ✅ 2026-10-12 已销项;台账三件套 ✅)
|
||||
W1 收尾 台架道: B6✅→N-33(M1) ∥ 代码道: B7✅→{B8∥B9}(M2) → B10 送检(M3, Fixed Date) 详表 W1-采集保护收尾.md
|
||||
(B4 IEC104 ✅ / B5 protectTask ✅ / B6 台架复测 ✅ / B7 定值持久化+软压板 ✅ 2026-10-12 已销项;台账三件套 ✅)
|
||||
↓
|
||||
W2 数据 N-21 dhara is_free/copy(配主机侧移植层测试)
|
||||
↓
|
||||
|
||||
+10
-8
@@ -12,7 +12,11 @@ B0 产品定义 2026-10-10 确认——上行 **IEC 60870-5-104**(以太网 TC
|
||||
B1 ADC 采集链路已 `@test` 实机闭环;B3 纪律门禁已固化进 `AGENTS.md`;
|
||||
**B4/B5 已销项(2026-10-12)**——证据见 `../子系统设计/IEC104上行设计说明.md`(82 断言 + 钩子)与
|
||||
`../算法/继电保护功能复现规划.md` §7 变更记录(protectTask 20 ms 判据节拍 + L5-4 采样闭锁 +
|
||||
IWDG bit8 + 堆 48→56 KB + prot_elm 28 用例)。
|
||||
IWDG bit8 + 堆 48→56 KB + prot_elm 28 用例);
|
||||
**B6/B7 已销项(2026-10-12)**——B6 证据 = `../测试说明/boot_log_data/README.md` §3
|
||||
(@test PASS + 门控缺陷 MISS→FIX 快照 + PC 主站 18/18,工具 `test/host/iec104_master.py`);
|
||||
B7 证据 = `../子系统设计/IEC104上行设计说明.md` §3.4 + boot_log_data B7 行
|
||||
(定值/压板跨复位保持 + YK12→YX 联动,主站 42+8 判据 + 主机 63+94 断言)。
|
||||
|
||||
**本波目标(用户决定 2026-10-12)**:把"采集→相量→保护→上送"链路从"代码落地"收口到
|
||||
**"台架闭环 + 功能面完整 + 可送检"**。规划方式 = **里程碑(时间驱动、判据退出)×
|
||||
@@ -22,8 +26,8 @@ IWDG bit8 + 堆 48→56 KB + prot_elm 28 用例)。
|
||||
|
||||
| 里程碑 | 退出判据(全部满足才算完成,随后销项) | 服务分类 |
|
||||
|---|---|---|
|
||||
| **M1 台架闭环** | B6 `@test` PASS + N-33 `stack_report` 0 FAIL(含 `@test` 复测腿) | Standard |
|
||||
| **M2 功能面完整** | B7/B8/B9 全部合入 + `ci_local` 全绿 + PC 客户端往返含"定值掉电保持"与"SOE 时标" | Standard |
|
||||
| **M1 台架闭环** | N-33 `stack_report` 0 FAIL(含 `@test` 复测腿);B6 `@test` PASS ✅ 2026-10-12(min_ever 背书就绪) | Standard |
|
||||
| **M2 功能面完整** | B8/B9 全部合入 + `ci_local` 全绿 + PC 客户端往返含"SOE 时标"("定值掉电保持" ✅ B7 台架 2026-10-12) | Standard |
|
||||
| **M3 可送检** | B10 注入判据 + 第三方主站全流程通过,证据归档 | **Fixed Date**(送检窗口一到全道让路;窗口前 2 日特性冻结,只修稳定——Zephyr RC 语义) |
|
||||
|
||||
## 3. 并行道(台架 = 约束资源永不空转;代码道 = worktree 并行、绿即合)
|
||||
@@ -34,8 +38,8 @@ graph LR
|
||||
B6[B6 @test 复测] --> N33[N-33 栈收口+复测]
|
||||
end
|
||||
subgraph CL[代码道 🟢 worktree 并行 绿即合]
|
||||
B7[B7 定值持久化] -->|合并次序| B8[B8 频率保护]
|
||||
B7 -->|合并次序| B9[B9 动作记录/SOE]
|
||||
B8[B8 频率保护]
|
||||
B9[B9 动作记录/SOE]
|
||||
end
|
||||
N33 --> M1((M1))
|
||||
B8 --> M2((M2))
|
||||
@@ -48,13 +52,11 @@ graph LR
|
||||
|
||||
> 资源图例:🔴 台架(COM6/ST-LINK,`bench.lock` 独占)· 🟡 外部(标准源/第三方主站)· 🟢 纯软件(可并行)。
|
||||
> 状态:⬜ 未开始 · 🟦 进行中(销项行直接删除,见 `docs/任务规划/README.md` §3 维护约定)。
|
||||
> ⚠ **写范围相交**:B7×B8(`App/algo/prot_set.*`)、B7×B9(`App/protocol/iec104/iec104_pts.c`)→ **B7 先合**,其后 B8∥B9(互不相交)。
|
||||
> ⚠ **写范围相交**:B7 已先合入(2026-10-12,`App/algo/prot_set.*` 与 `App/protocol/iec104/iec104_pts.c` 定值段已释放);B8∥B9 写范围互不相交,可直接并行。
|
||||
|
||||
| 序 | 任务 | DoD(可验证验收判据) | 硬依赖 | 资源 | 写范围 | 状态 | 出处 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| **B6** | **台架 `@test` 闭环复测(B4/B5 验收窗口)** | `@test` PASS:`protect task start` 锚点 ×1;`[STACK] protect`/`iec104` 水位行在且 free 达标;新堆 min_ever 记录、无 `HEAP_LOW_WATER_B` 告警;PC 客户端 2404 总召/变位往返日志;采样闭锁不误报 | — | 🔴 | `.serialtest/config.json`(无新固件代码) | ✅ 完成(2026-10-12,**待销项删行**):首跑 FAIL 暴露 protectTask 启动行违反写者门控纪律(B5 台架腿缺口实锤,缺陷快照留档)→ 启动行 writer-ready 首拍补打修复(+16 B 固件代码,经用户认可随修)→ 复测 PASS 全判据;104 往返 18/18(两版固件);证据 `../测试说明/boot_log_data/`(20261012_B6_* 四份快照) | 保护规划 §7 变更记录"遗留";`../测试说明/自动化测试流程.md` |
|
||||
| **N-33** | **栈余量收口**(defaultTask 余 1080 B < 30% 线 / timeSyncTask 余 784 B < ISR 底线,2026-10-12 实测;**既有债非 B4/B5 引入**;链 = dhara GC→控制台回显尾→`(Cycle)`) | `stack_report.py` 9 任务 0 FAIL + `@build` 0/0;若抬栈:台账 §6 登记 + `@test` 复测 PASS | B6 ✅(min_ever=10000 已背书 2026-10-12,AGENTS 抬栈门禁) | 🟢(瘦链调研)+ 🔴(复测腿) | `Src/freertos.c`(USER CODE)/ 瘦链目标文件 | ⬜ | 2026-10-12 `stack_report.py` 实测 |
|
||||
| **B7** | **定值持久化 + 遥控软压板(P4)** | 主机单测:定值存/取往返、损坏→all-or-nothing 拒绝、YK12 两段式转真执行;`@build` 0/0;**台架腿**:104 C_SE 写 → 断电重启 → 定值保持;写+seal 原子化(B5 竞态窗口关闭,回填保护规划 §3.5) | —(代码);验证腿 🔴 | 🟢 + 🔴 | `App/algo/prot_set.*`、`App/cfg/`、`App/protocol/iec104/iec104_pts.c`(定值段)、`App/task/iec104_serv.c` | 🟦 代码腿完成(2026-10-12:prot_set 63 + iec104 94 断言全绿、`@build` 0/0;`/prot_set.bin` 原子持久化 + YK12 转真 + 竞态收口已落地);**台架腿待窗口 🔴**(C_SE 两段写路径已随 B6 窗 2026-10-12 验证:104 往返 18/18;剩余 = 断电重启→定值保持 + YK12→YX 联动) | 保护规划 §3.5 L5-1、§5;`../子系统设计/IEC104上行设计说明.md` §3.3 |
|
||||
| **B8** | **频率测量算法 + 过频/低频保护(P2 剩余)** | 频率测量主机单测(45~55 Hz 扫描,精度判据写入文档)+ OF/UF 实例单测;`@build` 0/0;心跳行显示频率值。OV/UV/3U0 实例 B5 起已在跑,注入判据归 B10 | — | 🟢 | `App/algo/phasor.*`(或新 `freq.*`)、`App/algo/prot_elm.*`、`App/algo/prot_set.*`(定值行) | ⬜ | 保护规划 §3.3 L3-5、保护规划 §7 P2 |
|
||||
| **B9** | **动作记录 + 时标 SOE(L4)** | SOE 记录编解码主机单测 + iec104 单测(M_SP_TB_1);`@build` 0/0;protectTask 静态链不变(动作路径无 NAND I/O,记录走队列异步);**台架腿**:动作边沿 → `/log` 记录可见。出口跳闸仍否定确认(R7 口径不变) | —(代码);验证腿 🔴 | 🟢 + 🔴 | `App/log/`、`App/protocol/iec104/iec104_asdu.*` + `iec104_pts.c`(YX 时标段)、`App/task/protect_task.c` | ⬜ | 保护规划 §3.4 L4、保护规划 §7 P4;`../子系统设计/IEC104上行设计说明.md` §3.2 注 |
|
||||
| **B10** | **标准源注入 + 第三方 104 主站往返(送检窗口)** | 标准源注入:L1-5 标定复核 / L1-7 等周波 / P1 过流·过负荷 / P2 电压 + 频率类判据全通过;第三方主站总召/周期/变位/遥控全流程(`../子系统设计/IEC104上行设计说明.md` §7/§8 核对单);证据归档 | M1 + M2 | 🟡 | —(窗口内缺陷修复走 Expedite 类) | ⬜ | 保护规划 §7 P1/P2 验收;`../子系统设计/IEC104上行设计说明.md` §7/§8 |
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
|---|---|
|
||||
| L0.5 | `test/host/iec104/`:APCI 重组/坏帧、STARTDT 握手、总召全流程(含 RBT/分片/预算)、COV、k/w 窗、t1/t2/t3(假时基)、遥控两段式与 PN、YK12 软压板两段转真 + 置脏(B7)、定值两段写 + set_sealed 后 selfcheck、C_RD(含本地项不可寻址)、C_CS(含闰年)、错地址/错类型 EVI;`test/host/prot_set/`:blob 往返 + 损坏整表拒绝(all-or-nothing)|
|
||||
| L0 | `iec104-unit-test` 钩子 + cppcheck/coding-standard |
|
||||
| 台架 | `@test` 锚点(104 服务启动/监听行);**PC 主站客户端 `test/host/iec104_master.py`(纯标准库,B6 2026-10-12 就绪)**:STARTDT/总召四组+actterm/C_SE 定值两段写→YX15·16 变位(COT=3)/恢复复归/YK11 两段正答/C_RD 读回,台架往返 **18/18 PASS**(证据 `../测试说明/boot_log_data/20261012_B6_iec104_roundtrip_log.txt`);lib60870 级第三方全流程归 B10 |
|
||||
| 台架 | `@test` 锚点(104 服务启动/监听行);**PC 主站客户端 `test/host/iec104_master.py`(纯标准库,B6 2026-10-12 就绪)**:STARTDT/总召四组+actterm/C_SE 定值两段写→YX15·16 变位(COT=3)/恢复复归/YK11 两段正答/C_RD 读回,台架往返 **18/18 PASS**(证据 `../测试说明/boot_log_data/20261012_B6_iec104_roundtrip_log.txt`);**B7 持久化模式 `--b7-pre/--b7-post/--b7-mark/--b7-check`**(中间 ST-LINK 复位):YK12 两段投退→保护退出/联动、**定值与压板态跨复位保持**(含非默认 7.5 往返),**21/21 + 13/13 + 4/4+4/4 PASS**(证据 `../测试说明/boot_log_data/20261012_B7_iec104_persist_log.txt`);lib60870 级第三方全流程归 B10 |
|
||||
|
||||
## 8. V0.1 限制与待办(如实登记)
|
||||
|
||||
@@ -174,3 +174,4 @@
|
||||
| 2026-10-12 | 建档(B4):范围/分层/点表/链路流程/接入决策/预算/测试方案;§5 接线细节随实现回填 |
|
||||
| 2026-10-12 | B4 落地回填:承载改**专用 iec104Task**(netTask 承载会 RPC 自死锁);§5 全量回填(门控/代次/拆链/对时/看门狗位 7);抢占策略修正为**首到优先**(§8 第 7 条);§6 实测(640 words,链 1456 B,余 43% PASS) |
|
||||
| 2026-10-12 | **B7 定值持久化 + 软压板**:YK12 转真(§3.3,两段式 → `PS_GLOBAL_EN`);定值执行段改 `prot_set_set_sealed` 原子写+封存(§3.4,收口 B5 竞态窗口);本地项 `comm_addr=0` 不可寻址;持久化 = 脏标志 → `SYS_EVT_PROT_SET_SAVE` → defaultTask 原子写 `/prot_set.bin`,开机屏障前整表原子装载(损坏拒绝保默认 + 自检留痕);单测 +7(iec104 94 断言)+ prot_set blob 往返/损坏 33 断言 |
|
||||
| 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_*` |
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
B7 bench leg: IEC104 setpoint persistence + global soft plate (YK12) round-trip
|
||||
fw: HEAD dafcf80 (B7 1fe163b + B6 gating fix), device 192.168.1.100:2404
|
||||
tool: test/host/iec104_master.py --b7-pre / --b7-post / --b7-mark / --b7-check
|
||||
sequence: pre(reset 前) -> ST-LINK reset -> post; mark(7.5) -> reset -> check
|
||||
date: 2026-10-12 16:42~16:45 +08:00
|
||||
|
||||
==== phase 1: --b7-pre (21/21 PASS) ====
|
||||
[ 0.006s] iec104 master client -> 192.168.1.100:2404 mode=pre
|
||||
[ 0.010s] TX U STARTDT act 68 04 07 00 00 00
|
||||
[ 0.179s] RX U STARTDT con
|
||||
[ 1.190s] CHECK startdt_con PASS
|
||||
[ 1.190s] TX I C_IC act (pre) 68 0E 00 00 00 00 64 01 06 00 01 00 00 00 00 14
|
||||
[ 1.281s] RX I type=100 cot=7 body=00 00 00 14
|
||||
[ 1.281s] TX S N(R)=1 68 04 01 00 02 00
|
||||
[ 1.282s] TX S N(R)=2 68 04 01 00 04 00
|
||||
[ 1.283s] RX I M_SP ioa=15 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.283s] RX I M_SP ioa=16 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.283s] RX I M_SP ioa=17 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.283s] RX I M_SP ioa=18 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.283s] RX I M_SP ioa=23 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.283s] RX I M_SP ioa=31 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.283s] TX S N(R)=3 68 04 01 00 06 00
|
||||
[ 1.285s] TX S N(R)=5 68 04 01 00 0A 00
|
||||
[ 1.385s] RX I type=100 cot=8 body=00 00 00 14
|
||||
[ 1.385s] TX S N(R)=6 68 04 01 00 0C 00
|
||||
[ 2.400s] CHECK gi_actterm_pre PASS
|
||||
[ 2.400s] CHECK baseline_yx16_off PASS yx16=(0, False)
|
||||
[ 2.400s] TX I C_SE select 0x8858 = 7.500 (mark) 68 12 02 00 0C 00 32 01 06 00 01 00 58 88 00 00 00 F0 40 80
|
||||
[ 2.487s] RX I type=50 cot=7 body=58 88 00 00 00 F0 40 80
|
||||
[ 2.487s] TX S N(R)=7 68 04 01 00 0E 00
|
||||
[ 3.497s] CHECK se_sel_mark PASS
|
||||
[ 3.497s] TX I C_SE exec 0x8858 = 7.500 (mark) 68 12 04 00 0E 00 32 01 06 00 01 00 58 88 00 00 00 F0 40 00
|
||||
[ 3.497s] CHECK se_exe_mark PASS
|
||||
[ 3.497s] TX I C_RD 0x8858 68 0D 06 00 0E 00 66 01 05 00 01 00 58 88 00
|
||||
[ 3.588s] RX I type=50 cot=7 body=58 88 00 00 00 F0 40 00
|
||||
[ 3.588s] TX S N(R)=8 68 04 01 00 10 00
|
||||
[ 3.689s] RX I M_ME_NC ioa=0x8858 val=7.500 qds=0x00 cot=5
|
||||
[ 3.689s] TX S N(R)=9 68 04 01 00 12 00
|
||||
[ 4.702s] CHECK rd_mark_7.5 PASS read=7.500 want=7.500
|
||||
[ 4.702s] TX I C_DC 0x600B select QDC=81 68 0E 08 00 12 00 34 01 06 00 01 00 0B 60 00 81
|
||||
[ 4.790s] RX I type=52 cot=7 body=0B 60 00 81
|
||||
[ 4.790s] TX S N(R)=10 68 04 01 00 14 00
|
||||
[ 5.805s] CHECK yk12_off_sel PASS
|
||||
[ 5.805s] TX I C_DC 0x600B execute QDC=01 68 0E 0A 00 14 00 34 01 06 00 01 00 0B 60 00 01
|
||||
[ 5.805s] CHECK yk12_off_exe PASS
|
||||
[ 5.805s] TX I C_SE select 0x8858 = 0.050 (low) 68 12 0C 00 14 00 32 01 06 00 01 00 58 88 00 CD CC 4C 3D 80
|
||||
[ 5.805s] CHECK se_sel_low PASS
|
||||
[ 5.805s] TX I C_SE exec 0x8858 = 0.050 (low) 68 12 0E 00 14 00 32 01 06 00 01 00 58 88 00 CD CC 4C 3D 00
|
||||
[ 5.805s] CHECK se_exe_low PASS
|
||||
[ 5.891s] RX I type=52 cot=7 body=0B 60 00 01
|
||||
[ 5.891s] TX S N(R)=11 68 04 01 00 16 00
|
||||
[ 5.993s] RX I type=50 cot=7 body=58 88 00 CD CC 4C 3D 80
|
||||
[ 5.993s] TX S N(R)=12 68 04 01 00 18 00
|
||||
[ 6.036s] RX I type=50 cot=7 body=58 88 00 CD CC 4C 3D 00
|
||||
[ 6.036s] RX S N(R)=8
|
||||
[ 6.036s] TX S N(R)=13 68 04 01 00 1A 00
|
||||
[ 9.071s] CHECK plate_out_no_trip PASS YX16 must stay OFF while plate OUT (protection disabled)
|
||||
[ 9.071s] TX I C_RD 0x8858 68 0D 10 00 1A 00 66 01 05 00 01 00 58 88 00
|
||||
[ 9.101s] RX I M_ME_NC ioa=0x8858 val=0.050 qds=0x00 cot=5
|
||||
[ 9.101s] TX S N(R)=14 68 04 01 00 1C 00
|
||||
[ 10.113s] CHECK rd_low_0.05 PASS read=0.050 want=0.050
|
||||
[ 10.113s] TX I C_DC 0x600B select QDC=82 68 0E 12 00 1C 00 34 01 06 00 01 00 0B 60 00 82
|
||||
[ 10.113s] CHECK yk12_on_sel PASS
|
||||
[ 10.113s] TX I C_DC 0x600B execute QDC=02 68 0E 14 00 1C 00 34 01 06 00 01 00 0B 60 00 02
|
||||
[ 10.113s] CHECK yk12_on_exe PASS
|
||||
[ 10.201s] RX I type=52 cot=7 body=0B 60 00 82
|
||||
[ 10.201s] TX S N(R)=15 68 04 01 00 1E 00
|
||||
[ 10.303s] RX I type=52 cot=7 body=0B 60 00 02
|
||||
[ 10.303s] TX S N(R)=16 68 04 01 00 20 00
|
||||
[ 10.504s] RX I M_SP ioa=15 val=1 iv=0 cot=3 [N(R)=11]
|
||||
[ 10.504s] TX S N(R)=17 68 04 01 00 22 00
|
||||
[ 10.505s] RX I M_SP ioa=16 val=1 iv=0 cot=3 [N(R)=11]
|
||||
[ 10.505s] TX S N(R)=18 68 04 01 00 24 00
|
||||
[ 11.512s] CHECK spont_yx16_ON PASS
|
||||
[ 11.512s] CHECK spont_yx15_ON PASS
|
||||
[ 11.512s] TX I C_SE select 0x8858 = 10.000 (restore) 68 12 16 00 24 00 32 01 06 00 01 00 58 88 00 00 00 20 41 80
|
||||
[ 11.607s] RX I type=50 cot=7 body=58 88 00 00 00 20 41 80
|
||||
[ 11.607s] TX S N(R)=19 68 04 01 00 26 00
|
||||
[ 12.614s] CHECK se_sel_restore PASS
|
||||
[ 12.614s] TX I C_SE exec 0x8858 = 10.000 (restore) 68 12 18 00 26 00 32 01 06 00 01 00 58 88 00 00 00 20 41 00
|
||||
[ 12.614s] CHECK se_exe_restore PASS
|
||||
[ 12.707s] RX I type=50 cot=7 body=58 88 00 00 00 20 41 00
|
||||
[ 12.707s] TX S N(R)=20 68 04 01 00 28 00
|
||||
[ 12.708s] RX I M_SP ioa=15 val=0 iv=0 cot=3 [N(R)=13]
|
||||
[ 12.709s] TX S N(R)=21 68 04 01 00 2A 00
|
||||
[ 12.710s] RX I M_SP ioa=16 val=0 iv=0 cot=3 [N(R)=13]
|
||||
[ 12.710s] TX S N(R)=22 68 04 01 00 2C 00
|
||||
[ 13.720s] CHECK yx16_off_after_restore PASS via spontaneous COT=3
|
||||
[ 13.720s] TX I C_DC 0x600B select QDC=81 68 0E 1A 00 2C 00 34 01 06 00 01 00 0B 60 00 81
|
||||
[ 13.811s] RX I type=52 cot=7 body=0B 60 00 81
|
||||
[ 13.811s] TX S N(R)=23 68 04 01 00 2E 00
|
||||
[ 14.813s] CHECK yk12_off_final_sel PASS
|
||||
[ 14.813s] TX I C_DC 0x600B execute QDC=01 68 0E 1C 00 2E 00 34 01 06 00 01 00 0B 60 00 01
|
||||
[ 14.813s] CHECK yk12_off_final_exe PASS
|
||||
[ 14.813s] wait 2s: dirty -> SYS_EVT_PROT_SET_SAVE -> /prot_set.bin
|
||||
[ 16.813s] SUMMARY: 21/21 checks PASS -> PASS
|
||||
|
||||
==== phase 2: --b7-post (13/13 PASS) ====
|
||||
[ 0.007s] iec104 master client -> 192.168.1.100:2404 mode=post
|
||||
[ 0.024s] TX U STARTDT act 68 04 07 00 00 00
|
||||
[ 0.120s] RX U STARTDT con
|
||||
[ 1.126s] CHECK startdt_con PASS
|
||||
[ 1.126s] TX I C_IC act (post) 68 0E 00 00 00 00 64 01 06 00 01 00 00 00 00 14
|
||||
[ 1.221s] RX I type=100 cot=7 body=00 00 00 14
|
||||
[ 1.221s] TX S N(R)=1 68 04 01 00 02 00
|
||||
[ 1.223s] TX S N(R)=2 68 04 01 00 04 00
|
||||
[ 1.224s] RX I M_SP ioa=15 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.224s] RX I M_SP ioa=16 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.224s] RX I M_SP ioa=17 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.224s] RX I M_SP ioa=18 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.224s] RX I M_SP ioa=23 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.224s] RX I M_SP ioa=31 val=0 iv=0 cot=4 [N(R)=1]
|
||||
[ 1.224s] TX S N(R)=4 68 04 01 00 08 00
|
||||
[ 1.225s] TX S N(R)=5 68 04 01 00 0A 00
|
||||
[ 1.325s] RX I type=100 cot=8 body=00 00 00 14
|
||||
[ 1.327s] TX S N(R)=6 68 04 01 00 0C 00
|
||||
[ 2.337s] CHECK gi_actterm_post PASS
|
||||
[ 2.337s] CHECK baseline_yx16_off PASS yx16=(0, False) (plate OUT after reboot -> protection disabled)
|
||||
[ 2.337s] TX I C_RD 0x8858 68 0D 02 00 0C 00 66 01 05 00 01 00 58 88 00
|
||||
[ 2.428s] RX I M_ME_NC ioa=0x8858 val=10.000 qds=0x00 cot=5
|
||||
[ 2.428s] TX S N(R)=7 68 04 01 00 0E 00
|
||||
[ 3.429s] CHECK persist_rd_10.0 PASS read=10.000 want=10.000
|
||||
[ 3.429s] TX I C_SE select 0x8858 = 0.050 (low) 68 12 04 00 0E 00 32 01 06 00 01 00 58 88 00 CD CC 4C 3D 80
|
||||
[ 3.528s] RX I type=50 cot=7 body=58 88 00 CD CC 4C 3D 80
|
||||
[ 3.528s] TX S N(R)=8 68 04 01 00 10 00
|
||||
[ 4.539s] CHECK se_sel_low PASS
|
||||
[ 4.539s] TX I C_SE exec 0x8858 = 0.050 (low) 68 12 06 00 10 00 32 01 06 00 01 00 58 88 00 CD CC 4C 3D 00
|
||||
[ 4.539s] CHECK se_exe_low PASS
|
||||
[ 4.628s] RX I type=50 cot=7 body=58 88 00 CD CC 4C 3D 00
|
||||
[ 4.628s] TX S N(R)=9 68 04 01 00 12 00
|
||||
[ 7.649s] CHECK plate_out_persisted_no_trip PASS plate OUT state survived the reset
|
||||
[ 7.649s] TX I C_DC 0x600B select QDC=82 68 0E 08 00 12 00 34 01 06 00 01 00 0B 60 00 82
|
||||
[ 7.731s] RX I type=52 cot=7 body=0B 60 00 82
|
||||
[ 7.731s] TX S N(R)=10 68 04 01 00 14 00
|
||||
[ 8.734s] CHECK yk12_on_sel PASS
|
||||
[ 8.734s] TX I C_DC 0x600B execute QDC=02 68 0E 0A 00 14 00 34 01 06 00 01 00 0B 60 00 02
|
||||
[ 8.734s] CHECK yk12_on_exe PASS
|
||||
[ 8.831s] RX I type=52 cot=7 body=0B 60 00 02
|
||||
[ 8.831s] TX S N(R)=11 68 04 01 00 16 00
|
||||
[ 8.934s] RX I M_SP ioa=15 val=1 iv=0 cot=3 [N(R)=6]
|
||||
[ 8.934s] TX S N(R)=12 68 04 01 00 18 00
|
||||
[ 8.936s] RX I M_SP ioa=16 val=1 iv=0 cot=3 [N(R)=6]
|
||||
[ 8.936s] TX S N(R)=13 68 04 01 00 1A 00
|
||||
[ 9.946s] CHECK spont_yx16_ON_after_reboot PASS
|
||||
[ 9.946s] TX I C_SE select 0x8858 = 10.000 (restore) 68 12 0C 00 1A 00 32 01 06 00 01 00 58 88 00 00 00 20 41 80
|
||||
[ 10.039s] RX I type=50 cot=7 body=58 88 00 00 00 20 41 80
|
||||
[ 10.040s] TX S N(R)=14 68 04 01 00 1C 00
|
||||
[ 10.539s] RX I M_SP ioa=15 val=0 iv=0 cot=3 [N(R)=7]
|
||||
[ 10.539s] TX S N(R)=15 68 04 01 00 1E 00
|
||||
[ 10.541s] RX I M_SP ioa=16 val=0 iv=0 cot=3 [N(R)=7]
|
||||
[ 10.541s] TX S N(R)=16 68 04 01 00 20 00
|
||||
[ 10.643s] RX I M_SP ioa=15 val=1 iv=0 cot=3 [N(R)=7]
|
||||
[ 10.643s] TX S N(R)=17 68 04 01 00 22 00
|
||||
[ 10.644s] RX I M_SP ioa=16 val=1 iv=0 cot=3 [N(R)=7]
|
||||
[ 10.644s] TX S N(R)=18 68 04 01 00 24 00
|
||||
[ 10.745s] RX I M_SP ioa=15 val=0 iv=0 cot=3 [N(R)=7]
|
||||
[ 10.745s] TX S N(R)=19 68 04 01 00 26 00
|
||||
[ 10.746s] RX I M_SP ioa=16 val=0 iv=0 cot=3 [N(R)=7]
|
||||
[ 10.746s] TX S N(R)=20 68 04 01 00 28 00
|
||||
[ 10.848s] RX I M_SP ioa=15 val=1 iv=0 cot=3 [N(R)=7]
|
||||
[ 10.848s] TX S N(R)=21 68 04 01 00 2A 00
|
||||
[ 10.849s] RX I M_SP ioa=16 val=1 iv=0 cot=3 [N(R)=7]
|
||||
[ 10.849s] TX S N(R)=22 68 04 01 00 2C 00
|
||||
[ 11.250s] RX S N(R)=7
|
||||
[ 11.251s] CHECK se_sel_restore PASS
|
||||
[ 11.251s] TX I C_SE exec 0x8858 = 10.000 (restore) 68 12 0E 00 2C 00 32 01 06 00 01 00 58 88 00 00 00 20 41 00
|
||||
[ 11.251s] CHECK se_exe_restore PASS
|
||||
[ 11.351s] RX I type=50 cot=7 body=58 88 00 00 00 20 41 00
|
||||
[ 11.351s] TX S N(R)=23 68 04 01 00 2E 00
|
||||
[ 11.351s] RX I M_SP ioa=15 val=0 iv=0 cot=3 [N(R)=8]
|
||||
[ 11.352s] TX S N(R)=24 68 04 01 00 30 00
|
||||
[ 11.352s] RX I M_SP ioa=16 val=0 iv=0 cot=3 [N(R)=8]
|
||||
[ 11.352s] TX S N(R)=25 68 04 01 00 32 00
|
||||
[ 12.360s] CHECK yx16_off_final PASS via spontaneous COT=3
|
||||
[ 12.360s] wait 1s: final dirty -> save, leave plate IN
|
||||
[ 13.360s] SUMMARY: 13/13 checks PASS -> PASS
|
||||
|
||||
==== phase 3: --b7-mark (4/4 PASS) ====
|
||||
[ 0.007s] iec104 master client -> 192.168.1.100:2404 mode=mark
|
||||
[ 0.036s] TX U STARTDT act 68 04 07 00 00 00
|
||||
[ 0.166s] RX U STARTDT con
|
||||
[ 1.172s] CHECK startdt_con PASS
|
||||
[ 1.172s] TX I C_SE select 0x8858 = 7.500 (distinct) 68 12 00 00 00 00 32 01 06 00 01 00 58 88 00 00 00 F0 40 80
|
||||
[ 1.268s] RX I type=50 cot=7 body=58 88 00 00 00 F0 40 80
|
||||
[ 1.268s] TX S N(R)=1 68 04 01 00 02 00
|
||||
[ 2.273s] CHECK se_sel_distinct PASS
|
||||
[ 2.273s] TX I C_SE exec 0x8858 = 7.500 (distinct) 68 12 02 00 02 00 32 01 06 00 01 00 58 88 00 00 00 F0 40 00
|
||||
[ 2.273s] CHECK se_exe_distinct PASS
|
||||
[ 2.273s] TX I C_RD 0x8858 68 0D 04 00 02 00 66 01 05 00 01 00 58 88 00
|
||||
[ 2.368s] RX I type=50 cot=7 body=58 88 00 00 00 F0 40 00
|
||||
[ 2.368s] TX S N(R)=2 68 04 01 00 04 00
|
||||
[ 2.469s] RX I M_ME_NC ioa=0x8858 val=7.500 qds=0x00 cot=5
|
||||
[ 2.469s] TX S N(R)=3 68 04 01 00 06 00
|
||||
[ 3.473s] CHECK rd_distinct PASS read=7.500 want=7.500
|
||||
[ 3.473s] wait 1.5s: dirty -> save (/prot_set.bin)
|
||||
[ 4.973s] SUMMARY: 4/4 checks PASS -> PASS
|
||||
|
||||
==== phase 4: --b7-check (4/4 PASS, non-default 7.5 survived reset) ====
|
||||
[ 0.006s] iec104 master client -> 192.168.1.100:2404 mode=check
|
||||
[ 0.029s] TX U STARTDT act 68 04 07 00 00 00
|
||||
[ 0.186s] RX U STARTDT con
|
||||
[ 1.198s] CHECK startdt_con PASS
|
||||
[ 1.198s] TX I C_RD 0x8858 68 0D 00 00 00 00 66 01 05 00 01 00 58 88 00
|
||||
[ 1.293s] RX I M_ME_NC ioa=0x8858 val=7.500 qds=0x00 cot=5
|
||||
[ 1.293s] TX S N(R)=1 68 04 01 00 02 00
|
||||
[ 2.297s] CHECK persist_distinct_after_reset PASS read=7.500 want=7.500
|
||||
[ 2.297s] TX I C_SE select 0x8858 = 10.000 (restore) 68 12 02 00 02 00 32 01 06 00 01 00 58 88 00 00 00 20 41 80
|
||||
[ 2.387s] RX I type=50 cot=7 body=58 88 00 00 00 20 41 80
|
||||
[ 2.387s] TX S N(R)=2 68 04 01 00 04 00
|
||||
[ 3.391s] CHECK se_sel_restore PASS
|
||||
[ 3.391s] TX I C_SE exec 0x8858 = 10.000 (restore) 68 12 04 00 04 00 32 01 06 00 01 00 58 88 00 00 00 20 41 00
|
||||
[ 3.391s] CHECK se_exe_restore PASS
|
||||
[ 3.391s] wait 1s: restore saved, bench left at defaults
|
||||
[ 4.392s] SUMMARY: 4/4 checks PASS -> PASS
|
||||
@@ -0,0 +1,60 @@
|
||||
[SYS] 2026-10-12T16:44:51.032+08:00 log cleared (gen=144)
|
||||
[RX] 2026-10-12T16:44:51.475+08:00 [----/--/-- --:--:--][APP] boot: syslog init OK
|
||||
[RX] 2026-10-12T16:44:51.475+08:00 [----/--/-- --:--:--][APP] fw build: Oct 12 2026 14:02:47 suite=NONE dstr=off
|
||||
[RX] 2026-10-12T16:44:51.489+08:00 [----/--/-- --:--:--][APP] reset cause: software (NVIC_SystemReset) (CSR=0x14000000)
|
||||
[RX] 2026-10-12T16:44:51.489+08:00 PREVRUN seg=2 seq=1933923012 t=123484
|
||||
[RX] 2026-10-12T16:44:51.500+08:00 TICKRUN uw=123508 n=123508 duw=24
|
||||
[RX] 2026-10-12T16:44:51.500+08:00 [----/--/-- --:--:--][RTC] sd2506_init: OK
|
||||
[RX] 2026-10-12T16:44:51.511+08:00 [----/--/-- --:--:--][APP] SD2506 init: OK (ret=0)
|
||||
[RX] 2026-10-12T16:44:51.511+08:00 [2026-10-12 08:44:49][CLK] sys_clock_init: RTC initial time 2026-10-12 08:44:49
|
||||
[RX] 2026-10-12T16:44:51.521+08:00 [2026-10-12 08:44:49][CLK] sys_clock_init: wall clock base = unix 1791794689, base_tick=139
|
||||
[RX] 2026-10-12T16:44:51.532+08:00 [2026-10-12 08:44:49][APP] RS485 init: OK (UART4, DE=PA15)
|
||||
[RX] 2026-10-12T16:44:51.543+08:00 [2026-10-12 08:44:49][NAND] Resetting NAND...
|
||||
[RX] 2026-10-12T16:44:51.564+08:00 [2026-10-12 08:44:49][NAND] Reading NAND ID...
|
||||
[RX] 2026-10-12T16:44:51.564+08:00 [2026-10-12 08:44:49][NAND] NAND ID: MID=0xC8, DID=0x52
|
||||
[RX] 2026-10-12T16:44:51.574+08:00 [2026-10-12 08:44:49][NAND] Scanning bad blocks...
|
||||
[RX] 2026-10-12T16:44:51.700+08:00 [2026-10-12 08:44:49][NAND] BBT scan: 0 bad blocks found
|
||||
[RX] 2026-10-12T16:44:51.711+08:00 [2026-10-12 08:44:49][NAND] Enabling ECC...
|
||||
[RX] 2026-10-12T16:44:51.711+08:00 [2026-10-12 08:44:49][NAND] Unlocking block protection...
|
||||
[RX] 2026-10-12T16:44:51.721+08:00 [2026-10-12 08:44:49][NAND] Locating BBT pool...
|
||||
[RX] 2026-10-12T16:44:51.721+08:00 [2026-10-12 08:44:49][NAND] Loading persisted BBT...
|
||||
[RX] 2026-10-12T16:44:51.732+08:00 [2026-10-12 08:44:49][NAND] NAND init OK
|
||||
[RX] 2026-10-12T16:44:51.732+08:00 [2026-10-12 08:44:49][APP] NAND init: OK
|
||||
[RX] 2026-10-12T16:44:51.732+08:00 [2026-10-12 08:44:49][ADC] Init OK
|
||||
[RX] 2026-10-12T16:44:51.743+08:00 [2026-10-12 08:44:49][APP] ADC init: OK
|
||||
[RX] 2026-10-12T16:44:51.743+08:00 [2026-10-12 08:44:49][APP] ADC input layer init: OK
|
||||
[RX] 2026-10-12T16:44:51.753+08:00 [2026-10-12 08:44:49][APP] phasor layer init: OK (inst=5)
|
||||
[RX] 2026-10-12T16:44:51.753+08:00 [2026-10-12 08:44:49][APP] protection init: OK (set=32 elm=7)
|
||||
[RX] 2026-10-12T16:44:51.764+08:00 [2026-10-12 08:44:49][APP] SD2506 ID: 2512153425482405
|
||||
[RX] 2026-10-12T16:44:51.764+08:00 [2026-10-12 08:44:49][APP] SD2506 time: 2026-10-12 08:44:50 (week 4)
|
||||
[RX] 2026-10-12T16:44:51.774+08:00 [2026-10-12 08:44:49][APP] SD2506 temp: 28 C
|
||||
[RX] 2026-10-12T16:44:51.774+08:00 [2026-10-12 08:44:49][APP] SD2506 battery: 3.11 V
|
||||
[RX] 2026-10-12T16:44:51.785+08:00 [2026-10-12 08:44:49][APP] App init OK
|
||||
[RX] 2026-10-12T16:44:51.785+08:00 [2026-10-12 08:44:49][NAND_FTL] Initializing NAND FTL...
|
||||
[RX] 2026-10-12T16:44:51.816+08:00 [2026-10-12 08:44:49][NAND_FTL] Map resumed: 14094/97504 sectors used
|
||||
[RX] 2026-10-12T16:44:51.816+08:00 [2026-10-12 08:44:49][NAND_FTL] Map head=18496 tail=290 epoch=2
|
||||
[RX] 2026-10-12T16:44:51.827+08:00 [2026-10-12 08:44:49][NAND_FTL] NAND FTL ready (capacity: 97504 pages = 190 MB)
|
||||
[RX] 2026-10-12T16:44:51.899+08:00 [2026-10-12 08:44:49] [FS] FATFS mounted
|
||||
[RX] 2026-10-12T16:44:51.952+08:00 [2026-10-12 08:44:49][SYSLOG] runlog boot entry: reboot
|
||||
[RX] 2026-10-12T16:44:51.962+08:00 [2026-10-12 08:44:49][CFG] register: section 'network' (4 keys)
|
||||
[RX] 2026-10-12T16:44:51.962+08:00 [2026-10-12 08:44:49][CFG] register: section 'ftp' (3 keys)
|
||||
[RX] 2026-10-12T16:44:51.973+08:00 [2026-10-12 08:44:49][CFG] load: OK (523B, heap free 18088B)
|
||||
[RX] 2026-10-12T16:44:51.973+08:00 [2026-10-12 08:44:49][NET_CFG] load: OK ip=192.168.1.100
|
||||
[RX] 2026-10-12T16:44:51.983+08:00 [2026-10-12 08:44:49] [CFG] prot set loaded (/prot_set.bin)
|
||||
[RX] 2026-10-12T16:44:52.015+08:00 [2026-10-12 08:44:49][ADC_TASK] first: UA=11428 UB=957 UC=821 UN=11454 IA=11453 IB=938 IC=983 IN=878 T=915
|
||||
[RX] 2026-10-12T16:44:52.015+08:00 [2026-10-12 08:44:49][ADC_TASK] phasor(first) C01-IA-F1: Re=-4 Im=1 rms=4 (x0.1)
|
||||
[RX] 2026-10-12T16:44:52.025+08:00 [2026-10-12 08:44:49][ADC_TASK] phasor(first) C02-UA-F1: Re=-2 Im=0 rms=3 (x0.1)
|
||||
[RX] 2026-10-12T16:44:52.035+08:00 [2026-10-12 08:44:49][ADC_TASK] phasor(first) C03-UN-F1: Re=-4 Im=-2 rms=5 (x0.1)
|
||||
[RX] 2026-10-12T16:44:52.046+08:00 [2026-10-12 08:44:49][ADC_TASK] phasor(first) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
|
||||
[RX] 2026-10-12T16:44:52.046+08:00 [2026-10-12 08:44:49][ADC_TASK] phasor(first) C05-IA-F5: Re=0 Im=-1 rms=1 (x0.1)
|
||||
[RX] 2026-10-12T16:44:52.056+08:00 [2026-10-12 08:44:49][NET_TASK] === Network Init ===
|
||||
[RX] 2026-10-12T16:44:52.056+08:00 [2026-10-12 08:44:49][PROT] protect task start: cycle=20ms elm=7
|
||||
[RX] 2026-10-12T16:44:52.067+08:00 [2026-10-12 08:44:49][NET] ch395f ver=0x4A fun_para=0x08
|
||||
[RX] 2026-10-12T16:44:52.067+08:00 [2026-10-12 08:44:49][NET_TASK] net init: OK
|
||||
[RX] 2026-10-12T16:44:52.077+08:00 [2026-10-12 08:44:49][NET_TASK] MAC: 3C:AB:72:53:2B:12
|
||||
[RX] 2026-10-12T16:44:52.077+08:00 [2026-10-12 08:44:49][NET_TASK] IP_INF: IP=192.168.1.100 GW=192.168.1.1 MASK=255.255.255.0
|
||||
[RX] 2026-10-12T16:44:52.087+08:00 MISS start snap=0x000001E7 req=0x000001F7 t=716
|
||||
[RX] 2026-10-12T16:44:52.098+08:00 [2026-10-12 08:44:49][WD] [WD] armed: timeout ~2498ms (worst ~1701ms), miss_tol=800ms
|
||||
[RX] 2026-10-12T16:44:52.108+08:00 [2026-10-12 08:44:49][UI_TASK] UI task: started, wait net ready
|
||||
[RX] 2026-10-12T16:44:53.611+08:00 [2026-10-12 08:44:51][PROT] elm OC1-IA asserted=1 picked=1
|
||||
[RX] 2026-10-12T16:44:53.673+08:00 [2026-10-12 08:44:51][PROT] elm OC1-IA asserted=0 picked=0
|
||||
@@ -33,6 +33,7 @@
|
||||
| 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` |
|
||||
| 2026-10-12 | 同 MISS 固件(d3107f3)/ **PC 主站 2404 往返**(`test/host/iec104_master.py`) | STARTDT/总召四组+actterm/C_SE 两段写触发 YX15·16 变位(COT=3)/恢复复归/YK11 两段正答/C_RD 读回 10.000 → **18/18 PASS**(104 链与锚点缺陷无关,验收窗口固件本身上先行闭环) | `20261012_B6_iec104_roundtrip_pre-fix_log.txt` |
|
||||
| 2026-10-12 | 同 PASS 固件(B7+fix)/ **PC 主站 2404 往返**(复测) | 同上全链 18/18 PASS——B7 `set_sealed`+持久化写路径下 C_SE→YX 联动仍成立(B5 遗留"104 YX 联动"腿闭环) | `20261012_B6_iec104_roundtrip_log.txt` |
|
||||
| 2026-10-12 | 同 PASS 固件 / **B7 定值持久化 + 软压板 YK12 台架腿**(`test/host/iec104_master.py --b7-pre/--b7-post/--b7-mark/--b7-check`,中间 ST-LINK 复位) | pre **21/21**:C_SE 写 7.5+C_RD 回读、YK12 两段 OFF → 0.05 A 低定值**不动作**(保护退出)、YK12 ON → YX15/16 立即动作(COT=3)、收尾留压板退出;post **13/13**:**压板退出态跨复位保持**(开机日志 `global plate OUT -> protection disabled` + 低定值仍不动作)、重启后 YK12 ON 即动作(联动在位);mark/check **4/4+4/4**:**非默认定值 7.5 跨复位保持**(C_RD=7.500,与出厂默认可区分);开机日志两次 `[CFG] prot set loaded (/prot_set.bin)` | `20261012_B7_iec104_persist_log.txt` / `20261012_B7_persist_boot_log.txt` |
|
||||
|
||||
## 4. 关联
|
||||
|
||||
|
||||
@@ -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)、L1-6 采样有效性校验与 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 判据节拍 + L5-4 采样故障闭锁 + L5-1 定值校验和巡检,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)**——L1 采集链路(B1,2026-10-10)、L1-6 采样有效性校验与 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 判据节拍 + L5-4 采样故障闭锁 + L5-1 定值校验和巡检,IWDG `TASK_WD_PROTECT` bit8,栈 512 words 静态链 872 B / 余 57%),判据结果经 B4 IEC104 遥信(YX15~23/31)上送;**B7 定值持久化 + 全局软压板 + 竞态收口完成(2026-10-12,含台架腿验证)**;**出口记录(L4)与标准源注入验收为下一步**(见 §7)。
|
||||
|
||||
---
|
||||
|
||||
@@ -469,7 +469,7 @@
|
||||
| **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 同批主机完成(同框架实例);**过频/低频待频率测量算法** |
|
||||
| **P3** | 异常检测与闭锁 | L5 自检闭锁、采样通道自检;三相类(涌流/PT·CT 断线/母线接地)**建接口不使能** | P1/P2 | 自检失败闭锁;未使能元件不误动 |
|
||||
| **P4** | 出口、记录与定值集成 | L4 出口与记录、§5 定值模型落 cfg_file、UI 显示、上送 | P1 | 动作出口 + SOE 记录 + UI 显示闭环(**定值持久化 + 软压板 + 竞态收口 = B7 已完成 2026-10-12**,台架腿待窗口 🔴) |
|
||||
| **P4** | 出口、记录与定值集成 | L4 出口与记录、§5 定值模型落 cfg_file、UI 显示、上送 | P1 | 动作出口 + SOE 记录 + UI 显示闭环(**定值持久化 + 软压板 + 竞态收口 = B7 完成 2026-10-12,台架腿已验 ✅**) |
|
||||
| **P5** | 方向/功率类(延后) | L3-13 方向元件等 | 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 硬件(N-18 修复 + 中点偏置),本期**建接口不使能**。
|
||||
@@ -606,5 +606,5 @@ B0 产品定义 ✅(2026-10-10 已确认,见 §1.5)
|
||||
| 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 定值持久化 + 全局软压板 + 竞态收口(W1 任务卡)** | **定值模型增项** `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` 已刷)。台架腿(104 C_SE 写→断电重启→定值保持 + YK12 联动 YX)待窗口 🔴 |
|
||||
| 2026-10-12 | **B7 定值持久化 + 全局软压板 + 竞态收口(W1 任务卡)** | **定值模型增项** `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 验收窗口,W1 任务卡)** | 首跑(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 仍待窗) |
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
| `ftp_speed_test.py` | FTP 传输速度测试 |
|
||||
| `ftp_capture.py` | FTP 流量抓取 |
|
||||
| `ftp_regression.py` | FTP 回归套件 |
|
||||
| `iec104_master.py` | **IEC 60870-5-104 主站客户端(B6)**:连设备 :2404 跑 STARTDT → 总召(actcon/四组背景扫描/actterm)→ 经 C_SE 两段写临时压低 OC1 定值确定性触发 YX16 变位(COT=3)→ 恢复 → YK11 两段式 → C_RD 读回;纯标准库,输出纯 ASCII 可直接重定向归档为台架证据(判据 exit 0/1/2) |
|
||||
| `iec104_master.py` | **IEC 60870-5-104 主站客户端(B6/B7)**:连设备 :2404 跑 STARTDT → 总召(actcon/四组背景扫描/actterm)→ 经 C_SE 两段写临时压低 OC1 定值确定性触发 YX16 变位(COT=3)→ 恢复 → YK11 两段式 → C_RD 读回;**B7 持久化模式 `--b7-pre/--b7-post/--b7-mark/--b7-check`**(中间 ST-LINK 复位):YK12 两段投退→保护退出/联动、定值与压板态跨复位保持(含非默认 7.5 往返);纯标准库,输出纯 ASCII 可直接重定向归档为台架证据(判据 exit 0/1/2) |
|
||||
|
||||
### 时间 / 时延
|
||||
|
||||
|
||||
+182
-2
@@ -29,6 +29,19 @@ round-trip log as bench evidence).
|
||||
Usage: python iec104_master.py [--ip 192.168.1.100] [--port 2404]
|
||||
[--addr 0x8858] [--low 0.05]
|
||||
[--restore 10.0]
|
||||
|
||||
B7 bench leg modes (setpoint persistence + global soft plate, task card
|
||||
docs/任务规划/W1-采集保护收尾.md B7; firmware side App/cfg/prot_set_store.c):
|
||||
--b7-pre : before reset: mark setpoint 7.5 (C_SE+C_RD), YK12 OFF (two-step)
|
||||
-> low setpoint 0.05 must NOT trip YX16 (plate OUT disables
|
||||
protection); YK12 ON -> YX16 trips (linkage); restore 10.0;
|
||||
leave plate OUT (persistence proof), wait for dirty->save.
|
||||
--b7-post: after reset: C_RD 10.0 (setpoint persisted); low setpoint 0.05
|
||||
still must NOT trip (plate OUT persisted); YK12 ON -> YX16
|
||||
trips (linkage after reboot); restore 10.0, leave plate IN.
|
||||
--b7-mark / --b7-check [--mark 7.5]: write a distinctive NON-default
|
||||
setpoint (save), reset, read it back (literal "setpoint
|
||||
hold" proof, distinguishable from factory default), restore.
|
||||
"""
|
||||
import argparse
|
||||
import collections
|
||||
@@ -263,6 +276,145 @@ def actcon_of(type_id, want_pn=None):
|
||||
and (want_pn is None or e[1][2] == want_pn))
|
||||
|
||||
|
||||
def spont(ioa, val):
|
||||
return lambda e: (e[0] == "yx" and e[1][0] == ioa
|
||||
and e[1][1] == val and e[1][3] == COT_SPONT)
|
||||
|
||||
|
||||
def gi_baseline(m, ck, tag):
|
||||
"""General interrogation; wait for actterm (baseline YX state loaded)."""
|
||||
m.send_i(asdu(T_C_IC_NA_1, 1, COT_ACT, 0, ioa=0, payload=bytes([RQT_GROUP1])),
|
||||
"I C_IC act (%s)" % tag)
|
||||
ck.add("gi_actterm_%s" % tag, m.wait_event(
|
||||
lambda e: (e[0] == "asdu" and e[1][0] == T_C_IC_NA_1
|
||||
and e[1][1] == COT_ACTTERM), 15.0) is not None)
|
||||
|
||||
|
||||
def se_write(m, ck, addr, val, tag):
|
||||
"""Two-step C_SE_NC_1 write (select then execute), both must actcon."""
|
||||
pl = struct.pack("<f", val)
|
||||
m.send_i(asdu(T_C_SE_NC_1, 1, COT_ACT, 0, ioa=addr,
|
||||
payload=pl + bytes([0x80])),
|
||||
"I C_SE select 0x%X = %.3f (%s)" % (addr, val, tag))
|
||||
ck.add("se_sel_%s" % tag, m.wait_event(actcon_of(T_C_SE_NC_1, False),
|
||||
5.0) is not None)
|
||||
m.send_i(asdu(T_C_SE_NC_1, 1, COT_ACT, 0, ioa=addr,
|
||||
payload=pl + bytes([0x00])),
|
||||
"I C_SE exec 0x%X = %.3f (%s)" % (addr, val, tag))
|
||||
ck.add("se_exe_%s" % tag, m.wait_event(actcon_of(T_C_SE_NC_1, False),
|
||||
5.0) is not None)
|
||||
|
||||
|
||||
def rd_set(m, ck, addr, want, name):
|
||||
m.send_i(asdu(T_C_RD_NA_1, 1, COT_REQ, 0, ioa=addr), "I C_RD 0x%X" % addr)
|
||||
e = m.wait_event(lambda ev: (ev[0] == "yc" and ev[1][0] == addr
|
||||
and ev[1][3] == COT_REQ), 5.0)
|
||||
ck.add(name, e is not None and abs(e[1][1] - want) < 0.1,
|
||||
"read=%.3f want=%.3f" % (e[1][1], want) if e else "no response")
|
||||
|
||||
|
||||
def yk_two_step(m, ck, ioa, qdc_sel, qdc_exe, name):
|
||||
m.send_i(asdu(T_C_DC_NA_1, 1, COT_ACT, 0, ioa=ioa,
|
||||
payload=bytes([qdc_sel])),
|
||||
"I C_DC 0x%X select QDC=%02X" % (ioa, qdc_sel))
|
||||
ck.add(name + "_sel", m.wait_event(actcon_of(T_C_DC_NA_1, False),
|
||||
5.0) is not None)
|
||||
m.send_i(asdu(T_C_DC_NA_1, 1, COT_ACT, 0, ioa=ioa,
|
||||
payload=bytes([qdc_exe])),
|
||||
"I C_DC 0x%X execute QDC=%02X" % (ioa, qdc_exe))
|
||||
ck.add(name + "_exe", m.wait_event(actcon_of(T_C_DC_NA_1, False),
|
||||
5.0) is not None)
|
||||
|
||||
|
||||
def yx16_off_confirmed(m, ck, name):
|
||||
"""YX16 back to OFF: spontaneous COT=3, else second GI background scan."""
|
||||
m.events.clear()
|
||||
if m.wait_event(spont(16, 0), 5.0) is not None:
|
||||
ck.add(name, True, "via spontaneous COT=3")
|
||||
return
|
||||
log("no spont OFF within 5s -> second GI background scan")
|
||||
gi_baseline(m, ck, "off-scan")
|
||||
ck.add(name, m.yx.get(16) == (0, False), "via GI scan, yx16=%r"
|
||||
% (m.yx.get(16),))
|
||||
|
||||
|
||||
def b7_pre(m, ck, args):
|
||||
"""B7 phase 1 (before reset): plate linkage + mark setpoint for save."""
|
||||
addr = int(args.addr, 0)
|
||||
gi_baseline(m, ck, "pre")
|
||||
v16 = m.yx.get(16)
|
||||
ck.add("baseline_yx16_off", v16 is not None and v16 == (0, False),
|
||||
"yx16=%r" % (v16,))
|
||||
|
||||
se_write(m, ck, addr, 7.5, "mark")
|
||||
rd_set(m, ck, addr, 7.5, "rd_mark_7.5")
|
||||
|
||||
yk_two_step(m, ck, 0x600B, 0x81, 0x01, "yk12_off") # plate OUT
|
||||
se_write(m, ck, addr, args.low, "low") # 0.05 A
|
||||
m.events.clear()
|
||||
ck.add("plate_out_no_trip", m.wait_event(spont(16, 1), 3.0) is None,
|
||||
"YX16 must stay OFF while plate OUT (protection disabled)")
|
||||
rd_set(m, ck, addr, args.low, "rd_low_0.05") # setpoint still writable
|
||||
|
||||
yk_two_step(m, ck, 0x600B, 0x82, 0x02, "yk12_on") # plate IN -> linkage
|
||||
m.events.clear()
|
||||
ck.add("spont_yx16_ON", m.wait_event(spont(16, 1), 5.0) is not None)
|
||||
ck.add("spont_yx15_ON", m.wait_event(spont(15, 1), 3.0) is not None)
|
||||
|
||||
se_write(m, ck, addr, args.restore, "restore") # back to 10.0
|
||||
yx16_off_confirmed(m, ck, "yx16_off_after_restore")
|
||||
|
||||
yk_two_step(m, ck, 0x600B, 0x81, 0x01, "yk12_off_final") # leave OUT
|
||||
log("wait 2s: dirty -> SYS_EVT_PROT_SET_SAVE -> /prot_set.bin")
|
||||
time.sleep(2.0)
|
||||
|
||||
|
||||
def b7_post(m, ck, args):
|
||||
"""B7 phase 2 (after reset): persistence + linkage after reboot."""
|
||||
addr = int(args.addr, 0)
|
||||
gi_baseline(m, ck, "post")
|
||||
v16 = m.yx.get(16)
|
||||
ck.add("baseline_yx16_off", v16 is not None and v16 == (0, False),
|
||||
"yx16=%r (plate OUT after reboot -> protection disabled)" % (v16,))
|
||||
|
||||
rd_set(m, ck, addr, args.restore, "persist_rd_10.0") # setpoint persisted
|
||||
|
||||
se_write(m, ck, addr, args.low, "low")
|
||||
m.events.clear()
|
||||
ck.add("plate_out_persisted_no_trip",
|
||||
m.wait_event(spont(16, 1), 3.0) is None,
|
||||
"plate OUT state survived the reset")
|
||||
|
||||
yk_two_step(m, ck, 0x600B, 0x82, 0x02, "yk12_on") # linkage after reboot
|
||||
m.events.clear()
|
||||
ck.add("spont_yx16_ON_after_reboot",
|
||||
m.wait_event(spont(16, 1), 5.0) is not None)
|
||||
|
||||
se_write(m, ck, addr, args.restore, "restore")
|
||||
yx16_off_confirmed(m, ck, "yx16_off_final")
|
||||
log("wait 1s: final dirty -> save, leave plate IN")
|
||||
time.sleep(1.0)
|
||||
|
||||
|
||||
def b7_mark(m, ck, args):
|
||||
"""B7 distinctive-value mark: write non-default setpoint, let it save."""
|
||||
addr = int(args.addr, 0)
|
||||
se_write(m, ck, addr, args.mark, "distinct")
|
||||
rd_set(m, ck, addr, args.mark, "rd_distinct")
|
||||
log("wait 1.5s: dirty -> save (/prot_set.bin)")
|
||||
time.sleep(1.5)
|
||||
|
||||
|
||||
def b7_check(m, ck, args):
|
||||
"""B7 distinctive-value check after reset: must read back non-default,
|
||||
then restore default so the bench is left in a clean state."""
|
||||
addr = int(args.addr, 0)
|
||||
rd_set(m, ck, addr, args.mark, "persist_distinct_after_reset")
|
||||
se_write(m, ck, addr, args.restore, "restore")
|
||||
log("wait 1s: restore saved, bench left at defaults")
|
||||
time.sleep(1.0)
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
ap.add_argument("--ip", default="192.168.1.100")
|
||||
@@ -273,12 +425,24 @@ def main():
|
||||
help="temporary low OC1 setting (A) to force pickup")
|
||||
ap.add_argument("--restore", type=float, default=10.0,
|
||||
help="OC1 default setting to restore (A)")
|
||||
ap.add_argument("--b7-pre", action="store_true",
|
||||
help="B7 phase 1 (before reset) instead of B6 flow")
|
||||
ap.add_argument("--b7-post", action="store_true",
|
||||
help="B7 phase 2 (after reset) instead of B6 flow")
|
||||
ap.add_argument("--b7-mark", action="store_true",
|
||||
help="B7 write distinctive non-default setpoint (pre-reset)")
|
||||
ap.add_argument("--b7-check", action="store_true",
|
||||
help="B7 verify distinctive setpoint survived reset, restore")
|
||||
ap.add_argument("--mark", type=float, default=7.5,
|
||||
help="distinctive setpoint value (A), must be non-default")
|
||||
args = ap.parse_args()
|
||||
addr = int(args.addr, 0)
|
||||
b7_mode = ("pre" if args.b7_pre else "post" if args.b7_post else
|
||||
"mark" if args.b7_mark else "check" if args.b7_check else None)
|
||||
|
||||
ck = Checks()
|
||||
log("iec104 master client -> %s:%d (COV trigger: write 0x%X %.2f then "
|
||||
"restore %.2f)" % (args.ip, args.port, addr, args.low, args.restore))
|
||||
log("iec104 master client -> %s:%d mode=%s"
|
||||
% (args.ip, args.port, b7_mode or "b6"))
|
||||
|
||||
try:
|
||||
m = Master(args.ip, args.port)
|
||||
@@ -293,6 +457,22 @@ def main():
|
||||
ck.add("startdt_con", m.wait_event(
|
||||
lambda e: e[0] == "startdt_con", 5.0) is not None)
|
||||
|
||||
if b7_mode is not None:
|
||||
if b7_mode == "pre":
|
||||
b7_pre(m, ck, args)
|
||||
elif b7_mode == "post":
|
||||
b7_post(m, ck, args)
|
||||
elif b7_mode == "mark":
|
||||
b7_mark(m, ck, args)
|
||||
else:
|
||||
b7_check(m, ck, args)
|
||||
m.close()
|
||||
rc = 0 if all(ok for _, ok, _ in ck.items) else 1
|
||||
n_ok = sum(1 for _, ok, _ in ck.items)
|
||||
log("SUMMARY: %d/%d checks PASS -> %s"
|
||||
% (n_ok, len(ck.items), "PASS" if rc == 0 else "FAIL"))
|
||||
return rc
|
||||
|
||||
# 2. first general interrogation
|
||||
m.send_i(asdu(T_C_IC_NA_1, 1, COT_ACT, 0, ioa=0,
|
||||
payload=bytes([RQT_GROUP1])),
|
||||
|
||||
Reference in New Issue
Block a user