4a4ad6bc5f
现状口径:/keil-build 与 /serial-boot-test 是 DSH 会话的技能调用名, 不是 shell 命令;「名 + 命令行参数」的命令形态改为可执行体 run_boot_test.py 的真实调用。 - AGENTS.md:别名说明重写为「技能调用名不是 shell 命令」,两条目改 「编译(/keil-build)」「串口回归(/serial-boot-test)」 - keil-build / serial-boot-test 两 skill 调用名与示例同步;task-worktree 方案文档去掉 @build/@test 惯例从句;@task 保留(不在点名范围) - 123 文件现状陈述全改;台架捕获、变更记录/时间线、rename 映射输入 等 41 行历史证据保留旧名 - gen_memory_svg.py 6 处措辞随改,3 张 SVG 产物同批重跑 - 顺手补并行方案同行漏网计数 51→52 钩子 验证:提交期快钩子对 123 文件实跑全 Passed;check_doc_links --all rc=0(3038 处、无法判定 0);check_mermaid --all rc=0;YAML 解析 52 钩子不变;skill-size rc=0;py_compile 全过;字节卫生零漂移。
258 lines
23 KiB
Markdown
258 lines
23 KiB
Markdown
# IEC 60870-5-104 上行设计说明(B4)
|
||
|
||
> **定位**:DTU 上行规约 IEC 60870-5-104(DL/T 634.5104-2009)的设计基线——
|
||
> 范围、点表、链路流程、板端接入、预算与测试。规格来源
|
||
> `docs/算法/继电保护功能复现规划.md` §1.5(B0 产品定义,验收 = 省电科院点表);
|
||
> 代码落点 `App/protocol/iec104/`;未闭环的送检验收挂 `docs/任务规划/登记簿.md` §7。
|
||
> **角色**:本 DTU = **被控站(受控端)**,104 **TCP 服务器,端口 `[comm]` 段 `port`(工厂默认 2404)**;主站
|
||
> (控制端,点表参考 `192.168.1.199`)主动连入。
|
||
|
||
## 1. 范围(V0.1 子集)
|
||
|
||
| 面 | 本期做 | 本期不做(登记 §8) |
|
||
|---|---|---|
|
||
| 链路 | APCI U/S/I、STARTDT/STOPDT/TESTFR、k/w 窗、t1/t2/t3 | 多主站并发(单连接语义,见 §5) |
|
||
| 遥测 YC | 短浮点 M_ME_NC_1(系数 1):背景/周期/死区上送 | 归一化/标度、谐波轨(「遥测谐波轨(可选)」) |
|
||
| 遥信 YX | 单点 M_SP + 双点 M_DP:背景 + 突发(COT=3);**突发单点带 CP56 时标 = M_SP_TB_1(B9,随「SOE 记录」 SOE 落地)** | 双点带时标(V0.1 双点恒 IV,无意义) |
|
||
| 遥控 YK | 双点 C_DC 两段式(选择 82H/执行 02H) | 带时标、升降/步位 |
|
||
| 定值 | C_RD 读 + C_SE_NC 两段写(地址 = prot_set `comm_addr`) | 定值区切换/下装文件 |
|
||
| 其他 | C_CS 对时(→ `sys_clock`)、C_TS、C_RP | 固有参数 8001H~800AH(字符串类)、C_CI 电度、文件传输(录波) |
|
||
|
||
## 2. 分层与模块(采集链路测试可验证性约束:协议解析与硬件 I/O 分离)
|
||
|
||
| 模块 | 文件 | 职责 | I/O |
|
||
|---|---|---|---|
|
||
| ASDU 编解码 | `App/protocol/iec104/iec104_asdu.c/h` | 类型/COT 常量、ASDU 头、IOA 3B 小端、短浮点、CP56Time2a↔epoch | 零 |
|
||
| 点表/数据源 | `App/protocol/iec104/iec104_pts.c/h` | YC/YX/YK/定值表、COV(变位+死区)、**数据源 vtable**(板端绑 phasor/prot_*,单测绑假源) | 零(源注入) |
|
||
| 链路状态机 | `App/protocol/iec104/iec104_link.c/h` | TCP 流重组、U/S/I、k/w/t1/t2/t3、总召/突发/遥控/定值/对时编排 | 零(收=on_rx 喂流,发=回调,时基注入) |
|
||
| 板端胶水 | `App/task/iec104_serv.c/h`(随实现定名) | `[comm]` port 监听(工厂默认 2404)、数据通道收发、断链重听、netTask 驱动 | 全部(net_* API) |
|
||
| 通讯参数段 | `App/protocol/iec104/iec104_comm.c/h`(道G task-8) | `[comm]` 段注册 + ca/端口 getter 合法带自愈 / setter 守卫 | cfg_file 引擎(只注册不属主) |
|
||
|
||
> 三个纯逻辑模块 + 真实数据源(`App/algo/` 全纯逻辑)可整体在主机侧编译 →
|
||
> 主机侧纯逻辑单测覆盖**全协议栈**(`test/host/iec104/`),与 `test/host/prot_elm/` 同模式。
|
||
|
||
## 3. 点表(V0.1)
|
||
|
||
### 3.1 遥测 YC(IOA 0x4011+,短浮点,系数 1)
|
||
|
||
| IOA | 点 | 来源 | V0.1 状态 |
|
||
|---|---|---|---|
|
||
| 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 原句) |
|
||
|
||
- **数据源 = 测频与遥测快照**(`App/algo/meas.h`,「数据可信」遥测快照发布与 104 消费):200 ms 基波有效值
|
||
+ 每点品质,104 与 UI 共用同一份上游;读数单位 = ADC 引脚电压(eng=0,`App/algo/adc_cal`
|
||
折算层 2026-10-25 落地;二次值等两点标定置 VALID)。槽位值/品质整体透传,本层
|
||
**不再自行判新旧**(快照 `seq` 仅供 COV 去重)。
|
||
- 品质映射:快照 `MEAS_QDS_*` 低字节与线上 QDS 同值直传;**CLIPPED → IV**(「削顶通道
|
||
恒 IV」口径不变、改由品质驱动,docs/任务规划/数据可信.md §8 风险表「削顶通道被当成可测」行的单测要求);
|
||
快照从未发布(开机 <200 ms)→ IV|NT;判定顺序 IV 优先于 NT。
|
||
- 死区(104 改读快照):从「越死区即报」改为**连续 2 个新测量点越限才确认**——板端测量点 =
|
||
快照换帧(100 ms 轮询 vs 200 ms 快照按 `seq` 去重,防同一帧把单点噪声重复计满 2 点;
|
||
基准恒为**上次上送值**,非上次读值——防慢漂移把基准吃掉,参考系统同款);品质翻转
|
||
当拍直报、不计数。死区数值 = 运行时副本(`iec104_pts_yc_set_deadband`,ROM 默认沿
|
||
下游常数按工程量重定的额定 0.5% 档:0.5 V / 0.005 A / 0.5 Hz;运行参数段接 8020H 段后主站可读写);
|
||
标准源注入复核(两点标定)待台架。
|
||
|
||
### 3.2 遥信 YX(IOA 1~33)
|
||
|
||
| 段 | 点 | 来源 | V0.1 状态 |
|
||
|---|---|---|---|
|
||
| 1~4 | 开关位置(双点) | 无出口/位置硬件 | ❌ IV |
|
||
| 5~14 | 预留 | — | ❌ IV |
|
||
| 15 | 故障总 | OC1∨OC2∨OC3∨3U0(`prot_elm`) | ✅ |
|
||
| 16~18 | 过流 Ⅰ/Ⅱ/Ⅲ 段 | `PE_OC1/2/3` asserted | ✅ |
|
||
| 19~20 | 零序过流 Ⅰ/Ⅱ | 「三段式零序过流」未实现 | ❌ IV |
|
||
| 21~22 | 接地故障/重载 | 未实现 | ❌ IV |
|
||
| 23 | 过载 | `PE_OL` asserted | ✅ |
|
||
| 24~30 | 外部遥信(RS-485) | B2 暂缓(`docs/任务规划/暂缓-RS485.md`) | ❌ IV |
|
||
| 31 | 保护闭锁 | `prot_set_locked()` | ✅ |
|
||
| 32~33 | 预留 | — | ❌ IV |
|
||
|
||
> **点存在性优先**:无效点照常入总召/周期表并置 IV——点表是验收口径,缺行比
|
||
> 置 IV 更糟(主站侧无法区分"没做"与"接线错")。
|
||
>
|
||
> **保护类 YX(15/16~18/23/31)自 B5(2026-10-12)起为活数据**:protectTask
|
||
> 20 ms 判据节拍驱动 `prot_elm` 状态 → pts COV 变位上送(≤120 ms 端到端)。
|
||
>
|
||
> **突发单点遥信自 B9(2026-10-12)起带时标 = M_SP_TB_1(30)**:仅自发
|
||
> (COT=3)单点组(idx≥4)换型,信息体 = SIQ + CP56Time2a(8B);**总召/
|
||
> 周期扫描保持 M_SP_NA_1/M_DP_NA_1**(时标只用于变位事件,标准语义,防
|
||
> "全量换型")。时标源 = `sys_clock`(link cfg `epoch_ms` 回调):秒域时基
|
||
> → ms 域 = 秒×1000(亚秒恒 0,不造假);墙钟未建 → CP56 IV 位如实置位。
|
||
> 与 `/log/soe.log` 落盘记录同源同时基(`App/log/soe_store.c`,见
|
||
> `App/log/README.md`)——104 时标 = 事件上送时刻,SOE 记录 = 事件发生
|
||
> 时刻(20 ms 判据拍),两者差 ≤ 一拍 + 排空延迟(≤50 ms)。
|
||
|
||
### 3.3 遥控 YK(IOA 0x6000+,双点两段式)
|
||
|
||
| IOA | 点 | V0.1 行为 |
|
||
|---|---|---|
|
||
| 0x6000~0x6003 | YK1~4 开关 | **否定确认**(无出口硬件,`docs/算法/继电保护功能复现规划.md` R7) |
|
||
| 0x600A | YK11 信号复归 | ✅ 执行段 → `prot_elm_request_reset()`(B5 起跨上下文安全:请求由 protectTask 下一拍 eval 头部消费,不当拍直接复位) |
|
||
| 0x600B | YK12 遥控软压板 | ✅ 两段式转真(B7):选择段校验 DPC(ON/OFF,非法即 PN);执行段 → `prot_set_set_sealed(PS_GLOBAL_EN)` 原子写+封存;protectTask 下一拍读到退出态即复位元件并停判据(`App/task/protect_task.c`) |
|
||
| 0x600C | YK13 电池活化 | 否定确认(无对应硬件) |
|
||
| 0x600D | YK14 解除闭锁 | 否定确认(闭锁源于定值校验和,只能重写定值解除) |
|
||
|
||
### 3.4 定值(IOA = 通讯地址)
|
||
|
||
- 地址 = `App/algo/prot_set.h` 元数据 `comm_addr`(0x8820 基址 + 告警段 0x8027~0x802A,
|
||
逐项对照参考项目 `Const_CommSetPara.c`,见 `docs/算法/继电保护功能复现规划.md` §5.4)——
|
||
**点表不另立地址表**,prot_set 即单一事实源。`comm_addr = 0` 的本地项(投退/返回系数/
|
||
全局软压板)不可经 C_RD/C_SE 寻址(B7 起显式排除,防 IOA=0 误命中首个本地项)。
|
||
- 写两段式:选择 = 范围校验;执行 = `prot_set_set_sealed`(**原子写+封存**:影子区
|
||
写好后单字交换活跃区,protectTask 的「定值校验和」巡检任何时刻都看到自洽快照,
|
||
B5 登记的 µs 级竞态窗口就此收口)。
|
||
- 持久化(B7):执行段置 prot_set 脏标志 → iec104Task 每轮 poll `dirty_peek` 投递
|
||
`SYS_EVT_PROT_SET_SAVE` → **defaultTask(配置引擎属主)** 经 `App/cfg/prot_set_store.c`
|
||
原子写 `/prot_set.bin`(blob = magic+版本+计数+值区+sum32 正/反码对);
|
||
开机在 STORAGE_READY 屏障前装载,损坏/越界/版本换代 = 整表拒绝保持出厂默认
|
||
(all-or-nothing)+ 自检留痕 `prot set corrupt`;写盘失败脏标志保留 = 下轮重试。
|
||
|
||
**运行参数段 `0x8020H~0x8058H`(「数据可信」交付项,2026-10-25 落实)**:
|
||
|
||
> ⚠ 逐项地址为**本仓自定**(`docs/算法/继电保护功能复现规划.md` §5.4 的权威表不在仓——
|
||
参考项目 `CommPara_ConfigTable` 拿不到,送检点表到位后**以送检为准替换常量表**,
|
||
映射表只落在 `App/algo/run_par.c` 顶部常量段一处)。
|
||
|
||
| 地址 | 项 | 域(C_SE/C_RD 浮点工程量) | 工厂默认 | 真源与守卫 |
|
||
|---|---|---|---|---|
|
||
| 0x8030~0x8038 | 遥测死区 UA/UB/UC/UN/IA/IB/IC/IN/FREQ | V / A / Hz,分档上限 50/1/5 | 下游常数按工程量重定的额定 0.5 % 档(0.5 V ×4 / 0.005 A ×4 / 0.5 Hz) | `run_par` [run_par] 段 9 键 int32 毫单位;落盘键表 → `docs/子系统设计/网络配置说明.md` §3.5 |
|
||
| 0x8040~0x8047 | 通道 k 覆盖(µV/码) | 正浮点;adc_cal 合法带 ROM×[0.5,2.0] 执行段裁决 | 回显生效值(ROM = 152.587890625 / 805.6640625) | **写 = `adc_cal_set` 代理,系数唯一真源在 [adc_cal] 段,run_par 不存系数**(防后人拿 run_par 表当真源表) |
|
||
| 0x8048~0x804F | 通道 b 覆盖(码值,可负) | ±8192(adc_cal 带) | 0(回显) | 同上;单侧写 RMW 用另一侧**当前生效值** |
|
||
| 其余 | 留白(PT/CT 变比等未启用类别) | — | — | C_RD → COT14+EVI / C_SE → actcon+PN |
|
||
|
||
- `0x8027~0x802A` 是 prot_set 告警段(过压/欠压),**run_par 命中集精确匹配、永不覆盖**;
|
||
两表共存的路由顺序 = **run_par 表先、未命中落 prot_set**(`iec104_pts.c` set 路由,
|
||
证据钉在 TC-IEC104-029)。
|
||
- 现行门控 = 两段式 + 范围/合法带校验(与保护定值同款),**无「仅暂停/测试态可写」
|
||
门控**——文档现行如此,不造新语义;若送检点表要求该类门控,接线点在
|
||
`run_par_104_write` 执行段入口,加一处即可。
|
||
- 持久化(运行参数段):任一写成功置 `run_par` 脏 → iec104Task 同款 peek 投递
|
||
`SYS_EVT_RUN_PAR_SAVE`(1<<8) → defaultTask `run_par_store_save()` 调 `cfg_file_save()`
|
||
整档外科保存(一趟覆盖 [run_par] 9 键 + 被代理改写的 [adc_cal]/[adc_cal_ofs],
|
||
lead 裁②一条事件位一趟够用);失败脏保留 = 下轮重试。消费侧(COV 判定)**实时读
|
||
引擎副本**,无缓存无投递(104 改读快照时的 pts 层 s_yc_db 副本已收编进 run_par)。
|
||
|
||
## 4. 链路与流程
|
||
|
||
- 参数:k=12 / w=8 / t1=15s / t2=10s / t3=20s(标准默认);序号 15bit 回绕,
|
||
超时判定一律差值法(tick 回绕安全,同 `App/algo/` 惯例)。
|
||
- 状态机:IDLE→(TCP 建立)OPEN→(STARTDT act/con)RUN⇄STOPPED;t1 超时或坏帧
|
||
→ 实例回 IDLE,**由胶水层负责断 socket**(纯逻辑层不感知 I/O)。
|
||
- 总召(C_IC 组 1):actcon → 分片背景扫描(YX 双点组 SQ=1 → YX 单点组 SQ=1 →
|
||
YC 组 SQ=1 → 频率单点)→ actterm;首召/ RBT 位 → COT=4(初始化),否则 COT=2。
|
||
单次 poll 发送预算 4 个 ASDU(防大扫描饿死宿主任务)。
|
||
- 突发:COV = 遥信变位 + 遥测**死区 2 点确认 + 品质翻转直报**(`iec104_pts_cov_check`,
|
||
104 改读快照语义见 §3.1 注),COT=3 逐点 SQ=0。
|
||
- 周期:RUN 态 60 s 全 YC 上送 COT=1。
|
||
- 遥控/定值写:两段式,失配/越界 → COT|PN 否定确认;未知 IOA → COT=14+EVI、
|
||
错公共地址 → COT=13+EVI、未知类型 → COT=12+EVI。
|
||
- 对时 C_CS:CP56 → epoch ms → 胶水层 `sys_clock` 设置(IV 位置起即 PN)。
|
||
|
||
## 5. 板端接入(iec104Task 胶水,2026-10-12 实现回填)
|
||
|
||
- **承载任务 = 专用 iec104Task(640 words / Normal)**,非 netTask:netTask 是
|
||
socket RPC 执行者,`net_recv/net_send` 在 netTask 内调用 = 自己等自己回执(死锁)。
|
||
手写于 `Src/freertos.c` USER CODE 区(timeSyncTask/adcTask 同款先例),文件
|
||
`App/task/iec104_serv.c`(纯编排,协议语义全在 `App/protocol/iec104/`)。
|
||
- **看门狗**:`TASK_WD_IEC104 = 7` 纳入 `wd_required_mask()` 两分支(产品 0x1F7 /
|
||
HW 测试层 0x1F5,含 B5 protect 位 bit8);主循环 100ms 节拍喂位,屏障等待按
|
||
100ms 分片喂位(timeSyncTask 2026-10-02 台架先例)。
|
||
- **就绪屏障**:等 `SYS_EVT_NET_READY`(`osFlagsNoClear` + 分片)后才建监听。
|
||
- **单连接语义**(`AGENTS.md` 模块约定,抄 `ui_net_sink.c` 模板):2404 监听与
|
||
数据通道复用同一 socket(accept 返回即 listen fd);EOF 时 net 层 auto_relisten,
|
||
应用层**不得**关 fd(`client == listen` 分支);仅模拟器多连接后端(fd 不同)显式关。
|
||
- **门控 + 兜底**:`net_listener_armed`/`net_can_read`(纯 RAM 读)省无谓 RPC 往返
|
||
(门控不用只认 ESTABLISHED 的 `net_can_accept`——那会把监听
|
||
服役窗口全挡掉,CONNECT 事件补 accept 探针从不运行);
|
||
每 32 轮无条件 recv 一次防 RECV_OK 事件未收到(沿用 UI 推流侧「周期 recv 兜事件丢失」的先例)。
|
||
- **网络代次自愈**:`net_get_generation()` 变化 → 关旧 fd 重建监听(netTask
|
||
NET_RECONFIG 重建路径的既有约定)。
|
||
- **主动拆链**(与 EOF 路径相对):协议故障(坏帧/N(R) 倒退/t1 超时)或发送连续
|
||
3 次失败(短写先例)→ 本端 `net_close` + 重建监听,促主站重连——违例时
|
||
主站不会自行断开,必须本端断(time_sync 会话收尾先例,非芯片 auto_relisten 风暴路径)。
|
||
- **抢占策略修正(V0.1 如实登记)**:建档时定"后连优先",实现后确认单连接
|
||
socket 在连接态无法 accept(监听即数据通道),**V0.1 实为首到优先**——旧会话
|
||
经 EOF/t1/拆链结束后新主站才能接入;后连优先需 net 层支持,见 §8 第 7 条。
|
||
- **k/w 与 RPC 时延**:`net_send` 经 netTask 串行 RPC(最坏往返无界 ≈4 s);
|
||
t1/t2/t3 全部用注入 tick 判定,单次 RPC 停顿不会误触 t1(15 s),连续停顿由
|
||
"发送 3 连败拆链"兜底。COV 突发延迟 ≤100ms(服务周期),远小于 SOE 5000ms 线。
|
||
- **对时**:C_CS → `sys_clock_set_unix()`(含 SD2506 RTC 写回);epoch 秒 >2^32
|
||
(2106-02-07 后)显式拒绝回 PN。
|
||
- **通讯参数可配置化(道G task-8,2026-10-26 落地)**:公共地址与监听端口真源 =
|
||
`/config.ini` `[comm]` 段(键表 → `docs/子系统设计/网络配置说明.md` §3.6)。消费方式 =
|
||
`iec104Task` 启动读一次 `iec104_comm_ca()` 填链路 cfg(**ca 生效 = 改后重启**),
|
||
`s_bind_listen()` 每次现取 `iec104_comm_port()`(端口另在下次重 bind 自然生效);
|
||
getter 合法带 ca∈1..65535 / port∈1024..65535,带外自愈回工厂默认 1/2404
|
||
(adc_cal 合法带哨兵同款;getter 不打日志,省 iec104Task 深链栈)。不挂段回调、
|
||
不新增事件位、不走 SYS_EVT_NET_RECONFIG(热切换代价见 §8,原「V0.1 固定 1」口径作废)。
|
||
- **面板编辑(道G task-9,2026-10-27)**:「通讯参数 → 通讯设置」页(`#page=comm`,
|
||
`Drivers/BSP/UI/ui_page_comm.c`)经**通道六注入**(`ui_data_comm_ops_t`,理由与
|
||
通道五同构:分层 / 模拟器 / 「写值+置脏」原子性)编辑 ca/port;合法带由执行侧
|
||
现给(面板粗守与 setter 守卫同一出口,抄数即第二真源)。保存行 ENTER →
|
||
WAIT/OK 锁存判定 = `iec104_comm_dirty_peek()`,落盘 = defaultTask 每轮无条件
|
||
`iec104_comm_store_save()`(run_par/prot_set 同款 B7 脏位形态,**无事件位**,
|
||
延续上条 D5 口径)。屏上 OK 只证明**落盘完成**,不证明"已在新值上运行"——
|
||
生效时刻仍按上条(ca 重启 / port 重 bind)。容量核对:生产占 **6/8 段、
|
||
[comm] 2/16 键**,超限现象 = 注册返 -1 → `comm init: FAIL` 启动锚 + getter
|
||
回 ROM 默认,语义由 cfg_file 宿主套 TC-CONFIG-056/057 钉住,不抬宏。
|
||
|
||
- **观测计数(只读 getter,2026-10-27 道G task-12)**:`App/task/iec104_serv.c` 另有四枚
|
||
**只增不清**的计数,经 `iec104_serv_get_stats()`(声明在 `App/task/iec104_serv.h`)对外只读:
|
||
`conn_up`(主站接入次数)/ `apdu_tx`(成功发出的 APDU 帧数)/ `tx_fail`(发送短写或失败次数)/
|
||
`rx_bytes`(收到的**字节**数,不是帧数——帧边界在 link 层重组,serv 层看不见)。口径是
|
||
**上电以来、跨重连不清零**,给页面用时那一栏要写「本次开机以来」,与运行时长同一类。
|
||
⚠ 与本节三枚**控制量**(`s_liveness_ctr` / `s_send_fail_run` / `s_conn_dead`,为"要不要拆链"
|
||
服务、会被复位、只有 8 位)无关,拿它们当统计数字必错。为什么留在 serv.c 而不并进通用
|
||
统计模块、也不放进 `iec104_link_t`(实例是文件级 static,喂数据侧拿不到指针,且
|
||
`link_open/link_close` 会把"上电以来"洗成"本次连接"):104 的账本归 104。getter
|
||
**任意上下文可读**(不取锁、不读时刻、不碰 socket;四枚 u32 单字原子,跨字段不保证同一
|
||
瞬间,四枚之间没有"合起来才成立"的判据),到顶饱和不回绕。**「总召次数 / 上送 I 帧数」
|
||
不在这里**:那是 link 层事件,serv 照不到,需要它得去
|
||
`App/protocol/iec104/iec104_link.c` 加——本卡未做,别在页面上摆一个数却没有产生它的地方。
|
||
|
||
## 6. RAM / 栈预算(2026-10-12 实测)
|
||
|
||
| 项 | 实测 | 依据 |
|
||
|---|---|---|
|
||
| 静态(新增) | link 实例 ~560 B(含 512 B 流重组缓冲)+ pts 快照 ~120 B + 胶水 rx 128 B | `iec104_link_t` 字段和 |
|
||
| iec104Task 栈 | 640 words(2560 B):静态最坏链 1456 B(拆链→重建监听→net_bind→SPI 故障→日志尾),余 1104 B / 43% **PASS** | `stack_report.py` 2026-10-12;512 words 时余 592 B < ISR 底线 → 抬栈 |
|
||
| CCM 堆 | 任务栈 2.5 KB + TCB,min_ever 6,640 → ≈6,100 B(> 3,072 告警线) | adcTask 抬栈同口径台账 |
|
||
| 总量门禁 | RW_IRAM1 73.1% / RW_CCM 75.3%(<92%) | `ram_baseline.py --update` 2026-10-12 |
|
||
|
||
## 7. 测试方案
|
||
|
||
| 层 | 内容 |
|
||
|---|---|
|
||
| 主机侧纯逻辑单测 | `test/host/iec104/`:APCI 重组/坏帧、STARTDT 握手、总召全流程(含 RBT/分片/预算)、COV、k/w 窗、t1/t2/t3(假时基)、遥控两段式与 PN、YK12 软压板两段转真 + 置脏(B7)、定值两段写 + set_sealed 后 selfcheck、C_RD(含本地项不可寻址)、C_CS(含闰年)、错地址/错类型 EVI;**板端默认源真实链**(ring→phasor→freq→meas 快照,非桩):值/品质透传、CLIPPED→IV、0x401D 绑频(收敛 ±0.02 Hz / 未新鲜 IV)、死区运行时化 + 2 点确认/回摆撤销、seq 去重(104 改读快照与频率点绑定,TC-IEC104-025~028)+ 运行参数段路由/两段式/RMW(TC-IEC104-029)+ `[comm]` 段真链(道G task-8,TC-IEC104-031~033:注册/出厂模板/沉降重载/带外自愈/setter 守卫/ca 端到端 = C_RD 正答与旧写死 ca=1 转 COT13+EVI);`test/host/iec104_serv/` 钉端口与 ca 取值来源(TC-I104SRV-001b/c);`test/host/cfg_file/` 钉段/键容量上限(TC-CONFIG-056/057);`test/host/run_par/`:[run_par] 注册/落盘往返/守卫/系数直通合法带(TC-RUNPAR-001~008);`test/host/prot_set/`:blob 往返 + 损坏整表拒绝(all-or-nothing)|
|
||
| 静态门禁 | `iec104-unit-test` 钩子 + cppcheck/coding-standard |
|
||
| 台架 | `/serial-boot-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`);**B9 SOE 腿**(同工具同轮回归):自发 YX 断言 **M_SP_TB_1 带 ts**(工具解析 type 30/1 双型)+ FTP 下载 `/log/soe.log` 经 `test/host/soe/decode_soe.py` 解码断言(校验和/seq 单调/CP56↔epoch UTC 交叉),pre 21/21 + post 13/13 不回归;lib60870 级第三方全流程归 B10 |
|
||
|
||
## 8. V0.1 限制与待办(如实登记)
|
||
|
||
1. 固有参数 8001H~800AH 未实现(字符串类无法短浮点上送)→ 未知 IOA 应答;随送检需求再设计。
|
||
2. ~~SOE 带时标~~ **突发单点已带 CP56 时标 = M_SP_TB_1(B9 落地,见 §3.2)**;
|
||
双点带时标不做(V0.1 双点恒 IV,无意义)。
|
||
3. YK1~4/13/14 否定确认——出口硬件确认后(R7)转真执行(YK12 已于 B7 转真)。
|
||
4. ~~遥测死区 10.0 码值为拟定值~~——工程量死区已于 2026-10-25 随下游常数按工程量重定落地(额定 0.5%);
|
||
104 改读快照已加 2 点确认;运行参数段(2026-10-25)已落地 **0x8020~0x8058 读写映射 + [run_par]
|
||
持久化 + 系数覆盖直通 adc_cal**——死区系数唯一真源 = cfg 引擎副本(run_par 存死区、
|
||
**不存系数**,系数真源在 [adc_cal] 段,见 §3.4 表注),`iec104_pts_yc_set_deadband`
|
||
降级为转发壳。
|
||
5. 多主站/双链路冗余不做(单连接语义)。
|
||
6. 主站侧验证工具 = `test/host/iec104_master.py`(B6 2026-10-12 就绪,台架往返 18/18,覆盖总召/变位/遥控/定值);**第三方送检环境仍未就绪**——lib60870 级第三方全流程归 B10。
|
||
7. **后连优先未实现**(V0.1 = 首到优先):单连接 socket 连接态无法 accept,
|
||
旧会话结束前新主站接入被拒;后连优先需 net 层(CH395F 单连接模型)支持,
|
||
真需要冗余切换时随 net 扩展立项。
|
||
8. ~~公共地址固定 1、监听端口固定 2404~~——**可配置化已落地**(道G task-8,
|
||
2026-10-26,`[comm]` 段,见 §5 与 `docs/子系统设计/网络配置说明.md` §3.6)。
|
||
**主站地址(accept 侧 IP 白名单)仍不做**:现无既有消费点;单连接 socket 上
|
||
「拒绝非白名单」= close + re-listen,端口扫描可打成 SPI/看门狗风暴,且配错
|
||
即锁死真主站(FTP 口令那套失败锁的代价在 104 侧没有等价护栏可低成本复刻)
|
||
→ 待送检/现场需求明确后另行立项,`[comm]` 段当前**没有**该键。
|