198 KiB
STM32F4-Base 产品需求设计文档
文档定位:本项目面向产品的需求基线——把散落在架构、子系统、测试、问题记录各文档中的 "产品做什么 / 做到什么程度 / 依据是什么"收敛成一份可评审、可追溯的需求说明,供甲方、产品、 开发、测试与评审者建立统一认知。 范围:硬件规格、系统架构、功能需求(FR)、接口规范、非功能需求(NFR)、UI 规格、平台约束、 待实现项与路线图、验收判据。 事实来源:本文所有数值与结论均取自仓库内受管事实源(代码、
.ioc、.map、网表分析报告与 各模块设计文档),凡与其它文档冲突处,以本文标注的权威来源为准。 版本:v1.9 日期:2026-10-28 状态:现状基线(含已实现项 + 待实现项) 阅读前提:建议先读docs/README.md(文档索引)与docs/架构设计/项目架构总览.md(全景架构)。 范围口径:1:1 复刻——本产品是参考产品 CLS100(Scatter_P_HV03.01_SV01.01,OMAP-L138 ARM+DSP 双核 + VxWorks 配电保护测控装置)的逐模块复刻。产品范围 = 参考源码的能力全集, 差异只允许来自物理不可移植项(§2.4.1)。§2.5 以参考工程源码的常量表与模块文件为唯一清单, 给出 20 项能力对照与复刻进度;§9 的缺口一律表述为"复刻进度"而非"不做", 其中 §9.4~§9.13 是逐项明细(每个定值 / 每个点 / 每个模块 / 每条链路的报文差在哪、怎么算做完)。 产品定义的技术细化见docs/算法/继电保护功能复现规划.md。
1. 文档说明
1.1 目的与范围
本文回答三个问题:
- 产品是什么——一块工业级嵌入式 DTU 平台固件,做什么、面向谁、部署在哪;
- 产品要做到什么程度——每一项功能/接口/性能/可靠性的可验收要求;
- 产品当前做到哪一步——已实现、已验收、待实现的明确边界。
不含:具体代码实现细节(见各模块设计文档)、测试用例步骤(见 docs/测试说明/)、
未闭环事项的逐条跟踪(见 docs/任务规划/README.md)。
1.2 术语与缩写
| 术语 | 全称 / 含义 |
|---|---|
| DTU | Data Transfer Unit,数据传输单元;本产品的设备角色 |
| MCU | STM32F407ZGTx(Cortex-M4,LQFP144) |
| FTL | Flash Translation Layer,闪存转换层(本项目用 dhara 实现) |
| BBT | Bad Block Table,NAND 坏块表(持久化在保留块池) |
| FatFs | 通用 FAT 文件系统模块(Lib/FatFs) |
| BSD Socket API | 本项目在 CH395F 之上封装的 net_socket 接口(socket/bind/listen/accept/recv/send/close) |
| RemoDispBus | 远程显示总线协议(MCU 无屏,UI 以 1bpp 帧经 TCP 推流到远端客户端) |
| cfg_file | 通用配置引擎(INI 段键表,MCU/模拟器双端共享核心) |
| sys_clock | 系统墙钟时间服务(RTC 基准 + tick 推进) |
| sys_log | 定长 64B 记录引擎(运行/自检日志) |
| IWDG | Independent Watchdog,独立看门狗(LSI 时钟源) |
| 就绪屏障 | 用 CMSIS-RTOS2 Event Flags 表达"子系统就绪"的启动顺序机制 |
| 双端 | MCU(Keil/ARMCC)与 PC 模拟器(CMake/MSVC)共用同一份 UI/配置源码 |
| @build / @test | 仓库约定的构建 / 自动化测试命令别名 |
| 语义取数与有效性 / 标定折算 / 全周傅氏相量 / 测频与遥测快照 / 保护判据 | 采集链路分层:语义取数与有效性(语义取数与有效性)→ 标定折算(标定折算)→ 全周傅氏相量(全周傅氏相量)→ 测频与遥测快照(测频与遥测快照)→ 保护判据(保护判据) |
| 全周傅氏 | 单频 DFT 取基波相量,窗长 = 整周波(20 点);幅值即基波有效值 |
| 相量 | {fRe, fIm, fAm, fAmSQ},实部 / 虚部 / 幅值 / 有效值 |
| 双区交换 | 相量(及遥测快照)计算区 / 使用区索引单字节翻转,读者无锁取整份快照 |
| 等周波采样 | 软件测频 + 调采样周期,使窗长恒等于实际周波(严格 20 点/周波) |
| 标定 k / b | 通道折算系数(µV/码,Q16 定点)与零点(码值);工程量 = (code + b) × k |
| QDS | IEC 60870-5-104 的品质描述符字节(OV / NT / IV 等位) |
| SOE | Sequence of Event,带时标的事件顺序记录(本产品落 /log/soe.log) |
| CP56Time2a | 104 的 7 字节时标格式(毫秒 / 分 / 时 / 日 / 月 / 年 + 时标标志位) |
| 点表 / IOA | 104 上送对象表与信息体地址;本产品点表口径见 §6.8 |
| 固有 / 运行 / 保护定值 | 三类参数:只读身份信息、可整定的运行参数、可整定的保护定值(§5.13) |
| 软压板 | 软件投退开关(全局软压板 = 保护总投入,可经 104 遥控投退) |
| 遥测死区 | 遥测变化上送门槛;本产品按"连续 2 个新测量点越限才确认" |
| CLS100 | 参考产品(配电保护测控装置,ARM + DSP 双核 / VxWorks),仅作能力对照,非本产品代次 |
1.3 读者与相关文档
| 角色 | 建议读法 |
|---|---|
| 甲方 / 产品 | §2 产品概述 → §5 功能需求 → §9 待实现项与路线图 → §10 验收判据 |
| 开发 | 全文;深入时按 §11 指向各模块设计文档 |
| 测试 / 验证 | §5、§6、§7、§10 + docs/测试说明/ |
| 评审 | §2、§7、§8、§9 |
2. 产品概述
2.1 产品定位
STM32F4-Base 是一块工业级嵌入式 DTU 平台固件,基于 STM32F407ZGTx,集成 以太网通信、SPI NAND 存储、ADC 采集、RS-485 通信与 FTP 文件服务,并自带 远程显示(UI 推流)、墙钟对时、看门狗自恢复、运行/自检记录等工业现场能力。
它的产品目标是 1:1 复刻参考产品 CLS100(配电保护测控装置)——按参考工程源码的 常量表与模块文件逐项对齐点表、定值、保护元件与规约栈(§2.4、§2.5)。在此过程中沉淀出的 分层底座(采集链 语义取数与有效性~出口与记录、配置引擎、就绪屏障、双端测试)同时是可复用的平台能力。
产品现状一句话:平台能力(网络 / 存储 / 时间 / UI / 日志 / 看门狗 / FTP / 配置) 已实现并台架验收;采集主线(语义取数与有效性采集 → 标定折算 → 全周傅氏相量 → 测频与遥测快照 → 保护判据 → 出口与记录 SOE → IEC 60870-5-104 上送)软件链路已全线贯通并台架闭环;与参考产品的差距 集中在三处:① 保护判据处于未标定闭锁态(等标准源两点标定)、② 点表规模远小于参考 (定值 40 vs 249 项、遥测 9 vs 31 点、开入开出 0 vs 138/31 点)、③ 独立子系统未立项 (故障录波、电度、多规约、SNTP)。即:"数"与"判据"已可信到引脚电压口径, 缺的是标定、点表铺开与一次设备接口(明细见 §2.5.2、§9)。
2.2 产品形态与部署
flowchart LR
subgraph DEV["开发机(Windows)"]
K[Keil MDK-ARM v5<br/>编译/烧录]
SIM[LVGL PC 模拟器<br/>CMake + SDL2]
PY[Python .venv<br/>脚本/测试]
end
subgraph TGT["目标板(DTU 硬件)"]
M[STM32F407ZGTx @168MHz]
P[CH395F / GD5F2GQ5UE / TPAFE5160 / SD2506 / RS-485 / LED×6]
end
subgraph RMT["远端客户端(PC/浏览器)"]
C[DTU-RemoteLCD 或任意 TCP 客户端]
end
DEV -- "USB:ST-Link 下载器" --> TGT
DEV -- "USB 串口 USART1 @115200 调试日志" --> TGT
TGT -- "以太网 CH395F<br/>FTP:21 / 对时:8888 / 远程显示:7003" --> RMT
| 环境 | 角色 | 必需性 |
|---|---|---|
| ① 开发机 | 编译/烧录、UI 模拟器、脚本工具链 | 开发/测试必需 |
| ② 目标板 | 运行固件的 DTU 硬件 | 上机必需 |
| ③ 远端客户端 | 远程看图/按键、对时推送、FTP 文件操作 | 现场使用必需 |
关键产品特征:MCU 端无物理屏幕——UI 画面以 160×160 单色位图(1bpp)经 TCP 推送到远端 客户端渲染,按键亦由远端下发(见 §5.6、§8)。
2.3 设计目标与原则
| # | 目标 | 落地手段 |
|---|---|---|
| G1 | 可靠:现场死机可自恢复、掉电不丢配置、错误可追溯 | IWDG + 任务心跳位图、原子写 + 迁移、错误码通道四要素 |
| G2 | 可维护:分层解耦、单一事实源、双端复用、门禁强制 | 六层架构、就绪屏障、生成器(菜单/字体/任务表)、pre-commit 钩子族 |
| G3 | 可移植:UI/配置源码 MCU 与 PC 模拟器共用 | 平台后端抽象(*_mcu.c / *_sim.c),核心零平台依赖 |
| G4 | 可扩展:新子系统/新配置段/新页面按模板接入 | 事件位扩展、段注册三步、页面插件描述符、App/protocol/ 预留 |
| G5 | 可验收:每项能力有明确判据与自动化门禁 | @build / @test / 静态门禁 / 主机侧纯逻辑单测 / 台架验证 |
设计原则(贯穿全项目):
- 上层只依赖相邻下层(单向);禁止反向依赖(例外经登记)。
- 状态位常驻、命令位消费——Event Flags 就绪位必须
osFlagsNoClear。 - 能推导的就不存——持久化"不可推导"的状态(导航历史、配置、日志),其余现算。
- 单写者——配置文件属主 =
defaultTask;syslog 唯一写者 =defaultTask;控制台唯一发送者 =defaultTask。 - 一切写入 = 临时文件 + rename(原子替换),半截窗口结构消除。
- 测量不可信就不判据——未标定(VALID 未置位)或采样故障时保护停走,品质位如实上送, 绝不用"看起来对"的数去动作(§5.12、§5.15)。
- 点表优先于实现——本期做不了的 104 点照常入表并置 IV;缺行比置 IV 更糟, 主站将无法区分"没做"与"接线错"(§6.8)。
2.4 产品范围(1:1 复刻口径)
产品范围 = 参考产品 CLS100 的可移植能力全集。 本产品不是"在参考产品里挑一部分做", 而是按参考工程源码逐模块复刻:凡参考源码中存在的点表、定值单元、保护元件、记录类型、 规约栈,都属本产品目标范围;差异只允许来自物理不可移植项(§2.4.1)。
范围按复刻完成度分三档,判定口径见 §2.5.1:
| 档 | 含义 | 处置 |
|---|---|---|
| ✅ 已对齐 | 参考源码能力在本产品上已实现,且有台架/单测证据 | 进 §10 验收判据 |
| 🔶 部分对齐 | 骨架、口径、地址编排已对齐,覆盖范围小于参考(通道数 / 元件数 / 点数) | 差额逐条进 §9 |
| ⬜ 未开始 | 参考源码存在、本产品无对应实现 | 逐条进 §9,不等于"不做" |
当前分布(20 项能力,明细见 §2.5.2):✅ 2 项(采样节拍、自检类型)、🔶 10 项、 ⬜ 7 项、— 1 项(双核分工,不可移植)。
2.4.1 不可移植项(唯一允许落在范围外的部分)
| # | 不可移植项 | 参考实现 | 本产品 | 归因 |
|---|---|---|---|---|
| X1 | 双核 ARM + DSP 分工 | OMAP-L138(ARM 跑通信/HMI,DSP 跑保护) | 单核 Cortex-M4F 按任务划分承担 | 芯片形态 |
| X2 | 实时操作系统与工具链 | VxWorks 5.x + CCS | FreeRTOS V10.3.1 + Keil ARMCC | 平台形态 |
| X3 | 一次设备接口 | KO / KI 板卡(出口、开入、硬压板) | V0.1 无该硬件(§4.6 H3) | 硬件缺失 |
| X4 | 独立计量通道 | 专用计量芯片(电度) | 无(跨转换器无同刻,§4.6 H1) | 硬件缺失 |
X1~X4 是范围外项的全部。 除此以外不存在"参考有、我们决定不做"的能力—
2.5 1:1 复刻基线(参考源码能力清单)
判定口径:本节所有"参考能力"的数字,**一律从参考工程源 (实测已发现"89 个元件模块"实为 45 个、定值"约 260 项"实为 249 项两处偏差)。
2.5.1 复刻基线三要素
- 点表即契约:参考源码用常量表(
g_t*Tab[])定义点表、定值、事件、压板。 这些表就是"要复刻什么"的唯一清单——表有几行,目标就有几个点。 - 地址即接口:104 的 IOA 由
Rly_IEC104.h的基址宏划分段,段基址必须逐字对齐(§2.5.3)。 - 模块即元件:
RelayUnit/下一个.c对应一个保护元件,元件数 = 文件数(§2.5.5)。
2.5.2 能力清单与复刻进度(源码实测)
| # | 能力 | 参考源码出处 | 参考数量 | 本产品现状 | 状态 |
|---|---|---|---|---|---|
| 1 | 定值项 | APP/EquipCfg/Const_Set.c g_tSetModelTab |
249 项 | 40 项(PS_ID_COUNT) |
🔶 |
| 2 | 定值单元 | APP/EquipCfg/Const_Set.h EN_SET_CELL_* |
23 个有项(枚举 28) | 5 组(短路/接地/过负荷/电压/频率) | 🔶 |
| 3 | 104 定值映射 | Comm/Pub/Const_CommSetPara.c g_tCommSetParaTab |
107 项,0x8820~0x8891 |
40 项(0x8820~0x8890 局部) |
🔶 |
| 4 | 遥测 YC | APP/EquipCfg/Const_Ana.c g_tYcIndexTab |
31 点 | 9 点(0x4011~0x4018 + 0x401D) |
🔶 |
| 5 | 遥测模型 | 同上 g_tAnaModelTab |
35 行 | 0 | ⬜ |
| 6 | 电度 YM | 同上 g_tYmIndexTab |
8 种 | 0 | ⬜ |
| 7 | 开入 KI | APP/EquipCfg/Const_IO.c g_tInputModelTab |
138 点 | 0(无硬件,X3) | ⬜ |
| 8 | 开出 KO | 同上 g_tOutputModelTab |
31 点 | 0(无硬件,X3) | ⬜ |
| 9 | 动作事件 | APP/EquipCfg/Const_Rec.c g_tActRecTab |
33 条(421~453) | 7 类记录(App/log/sys_log.h) |
🔶 |
| 10 | 录波测量通道 | 同上 g_tMeasureModelTab |
65 通道 | 8(本波口径,2026-10-29 代码面已交付;65 通道仍为 0,参考机口径未改) | 🔶 |
| 11 | 软压板 | APP/EquipCfg/Const_Soft.c g_tSoftTab |
9 面(表容量 32) | 1 面(PS_GLOBAL_EN) |
🔶 |
| 12 | 保护元件 | RelayUnit/*.c |
45 个模块 | 9 个实例 | 🔶 |
| 13 | 记录队列 | RecUnit/RecFile.c + GlobalDef/Const_Sys.h |
13 类(128/256 条) | 8 通道(7 文本 + SOE) | 🔶 |
| 14 | 自检类型 | GlobalUnit/SelfChk.c |
3 类型 + 2 闭锁 | 3 类 | ✅ |
| 15 | 故障录波 | APP/EquipCfg/Const_Wave.h |
3 类型 / 6 段 / RAM 16 个 | 0 | ⬜ |
| 16 | 采样节拍 | APP/EquipCfg/Const_VisEquip.h |
20 点/周波(50 Hz) | 20 点/周波(1000 Hz) | ✅ |
| 17 | 上行规约 | Comm/Pub/、Comm/Mon/ |
12 种 | 1 种(104) | 🔶 |
| 18 | 加密算法 | Comm/Ecc/ |
SM2 / SM3 / ECDSA | 0 | ⬜ |
| 19 | 双核分工 | CLS100_Arm/、CLS100_Dsp/ |
ARM + DSP | 单核(X1) | — |
| 20 | 远端屏与按键链路 | HMI/RemoeDisp/RemoDispBus.c、HMI/Dsp/Key.c、HMI/Dsp/Disp_Pub.c;屏板侧 DTU-LCD |
串口屏板通道(显存 3200 B + 状态灯 4 B 位掩码下行 / 键号上行)+ TCP 7003 镜像 | 7003 四命令已通;串口屏板通道整条缺失(协议已按屏板源码定版,见 §5.16.2);INIT 应答 8 B(参考 29 B,其中 13 B 颜色信息不对齐)、无断点续传、无链路监视、缺 F1/F2 | 🔶 |
读法:🔶 / ⬜ 行全部是待办,逐条对应 §9.1;
—只出现在 X1~X4 不可移植项上。 本表是范围判定的唯一出处,§9 不再重复解释"为什么缺"。
2.5.3 104 地址空间(段基址逐字对齐)
| 段 | 基址 | 范围 | 容量 | 本产品使用 |
|---|---|---|---|---|
| 遥信 YX | 0x0001 |
0x0001~0x1000 |
4096 | 定义 1 |
| 保护 BH | 0x1001 |
0x1001~0x4000 |
12288 | 0 |
| 遥测 YC | 0x4001 |
0x4001~0x5000 |
4096 | 0x4011~0x4018、0x401D |
| 参数 PM | 0x5001 |
0x5001~0x6000 |
4096 | 0 |
| 遥控 YK | 0x6001 |
0x6001~0x6200 |
512 | 0x600A(信号复归)、0x600B(全局压板) |
| 设定 YS | 0x6201 |
0x6201~0x6400 |
512 | 0 |
| 电能 YM | 0x6401 |
0x6401~0x6600 |
512 | 0 |
| 步位置 STEP | 0x6601 |
0x6601~0x6700 |
256 | 0 |
⚠ 段基址是
0x4001/0x6001,不是0x4000/0x6000。参考源码Comm/Pub/Rly_IEC104.h的CONST_104_BASEADDR_YC/_YK明确 1 起编 (注释即写4001-5000H、6001-6200H)。本仓 v1.1 及更早文档按4000H+/6000H+描述 属笔误,以本表为准;§5.15、§6.8 已同步更正。
2.5.4 定值单元(23 个有项单元,合计 249 项)
| 单元 | 语义 | 项数 | 本产品 |
|---|---|---|---|
EN_SET_CELL_WatchDog |
看门狗功能 | 63 | ⬜ |
EN_SET_CELL_SYS3 |
系统参数 | 45 | 🔶 |
EN_SET_CELL_VolTimeRecv |
电压时间型自愈 | 17 | ⬜ |
EN_SET_CELL_AutoReCls |
重合闸 | 16 | ⬜ |
EN_SET_CELL_SYN |
同期元件(FTU 型) | 13 | ⬜ |
EN_SET_CELL_OverCurI0 |
接地告警 | 13 | 🔶 |
EN_SET_CELL_VolPro |
电压保护 | 13 | 🔶 |
EN_SET_CELL_WAVESTART |
录波启动 | 12 | ⬜ |
EN_SET_CELL_MeaLimit |
遥测越限 | 10 | ⬜ |
EN_SET_CELL_OverCurSpeed |
过流加速 | 8 | ⬜ |
EN_SET_CELL_SYS1 |
PT 参数 | 6 | 🔶 |
EN_SET_CELL_SYS2 |
CT 参数 | 4 | 🔶 |
EN_SET_CELL_Auto_FG |
自动分闸 | 4 | ⬜ |
EN_SET_CELL_Auto_HH |
自动合闸 | 4 | ⬜ |
EN_SET_CELL_InRush |
励磁涌流闭锁 | 3 | ⬜ |
EN_SET_CELL_OverCur |
短路告警 | 3 | 🔶 |
EN_SET_CELL_VolQuaRate |
电压合格率 | 3 | ⬜ |
EN_SET_CELL_FZDDL |
非遮断电流闭锁 | 3 | ⬜ |
EN_SET_CELL_BHKO |
保护出口展宽 | 2 | ⬜ |
EN_SET_CELL_MeaRecord |
遥测记录 | 2 | ⬜ |
EN_SET_CELL_PowerSet |
功率电压设置 | 2 | ⬜ |
EN_SET_CELL_PTBreak |
PT 断线告警 | 2 | ⬜ |
EN_SET_CELL_AutoCtrl |
自动控制(活化/复归) | 1 | ⬜ |
枚举中另有 4 个单元在参考源码表内无项(
EN_SET_CELL_YB_TY功能软压板、OnceCch一次重合闸、TwiceCch二次重合闸、OverLoad过负荷保护)——已被条件编译或注释掉, 因此 249 项分布在 23 个单元而非枚举的 28 个。另有 3 个单元(SYN/OverCurSpeed/VolTimeRecv)受CN_DEV_TYPE_FTU宏控制,属 FTU 型专属。104 定值地址编排:107 项占
0x8820~0x8891连续段中的 107 个地址,8 个空洞 (0x8822、0x8823、0x883E、0x883F、0x8842、0x8851、0x8852、0x8853) 对应参考源码中被注释掉的 4 条映射(ULTV_PARA_2、ULTV_Phase等)。
2.5.5 保护元件(45 个模块 → 覆盖 8 个模块 / 9 个实例)
按功能归类(RelayUnit/ 文件名去 PRS_ 前缀):
| 类别 | 元件模块 | 个数 | 本产品 |
|---|---|---|---|
| 过流类 | OverCurrent、OverCurrent_I0、OverCurrent_SpeedUp、OverCurrentI0_SpeedUp、FZDOverCur、OverCurWarn、OverCurWarn_I0、OverLoad |
8 | 🔶 过流 Ⅰ/Ⅱ/Ⅲ + 过负荷(4) |
| 电压类 | OverVol、OverVol_U0、LackVol、LineHaveVol、HaveVolCls、NoVolTrip、PTBreak、CTBreak |
8 | 🔶 过压 / 欠压 / 零序过压(3) |
| 频率类 | OverFr、LackFr |
2 | ✅ 过频 / 低频(2) |
| 重合闸 | AutoReCls、AutoReCls_JD、OnceCch、TwiceCch、ConnectBrkCls |
5 | ⬜ |
| 方向 / 功率 | DirCell、PowDirJudge、PowerSet、YcOverLimit |
4 | ⬜ |
| 涌流 / 故障 | InRushCur、FaultIsola、FaultRecov、BusEarthAlm、SgzAlarm |
5 | ⬜ |
| 自动控制 | AutoCtrlTrip、ManualTrip、MusterRecov、ExvRec、ExvRecGW |
5 | ⬜ |
| 记录类 | SOERecord、CORecord、FrzRecord、YcMeaRecord、YcMeaLimitRec、YcVolQuaRate |
6 | 🔶 SOE 落盘(1,非判据元件) |
| 录波 / 采样 | WaveQdCell、RlyCommSam |
2 | ⬜ |
判据结构对齐(以 PRS_OverCurrent.c 为样板,三段过流共用一个核):
M_GRly_OverRelay(&bRelay, fAmp, fSetStart, fSetRet) 越限 + 返回系数滞回
∧ bFyOpen ∧ bDirOpenX ∧ bNOVOpen 复压 / 方向 / 低压闭锁
GRly_TimeRelay(&bRelay, &tTimer, dwSetDelay, CN_T10MS) 定时限(10 ms 基准)
tTimer_KeepKI 电流保持(返回后仍延时保持)
tTimer_NoUI 无压无流判据(CN_T20MS / CN_T200MS)
本产品
prot_elm.c的"越限 + 返回系数滞回 + 定时限"三元核与上述结构同构; 差异在于本产品用每元件独立实例表替代参考的全局定时器数组——这是单核移植的必要调整, 不改变判据语义。逐元件复刻计划见docs/算法/继电保护功能复现规划.md。
2.5.6 上行规约全集(12 种 → 已复刻 1 种;加密算法另计)
| 方向 | 规约 | 参考源码 | 本产品 |
|---|---|---|---|
| 主站侧(对上) | IEC 60870-5-101 | Comm/Pub/Rly_IEC101.c、Rly_IEC101_B.c |
⬜ |
| IEC 60870-5-102(电度) | Comm/Pub/Rly_IEC102.c |
⬜ | |
| IEC 60870-5-103 | Comm/Pub/RLY_IEC103.c、RLY_IEC103-tcp.c、Rly_IEC103T.c |
⬜ | |
| IEC 60870-5-104 | Comm/Pub/Rly_IEC104.c |
✅ | |
| ModBus | Comm/Pub/Rly_ModBus.c |
⬜ | |
| CDT | Comm/Pub/Rly_Cdt.c |
⬜ | |
国标电度 Whm_GB |
Comm/Pub/Whm_GB.c |
⬜ | |
| IEC 61850(MMS / GOOSE / SV) | Comm/Pub/struct61850.h、GlobalUnit/SttnLvlGoose.c |
⬜ | |
| CAN | Comm/Pub/Rly_Can.h |
⬜ | |
| 子站侧(对下) | IEC 101(含 ABB / 西门子 / 无优先级变体) | Comm/Mon/Rtu_IEC101*.c |
⬜ |
| IEC 104(含调试 / RIS 变体) | Comm/Mon/Rtu_IEC104.c、Rtu_Dbg104.c、Rtu_RIS104.c |
⬜ | |
| BALA101 / ModBus | Comm/Mon/Rtu_BALA101*.c、Rtu_ModBus.c |
⬜ | |
| 加密 | SM2 / SM3 / ECDSA | Comm/Ecc/ |
⬜ |
排期判断:104 已对齐;对下 ModBus RTU 与 101 是"配网终端"的必要项(接一次开关 / FTU), 与 RS-485 簇同批解冻;61850 依赖以太网多播与 MMS 栈,单核 M4 资源上需单独评估,属最末批。
2.5.7 差异归因与结论
| 归因 | 涉及条目 | 解除方式 |
|---|---|---|
| 外部资源(标准源、端子变比) | 定值标定、保护判据解卡 | 两点标定(§9.2 第 4 步) |
| 硬件缺失(X3 / X4) | 开入 138、开出 31、电度 8、同期、三相通道 | V0.2 硬件 |
| 立项未排 | 多规约、SNTP、定值铺开 | 按 §9.2 顺序。录波最小闭环已交付代码面(2026-10-29,卡片 docs/任务规划/故障录波.md、设计 docs/子系统设计/故障录波设计说明.md;1 kHz 起步与本文 80 点/周波口径的偏离在该设计文档 §2 显式登记);4 kHz 全速、多段、COMTRADE、104 文件传输仍未排,属二期范围 |
| 算力 / 形态(X1 / X2) | 双核分工、VxWorks | 不解除。屏板链路已从范围外项移入范围内待做(规格 §5.16,执行规划 docs/任务规划/屏板链路.md):主机侧链路与参考 1:1 同构,不属"替代方案" |
结论:本产品与参考产品的差距全部是"进度"而非"范围"——没有一项是"参考有而我们不做"。 已对齐的是软件骨架(采样节拍、相量算法、定值模型、104 上行、SOE 落盘、自检闭锁); 未对齐的是点表规模(249 / 31 / 138 / 31 / 33 / 65 vs 40 / 9 / 0 / 0 / 7 / 0) 与独立子系统(录波、电度、多规约)。因此 §9 统一表述为"复刻进度",不再出现"不做"。
3. 系统总体架构
3.1 六层分层架构
上图由
tools/arch_diagram/gen_arch_svg.py生成(手绘 SVG,零连线交叉);改架构后编辑脚本顶部ROWS数据重跑即可,源数据与下表一致。
分层原则:上层只依赖相邻下层(单向);① 业务层为顶层(仅 net_cfg,被 UI 与基础服务共用),
② UI 层与 ③ 基础服务层同级并列。
| 层 | 目录 | 职责 | 关键模块 |
|---|---|---|---|
| ① 业务层 | 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/*(语义取数与有效性~保护判据)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 |
| ⑦ 硬件 | — | STM32F407ZGTx @168MHz | SPI1 / SPI2 / I2C1 / UART4 / USART1 / DMA / GPIO / TIM7 |
3.2 运行时任务模型
九个 FreeRTOS 任务(Src/freertos.c 创建,任务体在 App/task/、App/sync/):
| 任务 | 栈(words / B) | 优先级 | 职责 |
|---|---|---|---|
defaultTask |
1280 / 5120 | Normal | FatFS 挂载(无卷 f_mkfs)→ 卷健康探针/自愈 → net_cfg_load + 定值/运行参数/通讯参数装载(配置引擎属主)→ 置 STORAGE_READY → 日志落盘(唯一写者)+ 2 s 配置轮询 + 各模块脏位落盘(prot_set / run_par / comm)+ SOE 排空 + LED 闪烁 + 栈水位观测 + 看门狗唯一喂狗者 |
netTask |
960 / 3840 | Normal | 等存储 → net_stack_bring_up() → 置 NET_READY → net_poll 轮询 + CH395F 操作串行化(消息队列执行者) |
ftpTask |
1024 / 4096 | Normal | 等网络且存储(WaitAll)→ lftpd_start("/", 21) → 单客户端会话循环 |
testTask |
2048 / 8192 | BelowNormal | 测试套件入口(test/board/test_config.h 选择)。产品构建不创建(未选套件时立即 vTaskDelete 回收其 8 KB CCM 栈) |
uiTask |
4096 / 16384 | BelowNormal | 等网络 → ui_port_init/ui_menu_init/ui_standby_init(空闲 60 s 切待机屏)/ui_net_sink → 10 ms 刷新 + 数据注入 |
timeSyncTask |
640 / 2560 | Normal | 等网络 → TCP :8888 收 PC 推送时间 → 写 RTC |
adcTask |
640 / 2560 | AboveNormal | 采集主线唯一消费者:每拍 adc_input_poll()(TPAFE 快照 + ADC1 DMA 帧)→ adc_health 有效性 → phasor_run() 相量 → freq_run() 测频 → 每 200 ms meas_tick() 发布遥测快照 |
iec104Task |
640 / 2560 | Normal | 等网络 → TCP :2404 监听 → 104 链路状态机(总召/变位/周期/遥控/定值/对时)+ 断链重听 + 网络代次自愈 |
protectTask |
512 / 2048 | Normal | 20 ms 判据节拍:采样故障闭锁判定 → 定值校验和巡检 → prot_elm_run() 元件判据 → 动作边沿投递 SOE(不做 NAND I/O) |
idle(128 words)/timer(256 words)由 FreeRTOS 内核创建。所有任务栈从 56 KBheap_4堆 (CCM)分配;CCM 水位 87.9%(<92% 门禁)。 任务表与Src/freertos.c的osThreadAttr_t一致,由scripts/gen_task_table.py生成并门禁校验; 栈配置与实测余量见 §7.3,改栈前后必须重跑scripts/stack_report.py。⚠ 节拍同源:TIM3 更新事件(1 kHz)同时触发 TPAFE
CONVST与(经 TRGO)ADC1 一轮 9 通道扫描, 并在 ISR 内唤醒adcTask——采集节拍与任务唤醒不允许各自计时。 ⚠ ADC1 必须在挂 DMA 的瞬间处于关闭态:app_main_init()步骤 4b-pre 的adc1_disable()不可删、不可后移, 否则 DMA 乒乓缓冲整体旋转 2 格(表象与"映射表写错"一致)。证据见docs/子系统设计/ADC采样节拍设计说明.md§4.5。
3.3 就绪屏障(Event Flags)
用 CMSIS-RTOS2 Event Flags(sys_evtHandle)表达"子系统就绪",取代魔法延时与全局标志轮询。
生产者与消费者互不知晓,只经事件组解耦;新增子系统只需定义新 bit + 各自 wait/set。
| 位 | 名称 | 类型 | 语义 |
|---|---|---|---|
| bit0 | SYS_EVT_NET_READY |
状态位 | netTask:net_init + PHY 稳定完成 |
| bit1 | SYS_EVT_STORAGE_READY |
状态位 | defaultTask:FTL/FatFS 挂载 + 配置就绪 |
| bit2 | SYS_EVT_FTP_READY |
状态位 | ftpTask:lftpd_start 完成 |
| bit3 | SYS_EVT_TIMESYNC_READY |
状态位 | timeSyncTask:首次时间同步完成 |
| bit4 | SYS_EVT_NET_RECONFIG |
命令位 | UI:请求立即应用新网口配置 |
| bit5 | SYS_EVT_CFG_SAVE |
命令位 | UI:网口配置保存请求(defaultTask 消费并写盘) |
| bit6 | SYS_EVT_CONSOLE_TX |
命令位 | 控制台单写者:生产者入环形缓冲后置位 |
| bit7 | SYS_EVT_PROT_SET_SAVE |
命令位 | 保护定值落盘请求:104 检测到定值脏后置位,defaultTask 原子写 /prot_set.bin |
| bit8 | SYS_EVT_RUN_PAR_SAVE |
命令位 | 运行参数段落盘请求:104 写运行参数后置位,defaultTask 整档外科保存 |
⚠️ 铁律:状态位(bit0
3)表达持久状态,任何消费者都不许消费——必须8)表达"请做一件事",必须恰好被消费一次(消费型等待)。 历史事故:就绪位被先到的等待者消费,导致osFlagsWaitAny|osFlagsNoClear。命令位(bit4ftpTask的WaitAll(bit0|bit1)永不成立、21 端口从未监听(静默)。
3.4 启动时序
sequenceDiagram
autonumber
participant M as main
participant A as app_main_init
participant K as osKernelStart
participant D as defaultTask
participant N as netTask
participant S as adcTask / protectTask
participant F as ftpTask
participant U as uiTask
participant I as iec104Task / timeSyncTask
M->>M: HAL_Init + CubeMX 外设初始化<br/>(SPI1/SPI2/I2C1/UART4/USART1/DMA/GPIO/TIM3/TIM7)
M->>A: app_main_init()
Note over A: 时间子系统优先,使后续日志带时间戳
A->>A: sd2506_init() → sys_clock_init()(墙钟基准)
A->>A: rs485_init() → gd5f2gq5ue_init()(BBT 扫描)
A->>A: tpafe5160_init() → adc_input_init()(语义映射自检)
A->>A: 配置段注册(adc_cal / run_par / prot_set / comm)→ 定值/元件初始化
A->>A: adc1_disable() → ADC1 挂 DMA(4b-pre,顺序不可变)→ 启动 TIM3 1 kHz 节拍
A-->>M: "App init OK"
M->>K: osKernelStart()
K->>D: 调度
D->>D: f_mount(无卷则 f_mkfs FAT32)→ 卷探针/自愈 → 配置装载<br/>→ 定值整表原子装载(损坏则保出厂默认 + 自检留痕)
D-->>N: set SYS_EVT_STORAGE_READY
S->>S: adcTask:等 TIM3 节拍 → 采集 → 相量/测频 → 200 ms 遥测快照
S->>S: protectTask:20 ms 判据(未标定/采样故障则停走)
N->>N: wait STORAGE_READY(Any|NoClear)→ net_init(ip,mask,gw,mac)<br/>→ PHY 强制 100M 全双工 → 等链路 ≤3s
N-->>F: set SYS_EVT_NET_READY
F->>F: wait NET_READY|STORAGE_READY(All|NoClear)→ lftpd_start("/", 21)
U->>U: wait NET_READY(Any|NoClear)→ ui_port_init → ui_menu_init → ui_net_sink_start(7003)
I->>I: wait NET_READY(Any|NoClear)→ TCP listen :2404 / :8888
顺序铁律:① 配置段注册必须先于
cfg_file_load(否则 FTP 上传的段不生效); ②adc1_disable()必须在挂 DMA 之前;③osKernelStart之前禁调任何内核 API(含osDelay/ 队列)。
3.5 线程间通信
| 机制 | 对象 | 用途 |
|---|---|---|
| Event Flags | sys_evtHandle |
启动就绪屏障 + 命令位(§3.3) |
| Message Queue | netMsgQueue(深度 8,net_msg_t) |
所有 CH395F 操作经队列串行化到 netTask 执行,保证 SPI 单线程访问 |
| 双区 + 序号(无锁) | phasor 相量区、meas 遥测快照 |
写侧填满计算区后单字节翻转活跃索引;读者先取索引再整份拷贝,seq 判"是否换帧" |
| SPSC 环(无锁) | soe_store(深度 8) |
protectTask 只投递动作边沿,defaultTask 排空落盘——保护路径零 NAND I/O |
| 脏位 + 事件位 | prot_set / run_par / comm |
写入方置脏;104 侧 peek 后投递事件位,配置属主(defaultTask)落盘,失败保留脏位下轮重试 |
| 单字请求标志 | prot_elm_request_reset() |
跨上下文复归请求(104 遥控 YK11 在 iec104Task 落请求,protectTask 下一拍消费) |
4. 硬件规格
4.1 主控与内存
| 项 | 值 | 说明 |
|---|---|---|
| MCU | STM32F407ZGTx | Cortex-M4(FPU),LQFP144 |
| 主频 | 168 MHz | HSE 8 MHz → PLL M=4 / N=168 / P=2 |
| Flash | 1 MB(0x08000000) | 片内 |
| SRAM | 192 KB(128 KB 主 SRAM1+SRAM2 + 64 KB CCM) | 链接器映射 128 KB 主 SRAM;CCM 用于 FreeRTOS 堆(任务栈) |
| RTOS | FreeRTOS V10.3.1(CMSIS-RTOS2) | HAL 时基 TIM7,tick = 1 ms;NVIC 4 位抢占,外设中断优先级 ≥5 |
| 工具链 | Keil MDK-ARM v5(ARMCC v5) | 工程锁 uAC6=0,不支持 armclang |
| CubeMX | 6.17.0 + STM32Cube FW_F4 V1.28.3 | 与 .ioc 记录一致,再生成须用此组合 |
4.2 外设与引脚分配
权威来源:V0.1 网表分析报告 +
Inc/main.h(代码已迁移至 V0.1)。下表为 V0.1 硬件的引脚。
| 外设 | 接口 | 引脚 | 说明 |
|---|---|---|---|
| CH395F 以太网 | SPI2 | PB12 CS / PB13 SCK / PB14 SDO / PB15 SDI | 10/100M 以太网控制器;PHY 强制 100M 全双工;SPI 分频系数必须为 8(PCB 设计约束) |
| GD5F2GQ5UE NAND | SPI1 | PE0 CS / PB3 SCK / PB4 MISO / PB5 MOSI / PB8 WP / PE1 HOLD | 256 MB SPI NAND(2 Gbit) |
| TPAFE5160 ADC | 并行 16 位 | PG0~PG15 数据 / PC6 FRSTDATA / PC7 BUSY(EXTI) / PC8 RD / PC9 CONVST / PA8 OS2 / PA11 OS1 / PA12 OS0 | 高精度多通道 ADC |
| SD2506 RTC | I2C1 | PB6 SCL / PB7 SDA | 提供墙钟基准与日志时间戳 |
| USART1(调试串口 / U5 直连 TTL) | UART | PA9 TX / PA10 RX | 115200 8N1;现为 printf 日志 + @test 采集通道。端口重排后改作屏板链路(700 kbaud,§5.16.2);PA10 双向均已接线 |
| UART4(RS-485) | UART | PC10 TX / PC11 RX / PA15 DE | 半双工通信(V0.1 轮换后 RS485#4 = UART4,docs/硬件平台/V0.1_网表详细分析报告.md §4.2) |
| USART2(RS-232 #3) | UART | PD5 TX / PD6 RX | 经 U10 隔离 → U13 TPT3232E → CN1;端口重排后为日志口 |
| UART5(RS-232 #1) | UART | PC12 TX / PD2 RX | 经 U9 隔离 → U13 → CN1;备选日志口 |
| 状态 LED ×6 | GPIO | PC5 / PB0 / PB1 / PB2 / PF11 / PF12 | 低电平点亮 |
| SWD | — | PA13 SWDIO / PA14 SWCLK | V0.1 已修复 V0.0 的 SWCLK 引脚缺陷 |
| 调试口 | — | CN2(XH-3A,1=SWDIO/2=SWCLK/3=GND) | V0.1 由 H2 排针改为 XH 端子 |
⚠️ V0.0 / V0.1 差异:V0.1 相比 V0.0 做了接口裁剪(删 8080 LCD 与 8 键)+ U17 大面积引脚重排 + ADC 前端通道置换(17 路中 13 路变化)+ 调试口改型。固件 BSP 与 ADC 通道映射表必须按 V0.1 重映射; 详见
docs/硬件平台/V0.1_网表详细分析报告.md。
4.3 存储器件
| 器件 | 容量 | 组织 | 软件栈 |
|---|---|---|---|
| GD5F2GQ5UE | 2 Gbit(256 MB) | 2048 块 × 64 页 × 2048 B | FatFS(FAT32)→ dhara FTL(磨损均衡 / 坏块管理 / GC)→ NAND 驱动 |
| SD2506 | — | I2C1 | RTC(时间/温度/电池诊断) |
- BBT 持久化:坏块表存于保留块池(顶部 4 块),不交给 dhara 管理。
- 单写者纪律:
defaultTask拥有存储;netTask只读 RAM 配置副本,不触卷。 - FatFs 约束:
FF_USE_LFN=0(严格 8.3 文件名);FF_FS_REENTRANT=1+ffsystem.c互斥钩子(超时 1 s);FF_FS_NORTC=0(get_fattime直引用墙钟)。
4.4 硬件版本与兼容性
| 版本 | 状态 | 说明 |
|---|---|---|
| V0.0 | 历史 | 含 8080 LCD、8 按键;存在 2 处设计缺陷(SWCLK 引脚错误致 SWD 不通、ADC17 落在非 ADC 引脚) |
| V0.1 | 当前 | 架构与 V0.0 一致;裁剪 LCD/按键、U17 引脚重排、修复上述 2 处缺陷;固件已迁移 |
| V0.2 | 规划关注 | 新增关注项:VCAP 电容值未标注、PC13/14/15 子板 LED 3 mA 限流、SPI1 无法双落点 |
4.5 平台约束
| 约束 | 内容 |
|---|---|
| CubeMX 生成文件 | Inc/、Src/ 中带 USER CODE BEGIN/END 标记;自定义代码只能写标记区内 |
| 生成区外的定制 | 仅限 Src/iwdg.c 延后启动、4 个 Fault Handler 实体(scripts/check_cubemx_survival.py 审计兜底) |
osKernelStart 前 |
禁止任何 FreeRTOS / CMSIS-RTOS API 调用 |
| BOM / 编码 | 部分源文件带 BOM(Drivers/BSP/UI/*、App/task/ui_task.c、App/cfg/cfg_file.c、Lib/lv_conf.h),被工具改写丢 BOM 会导致 ARMCC 按 CP936 解码、中文字面量编译失败 |
| SDIO | V0.1 主板 SDIO 固定引脚组被 TPAFE/UART 全部占用 → 无 SDIO 能力(当前设计不受影响,FatFs 卷在 SPI NAND 上) |
| 新源文件 | 必须双端注册(Keil .uvprojx + simulator/CMakeLists.txt),否则不参与编译 |
4.6 V0.1 硬件能力边界(对产品的硬约束)
下列五条是硬件事实,不是软件缺陷;§5 的功能范围与 §9 的"等条件"项均由它们推导:
| # | 约束 | 具体内容 | 产品影响 | 解除条件 |
|---|---|---|---|---|
| H1 | 双转换器无共同采样触发 | 8 路电气量分属 TPAFE5160(16 位、8 通道同步、±5 V 双极性)与 STM32 ADC1(12 位、顺序扫描、0~3.3 V 单极性)两片;两片无共同触发,STM32 侧 9 通道一轮约 67 µs | 跨转换器的相位 / 功率 / 功率因数 / 对称分量 / 三相同时刻判据一律不成立 → 方向元件、PT/CT 断线、三相过流、零序过流延后 | V0.2 硬件:8 路电气量全部接 TPAFE(与备用路对调串联电阻,料号不变,走线级改动);固件只改映射表内容 |
| H2 | STM32 侧无中点偏置 | 单极性 0~3.3 V,交流量负半周削顶 | UB/UC/IB/IC/IN 无有效值/相量,只能读码值监视;104 对应点恒置 IV |
V0.2 补偏置 |
| H3 | 无出口继电器与开入回路 | 无跳闸/告警出口、无硬压板与开入遥信 | 保护动作只体现为遥信 + 日志 + SOE;104 遥控 YK1~4/13/14 否定确认 |
开入开出独立立项 + 硬件 |
| H4 | 无本地屏与按键 | 160×160 单色屏仅存在于远端客户端 | UI 以 TCP :7003 推流 + 远端按键回注(§8) | 产品形态即如此,不解除 |
| H5 | 无 SDIO | SDIO 固定引脚组被 TPAFE/UART 占用 | FatFs 卷只能落 SPI NAND(当前设计不受影响) | 不解除 |
量纲口径(由 H1/H2 派生):在端子/子板变比确认与两点标定完成前,遥测与保护读数的单位是 ADC 引脚电压(
eng=0),不是二次值;此时ADC_CAL_F_VALID未置位, 保护判据整体停走(§5.12)。这是刻意设计,不是"保护不动作"的缺陷。
5. 功能需求
每项功能给出:需求描述 → 实现要点 → 验收判据。状态标注:✅ 已实现并验收 / ⚠️ 已实现待专项 / ⬜ 待实现。
5.1 网络通信子系统(FR-NET)✅
FR-NET-1 以太网组网
- 需求:上电后按配置的 IP/掩码/网关/MAC 完成以太网初始化,PHY 强制 100M 全双工,等链路稳定后置就绪位。
- 实现:
netTask等STORAGE_READY→ 读 RAM 配置副本 →net_init(ip,mask,gw,mac)→ 等链路 ≤3 s → 置NET_READY。 - 判据:串口出现
Network Init/net init: OK/PHY: 100M FULL;PC 能 ping 通设备 IP。
FR-NET-2 网络抽象层(BSD Socket API)
- 需求:为上层提供
socket/bind/listen/accept/recv/send/close与select/poll多路复用;所有 CH395F 操作串行化。 - 实现:
net_socket.c(BSD API)→netMsgQueue(深度 8)→netTask串行执行;net_select.c提供 I/O 多路复用。 - 判据:三个 TCP 服务(FTP / 对时 / 远程显示)均经同一 API 工作;单连接模型下连接断开自动回到 LISTEN。
FR-NET-3 单连接模型与自愈
- 需求:CH395F 配置为 8 Socket(索引寻址)+ TCP Server 单连接(
set_fun_para(0x08),bit3 SOCKET_CLOSE;bit0 为保留位必须为 0),Socket 0 复用监听与数据通道;网络重建后服务自动重连。 - 实现:三个 TCP 服务串行占用连接,断开自动重听;代次号(
net_get_generation())驱动服务自愈。 - 判据:FTP 旧会话异常断开后约 30 s 恢复监听;网络重建(改 IP)后服务自动重建监听。
网络层是全项目最成熟子系统(pending 机制 + 四份 Trap 记录 + 量化基线 + 探针族)。
5.2 存储子系统(FR-STO)✅
FR-STO-1 三层存储栈
- 需求:在 SPI NAND 上提供 FAT32 文件系统;具备磨损均衡、坏块管理、垃圾回收;上电无卷自动格式化。
- 实现:FatFS(FAT32)→ dhara FTL → gd5f2gq5ue 驱动;
defaultTask挂载(无卷f_mkfs)+ 卷健康探针/自愈。 - 判据:FTP 可列目录/读写卷根文件;掉电后数据仍在。
FR-STO-2 坏块管理与持久化 BBT
- 需求:坏块表持久化,重启后不丢失;不交给 dhara 管理。
- 判据:全片擦除后容量恢复流程可用(见
docs/测试说明/存储维护与容量恢复.md)。
FR-STO-3 卷并发一致性
- 需求:FTP 传输(ftpTask)与配置读写(defaultTask)并发访问卷时不得损坏。
- 实现:
FF_FS_REENTRANT=1+ 逐次加锁/放锁(超时 1 s);三条一致性协议(写 tmp+rename / 沉降去抖 / 单写者)。 - 判据:并发 FTP 下载 + UI 保存无卷损坏、无死锁。
5.3 时间子系统(FR-TIME)✅
FR-TIME-1 墙钟维护
- 需求:以 SD2506 RTC 建立 Unix epoch 墙钟基准,运行期以 tick 推进(零 I2C 流量),提供字符串格式时间。
- 实现:
sys_clock_init()读一次 RTC 建基准(无效时按默认值自动校时);base+delta 法;30 天惰性再基准化(防 49.7 天 tick 回绕);sys_clock_get_str()→"YYYY-MM-DD HH:MM:SS"。 - 判据:日志时间戳真实正确;主机侧单测 100 断言点通过。
FR-TIME-2 网络对时
- 需求:PC 主动通过 TCP :8888 推送时间到设备,设备写回 RTC。
- 实现:
timeSyncTask等NET_READY→ TCP listen :8888 → 收 PC 推送 → 写 RTC;30 s 无包则掉线重建监听。 - 判据:对时后设备墙钟更新、日志时间戳正确。
已知限制:uint32 epoch → 2038 年上限。
5.4 配置引擎(FR-CFG)✅
FR-CFG-1 通用配置文件
- 需求:网络参数(IP/掩码/网关/MAC)持久化到
/config.ini(INI[network]段);文件可经 FTP 下载/上传;格式纯文本、带注释、可编辑器编辑。 - 实现:
cfg_file段键表引擎(段 RAM 副本复用模块静态结构体,键表const映射键→偏移);工厂模板首启自动生成。 - 判据:文件缺失/损坏回退工厂默认并重建模板;FTP 上传后 2~5 s 自动生效。
FR-CFG-2 外科手术式保存 + 原子写
- 需求:保存时保留用户注释/未知段/未知键(降级安全);写入原子(并发读者只见旧完整或新完整文件)。
- 实现:受管键行替换,其余原样保留;临时文件 +
unlink目标 +f_rename;输出 >4096 B 拒绝保存。 - 判据:设备保存后下载文件,用户注释与未来版本段落原样保留。
FR-CFG-3 变更检测与立即应用
- 需求:FTP 上传配置后无需重启即生效;网络段变化触发网络重建。
- 实现:
defaultTask每 2 sf_stat比对 (size, mtime),连续 2 次稳定才重载(沉降去抖);[network]段变化 →SYS_EVT_NET_RECONFIG→ 网络重建(代次 +1,服务自愈)。 - 判据:FTP 改 IP 后 2~5 s 生效(网络重建含等链路 ≤3 s)。
FR-CFG-4 旧档迁移(已取消 · 2026-10-10)
- 原需求:旧固件的
/cfg/netcfg.bin(NCFG 二进制)首启自动迁移为 INI 并删除旧文件——已取消,不再实现。 - 现口径:旧档若存在则被忽略(不读、不删、不迁移),配置直接回落工厂默认(
/config.ini[network]段模板)。 - 取消理由:该一次性路径把整条配置写链(
net_cfg_save → cfg_file_save → cfg_store_write_atomic → f_rename → FatFS → dhara FTL)挂进启动期调用图,defaultTask 静态最坏栈链 +600 B;本仓库不存在携带旧档的设备。 - 判据:卷上残留
/cfg/netcfg.bin时开机不产生任何迁移日志、旧档不被改动,/config.ini按工厂默认生成。
FR-CFG-5 扩展性
- 需求:未来所有模块配置(ADC/RS-485/端口等)进同一文件、按段组织。
- 实现:未来模块接入三步——① 定义段结构体(静态工厂默认)② 写键表 ③
cfg_file_register()。
5.5 运行 / 自检记录与日志(FR-LOG)✅
FR-LOG-1 定长记录引擎
- 需求:运行记录与自检记录持久化到 NAND,FTP 可直下。
- 实现:
sys_log定长 64 B 文本记录(一行一条);/log/run.log(1024 条 / 64 KB 上限)、/log/selftest.log(512 条 / 32 KB);defaultTask唯一写者;ISO8601 时间戳 + epoch。 - 判据:UI"运行记录/自检记录"页可显示;FTP 可下载。
FR-LOG-2 控制台单写者日志
- 需求:多任务并发日志不得字符级交错;异常场景(HardFault)日志可控。
- 实现:4 KB 环形缓冲 +
defaultTask唯一发送(行级原子);内核前/ISR/异常钩子有界直发回退。 - 判据:日志无交错;崩溃时能输出归因日志。
FR-LOG-3 上电/重启分类与待机显示
- 需求:区分上电与重启;空闲切待机屏。
- 实现:
run.log末条 epoch 时间差推断;硬件复位原因(RCC_CSR)优先;ui_standby空闲 60 s 切入。
5.6 UI 与远程显示(FR-UI)✅
FR-UI-1 离屏渲染 + 双出口推流
- 需求:MCU 无物理屏幕,UI 以 160×160 单色位图(1bpp,3200 B)渲染到离屏显存, 经两个出口送出:串口屏板通道(主,§5.16.2)与 TCP :7003(镜像);两路的按键都回注 UI。
- 实现:LVGL 160×160 1bpp 离屏渲染到
g_ui_fbuf(3200 B)→ui_net_sink经 RemoDispBus 推流; 远端按键经协议注入。串口屏板通道尚未实现(§5.16.9 第 11 条)。 - 判据:DTU-RemoteLCD 连 7003 出图(160×160 1bpp)+ 远端菜单导航可用; 屏板实物接入后 280 ms 节拍出图 + 状态灯正确(§5.16.10 第 8~15 条)。
FR-UI-2 菜单与内容页
- 需求:42 节点层级菜单(最大 4 级)+ 内容页(装置信息/交流量/直流量等)。
- 实现:三层拆分(数据层
ui_menu_tab生成物 / 逻辑层ui_menu17 B 导航状态 / 显示层ui_menu_view级联框);内容页框架 + 页面插件描述符。2026-10-29 实到 43 节点(新增「录波回放」叶,需求原文的 42 是 V0.1 立项数)。 - 判据:
UI menu init: OK;菜单像素回归全 PASS。
FR-UI-3 待机屏
- 需求:空闲超时(默认 60 s)自动切待机屏,仅确认键回菜单。
- 判据:空闲后进入待机屏,按键返回菜单。
详见 §8 UI 规格。
5.7 看门狗与故障自恢复(FR-WD)✅
FR-WD-1 IWDG + 任务心跳位图
- 需求:任务级死锁/饿死/断言死循环可自恢复(硬件复位),无需人工到场;不误杀正常长耗时窗口。
- 实现:IWDG(LSI 独立时钟,PR=4 / RLR=1249 → 标称 2498 ms、最坏 ≈1701 ms);任务心跳位图(各自置位,无锁单字)+
defaultTask单一喂狗者(task_wd_poll每 100 ms 抽样);连续 8 次(800 ms)未达标 → 停喂 → 约 2.5 s 后复位;必需位掩码0x37。 - 判据:V2 任务饿死 ≤2.5 s 复位;V4 关中断死循环每 ~4.9 s 稳定复位;V5 30 min 真实负载零复位。
FR-WD-2 复位原因诊断
- 需求:复位后可区分上电 / 看门狗 / 软件 / 引脚 / 欠压。
- 实现:
HAL_Init()后一次性读RCC_CSR锁存并清标志;优先级 POR > PIN > IWDG > WWDG > SFT > LPWR > BOR。 - 判据:串口
[APP] reset cause: <类型>;[WD] armed:自检标记。
FR-WD-3 故障现场采集
- 需求:HardFault / MemManage / BusFault / UsageFault 触发时输出完整现场。
- 实现:4 个 Fault Handler 采集(PC/LR/xPSR/R0-R3/CFSR/HFSR/BFAR/MMFAR)+
fault_handler_enable()使能 SHCSR 后三者。 - 判据:日志形如
[ERR] MEMFAULT PC=... CFSR=... MMFAR=...。
已知边界:启动段(
app_main_init+ bring-up)无看门狗保护;ftpTask首期不纳入监视(掩码剔除)。
5.8 LED 状态指示(FR-LED)✅
- 需求:6 路 LED(低电平点亮)随系统状态变化。
- 实现:
defaultTask循环驱动(闪烁指示系统活跃)。 - 判据:目检 6 路 LED 随系统状态变化。
⚠ 本节只讲主板 LED。 屏板上另有 20 路状态指示灯(ID 0 电源常亮 + ID 1~19 位掩码), 由主机每帧下发 4 B 控制,属另一套输出,规格见 §5.16.3 ①。 两套 LED 的"位 → 业务状态"语义各自独立,不要混用同一个状态表。
5.9 ADC 采集与标定(FR-ADC)✅
FR-ADC-1 采样节拍与触发
- 需求:8 路电气量(
UA/UB/UC/UN、IA/IB/IC/IN)持续采集,1000 Hz(50 Hz 下 20 点/周波), 采集节拍与任务唤醒同源;不得用任务周期软定时冒充硬件节拍。 - 实现:TIM3 更新事件(1 kHz)在 ISR 内触发 TPAFE
CONVST,同一事件经 TRGO 触发 ADC1 一轮 9 通道并由 DMA2 循环搬入乒乓双缓冲;ISR 只置"消费者就绪"门并唤醒adcTask(不做重运算)。 - 判据:
frame_seq每 10 s 精确 +10000(1000.0 Hz)、frst_err=0、adc1_err=0、adc1_hw=0; 单拍消费耗时 ≤10 µs(DMA 搬运后实测 8 µs,软件轮询时为 122 µs)。
FR-ADC-2 语义通道映射
- 需求:按语义取数(
UA/UN/IA等),不写死缓冲区下标——V0.2 换映射表即可切换硬件归属。 - 实现:
App/algo/adc_input.c的语义表(TPAFEbuf[6]/[5]/[2];ADC1CH14/3/6/1/2/5)+ 开机 映射自检(STM32 映射通道必须落在扫描序列内,否则拒绝并自检留痕)。 - 判据:
ADC input layer init: OK;8 路 + 温度首帧全部读出、互异、非饱和。
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/码); 三态可用性ADC_CAL_F_VALID/ADC_CAL_F_CLIPPED由adc_cal_flags()单点查询,104 / UI / 保护闭锁共用。 - 判据:已知电压注入斜率与理论 LSB 偏差 ≤2%(2026-10-27 台架实测端子侧 6544.2 码/V,与引脚侧 理论 6553.6 差 −0.14%,零点 0~5 码、R²=0.9999997、极性对称 ≤0.34%);8 通道系数/零点往返一致。
- 证据与现场步骤:
docs/硬件平台/ADC通道映射说明.md§8.1、docs/测试说明/ADC前端注入验证流程.md。
FR-ADC-4 采样有效性校验
- 需求:芯片静默、丢帧、序号倒退、转换错误必须被检出并可闭锁保护,且不误报。
- 实现:
App/algo/adc_health.c纯逻辑判定层——静默 100 ms 门限(电平位、可自愈)、丢帧边沿计数、 序号倒退锁存、FRSTDATA/HAL 错误/STM32 停摆计数增量;严重事件与上升沿写自检记录(每类每次开机一次)。 - 判据:主机侧 31 用例全绿;台架零
[ERR](健康不误报),人为制造丢帧时tgap与adc1_gap同步可见。
FR-ADC-5 前端物理口径(已实测盖章)
1k 串联 + 1k 到地是源阻抗匹配、不是分压:ADCn节点只有 {串阻、滤波电容、转换器引脚}, 「1k 到地」接在差分负端(ADC7_GND→ R32 → AGND),故 AINn↔引脚变比 1:1。- 芯片手册 ±10 V 档的 LSB(305.18 / 1611.3 µV/码)是另一回事,不可与本板变比混用。
- 剩余未知量只有子板/端子板变比,因此系数只能推到"µV/码 @ 引脚"(§4.6 量纲口径)。
- 拓扑图
docs/images/ADC前端电路.svg。
5.10 RS-485 采集(FR-RS485)⬜ 冻结
- 需求(已确认):半双工 RS-485 对下 ModBus RTU 采集(下行采集口;上行走以太网 104)。
- 现状:
rs485_init()已调用;rs485_task.c为空桩、未在freertos.c创建;App/protocol/为该 协议族预留(当前仅 104 在用)。整簇冻结(用户决定,2026-10-12)。 - 重启门禁:先修「单缓冲包撕裂」「TX 超时拉 DE 未等 TC」两条,再谈接消费者;实现须满足 双缓冲 + 序号、DE 收尾超时路径、协议解析与硬件 I/O 分离。
- 详见
docs/任务规划/暂缓-RS485.md。
5.11 遥测与相量(FR-MEAS)✅
FR-MEAS-1 全周傅氏相量
- 需求:每 1 ms 产出基波/谐波相量,幅值直接是基波有效值,读者无锁取整份快照。
- 实现:
App/algo/phasor.c——N=20 全周 DFT,系数表离线预乘√2/N;5 个实例 (IA/UA/UN基波 +IA二次/五次);每来新点整窗重算,算完单字节翻转计算区/使用区。 - 判据:主机侧 57 用例全绿(系数表逐项复核、合成正弦幅值误差 ≤1%、双区交换);台架开机即产出 5 行
phasor(first),心跳持续刷新。 - 双轨有效值:保护用基波有效值(抗衰减直流与谐波误动),计量/遥测要真有效值(谐波方和根) ——两者不可混用;本产品当前只实现基波轨,谐波方和根轨未做(§9)。
FR-MEAS-2 频率测量(测频与遥测快照)
- 需求:45~55 Hz 内测频,精度优先于响应速度。
- 实现:
App/algo/freq.c——共轭乘积相位增量 + 解缠绕 + 自适应窗长(对齐纹波周期整数倍); 假值钳制带与系统合理带分离;幅值门 <50 码判无效;UA→IA优先级。 - 判据:45~55 Hz 扫频最坏误差 0.0101 Hz、1% 噪声 0.0160 Hz、启动收敛 ≤40 ms、阶跃 50→51 Hz ≤120 ms;
浮空(无信号)时
valid=0不发散。
FR-MEAS-3 遥测快照(200 ms)
- 需求:104 与 UI 共用同一份上游——"什么时候算新值、品质怎么判"只此一处决定;快照必须可无锁整体读。
- 实现:
App/algo/meas.c——每 200 ms(经过时间分频,非拍计数)取基波有效值 + 逐点品质,双区 +seq; 唯一发布者 = adcTask(meas_tick全仓仅一处调用),其余任务只读。 - 判据:主机侧布局用例钉死字段偏移(改字段 = 破协议);台架 104 与 UI 读数同源一致;快照未发布时
消费者得到
IV|NT而不是 0。
FR-MEAS-4 品质与死区
- 需求:品质必须如实反映"这一路能不能信";遥测变化上送不得被单点噪声触发。
- 实现:品质位低字节与 104
QDS同值直传;CLIPPED(削顶)由 104 侧映射为IV; 死区 = 连续 2 个新测量点越限才确认(基准恒为上次上送值,防慢漂移吃掉基准),品质翻转当拍直报。 - 判据:
UB/UC/IB/IC/IN五路恒 IV(品质驱动,V0.2 消除 H1 后零改动自动启用);死区两拍确认、 回摆撤销;TEMP通道恒 NT。
5.12 保护功能(FR-PROT)🔶 软件就绪,判据现闭锁
FR-PROT-1 元件框架
- 需求:统一"越限 + 返回系数滞回 + 定时限"元件核,判据为纯逻辑(吃测量值 + 定值),可离线单测; 新增元件只加实例表一行,不改核。
- 实现:
App/algo/prot_elm.c——数据驱动实例表 9 行;prot_elm_eval()纯判据、prot_elm_run()为 相量/频率到测量值的薄适配;延时用now_ms差值法(与节拍无关,精度不受 20 ms 节拍影响)。 - 判据:主机侧 47 断言全绿(1.01× 启动 / 0.9× 返回 / 滞回保持 / 欠量方向 / 投退 / 闭锁联动 / 时基回绕)。
FR-PROT-2 元件清单(V0.1 有效子集)
| 元件 | 测量量 | 判据要点 | 104 遥信 |
|---|---|---|---|
| 过流 Ⅰ/Ⅱ/Ⅲ 段 | IA |
越定值经延时动作,返回系数滞回 | YX16/17/18(并汇入 YX15 故障总) |
| 过负荷 | IA |
越定值告警(默认不跳闸) | YX23 过载 |
| 过压 / 欠压 | UA |
过量 / 欠量方向,各自延时 | 无遥信点(仅 SOE + 日志) |
| 零序过压 | UN(外部零序专用通道) |
越定值经延时 | 汇入 YX15 故障总 |
| 过频 / 低频 | 测频结果 | 过量 / 欠量方向,默认 51.0 / 49.0 Hz | 无遥信点(仅 SOE + 日志) |
⚠
YX15故障总的构成是 OC1∨OC2∨OC3∨3U0——电压类与频率类元件不在其中,其动作目前只能从 SOE、[PROT]日志与 UI 记录看到。这是点表层面的已知缺口(送检点表要求独立分点时再补), 不要把它误读成"元件没动作"。
- 未复刻的元件(建接口不使能,等条件):三相完整过流(B/C 相)、零序过流、方向/功率类、 PT/CT 断线、涌流制动、重合闸、故障隔离——原因见 §4.6 的 H1/H2,属 §9.1.1「三相与同期」, 解除条件为 V0.2 硬件。
- 判据:
[PROT] elm边沿日志与 104 变位一致;未使能元件不误动。
FR-PROT-3 判据节拍
- 需求:判据独立于采集任务,周期稳定,且不得阻塞在存储 I/O 上。
- 实现:
protectTask20 ms 节拍(元件吃 50 Hz 基波有效值,相量每工频周更新,20 ms 足够); 纳入 IWDG 必需位;动作只投递 SOE(SPSC 环),不做 NAND I/O。 - 判据:静态最坏链 872 B / 配置 2048 B(余 57%);动作到 104 上送端到端 ≤120 ms。
FR-PROT-4 闭锁(四源,任一命中即停走判据)
| 闭锁源 | 判据 | 行为 |
|---|---|---|
| 未标定 | UA/UN/IA 的 ADC_CAL_F_VALID 未全部置位 |
整条判据链停走(产品构建默认态,等两点标定) |
| 采样故障 | adc_health_flags() 电平位(TPAFE/STM32 静默、序号倒退) |
元件全部复位 + 本拍不判据,自愈后自动恢复 |
| 定值非法 | 定值校验和(sum32 正/反码)复核失败 | 闭锁相关保护并告警,需重写定值解除 |
| 全局软压板退出 | PS_GLOBAL_EN = OFF(104 遥控 YK12) |
元件复位 + 停判据,压板恢复即重返联 |
- 判据:
YX31保护闭锁遥信如实反映;锁存类事件位(FRSTDATA/HAL 错误)不构成"当前测量不可信", 只登记不闭锁(口径见docs/算法/继电保护功能复现规划.md§3.5)。
FR-PROT-5 出口(⬜ 未实现)
- 需求:判据满足驱动跳闸/告警出口继电器,带保持/脉冲与回读自检。
- 现状:V0.1 无出口硬件 → 保护"动作"= 遥信 + SOE + 日志;104 遥控
YK1~4为否定确认。 - 判据(立项后):动作驱动对应出口;出口回路自检可检出断线;遥控执行有确认与回读。
5.13 定值与运行参数(FR-SET)✅
FR-SET-1 三类参数
| 类 | 地址范围 | 内容 | 属性 | 本产品状态 |
|---|---|---|---|---|
| 固有参数 | 8001H~800AH |
终端类型 / 操作系统 / 制造商 / 硬件版本 / 软件版本 / 校验码 / 规约类型 / 型号 / ID / MAC | 只读 | ⬜ 未实现(字符串类无法短浮点上送,未知 IOA 应答) |
| 运行参数 | 8020H~8058H |
遥测死区、PT/CT 变比、负荷越限/重载/过载报警、录波投退与定值、功率置负 | 可整定 | 🔶 已落死区 9 点 + k/b 覆盖 16 点(0x8030~0x804F);其余类别无消费者,留白不预埋 |
| 保护定值 | 8820H~8882H |
过流 Ⅰ/Ⅱ/Ⅲ 段、零序过流、重合闸、低压/低频、励磁涌流闭锁、小电流接地等 | 可整定 | 🔶 40 项(Q10 定点):过流三段、过负荷、过压/欠压、零序过压、过频/低频 + 本地项(投退/返回系数/全局软压板) |
FR-SET-2 定值模型与封存
- 需求:定值改动必须原子可见——保护巡检任何时刻都看到自洽快照;范围校验失败整笔拒绝。
- 实现:
App/algo/prot_set.c——影子区写好后重封 sum32 正/反码,再单字交换活跃区;prot_set_selfcheck()用 seqlock 式复核(提交撞见则本轮跳过);范围校验 + 整表 all-or-nothing 装载。 - 判据:主机侧 90 断言(含伪造自洽越界对抗样本);104 写定值与巡检并发无 µs 级误锁。
FR-SET-3 持久化
- 需求:定值掉电保持;档案损坏与版本换代必须能区分,损坏不得静默使用。
- 实现:
/prot_set.bin(magic + 版本 + 计数 + 值区 + sum32 正/反码对),走临时文件 + rename 原子写; 写路径 = 脏标志 → 事件位 → defaultTask 落盘(失败保留脏位下轮重试); 装载在STORAGE_READY之前整表原子完成。 - 判据:非默认定值跨复位保持(台架 7.5 A 往返读回一致);版本换代(旧档)记 INFO, 真损坏记 ERROR + 自检留痕并回落出厂默认。
FR-SET-4 运行参数段
- 需求:死区与通道系数可由主站整定并持久化,且系数只有一份真源。
- 实现:
App/algo/run_par.c——[run_par]段 9 键(死区,毫单位 int32)+k/b覆盖 16 点;k/b写为adc_cal_set代理(合法带ROM×[0.5,2.0]由执行段裁决),run_par 不存系数。 - 判据:
0x8027~0x802A(过压/欠压告警段)永不被覆盖(路由 run_par 先、未命中落 prot_set); 越带写回否定确认;整档保存一趟覆盖[run_par]与被改写的[adc_cal]。
FR-SET-5 主站读写
- 需求:主站可读定值、两段式写定值,失配/越界必须明确否定。
- 实现:
C_RD读 +C_SE_NC两段写;地址 = prot_setcomm_addr(点表不另立地址表);comm_addr = 0的本地项显式不可寻址(防 IOA=0 误命中)。 - 判据:读回值 = 写入值(COT 正确);本地项读回 COT=14 + EVI;执行段写失败不影响旧值。
5.14 SOE 与动作记录(FR-SOE)✅
FR-SOE-1 记录格式
- 需求:动作与状态变化必须带时标留痕,且保护路径不得因写盘被拖慢。
- 实现:
App/log/soe_rec.c——64 B 定长记录 = 类型 + 元件号 + IV 位 +seq+CP56Time2a+ epoch + 值 + 校验和; 六类边沿:元件动作 / 复归、软压板投 / 退、采样数据块 / 恢复。 - 判据:
/log/soe.log经 FTP 下载后逐条解码通过(校验和、seq严格 +1、CP56 与 epoch 交叉一致)。
FR-SOE-2 落盘与上送
- 需求:写盘单写者;104 变位与落盘记录同源同时基。
- 实现:protectTask 投递 SPSC 环(深度 8,禁 DBG)→
defaultTask排空落盘; 104 自发单点换M_SP_TB_1(带 CP56 时标),总召/周期保持M_SP_NA_1。 - 判据:动作路径零 NAND I/O(protectTask 静态链 872 B 改前后不变);104 时标 = 事件上送时刻, 与落盘记录(事件发生时刻)差 ≤ 一拍 + 排空延迟(≤50 ms)。
FR-SOE-3 记录体系(✅ 软件面已落地;真机判据待台架)
- 现状:七类文本记录(运行 / 自检 / 事故 / 告警 / 启动 / 操作 / 遥控)+ 二进制 SOE 已落地, 「记录类型 = 日志 ID 本身」(一类记录一个文件,记录体内无类型字段位);UI 六页已绑 (记录 5 页 + 运行报告,2026-10-28)。运行报告的四个数取自 boot_stats(SD2506 用户 SRAM 上电次数 + 本次复位原因快照)与 iec104_serv 的四个只读观测计数,经 info 帧下发 (口径 docs/UI设计/UI_数据供给设计说明.md §4.4)。
- 判据:五类记录各有写入点、可翻最近 20 条、空记录明确显示"无记录"、共用 reader——软件面已满足 (空态与四个范围标签由 66 张像素黄金钉住;模拟器侧这些文件没有写入方,只拍到空态)。 真记录翻页、掉电后保持、清除记录后归零、boot_count 自增与四态判定待台架复核 (docs/任务规划/登记簿.md §7)。
5.15 IEC 60870-5-104 上行(FR-IEC104)✅
本产品为被控站(受控端):104 TCP 服务器,端口 [comm] 段 port(工厂默认 2404),主站主动连入。
点表口径见 §6.8,设计细节见 docs/子系统设计/IEC104上行设计说明.md。
FR-IEC104-1 链路层
- 需求:APCI U/S/I 帧、STARTDT/STOPDT/TESTFR、k/w 窗、t1/t2/t3;TCP 流重组与坏帧自恢复。
- 实现:
App/protocol/iec104/iec104_link.c(纯逻辑:收=喂流、发=回调、时基注入);参数 k=12 / w=8 / t1=15 s / t2=10 s / t3=20 s;序号 15 bit 回绕、超时一律差值法。 - 判据:主机侧 174 断言全绿;台架主站往返 STARTDT → 总召四组 → actterm 全通过。
FR-IEC104-2 遥测上送
- 需求:遥测短浮点、系数 1、点号落在
0x4001起的遥测段(段基址见 §2.5.3);支持背景/总召、 周期(60 s)、死区与品质上送。 - 实现:数据源 = 测频与遥测快照(§5.11);品质直传,
CLIPPED映射为IV;死区运行时副本(运行参数段可读写)。 - 判据:总召读回值与 UI 同源一致;死区两拍确认、品质翻转直报;削顶五路恒 IV。
FR-IEC104-3 遥信上送
- 需求:双位置遥信上双点、其余单点;变位突发 + 背景扫描;无效点也入表并置 IV。
- 实现:
iec104_pts.c点表(33 点)+ COV 判定;突发单点带 CP56 时标。 - 判据:
YX15~18/23/31为活数据;YX1~14/19~22/24~30/32~33恒 IV(缺行比置 IV 更糟)。
FR-IEC104-4 遥控
- 需求:双点命令两段式(选择
82H/ 执行02H),失配或越界否定确认。 - 实现:
YK11信号复归 → 跨上下文复归请求;YK12全局软压板 → 定值原子写;YK1~4开关、YK13电池活化、YK14解除闭锁 = 否定确认(无硬件)。 - 判据:
YK11/YK12两段正答且行为可观测(压板退出态跨复位保持);否定确认带正确 COT + PN。
FR-IEC104-5 定值与运行参数读写
- 需求:
C_RD读、C_SE_NC两段写;地址即定值表comm_addr;写成功即持久化。 - 实现:见 §5.13;路由顺序 = run_par 表先、未命中落 prot_set。
- 判据:读回一致、越界否定、断电重启保持。
FR-IEC104-6 对时
- 需求:主站
C_CS对时写入设备墙钟;时标无效如实置 IV。 - 实现:CP56 → epoch ms →
sys_clock(含 RTC 写回);epoch >2^32 显式拒绝回 PN。 - 判据:对时后日志时间戳跟随主站;
C_CS后 SOE 时标同步。
FR-IEC104-7 响应时间(点表推荐值)
| 参数 | 要求 | 本产品实测 / 设计 |
|---|---|---|
| 终端启动时间 | ≤100 s | 开机到 net init: OK ≈0.6 s,到 104 监听 <2 s |
| 104 连接 / 总召 | ≤3 s / ≤8 s | 连接 <1 s;总召分片 + 单轮 4 ASDU 预算,实测远小于 8 s |
| SOE 上送 | ≤5 s | 变位到上送 ≤120 ms |
| 遥控选择 / 撤销 / 执行 | ≤5 s | 同轮应答(ms 级) |
| 读定值 / 改定值预置 / 执行 | ≤10 s / ≤5 s | 同轮应答(ms 级) |
| 读文件目录 / 文件 | ≤30 s | ⬜ 未实现(文件传输未立项) |
| 录波文件存储 | ≤15 s | ⬜ 未验收(代码面 2026-10-29 已交付:/wave 段文件 + FTP 取回;本波按 1 kHz / 8 路 / 单段做;≤15 s 时限未测,80 点/周波属二期;卡片见 docs/任务规划/故障录波.md) |
FR-IEC104-8 单连接与自愈
- 需求:单连接语义(CH395F 单 socket);断链自动重听;网络重建(改 IP)后服务自愈;协议故障主动拆链。
- 实现:监听与数据通道复用同一 socket(EOF 时 net 层 auto_relisten,应用层不关 fd);
net_get_generation()变化即重建;坏帧 / N(R) 倒退 / t1 超时 / 发送 3 连败 → 本端拆链促主站重连。 - 判据:断链后自动恢复监听;改 IP 后重建;V0.1 为首到优先(后连优先需 net 层支持,未实现)。
FR-IEC104-9 本期未实现项(如实登记,均为 §9.1 复刻进度条目)
| 项 | 原因 | 归属 |
|---|---|---|
| 多主站 / 双链路冗余 | 单连接 socket 语义;后连优先需 net 层扩展 | 规模型 |
| 归一化值 / 标度化值上送 | 点表要求短浮点(系数 1),无需另做 | 不适用 |
| 双点遥信带时标 | V0.1 双点恒 IV,无意义 | 随开入硬件(X3) |
| 定值区切换 / 定值文件下装 | 产品未定义多定值区(参考有 4 区) | 规模型 |
| 文件传输(目录 / 读文件 / 录波) | 录波已立项,段文件取回走现成 FTP(21 端口);规约侧文件服务仍未做 | 规模型 |
固有参数 8001H~800AH |
字符串类无法短浮点上送 | 规模型 |
| 主站 IP 白名单 | 单 socket 上"拒绝"= 断链重听,可被扫描打成 SPI 风暴且易锁死真主站 | 不适用 |
5.16 屏板链路:串口主通道 + 网络镜像(FR-HMI)🔶
口径(2026-10-28 定版):参考产品的屏与键不在主机板上。主机侧源码里 5 个"碰硬件"的函数
KeyGet()/WriteScreenByByte()/LCD_LED_Update()/getRs485Key()/anyNewKey()全树只有声明、没有实现(由屏板 BSP 库提供);按键轮询函数名即Key_Rs485_Process()(注释"轮询从485传来的按键值");屏板插槽号CN_SLOT_DISP = 0(注释"显示板插槽号固定为0")。 结论:屏和键都在一块独立的屏板板件上,主机只负责"送帧 + 收键"。本产品与参考同构, 不在本仓实现的只剩那块屏板板件硬件本体(独立工程 DTU-LCD);主机侧"送帧 + 收键"链路是范围内待做(§5.16)。两条通道,串口为主、网络为镜像:参考把同一份显存同时喂给两个出口——串口屏板通道 (
LCD_LED_Update变化驱动 +WriteScreenByByte500 ms 兜底)和网络显示总线(TCP 7003)。 也就是说"显示信息不只走网络,还走串口"。本产品目前只有网络这一路,串口屏板通道整条缺失 (§5.16.9 第 11 条),这是本项复刻的最大缺口——没有它,产品无法脱离 PC 独立带屏运行。屏板固件已到手(2026-10-28):屏板侧源码在
D:\Code\DTU Code\DTU-LCD(STM32F103ZE + UC1698U 160×160 单色 + 20 路状态指示灯 + 7 个物理按键),物理层与帧格式全部可从代码确定,见 §5.16.2、§5.16.3。 该链路不是可选项:屏板是主动召唤方,主机不应答则屏板无画面、无灯、无键。
5.16.1 一份显存、两个出口(串口为主,网络为镜像)
参考的 HMI 只有一份显存(g_tVsr[0].pwbyLCDMemory,物理基址 CN_VIDEO_ADDRESS_BASE = 0xC1F00000,
非 cache 区,3200 B),但有两个互不影响的出口——串口屏板通道是主通道,网络总线是镜像:
| 出口 | 归属任务 | 调用 | 下行载荷 | 节拍 |
|---|---|---|---|---|
| 串口屏板通道(主) | tDisp(Dsp_Main) |
LCD_LED_Update(ptr, 3200, ledbuf, 4) |
显存 3200 B + 面板 LED 4 B | 变化驱动(anyNewKey() || LCD_UPDATE_FLAG) |
| 串口屏板通道(周期兜底) | tRemoDisp(RDisp_Main) |
WriteScreenByByte(byLcdMemory) |
显存 3200 B | 500 ms(tTimerLCD) |
| 网络显示总线(镜像) | tRemoDisp(RDisp_Main) |
RDisp_Proc / RDisp_Send |
0xAA/0xBB 帧(INIT/KEY/LCDMEM) |
客户端召唤驱动 |
上行(按键)同样是两条,最后在 Key_Read() 汇合:
| 上行通道 | 采集方式 | 载荷 | 与另一路的关系 |
|---|---|---|---|
| 串口屏板通道(主) | getRs485Key() 轮询 + anyNewKey() / ClearNewKeyEvent() 事件 |
物理键号 1~9(实测 7 个物理键,§5.16.3 ②) |
映射为逻辑键值写入 g_tKey |
| 网络显示总线(镜像) | RDisp_Proc_SaveKey → g_tRemoteKey |
键值位掩码 1 B | 写入 g_tRemoteKey |
| 汇合点 | Key_Read()(Key.c:199) |
— | 先取远程、再被本地覆盖——两键同时挂起时本地(串口)优先 |
串口通道的物理层与协议以屏板源码为准(§5.16.2 / §5.16.3)。参考主机侧源码给不出物理层, 只能给出调用契约——能确定的只有这几项:
| 契约项 | 已确定的内容 | 依据 |
|---|---|---|
| 下行粒度 | 3200 B 整帧 + 4 B LED,一次调用一帧(无分片参数) | LCD_LED_Update(ptr,len,ledbuf,ledbuflen) 签名 |
| 上行粒度 | 单字节物理键号,0 表示无键 |
getRs485Key() 返回 uint8_t,Key.c:176 判 key == 0 即返回 |
| 事件语义 | 有"新键事件"与"清除事件"两个动作 | anyNewKey() / ClearNewKeyEvent() |
| 屏板地址 | 板件槽号 0(CN_SLOT_DISP) |
Key.c:8 注释"显示板插槽号固定为0" |
| 屏板初始化 | Lcd_init_display(0xC1F00000) 由 LocalDisp_StartTask() 调用,不经过任何 UART 打开动作 |
Disp_Main.c:56 |
5.16.2 串口通道:物理层与帧格式(屏板源码实测)
屏板固件工程 DTU-LCD 已在手(STM32F103ZE / 512 KB Flash / 64 KB RAM / 72 MHz,UC1698U 160×160 单色),
链路协议逐字节可确定,本节即主机侧必须实现的契约。
⚠ 角色与直觉相反:屏板是 Modbus 主站,主机是从站。 屏板主动发请求,主机在请求后应答; 主机从不主动推送,也不允许主动推送(半双工总线,谁先说谁占用)。 这与 §5.16.4 的 TCP 7003 通道方向相反——网络通道是客户端召唤,串口通道是屏板召唤。
物理层
| 项 | 屏板侧实测值 | 依据 |
|---|---|---|
| 接口 | RS-485 半双工 | rs485.c |
| 引脚 | TX = PA2、RX = PA3、DE = PA1 | rs485.h |
| DE 极性 | 低 = 发送,高 = 接收 | RS485_SEND_ENABLE() 拉低、RS485_RECEIVE_ENABLE() 拉高 |
| 波特率 | 700000 bps | #define BAUDRATE 700000 |
| 数据格式 | 8 数据位 / 无校验 / 1 停止位,无流控,16 倍过采样 | rs485.c 初始化 |
| 接收 | HAL_UARTEx_ReceiveToIdle_IT(空闲断帧),DMA 版本被注释掉 |
rs485.c:192-195 |
| 发送 | HAL_UART_Transmit(..., 1000) 阻塞发完,随即切回接收 |
RS485_SendBuff() |
| 缓冲 | RX 4208 B、TX 8 B | UART_RX_LEN / UART_TX_LEN |
700 kbaud 在两种候选时钟下都零误差:16 倍过采样(
OVER8 = 0)时USARTDIV = fCK / (16 × 波特率),写入值BRR = (整数部分 << 4) | (小数部分 × 16)。
- 屏板链路的默认端口 USART1 挂 APB2 = 84 MHz:
84 000 000 / (16 × 700 000) = 7.5→ 整数 7、小数 8 →BRR = 0x0078,误差 0 %。- 若改用 APB1 上的实例(UART4 / USART2 / USART3,42 MHz):
42 000 000 / (16 × 700 000) = 3.75→ 整数 3、小数 12 →BRR = 0x003C,误差 0 %。若改时钟树或改用 HSI,必须重算——700 kbaud 下 2 % 误差已足以丢帧。
屏板自己那侧不是零误差:它的串口挂 APB1 = 36 MHz,
UART_BRR_SAMPLING16(36e6, 700000)→BRR = 0x33(USARTDIV = 3.1875)→ 实跑 705 882 bps,比标称高 0.84 %;它源码里「手动写精确 BRR」 那段注释后面没有对应代码。与主机侧的 0 % 合起来 0.84 %,8 位数据 / 1 停止位(10 bit/帧)下在容差内; 但位宽与整帧耗时的实测判据要按 705 882 算,不是按 700 000(1 字符 ≈14.17 µs、整帧 ≈59.6 ms)。端口裁定(用户决定,2026-10-28):屏板走 USART1,日志口让位。 屏板链路改用 USART1(PA9/PA10)——这条通道是 MCU 引脚直出 TTL,不经过板上任何收发器, 因此收发器速率上限问题不复存在:本板 485 通道上的
U15 = TP8485E-SR只有 250 kbps (docs/芯片手册/TP8485E-SR.md)这件事,对屏板链路不再构成约束。 作为交换,调试日志迁到 RS-232 通道(V0.1 板上 RS232#3 = USART2 PD5/PD6, 备选 RS232#1 = UART5 PC12/PD2,两者都经隔离器 →U13TPT3232E → CN1), 迁移在屏板链路跑通之后做,见下方"主机侧端口重排"。PA10 一直是接线的(2026-10-28 用户确认)→ 屏板链路不需要额外飞线。
ORE 锁存的充分条件与接线无关——RX 使能了却从不读
DR:线上只要出现 任意一个字节或一个噪声沿,RXNE置位后没人读,下一个事件就把 ORE 锁存;而 ORE 只能用 "先读 SR 再读 DR"清除,于是永不自愈。这条对本实现有一条硬要求: 屏板链路要用 RX,就必须真的消费DR,并在HAL_UART_ErrorCallback里清 ORE 后重挂接收 (否则一次噪声就永久锁死,症状与"屏板不回帧"一模一样)。
帧 A:召唤 / 按键(屏板 → 主机,固定 6 B)
| 偏移 | 长度 | 字段 | 取值 |
|---|---|---|---|
| 0 | 1 | 从站地址 | 固定 0x01(主机的从站地址,不是屏板地址) |
| 1 | 1 | 功能码 | 固定 0x03(读保持寄存器) |
| 2 | 1 | 命令类型 | 0x00 = KEY_CMD(按键事件,立即召唤)0x01 = RT_CMD(周期刷新,280 ms 一次:RT_count > 55,第 56 拍 × 5 ms) |
| 3 | 1 | 按键值 | KEY_CMD 时有效(见 §5.16.3 键值表);RT_CMD 时恒为 0(按键发完即清 key_bk,见 RS485_Process()) |
| 4 | 1 | CRC-16 低字节 | CRC-16/MODBUS |
| 5 | 1 | CRC-16 高字节 | 同上 |
CRC-16/MODBUS(多项式 0xA001 反转式、初值 0xFFFF、查表法),
只覆盖前 4 字节,低字节在前——这是标准 Modbus RTU 的线上顺序(教科书校验值:数据 123456789
→ 0x4B37,线上写 37 4B)。
⚠ 屏板源码里的字节序注释是反的,别照抄:
Calculate_CRC()返回的不是标准 CRC 值,而是高低 互换后的「线上字」(123456789它返回0x374B)。于是RS485_RefreshScreenCMD()里那句cmdbuf[4] = crc>>8(注释写"CRC校验高字节")实际写出去的是低字节——两处命名都反,线上字节是对的。 主机侧按「标准值 + 低字节在前」实现,两侧字节逐一相同;若照字面写成"高字节在前",屏板会把每一帧 都判成 CRC 错,而它的超时判定只看"收没收到一整包"、不看 CRC,现场只表现为画面不刷新, 极易误判成波特率或时序问题。实测向量与实现见Drivers/BSP/ScreenLink/sb_proto.c文件头。
帧 B:图像应答(主机 → 屏板,固定 4208 B)
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 3200 | Picture[] |
显存位图:160 行 × 20 B/行,1 bpp,MSB 在前,bit=1 → 白 |
| 3200 | 4 | info[0..3] |
普通图:LED 状态,32 位位掩码,小端(info[0] = bit0~7)LOGO 图: info[0..1] = 宽、info[2..3] = 高(均大端) |
| 3204 | 1 | info[4] |
LOGO 魔数高字节 0x89 |
| 3205 | 1 | info[5] |
LOGO 魔数低字节 0x45 |
| 3206 | 2 | info[6..7] |
保留,屏板不读 |
| 3208 | 998 | 保留填充 | 屏板不读,但参与 CRC 计算,须固定填充(建议 0x00) |
| 4206 | 2 | CRC-16 | 覆盖 [0, 4205],低字节在前(与帧 A 同一口径,见上方的字节序说明) |
⚠ 帧长以代码为准:4208 B(屏板 readme 与
BMP_LEN写的"3208 字节"不作准):接收侧实参是Check_CRC(DR, UART_RX_LEN),UART_RX_LEN = 4208→ CRC 取DR[4206]/DR[4207]、覆盖DR[0..4205]。 有效载荷只有前 3208 B,其后 998 B 为凑齐 CRC 窗口的填充;主机只发 3210 B 时屏板会在DR[4206]读到陈旧字节,CRC 必失败并静默丢弃。此项须台架实测复核后固化。
⚠ 应答帧不是合法 Modbus RTU 响应:没有地址、没有功能码、没有字节数域,是一段裸二进制块。 因此不能套用现成 Modbus 从站栈,只能按上表手工组帧。
⚠ 同一 4 字节双解释:
info[0..3]在普通图里是 LED 位掩码、在 LOGO 图里是宽高。 区分只靠info[4..5] == 0x89 0x45。先判魔数再解释这 4 字节,顺序不能反。
时序与预算
| 参数 | 屏板侧常量 | 实际时间 | 含义 |
|---|---|---|---|
| 基准节拍 | 5 ms 定时器 | — | Process_Count() 每 5 ms 递增 |
| 周期召唤 | RS485_RT_COUNT_MAX = 55,判据 RT_count > 55 |
280 ms(第 56 拍 × 5 ms) | 无按键时每 280 ms 召唤一次;屏板 readme 与常见口径写的 275 ms 是按 55×5 算的 |
| 应答超时 | RS485_ACK_COUNT_MAX = 40,判据 ACK_count > 40 |
205 ms(第 41 拍 × 5 ms) | 到点只置「可以重发」标志 + 累计一次超时——不丢已收字节、不清缓冲、不重启串口;计时起点是召唤帧最后一位的 TC |
| 迟到的应答 | 收帧处理与超时判定相互独立,帧里没有序号 | — | 超过 205 ms 才到的完整帧照样显示(当成下一轮的应答,无从区分);代价 = 多一轮画面滞后 + 一次超时计数 |
| 有按键待报时 | 收到帧或超时即打开发送闸门 | 最早 约 205 ms 就可能再来一帧 | 上一答还在总线上 → 双向对撞;且键只发一次不重试(发完立刻清备份)→ 错过那一轮 = 丢键 |
| 收到任意一包 | 无论 CRC 是否通过 | — | 超时阶梯全部清零(ACK_count / ACK_OverTimeCnt)→ 主机把帧发断,屏板也不报超时,只表现为画面不更新 |
| 连续超时 | RS485_ACK_OVERTIME_MAX = 5 |
5 次 | 连续 5 次超时 → 强制允许重发(不重启串口,重初始化被注释) |
| 屏板自复位 | sysRunTime > 1 000 000 |
≈5000 s(83 min) | 屏板自己无条件 HAL_NVIC_SystemReset() |
真正的硬约束不是 200 ms,是下面三条(按风险排序,均出自屏板源码):
- 整帧零间隙:屏板按「总线空闲 1 个字符时间」断帧,而它的串口 IP 没有接收超时寄存器可调 (该系列 USART 只有 SR / DR / BRR / CR1 / CR2 / CR3 / GTPR)。705 882 bps 下 1 字符 ≈14.17 µs, 间隙 ≥2 字符(约 28 µs)必把一帧切成两帧,两半都过不了 CRC——这条才是卡主机实现方式的约束。
- 必须正好 4208 B:CRC 固定取
DR[4206]/DR[4207]、覆盖DR[0..4205],实收长度被丢弃 → 短帧永远通不过(998 B 填充是承重的);超过 4208 B 会让它把正在处理的那一帧撕裂(收满即回调、缓冲从头再填)。 - 绝不让它溢出:一旦 ORE 就永久收不到(它错误回调里的重启被注释掉),而屏幕上没有任何通信状态指示 (运行灯翻转被注释、故障显示函数无人调用)→ 唯一症状是「画面与状态灯一起冻死」,只能断电重上或等 83 min 自复位(自复位后是白屏,没有开机 LOGO)。此外它下发 LOGO 时要写 Flash + 4×500 ms 延时, 那段时间既不能处理也不能应答,是最容易撞上本条的窗口。
所以主机侧整帧必须一次性交给 DMA + 发送完成中断,不要逐块阻塞发:任务态轮询随时可能被几十 µs 的
ISR 抢占,一抢就撞第 1 条,而后果在屏板侧完全不可见。时间预算 4208 × 10 bit ÷ 705 882 ≈ 59.6 ms
(按标称 700 000 算是 60.1 ms),占 280 ms 周期约 21 %;「≤200 ms 内发完」仍是我们对自己的要求——
理由是不与下一轮召唤撞总线、不多一轮画面滞后,不是因为屏板会把迟到的帧判废。宿主与起发方式见
docs/任务规划/屏板链路.md 决策三(uiTask 组帧 + USART1 空闲中断点 DMA 起发)。
主机侧端口重排(2026-10-28 用户裁定)
| 串口 | 引脚 | V0.1 板上通道(docs/硬件平台/V0.1_网表详细分析报告.md §4.2) |
重排后用途 |
|---|---|---|---|
| USART1 | PA9 / PA10 | 调试口 + U5 直连 TTL(ST_TX0/RX0),MCU 直出、不经任何收发器 | ✅ 屏板链路(700 kbaud) |
| USART2 | PD5 / PD6 | RS232#3(U10 隔离 → U13 TPT3232E → CN1) | ✅ 调试日志(115200,屏板链路之后迁移) |
| UART5 | PC12 / PD2 | RS232#1(U9 隔离 → U13 → CN1) | 备选日志口,与 USART2 二选一 |
| UART4 | PC10 / PC11,DE = PA15 | RS485#4(U11 隔离 → U15 → A/B → CN1) | 冻结簇,本项不碰 |
| USART3 | PB10 / PB11 | U5 直连 TTL(ST_TX2/RX2) | 空闲 |
为什么是 USART1:它是唯一一条不经收发器、MCU 引脚直出的通道,而 700 kbaud 恰好卡在收发器上
(U15 = TP8485E-SR 只有 250 kbps,docs/芯片手册/TP8485E-SR.md)。换到这条线上,速率问题从根上消失,
也不用改任何硬件。UART4 保持 RS-485 冻结簇不动——rs485_init(&g_rs485, &huart4, …) 与 V0.1 一致,无需摘除。
这次重排带来一件事,必须在任务里体现:
- 日志口迁移不是一行改动:
App/log/console_log.c里huart1出现 5 处(含huart1.Instance == NULL的空指针短路判据),自愈函数con_uart_reinit()还直接写USART1_IRQn、__HAL_RCC_USART1_CLK_*、MX_USART1_UART_Init()。建议收口成一处可配置端口宏, 而不是逐处散改。
⚠ TTL 直连没有方向控制:主机侧不再有半双工方向切换,建立时间、"等 TC 收尾"一类约束全部不适用。
⚠ 主机 RX 只需吃下 6 B 召唤帧(不像屏板要吃 4208 B):16 B 缓冲 + 空闲中断断帧就够——TX / RX 是两根独立线,无自发自收。
5.16.3 屏板侧行为:状态灯 / 按键 / 背光 / LOGO
本节描述屏板固件实际做什么——决定主机侧要下发什么、以及哪些语义必须由产品自己定义。
① 状态指示灯(4 B 位掩码下行)
屏板有 20 路 LED,由主机每帧的 info[0..3] 控制。解码规则(LED_Printf):
leddata = (ledbuf[3]<<24) | (ledbuf[2]<<16) | (ledbuf[1]<<8) | ledbuf[0]; /* 32 位小端 */
LED_POW(LED_ON); /* ID 0 无条件常亮 */
for (i = 1; i < LED_COUNT; i++) /* LED_COUNT = 20 */
LED_Set(i, (leddata & (1UL << i)) ? LED_ON : LED_OFF);
- ID 0 = 电源灯,硬件常亮,不受位掩码控制(
leddata的 bit0 被忽略)。 - ID 1
19 一一对应 bit1bit19;bit20~bit31 未使用,填 0。 - 全部低电平点亮(
LED_ON= 低)、推挽输出、内部上拉、高速模式。 - 只在普通图像帧到达时刷新;LOGO 帧走另一分支,不动 LED。
屏板侧 LED 引脚表(led_config[20],仅备查——主机不直接驱动):
| ID | 引脚 | 备注 | ID | 引脚 | ID | 引脚 | ID | 引脚 |
|---|---|---|---|---|---|---|---|---|
| 0 | PC8 | 电源灯,常亮 | 5 | PC11 | 10 | PC7 | 15 | PC12 |
| 1 | PC9 | 运行灯 | 6 | PD0 | 11 | PA8 | 16 | PD1 |
| 2 | PA9 | 7 | PD2 | 12 | PA10 | 17 | PD3 | |
| 3 | PA11 | 8 | PD4 | 13 | PA12 | 18 | PD5 | |
| 4 | PA15 | 9 | PD6 | 14 | PC10 | 19 | PD7 |
对本产品的含义:§5.8 的主板 6 路 LED(LED1~6)与屏板 20 路指示灯是两套独立输出,
语义不同——主板 LED 表"设备自身状态",屏板指示灯是"操作员面前的状态/告警灯组"。
⚠ 位掩码 → 业务状态的映射表,参考源码里没有。参考的
LCD_LED_Update(ptr, 3200, ledbuf, 4)只证明"主机侧填这 4 B",填哪几位对应哪个业务状态在未实现的屏板 BSP 里。 因此"哪几号灯表哪个状态"必须由本产品定义(建议按 §5.8 的 6 路语义扩展到 19 路, 并保留 1~2 路作屏板自检/通信状态)。这是本项唯一需要"新设计"而非"照抄"的地方。
② 按键上行
| 项 | 屏板侧实测 |
|---|---|
| 库 | MultiButton,只绑 BTN_SINGLE_CLICK(单击事件) |
| 扫描 | 5 ms 定时器内 Button_Ticks() |
| 电气 | 输入模式、无内部上拉/下拉(依赖外部)、低电平有效 |
| 引脚 | KEY_ENTER=PD12、KEY_UP=PD11、KEY_DOWN=PD10、KEY_LEFT=PD13、KEY_RIGHT=PD8、KEY_ESC=PB15、KEY_RESET=PB3 |
| JTAG | PB3 需 __HAL_AFIO_REMAP_SWJ_NOJTAG() 才能当普通 GPIO |
| 回调 | 任意键按下 → BackLight_ON() + 更新 keyStatus,主循环转交 RS485_Process() |
键值枚举(KEY_TYPE,即帧 A 偏移 3 的 key 字节):
| 值 | 名称 | 值 | 名称 |
|---|---|---|---|
| 0 | KEY_NONE(无键) |
5 | KEY_ADD |
| 1 | KEY_ENTER |
6 | KEY_DEC |
| 2 | KEY_UP |
7 | KEY_LEFT |
| 3 | KEY_DOWN |
8 | KEY_RIGHT |
| 4 | KEY_ESC |
9 | KEY_RESET |
| 10 | KEY_FACTORY |
⚠ 两套键号只在 1~8 对齐,9/10 语义不同,必须显式建映射:
语义 屏板 KEY_TYPE(帧 A 的key)参考主机 getRs485Key()物理键号确认 ENT 1 1 上 UP 2 2 下 DOWN 3 3 取消 ESC 4 4 加 ADD 5 5 减 SUB 6 6 左 LEFT 7 7 右 RIGHT 8 8 9 KEY_RESET(复位键)F1 10 KEY_FACTORY(工厂模式键)F1|ENT组合帧 A 的
key字节只能按屏板枚举解释。主机收到 9/10 时不得按F1/F1|ENT处理。 若产品要求保留 F1/F2 语义,只有两条路:改屏板固件 或 在主机侧加语义映射表——二者选一,须先定。
⚠
key_configs[]只有 7 项,且与枚举不自洽:表内第 7 项为{PB3, KEY_RESET}(注释却写"加键"); 枚举有KEY_ADD(5) /KEY_DEC(6) /KEY_FACTORY(10),但key_configs[]没有映射任何 ADD/DEC 物理键。 即实物只有 7 个物理键(上/下/左/右/确认/取消/复位),ADD/DEC/FACTORY 有枚举无入口。 屏板 readme 的按键表列了 8 个键,与代码不符——以key_configs[]的 7 项为准。 这直接影响 §5.16.9 第 8 条"补 F1/F2"是否成立:屏板上根本没有 F1/F2 物理键, 网络通道的 8 键表是给远程工具用的;串口通道只可能收到1/2/3/4/7/8/9这 7 个值 (5/6/10有枚举无入口)。
③ 背光
- 任意键按下 →
BackLight_ON()(按键回调里,不在 5 ms 定时器内)。 - 5 ms 定时器每拍调
BackLight_Close(),超时熄灭(时长在160160D.C,屏板自管)。 - LOGO 帧到达时也会
BackLight_ON()。 - 主机侧不参与背光控制——参考主机的
Lcd_BackLight()/ 空闲 120 s 熄灭在主机 BSP里, 而屏板固件自己就管背光,两条路径不能同时启用。本产品按"屏板自管"实现,主机不做(§5.16.9 第 14 条)。
④ LOGO 与 Flash
- 魔数命中(
info[4]==0x89 && info[5]==0x45)→ 按 LOGO 处理:Picture存入屏板 Flash0x0803F000(扇区 126),宽高取info[0..1]/info[2..3](大端), 然后点背光、ClearScreen()、LOGO_Printf()、延时 2 s(4 ×delay_ms(500))。 - 上电时
BMP_Get()从同一地址读回并显示。 - LOGO 帧不刷新 LED、不进入常规画面;一帧 LOGO 会永久覆盖屏板上一次的 LOGO。
- 主机侧要提供"下发 LOGO"的一次性操作(建议放在屏板联调/出厂配置流程,不进常规刷新循环)。
⑤ 屏板自身的健壮性机制
| 机制 | 实现 | 对本产品的影响 |
|---|---|---|
| CRC 错计数 | 连续 ≥3 次错 → 计数清零(重初始化串口被注释掉) | 错帧静默丢弃,链路不会自愈,只能靠下一次召唤重试 |
| 应答超时 | 第 41 拍 = 205 ms;连续 5 次 → 只是打开重发闸门(重初始化被注释掉) | 主机长时间不应答不会锁死屏板,恢复后自动续上。但两个坑:① 收到任意一包就清零计数、不看 CRC → 主机把帧发断时屏板也不报超时,只表现为画面不更新;② 真会永久锁死的是接收溢出(§5.16.2 硬约束 3),不是超时 |
| 系统自复位 | sysRunTime > 1 000 000(≈5000 s)→ HAL_NVIC_SystemReset() |
每 83 分钟屏板重启一次,约 1 s 空窗 |
| 看门狗 | 5 ms 定时器内 Clear_Watchdog() |
主循环卡死 → 屏板复位 |
| DMA 接收 | 屏板提交记录明写"DMA 接收的问题没有解决" | 长帧接收可靠性未经充分验证,台架必须压测 |
⚠ 5000 s 周期性自复位必须被主机容忍:复位期间屏板约 1 s 不响应召唤。 主机的链路监视不能把这种周期性空窗判成"屏板掉线",更不能联动告警/保护。 判据建议:连续 ≥ 10 s 无任何应答才置"屏板离线"。
待与屏板固件方确认的 4 项(不影响本产品先开工,但验收前必须闭环):
Check_CRC用缓冲区容量而非实际接收长度,短帧会被误判;是否计划改为传Size。- 键值 9 / 10 是否要改成
F1/F1|ENT(对齐参考),还是保持"复位 / 工厂"语义。 key_configs[]是否要补 ADD / DEC 物理键(当前 7 键,枚举 11 项)。- 屏板 4208 B 接收缓冲与 700 kbaud 在长线(> 50 m)下的误码率实测数据。
5.16.4 链路 B 帧格式(逐字节)
| 项 | 规格 |
|---|---|
| 传输 | TCP 7003;设备为 Server(TcpAddServer + TcpAddConnection(..., EN_NET_MODE_SERVER, RDisp_MsgRecv));目标 IP 填 255.255.255.255 = 接受任意客户端 |
| 连接参数 | TcpSetConnPara(iTcpNo, 10240, 10240, 0, 30, 5);收发缓冲各 10240 B |
| 建链条件 | getnetport() != 1 才建 Server(该函数源码无注释,疑为单网口板件跳过本链路;未验证,勿照抄此条件) |
| 帧结构 | [TAG 1B][CMD 1B][LEN_H 1B][LEN_LO 1B][DATA nB][CRC 1B] |
| TAG | 0xAA = 客户端→设备(CN_RDISP_C_TAG);0xBB = 设备→客户端(CN_RDISP_R_TAG) |
| LEN | 数据段长度(不含 4 B 头与 CRC),大端 |
| CRC | 数据段逐字节异或(RDisp_CalCrc),不覆盖头与 CRC 自身 |
| 最长帧 | CN_RDISP_FRAME_LEN_MAX = 9800(数据段上限) |
| 接收定界 | 逐字节找 0xAA(最多 10240 次防死循环)→ 再收 3 B(CMD+LEN)→ LEN > 10237 视为噪声重新同步 → 再收 LEN+1 B(数据+CRC)→ 返回 LEN+4 |
接收侧不校验 CRC:
RDisp_MsgRecv只做定界;CRC 只在RDisp_Proc_LcdMem/RDisp_Proc_SaveKey内比对,且 INIT / KEEPLIVE 帧根本不校验。这是参考的既有行为, 本产品在全帧校验上更严(见 §5.16.9 第 10 行),不作退让。
5.16.5 命令集与数据段布局
| CMD | 名称 | 客户端请求 | 设备应答 | 备注 |
|---|---|---|---|---|
| 0 | KEEPLIVE |
空 | 不应答 | 源码 return,注释"无 keep alive 报文";仅重置 1 分钟通信计时 |
| 1 | INIT |
空 | 16 B(见下表) | 工具召唤屏幕参数 |
| 2 | KEY |
[键值 1B] |
空(LEN=0) | 键值写入 g_tRemoteKey,byKeyValid = EN_KEY_FLAG_NEW |
| 3 | LCDMEM |
[起始偏移 4B 大端] |
[起始偏移 4B][显存 nB] |
支持断点续传;拒绝语义见 §5.16.6 |
| 4 | ACK |
— | — | 参考 RDisp_Send 中为空分支,未使用 |
| 5 | NCK |
— | — | 同上,未使用 |
0xFF |
IDLE |
— | — | 内部空闲码,不上线 |
INIT 应答数据段(16 B,即 RDisp_Form_InitInf 的单色子集):
| 偏移 | 长度 | 字段 | 取值 |
|---|---|---|---|
| 0 | 2 | LCD 像素宽(大端) | UI_SCREEN_W = 160 |
| 2 | 2 | LCD 像素高(大端) | UI_SCREEN_H = 160 |
| 4 | 4 | 显存字节数(大端) | UI_FB_SIZE = (160*160)/8 = 3200 |
| 8 | 8 | 键值表 F1/F2/U/D/L/R/ENT/ESC |
0x04/0x80/0x02/0x40/0x10/0x08/0x20/0x01 |
为什么是 16 B 而不是参考的 29 B:参考的 29 B 里有 13 B 颜色信息(1 B 颜色位
CN_RDISP_LCD_TYPE+ 12 B RGBCN_RGB_RED/GREEN/BLUE),而这 13 B 在参考自己的构建里就是死字段:RemoDispBus.h:46的CN_RDISP_TYPE_MONO = TRUE→ 链路显存本身就是 1 bpp;三个 RGB 值是编译期 常量(每次召唤发同样的 12 B);RDisp_LcdColor_To_Mono()对CN_MODE_GREY_MONO直接return TRUE, RGB565 分支永不进入(§2.4.1)。本产品屏板同为单色 1 bpp(DTU-LCD的ScreenPrintf()只吃 1 bpp 点阵),这 13 B 既无接收方也无语义 → 整段删除,不对齐多色协议:29 − 13 = 16 B。
键值是位掩码,不是枚举——可组合下发:CN_KEY_F1|CN_KEY_ENT = 0x24(Key.c 物理键号 10 即此值)。
CN_KEY_ADD=0x82、CN_KEY_SUB=0x84 只在串口屏板通道使用,不进 7003 键值表。
5.16.6 显存上送的续传与拒绝语义
RDisp_Form_LcdMem / RDisp_Proc_LcdMem 的完整规则:
- 分片:
dwSendBase + 9800 > 3200成立 → 本帧发3200 - dwSendBase字节;否则发 9800 B。 因MEMSIZE = 3200 < 9800,实际恒为单帧 3204 B(4 B 偏移 + 3200 B 位图); 分片逻辑为"显存变大"预留,当前不触发。 - 推进:发完后
dwSendBase += dwLen;若>= MEMSIZE→bNeedFlash = TRUE、dwSendBase = 0。 - 拒绝:召唤时若
bNeedFlash为真(上一帧刚发完、新图还没拷贝)→ 返回-1,且把dwSendBase清 0,不应答。含义是"一帧图像只允许被完整上送一次",客户端要下一帧 必须等主机完成下一次刷新。 - 越界:
dwSendBase >= MEMSIZE→ 返回-2,不应答。 - 成功:返回
1,置wSendCode = LCDMEM,由RDisp_Send组帧发出。 - 刷新来源:
RDisp_Main每轮检查bNeedFlash,为真则memcpy(byLcdMemory, __Lcd_Pub_GetScreenAddr(0), 3200)→RDisp_LcdColor_To_Mono()转单色 → 清bNeedFlash、dwSendBase = 0。
RDisp_LcdColor_To_Mono()这一步本产品不需要(参考自己也不走):该函数按CN_LCD_TYPE分派, 而本构建CN_LCD_TYPE = CN_MODE_GREY_MONO→ 命中第一分支直接return TRUE,不做任何转换; 只有CN_MODE_COLOR_16B才调RDisp_Lcd16B_To_Mono()做 RGB565 → 单色,那条路是死代码。 本产品的g_ui_fbuf本来就是 1 bpp 单色(LVGL 单色渲染,UI_FB_SIZE = 3200),拷贝即可送, 没有"颜色 → 单色"的转换环节。这是"不对齐多色协议"带来的简化之一。
为什么必须有
bNeedFlash握手:显存由显示任务异步改写,若允许客户端随时按偏移拉取, 跨两次刷新的位图会在客户端拼成撕裂帧。参考用"整帧一次性 + 拒绝重拉"消除这个窗口, 本产品当前无此保护(§5.16.9 第 4 行)。
5.16.7 按键注入与状态机
| 项 | 规格 |
|---|---|
| 存储 | tagRKeyCtrl g_tRemoteKey { byUsrFlg, byKeyValid, byKeyValue, bUseRkey } |
| 有效性 | EN_KEY_FLAG_NULL=0(无新键)/ EN_KEY_FLAG_NEW=1(有新键)/ EN_KEY_FLAG_SAM=2(采样中) |
| 注入 | 收 KEY 帧 → byKeyValue = DATA[0]、byKeyValid = EN_KEY_FLAG_NEW |
| 消费 | Key_Read() 读到 NEW 后立即清 NULL(边沿消费,不重复触发) |
| 合并顺序 | 有本地键板时:先取远程 g_tRemoteKey,再被本地 g_tKey 覆盖——两键同时挂起时本地优先 |
| 连接联动 | TCP 连上 → bUseRkey = TRUE;断开 → FALSE + wSendCode = IDLE + dwSendBase = 0 |
| 背光 | Key_HaveNewKey() 每次调用都执行 MenuProc_Have_Key()(无新键也点背光),再返回是否有新键 |
5.16.8 时序、超时与重试
| 定时器 | 周期 | 作用 |
|---|---|---|
tTimerLCD |
500 ms | 参考主机侧串口屏板通道的周期兜底节拍(WriteScreenByByte)。⚠ 本产品不照抄:屏板固件自己按 275 ms 主动召唤(§5.16.2),主机只需"来一帧答一帧",无需自带节拍 |
tTimerComBrk |
1 分钟 | 通信中断判定;每收到任一帧、每次发送成功都重置 |
tTimerAbandon |
200 ms | 发送未完成时的放弃窗口 |
发送状态机(RDisp_Send):
TcpGetSendState(iTcpNo) <= 0→ 直接返回(链路未建或芯片发送忙),不组帧。wSendFlag == CN_RDISP_SEND_BUSY→ 重发上次缓冲;成功 →IDLE+ 重置tTimerComBrk; 失败且tTimerAbandon未到 → 返回;已到 →IDLE后重新组帧(宁可丢帧不阻塞)。- 组帧:
byCRC = XOR(DATA);填TAG=0xBB、CMD、LEN;CRC写在DATA之后。 TcpSend返回值 必须等于wMsgLen才算成功(部分发送视为失败,进 BUSY 重试)。
显存刷新互斥:g_tShareSetBuf.dwReserSet[3] 三态——0xaa = 被其他模块占用(本轮跳过)、
0x55 = 显示已刷新(供远程工具判断)、0 = 空闲。取用前查 0xaa、用后清 0。
任务模型:taskSpawn("tRemoDisp%d", 111, 0x0008, 0x35000, RDisp_Main, ...)
——prio 111、栈 0x35000(212 KB,VxWorks 字节语义)、主循环 taskDelay(1),
每轮 DogTask_InfoUpdate(EN_TASK_DSP, ...) 喂狗,退出时 DogTask_InfoError 报异常。
5.16.9 与参考的差异(本产品当前实现)
| # | 项 | 参考 | 本产品 | 处置 |
|---|---|---|---|---|
| 1 | INIT 应答长度 | 29 B(= 宽高 4 + 颜色位 1 + 显存 4 + RGB 三色 12 + 键值表 8) | 8 B(宽 2 + 高 2 + 帧字节 4) | 补 8 B 键值表 → 16 B;颜色 13 B 不对齐(单色屏无接收方,§5.16.5) |
| 2 | KEEPLIVE 应答 | 不应答 | 回显空 KEEPLIVE 帧 | 改为不应答(或留兼容开关) |
| 3 | LCDMEM 非 0 偏移 | 支持续传(从 dwSendBase 起) |
仅支持偏移 0,非 0 静默忽略 | 补续传 |
| 4 | 召唤拒绝语义 | bNeedFlash 为真 → -1 不发 |
无 | 补(防撕裂帧) |
| 5 | 越界语义 | >= 3200 → -2 不发 |
无 | 补 |
| 6 | 链路监视 | tTimerComBrk 1 分钟 |
无 | 补(掉线判定 / 重连驱动) |
| 7 | 发送重试 | BUSY + 200 ms 放弃 | 依赖 net_send 阻塞模型 |
评估是否需独立实现 |
| 8 | 键值集(网络通道) | 8 键(含 F1 / F2) | 6 键(无 F1 / F2) | 补 F1 / F2;仅网络通道——屏板无 F1/F2 物理键(§5.16.3 ②) |
| 9 | 任务模型 | 独立任务 prio 111 / 栈 212 KB | uiTask 10 ms 轮询(prio BelowNormal / 16 KB) |
形态差异,不追平(X1 / X2) |
| 10 | 接收侧 CRC | 仅 LCDMEM / KEY 校验 | 全帧校验 | 本产品更严,保留 |
| 11 | 串口屏板通道 | 有:显存 3200 B + 状态灯 4 B 下行、键号上行,变化驱动 + 500 ms 兜底 | 无(只有 7003 网络通道) | 新建,按 §5.16.2 逐字节实现,见 §9.13 |
| 12 | 双出口并发 | 同一份显存同时喂串口与网络,互不阻塞 | 只有网络一个出口 | 随第 11 条一并实现 |
| 13 | 屏板状态指示灯 | 20 路(ID 0 电源常亮 + ID 1~19 位掩码),4 B 小端随每帧下发 | 无;主板另有 6 路 GPIO LED(LED1~6) |
新建;"位 → 业务状态"映射须自定(参考源码无此表,§5.16.3 ①) |
| 14 | 背光 / 对比度 | 主机 BSP 有 Lcd_BackLight / Lcd_SetContrast + 空闲 120 s 熄灭 |
无 | 不做——屏板固件自管背光,两条路径不能同时启用 |
来自屏板固件的新增约束(参考主机侧源码里看不出来,但对实现是硬约束):
- 角色反转:屏板是 Modbus 主站(主动召唤),主机是从站
0x01;与网络通道"客户端召唤"方向相反。 - 帧长 4208 B(3208 B 有效载荷 + 998 B 填充 + 2 B CRC,§5.16.2)。
- 700000 8N1,主机侧走 USART1 TTL 直连(无方向控制)。
- 屏板每 ≈5000 s 自复位一次,约 1 s 空窗;主机链路监视须容忍(建议连续 ≥10 s 无应答才判离线)。
- 屏板只有 7 个物理键,键值
9/10是"复位 / 工厂",与参考主机的F1/F1|ENT语义不同。 - 单色:屏板是 1 bpp 单色面板,参考的 13 B 颜色信息(颜色位 + RGB 三色)无接收方,不对齐。
第 1 / 3 / 4 / 5 / 8 条是客户端可见的报文口径差异——现有
DTU-RemoteLCD按 8 B INIT 实现, 补到 16 B 后客户端必须同步改,否则会错位解析。这是本项复刻唯一的跨端风险点。 注意:16 B 与参考的 29 B 不是同一口径——客户端不得按 29 B 预留缓冲再截取前 16 B 使用 (从偏移 4 起含义即不同:参考偏移 4 是颜色位,本产品偏移 4 是显存大小的高字节)。第 11 / 12 / 13 条是整条链路缺失,不是报文细节差异——它决定了本产品能否脱离 PC 独立带屏运行。
第 14 条已决定不做:屏板固件自管背光与超时熄灭,主机再插一手会打架。
5.16.10 复刻完成判据
- 任意 TCP 客户端连 7003 → 发
INIT→ 收到 16 B(宽 2 + 高 2 + 显存 4 + 8 键值表), 字段值与 §5.16.5 逐字节一致;不得出现颜色位或 RGB 字段。 - 发
LCDMEM(0)→ 收到3204 B;再次发LCDMEM(0)(新图未就绪)→ 无应答(对应参考-1)。 - 发
LCDMEM(3200)→ 无应答(对应参考-2)。注:该分支在bNeedFlash为真时先被-1截住, 只能在"新图已拷贝、尚未上送"的窗口内触发,属边角路径,判据以"无应答且不越界读"为准。 - 发
KEEPLIVE→ 无应答,且链路 1 分钟内不被本端主动断开。 - 发
KEY(0x24)→ 收到空 KEY 应答,界面表现为F1+ENT组合键。 - 断开 TCP 60 s 以上 → 设备侧可观测到"通信中断"(日志 / 状态位),重连后自动恢复推流。
- 8 键逐个下发 → 界面动作与按键表一致;组合键
F1|ENT生效。
串口屏板通道(与上面 7 条并列,待建后验收):
- 主机上电后,屏板按 280 ms 节拍发帧 A(6 B,形如
01 03 01 xx CRC_H CRC_L);主机每帧在 ≤200 ms 内发完帧 B(4208 B,整帧无 2 个字符时间以上的间隙,CRC 覆盖[0, 4205]), 主机侧连续 10 分钟零超时、零 CRC 错帧(屏板不指示通信状态,计数只能在主机侧取)。 - 帧 B 前 3200 B 与主机
g_ui_fbuf逐字节一致(160 行 × 20 B,1 bpp,MSB 在前,bit = 1 → 白)。 - 屏板 7 个物理键逐个按下 → 主机收到的
key依次为1/2/3/4/7/8/9(ENTER / UP / DOWN / ESC / LEFT / RIGHT / RESET),界面动作与 §8.2 菜单树一致;0表示无键、不产生事件。 - 状态灯下行:主机把 19 路业务状态映射为位掩码 → 屏板 LED 1~19 的亮灭与掩码逐位一致; LED 0 恒亮、不受掩码控制(bit0 置位不改变任何灯)。
- 双通道并发:同一时刻 7003 客户端在拉帧、屏板在召唤,两侧画面一致,互不丢帧、不串帧; 串口侧 4208 B 发送阻塞不得导致 7003 侧超时(反之亦然)。
- 屏板自复位容忍:屏板跑满 ≈5000 s 触发自复位,主机不误判"屏板离线"(无告警、不触发保护), 约 1 s 后自动续上。
- 拔掉屏板 → 7003 侧不受影响;插回后自动恢复,无需复位主机。
- LOGO 下发:下发一帧 LOGO(
info[4..5] = 0x89 0x45)→ 屏板写 Flash0x0803F000并显示 2 s; 断电重启后仍显示该 LOGO,且屏板 LED 状态未被这帧改动。
6. 接口规范
6.1 网络服务端口
| 服务 | 协议 / 端口 | 用途 | 核对方法 |
|---|---|---|---|
| FTP | TCP 21 | 文件上传/下载(根目录 /,NAND 存储) |
登录后任意 FTP 客户端列目录/读写(鉴权见 §7.6) |
| 墙钟对时 | TCP 8888 | PC 主动推送时间到设备 | 对时后核对设备时间 / 日志时间戳 |
| 远程显示(RemoDispBus) | TCP 7003 | 远端看图(160×160 1bpp)+ 远端导航按键 | DTU-RemoteLCD 或任意 TCP 客户端连 7003 收帧 |
| IEC 60870-5-104 上行 | TCP 2404 | 被控站接入:遥测/遥信上送、总召、遥控/定值下发(点表见 §6.8) | 任意 104 主站连 2404,STARTDT+总召往返(→ docs/子系统设计/IEC104上行设计说明.md) |
现场组网要求:设备与客户端同网段(默认 .100/24、网关 .1);跨网段先改 IP 再上线。
6.2 RemoDispBus 协议
口径:本节按参考源码(
HMI/RemoeDisp/RemoDispBus.c)给线上格式;本产品当前实现与该口径的 逐项差异、以及为什么会有差异,见 §5.16.9。以参考为准,差异项按 §9.13 排期收敛。本节只讲网络通道(TCP 7003)。串口屏板通道不走本协议——它是 RS-485 上的 Modbus RTU 风格裸二进制帧(6 B 召唤 + 4208 B 图像应答,CRC-16/MODBUS 低字节在前), 帧格式已按屏板源码逐字节定版,见 §5.16.2。 两条通道共用同一份显存,但帧格式、校验、时序、主从方向全都不同,不能共用组帧代码。
| 项目 | 内容 |
|---|---|
| 传输 | TCP,端口 7003;设备为 Server,目标 IP 255.255.255.255 = 接受任意客户端 |
| 帧格式 | [TAG(1)][CMD(1)][LEN_H(1)][LEN_LO(1)][DATA(n)][CRC(1)] |
| 方向标识 | TAG 0xAA = 客户端→服务端,0xBB = 服务端→客户端 |
| 校验 | CRC = 数据段逐字节异或(低 8 位,不含 TAG/CMD/LEN,也不含 CRC 自身) |
| 字节序 | 多字节字段大端(网络字节序) |
| 最短帧 | 5 字节(LEN=0) |
| 最长帧 | 数据段 ≤ 9800 B(CN_RDISP_FRAME_LEN_MAX) |
| 缓冲 | 收发各 10240 B(CN_RDISP_BUF_RECV/SEND) |
| 接收方式 | 逐字节有限状态机(TAG 定界 + 长度定长 + CRC 校验,自动重同步) |
命令集:
| CMD | 名称 | 请求数据段 | 应答数据段 |
|---|---|---|---|
| 0 | KEEPLIVE | 无 | 无应答(仅重置 1 分钟通信计时) |
| 1 | INIT | 无 | [宽u16][高u16][显存u32][8 键值](16 B;参考的 29 B 含 13 B 颜色信息,本产品不对齐) |
| 2 | KEY | [按键码u8] |
无(空帧确认,LEN=0) |
| 3 | LCDMEM | [起始偏移u32] |
[偏移u32][1bpp位图 3200B](3204 B);偏移非 0 时续传,bNeedFlash 期间不应答 |
INIT 字段明细与按键码表:见 §5.16.5(含 16 B 逐字段偏移)。
单色口径:本产品只实现单色分支。参考
INIT里的颜色位CN_RDISP_LCD_TYPE与CN_RGB_RED/GREEN/BLUE(共 13 B)整段删除,不做多色对齐——屏板是 1 bpp 单色面板, 没有彩色/灰度的接收方;参考侧RDisp_LcdColor_To_Mono()这道"彩色转单色"也因此不存在 (本产品显存本来就是单色)。
按键码:F1=0x04 / F2=0x80 / UP=0x02 / DOWN=0x40 / LEFT=0x10 / RIGHT=0x08 /
ENTER=0x20 / ESC=0x01;位掩码可组合(如 F1|ENTER = 0x24)。
位图格式:1bpp 单色,MSB 优先(bit7 = 该字节第一个像素);像素 (x,y) → byte_i=(y*W+x)/8、bit_i=7-(x%8);位值 1=白、0=黑;160×160 → 3200 B。
关键常量:UI_NET_SINK_PORT=7003、RM_MAX_RX_PAYLOAD=256、RM_RX_BUF=64、帧重组缓冲 261 B
(本产品侧常量;参考侧对应 CN_RDISP_TCP_PORT / CN_RDISP_FRAME_LEN_MAX / CN_RDISP_MEMSIZE)。
详见
docs/UI设计/RemoDispBus协议与接收设计说明.md。MCU 与模拟器共用同一份ui_net_sink.c。
6.3 对时协议
- 载体:TCP :8888,PC 主动推送,设备接收并写 RTC。
- 行为:
timeSyncTask监听 → 收包 → 写回 RTC;30 s 无包则掉线重建监听(约 4 s)。 - 待补充:推送报文的具体帧格式(当前实现细节见
App/sync/time_sync.c与test/host/time_sync_server.py)。
6.4 FTP 服务
- 实现:lftpd(轻量 FTP 服务器),root =
/(FatFS 卷根),端口 21,单客户端。 - 支持命令:登录 / TYPE I / PASV / STOR / RETR / LIST / DELE / QUIT。
- 鉴权(已鉴权 · 2026-10-11):口令登录(
[ftp]段user/pwd_hash= SHA-256(user‖password) /write);未登录仅 USER/PASS/QUIT/FEAT/SYST/NOOP 放行,其余一律 530;write=0可禁 STOR/DELE;连续 5 次失败锁 60 s;出厂默认admin/admin,默认口令在用有启动告警。口径详见docs/子系统设计/网络配置说明.md§3.4。 - 启动门:
ftpTask必须等NET_READY且STORAGE_READY(两位NoClear)才lftpd_start。 - 注意:同一时刻只服务 1 个会话,旧会话异常断开后约 30 s 恢复监听;测试脚本须内置连接重试,不要用裸 TCP 工具探测 21 端口。
- 实测:128 KB 上传下载逐字节一致(约 49/60 KB/s)。
6.5 配置文件格式
位置:MCU /config.ini(卷根);模拟器 sim_config.ini(工作目录)。
语法:key=value(key [a-z0-9_]+ 大小写敏感);[section];;/# 注释行;UTF-8(容忍 BOM);CRLF(设备写出)/ LF 均接受;行长 >127 字符该行无效;文件 >4096 B 视为损坏。
出厂模板(首启自动生成):
; DTU 通用配置文件
[network]
; IP 地址
ip=192.168.1.100
; 子网掩码
mask=255.255.255.0
; 默认网关
gateway=192.168.1.1
; MAC 地址 (全零 = 使用芯片内置 MAC)
mac=00:00:00:00:00:00
值类型:IP4(a.b.c.d)、MAC(aa:bb:cc:dd:ee:ff)、UINT(十进制,兼容 0x)、STR(≤31 字符)。
工厂默认:IP 192.168.1.100 / 掩码 255.255.255.0 / 网关 192.168.1.1 / MAC 全零(= 芯片内置)。
MAC 全零是"使用芯片内置 MAC"的哨兵,不是"MAC 为 0"。恢复出厂:FTP
DELE /config.ini→ 下次上电重新生成模板。
6.6 调试串口
| 项 | 值 |
|---|---|
| 端口 | USART1(PA9 TX / PA10 RX),115200 8N1 |
| 用途 | printf 日志 + @test 采集通道 |
| 配置源 | .serialtest/config.json(单一配置源) |
| 工具 | 仓库内置 Python 串口助手(.dsh/skills/serial-assistant/,常驻 daemon + CLI) |
启动标记(@test 判据):
- Required:
App init OK/Network Init/net init: OK/PHY: 100M FULL - Forbidden:
FAIL/ERROR/HardFault/[ERR]
6.7 对外 API 一览
| 模块 | 关键 API | 说明 |
|---|---|---|
net_socket |
socket/bind/listen/accept/recv/send/close + select/poll |
BSD Socket 抽象 |
net_cfg |
net_cfg_load/save/get/set/get_mac/set_active_mac/fmt_ipv4/set_apply_cb/request_apply |
网络配置(签名与语义稳定) |
cfg_file |
cfg_file_register/load/save/poll/section_data |
配置引擎核心(双端共享) |
sys_clock |
sys_clock_init/get/get_str/get_time |
墙钟时间服务 |
sys_log |
syslog_post(RUN / SELFTEST) |
定长记录引擎 |
ui_net_sink |
ui_net_sink_start(port) / ui_net_sink_poll() |
远程显示服务端 |
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 |
语义取数与有效性语义取数(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 链路 / 点表 / 板端胶水 |
6.8 IEC 60870-5-104 点表摘要
权威口径:验收以《检测平台配电终端送检要求(点表)》为准;本表是 V0.1 实现摘要, 逐点细节与未实现项见
docs/子系统设计/IEC104上行设计说明.md§3。 段基址与参考产品逐字对齐(8 段全表见 §2.5.3):遥信0x0001、保护0x1001、遥测0x4001、 参数0x5001、遥控0x6001、设定0x6201、电能0x6401、步位置0x6601。 点表规模是当前最大差距:本产品 9 遥测 / 33 遥信 / 2 遥控,参考产品 31 遥测 / 138 开入 / 31 开出。
遥测(0x4001 段起,短浮点,系数 1)
| IOA | 点 | 来源 | V0.1 |
|---|---|---|---|
4011 / 4014 / 4015 |
1Ua / 1U0 / 1Ia |
遥测快照(TPAFE 侧,有效) | ✅ |
4012 / 4013 / 4016~4018 |
1Ub/1Uc/1Ib/1Ic/1I0 |
快照(STM32 侧,削顶) | ❌ 恒 IV |
4019~401C |
1P/1Q/1S/1Pf |
需跨转换器同刻 | ❌ 恒 IV(V0.2) |
401D |
1f 频率 |
测频结果 | ✅(未收敛则 IV) |
4010 / 401E / 401F |
UBA 后备电源 / V1/V2 直流 |
无硬件通道 | ❌ 未入表(X3) |
与参考的差额:参考
g_tYcIndexTab共 31 点——双回线各三相电流/电压(12)、双回线各三组 线电压(6)、双回零序电流/电压(3)、频率(1)、直流 2 路(2)、有功/无功/视在/功率因数 单相 3 + 三相 1(4)、电度 8 种另列。本产品 9 点,缺的是第二回线、线电压、零序双回与 功率四量——前者等通道(X4),后两者等标定后的功率运算。
遥信(0x0001 段起,V0.1 定义 33 点):1~4 开关位置(双点,恒 IV)、5~14 预留(IV)、
15 故障总、16~18 过流 Ⅰ/Ⅱ/Ⅲ 段、19~20 零序过流 Ⅰ/Ⅱ(IV)、21~22 接地故障/重载(IV)、
23 过载、24~30 外部遥信(RS-485 冻结 → IV)、31 保护闭锁、32~33 预留(IV)。
有效位图 YX_VALID_MASK = YX15~18 / 23 / 31(6 点)。
与参考的差额:参考
g_tInputModelTab共 138 点(开关合/分位、未储能、就地远方、接地位置、 隔离位置、停用重合闸、保护投入、检修压板、远方信号、手合手分、电源输入、活化状态、电池欠压…), 另g_tOutputModelTab31 点开出(保跳/保合/遥分/遥合/遥控备用/电池活化/电机保护/闭锁…)。 两者都需要一次设备接口硬件(X4),属 §9.1 阻塞型。
遥控(0x6001 段起,双点两段式):YK1~4 开关(否定确认)、YK11 信号复归、YK12 遥控软压板、
YK13 电池活化(否定)、YK14 解除闭锁(否定)。
定值与运行参数:保护定值地址 = prot_set.comm_addr(基址 0x8820,过压/欠压沿用告警段
0x8027~0x802A);运行参数段 0x8030~0x8038(死区 9 点)/ 0x8040~0x8047(k 覆盖 8 路)/
0x8048~0x804F(b 覆盖 8 路),共 25 项。
逐项地址为本仓自定,送检点表到位后以送检为准替换常量段。
与参考的差额:参考 104 定值映射 107 项占
0x8820~0x8891(8 个空洞), 底层定值表 249 项 / 23 单元。本产品 40 项,缺的是重合闸(16)、电压时间型自愈(17)、 同期(13)、看门狗(63)、遥测越限(10)等整单元(§2.5.4)。
链路参数:k=12 / w=8 / t1=15 s / t2=10 s / t3=20 s;IOA 3 字节、公共地址 2 字节、传送原因 2 字节;
公共地址与端口可配([comm] 段,工厂默认 1 / 2404,改后需重启生效)。
7. 非功能需求
7.1 可靠性
| 需求 | 要求 | 落地 |
|---|---|---|
| 自恢复 | 任务死锁/饿死/断言死循环 → 硬件复位 | IWDG + 心跳位图(§5.7) |
| 掉电不丢配置 | 配置原子写(旧档迁移已取消,2026-10-10) | tmp+rename;旧 /cfg/netcfg.bin 不读、不删、不迁移 |
| 错误可追溯 | 错误码分级/透传/留痕,不吞不猜 | 错误码通道四要素(分类/透传/分级/留痕) |
| 存储自愈 | 卷损坏可探针/自愈;丢弃可观测 | 卷健康探针 + 丢弃计数 + TX 僵尸通道自愈 |
| 不误杀 | 正常长耗时窗口不触发复位 | 启动段不喂狗 + 心跳切片 + 白名单 |
错误码通道四要素(CH395F 范式,后续任何驱动/子系统建立错误通道时应沿用): ① 分类(超时/真故障/参数错)② 透传(逐层上报,禁
(void)ret)③ 分级(可恢复重试/不可恢复上报) ④ 留痕(不可恢复写 syslog selftest,可恢复计数并 UI/日志可见)。 纪律:自愈逻辑严禁把"名字/参数类错误码"归入"卷损坏触发集"。
7.2 性能指标
| 指标 | 基线值 | 来源 |
|---|---|---|
| M3 压力档帧周期 | med 60.1 / p95 66.4 / max 69.3 ms(零尖峰) | docs/测试说明/链路延迟测试说明.md |
| 队列响应性(挂起客户端) | 92.5 ms(pending 一期) | test/host/e02_probe.py |
| FTP 传输速率 | 约 49 / 60 KB/s(上传/下载) | 128 KB 实测 |
| 网络重建生效 | 2~5 s(含等链路 ≤3 s) | 配置设计 |
| UI 刷新 | 10 ms 循环 | ui_task_func |
| IWDG 停喂到复位 | ≤2.5 s | IWDG 设计 |
| 采样节拍 | 1000 Hz(每 10 s 帧号 +10000,零丢帧) | 台架 @test |
| 单拍采集消费 | ≤10 µs(DMA 搬运后实测 8 µs) | adc_task 实测 |
| 相量刷新 | 1 ms(每拍整窗重算 5 实例) | phasor_run |
| 遥测快照周期 | 200 ms(经过时间分频) | meas_tick |
| 测频精度 | 45~55 Hz 最坏 0.0101 Hz | 主机侧扫频用例 |
| 保护判据节拍 | 20 ms(延时精度由 now_ms 差值保证) |
protectTask |
| 动作到 104 上送 | ≤120 ms(判据拍 + COV + 服务周期) | 台架主站往返 |
7.3 内存与资源预算
权威来源:
.map受管快照(docs/内存管理/RAM使用分析与优化方案.md§2.1,由scripts/check_mem_numbers.py --write生成)+ 2026-10-22 栈预算快照 (docs/内存管理/data/stack_report_20261022.md)。本节数值随代码演进会过期,提交前以受管快照为准。
静态区(产品构建,2026-10-24 .map):
| 区域 | 用量 | 容量 | 占比 |
|---|---|---|---|
| Flash ER_IROM1 | 261,928 B | 1024 KB | 25.0% |
| ROM 合计 | 263,500 B | 1024 KB | 25.1% |
| RW_IRAM1 | 81,072 B | 131,072 B | 61.9% |
| RW_CCM | 57,376 B | 65,280 B | 87.9% |
运行时栈预算(9 任务,静态最坏链 × 真机水位取更坏者):
| 任务 | 配置 | 静态最坏链 | 真机峰值 | 余量 | 判定 |
|---|---|---|---|---|---|
defaultTask |
5120 B | 3024 B | 2152 B | 40% | ✅ |
netTask |
3840 B | 1912 B | 1116 B | 50% | ✅ |
ftpTask |
4096 B | 1456 B | 740 B | 64% | ✅ |
uiTask |
16384 B | 1336 B | 4052 B | 75% | ✅ |
testTask |
8192 B | 736 B | — | 91% | ✅ |
timeSyncTask |
2560 B | 1264 B | 616 B | 50% | ✅ |
adcTask |
2560 B | 1320 B | 952 B | 48% | ✅ |
iec104Task |
2560 B | 1456 B | 580 B | 43% | ✅ |
protectTask |
2048 B | 872 B | 828 B | 57% | ✅ |
定栈规则:改栈或加大栈内局部变量前后必须重跑
scripts/stack_report.py(Keil 静态调用图 × 串口[STACK]水位,判定取两者更坏者;余量须 ≥ max(1024 B ISR, 30%))。 LVGL 内存池 16 KB(静态占用,2026-10-15 由 40 KB 收缩);FreeRTOS 堆 56 KB(CCM,水位 87.9% < 92% 门禁)。 卡点已从主 SRAM 移到 CCM(余 ~7.9 KB)——再加任务或抬栈前先看docs/内存管理/RAM使用分析与优化方案.md§4。
7.4 可维护性(测试与门禁)
测试分层:
| 层 | 内容 | 运行位置 |
|---|---|---|
| 静态门禁 | pre-commit 钩子族:格式 / 编码 / 静态分析 / 文档链接 / 体积 / 生成物新鲜度 / 编号 | 本地 / CI |
| 主机侧纯逻辑单测 | MSVC 离线编译真实源码 | 本地 / CI |
| 板端测试套件 | 板端套件(testTask 串口 [PASS]/[FAIL] 汇总) |
本地(需真机 + 串口) |
| 主机侧回归 | 模拟器像素 / 池水位回归 + 真机 @test 闭环(含探针) |
本地(模拟器免硬件;@test 需真机 + ST-LINK) |
构建 / 测试命令:
# 构建(@build):0 错 0 警
& '.venv\Scripts\python.exe' .dsh/skills/keil-build/scripts/keil_build.py # 退出码 0=PASS / 1=构建失败 / 2=环境错误
# 自动化测试(@test):串口采集 → 烧录 → 日志校验
& '.venv\Scripts\python.exe' .dsh/skills/serial-boot-test/scripts/run_boot_test.py # 0=PASS / 1=FAIL / 2=采集或烧录错误 / 3=用法错误
# 全库门禁
pre-commit run --all-files
pre-commit 门禁族(钩子数量随套件增长,以 .pre-commit-config.yaml 为准):
| 族 | 代表钩子 | 作用 |
|---|---|---|
| 格式 / 仓库卫生 | trailing-whitespace、end-of-file-fixer、check-added-large-files、check-merge-conflict、check-yaml、gitlint |
行尾与空白、超大文件、冲突标记、提交信息规范 |
| 编码与源码纪律 | no-mojibake、coding-standard、nested-comment、bom-guard、layer-deps、bsp-err |
乱码、命名与常量位置、注释嵌套、BOM 漂移、分层依赖、BSP 错误码契约 |
| 静态分析 | cppcheck、test-cppcheck |
主机侧与测试代码静态检查 |
| 文档一致性 | doc-links、id-check、task-table、mem-numbers、mem-budget、size-gate |
链接与章节引用、编号、任务表、内存数字、体积门禁 |
| 生成物新鲜度 | generated-fresh、font-charset、lv-conf-sync、ui-golden、setview-check、uinav-selftest |
菜单/字体/像素黄金等生成物与源一致 |
| 主机侧单测 | watchdog / sys-clock / cfg-file / phasor / adc-input / adc-health / adc-cal / meas / freq / prot-set / prot-elm / run-par / iec104 / soe / nand-port / ui-data 等 *-unit-test |
MSVC 离线编译真实源码跑断言 |
| 结构与注册 | registration-check、test-suite-switch、cubemx-survival |
双端注册、套件互斥、CubeMX 保护区审计 |
受管事实源(禁止手改,由脚本生成):
- 任务表(
README.md/AGENTS.md)←scripts/gen_task_table.py - 内存/Flash 快照 ←
scripts/check_mem_numbers.py - 菜单表 ←
tools/menu_gen/gen_menu.py - 中文字体 ←
tools/font_gen/make_font.py
7.5 可移植性(双端)
| 项 | MCU | 模拟器 |
|---|---|---|
| 构建 | Keil MDK-ARM v5(ARMCC) | CMake + SDL2 + MSVC |
| 共用源码 | Drivers/BSP/UI/*、Drivers/BSP/NETCFG/net_cfg.c、App/cfg/cfg_file.c |
同左 |
| 平台后端 | *_mcu.c(CH395F/FatFS) |
*_sim.c(Winsock/宿主文件) |
| 验证 | @build 0/0 → @test 串口闭环 |
check_menu_rows.py + check_content_pages.py(像素黄金参考) |
新源文件必须双端注册(Keil
.uvprojx+simulator/CMakeLists.txt),否则不参与编译。
7.6 安全与权限
| 项 | 现状 |
|---|---|
| FTP 鉴权 | 已鉴权(2026-10-11):口令登录([ftp] 段存 SHA-256 摘要,不存明文)+ 连续 5 次失败锁 60 s + write=0 可选只读;出厂默认 admin/admin,默认口令在用有启动告警。边界:FTP 明文传口令,挡未授权访问、不挡网络嗅探(详见 docs/子系统设计/网络配置说明.md §3.4) |
| UI 菜单权限 | 受保护叶子(行尾 #P)先经密码页;密码仅编译期写入(查看 000 / 修改 123),不落 Flash、无运行期设置页 |
| 远程显示 | 无鉴权,单连接;现场同网段部署 |
| 104 上行 | 无应用层鉴权(标准 104 本身不带认证):安全边界 = 现场同网段部署 + 单连接语义 + 首到优先。主站 IP 白名单不实现(单 socket 上"拒绝"= close + 重听,可被端口扫描打成 SPI 风暴,且配错即锁死真主站;属协议语义决定,非范围裁剪,见 §9 卷首)→ 需冗余/白名单时随 net 层立项 |
| 配置面 | 配置与定值只能经 FTP(需口令)或 104(同网段)改写;UI 侧修改需修改密码。本地无串口配置命令通道 |
8. UI 规格
8.1 屏幕与渲染
| 项 | 值 |
|---|---|
| 屏幕尺寸 | 160 × 160 px |
| 色深 | 1bpp 单色(MSB 优先),帧缓冲 3200 B;无灰度、无彩色——参考与本产品的链路都是单色,7003 INIT 的颜色字段已删(§5.16.5) |
| 渲染 | LVGL 离屏渲染到 g_ui_fbuf;MCU 无物理屏,经**串口屏板通道(主)+ TCP 7003(镜像)**双出口送出 |
| 内存池 | LV_MEM_SIZE = 16 KB(2026-10-15 由 40 KB 收缩,实测峰值占 40%) |
| 主题 | dark mono(单色深色) |
| 刷新 | uiTask 10 ms 循环 |
| 绘制缓冲 | I1 draw buffer 需 +8 B palette 头 |
8.2 菜单树(43 节点)
图里的节点数、绑页与密码门读数由
tools/arch_diagram/gen_menu_tree_svg.py现算自真值ui_menu_tree.txt(改菜单树 → 同步脚本内NODE_SRC重跑);级联框在屏上怎么摆(几何)→docs/UI设计/菜单页面设计.md§4.1。
规模:菜单节点 9 个(含根)+ 叶子节点 34 个 = 43 节点;最大深度 4 级(主界面 / 一级 / 二级 / 三级菜单)。
绑定现状(2026-10-29 复扫):已绑内容页 30 叶 / 未绑 4 叶(页面注册表 UI_PAGE_MAP_COUNT = 30,
与已绑叶数一致);未绑 4 叶 = 无开入硬件 3 + SNTP 1(取舍与重开条件见
docs/任务规划/UI补齐.md §5);原「当前执行 6 项」(记录 5 页 + 运行报告)已于 2026-10-28 落地绑页,
「手动录波」与「录波回放」两叶于 2026-10-29 随录波道绑页(判据见 docs/子系统设计/故障录波设计说明.md §4.1 与 §8.1)。
根页(主界面)7 个一级条目:装置信息 / 实时数据 / 参数定值 / 三遥设置 / 装置维护 / 通讯参数 / 记录查询。
完整层级树:
主界面
├─ 装置信息 [叶子]
├─ 实时数据 ▶ [菜单]
│ ├─ 交流量 ├─ 直流量 └─ 遥信量
├─ 参数定值 ▶
│ ├─ 整定 ▶(参数 / 定值 / 控制字 / 软压板)
│ └─ 查看 ▶(参数 / 定值 / 控制字 / 软压板)
├─ 三遥设置 ▶(遥测死区 / 遥测系数 / 遥信类型 / 遥信防抖 / 双点遥信)
├─ 装置维护 ▶(时钟设置 / 强制复归 / 手动录波 / 清除记录)
├─ 通讯参数 ▶(通讯设置 / 网口设置 / SNTP设置)
└─ 记录查询 ▶(SOE记录 / 事故记录 / 操作记录 / 保护告警 / 保护启动 /
遥控记录 / 自检记录 / 运行记录 / 运行报告 / 录波回放)
三层代码架构:数据层 ui_menu_tab(生成物,g_menu_tab[43] 扁平父子索引表,≈0.7 KB Flash)
- 逻辑层
ui_menu(唯一 17 B 导航状态)+ 显示层ui_menu_view(持全部 LVGL 对象,零导航状态)。
导航模型:树形逐级进入——ENTER/→ 进入子页,ESC/← 返回上一级;页面 = 对表的一次
parent == 节点 过滤(现算不落地)。
显示模型:横向级联子框——每级一个框,子框左缘 = 父框右缘(共享 1px 边框列);子框顶边对齐父框
"选中行"行顶,溢出时整框上移使底边对齐选中行行底;选中行整行反色(白带黑字),菜单行带 ▶。
改菜单流程:编辑 ui_menu_tree.txt(缩进即层级)→ 重跑 tools/menu_gen/gen_menu.py → 导航/渲染代码零改动。
8.3 内容页
已绑 30 页(按分组;逐页形态见 docs/UI设计/页面补齐规划.md):
| 分组 | 页面 | 形态 |
|---|---|---|
| 装置信息 | 装置信息 | 静态键值行 6 行不分页;副标题"馈线自动化终端" |
| 实时数据 | 交流量 / 直流量 / 遥信量 | 数据列表(交流量 24 行 / 每页 8,共 3 页;直流量 3 行单页) |
| 参数定值 | 查看 4 页(参数 / 定值 / 控制字 / 软压板) | 只读列表 |
| 参数定值 | 整定 4 页(参数 / 定值 / 控制字 / 软压板) | 可编辑(写值 + 置脏 + 保存反馈) |
| 三遥设置 | 遥测死区 / 遥测系数 | 可编辑(运行参数段,0x8030~0x804F) |
| 装置维护 | 时钟设置 / 强制复归 / 清除记录 / 手动录波 | 操作页(执行类必须出真反馈,不得"点了没效果";手动录波触发后回读同一份计数,判据见 docs/子系统设计/故障录波设计说明.md §8.2) |
| 通讯参数 | 通讯设置 / 网口设置 | 可编辑([comm] / [network] 段,保存后按各自生效时机) |
| 记录查询 | SOE 记录 / 自检记录 / 运行记录 | 记录列表(共用 reader) |
| 记录查询 | 事故记录 / 操作记录 / 保护告警 / 保护启动 / 遥控记录 | 记录列表(每记录 2 行、空态显「无记录」;写入点与判据见 App/log/README.md §五类记录) |
| 记录查询 | 运行报告 | 只读列表 13 行分 2 页;四个数逐个挂范围标签(自电池周期 / 本次开机),跨开机累计按裁定不做 |
| 记录查询 | 录波回放 | 单通道波形页(阶梯线自绘、8 路切换、单位徽标、削顶标记、空态与不可读态显式文案);显示契约见 docs/子系统设计/故障录波设计说明.md §8.1 |
未绑 4 叶(2026-10-28:记录 5 页与运行报告页已落地绑页,原「当前执行 6 项」清零;2026-10-29: 录波道落地,「手动录波」叶子随之一并绑页): 遥信类型 / 遥信防抖 / 双点遥信 = 等开入硬件(§9.1.1「出口与开入」);SNTP 设置 = 等 SNTP 对时(§9.1.2「SNTP 对时」)。
- 内容页为独立全屏屏,由框架一次性自绘(零 LVGL 子对象),
ESC返回菜单屏。 - 菜单导航状态不压层,返回即原样还原;同一时刻至多一个内容页打开。
- 节点→页映射在逻辑层
menu_content_page_for(node);未绑叶子进入空白终点框(不伪造数据)。 - 数据供给走注入通道(rt / par / info / 遥测死区与系数第四表),页面不直接触算法层; 像素黄金用例当前 66 张(菜单 8 状态另计;2026-10-28 记录 5 页与运行报告 2 页落地 +7 张;2026-10-29 录波 UI 道 6 张:手动录波 3 态 + 录波回放 3 态)。
8.4 密码与权限
| 项 | 值 |
|---|---|
| 查看密码 | 000(授只读权限) |
| 修改密码 | 123(授修改权限) |
| 存储 | ui_pwd_def.h 编译期写入,不落 Flash |
| 流程 | 受保护叶子先 arm → 开密码页 → 确认一致后回调 → 先关页再续做进入动作(携授予权限) |
8.5 中文字体
- 字体
ui_font_cn_12.c:宋体 12px 1bpp 子集(当前 224 唯一字 / 319 字形,2026-10-29 实测; 122/217、179/274、185/280 均为历史快照。字形数 = 汉字/符号数 + ASCII 0x20~0x7E 共 95 个)。 - 生成流程:
tools/font_gen/extract_cn.py(扫 UI 源码 →ui_cn_chars.txt)→tools/font_gen/make_font.py。 - 约束:任何 UI 文案新增汉字后必须走此流程,否则显示为空白方块。
9. 复刻进度与路线图
口径:本章条目全部来自 §2.5.2 的 🔶 / ⬜ 行——即"参考源码有、本产品还没做或只做了一部分"。 "不做"一词在本章不出现:1:1 复刻口径下没有主动放弃的能力,只有尚未排期的能力。 唯二例外是 §2.5.7 标为"不适用"的两条(归一化值上送、主站 IP 白名单),那是协议语义决定, 不是范围裁剪。
命名:本节条目一律用语义短语(编号规范 P-8 语义优先),不发字母+数字号—— 避免与其它文档的
S/A/P编号族撞名。
9.1 复刻缺口总表
按缺口性质分两类:阻塞型(缺外部资源或硬件,排期无用)与规模型(无外部依赖,只等排期)。
本节是清单;§9.4~§9.12 是逐项明细——参考源码到底有哪几项、本产品有哪几项、 差额具体落在哪个定值 / 哪个点 / 哪个模块上、以及"怎么算做完了"。排期与估算以明细为准。
9.1.1 阻塞型(等外部条件,排期不能解决)
| 条目 | 对应 §2.5.2 | 现状 | 缺的是 | 解除条件 |
|---|---|---|---|---|
| 标定闭锁 | 1~3 | 9 个元件、定值、闭锁链、SOE、104 上送全部就绪,但 ADC_CAL_F_VALID 未置位 → 判据整体停走 |
外部资源:子板/端子板变比 + 标准源 | 端子变比确认 → 8 通道两点标定 → VALID 置位(届时自动解卡,无需改代码) |
| 出口与开入 | 7、8 | 无硬件;保护动作只体现为遥信 + SOE;遥控开关量否定确认 | 硬件 + 立项:出口继电器、开入回路、回读自检 | 开入开出作为独立模块立项(不可移植项 X3 解除) |
| 三相与同期 | 4、12 | 建接口不使能(B/C 相与 IN 削顶、跨转换器无同刻) |
V0.2 硬件 | 8 路电气量全接 TPAFE + 中点偏置 |
| 电度计量 | 6 | 未实现(功率积分需跨转换器同刻) | V0.2 硬件 | 同上(不可移植项 X4 解除) |
| 对下采集 | 17(子站侧) | rs485_task.c 空桩、未建任务、协议族未实现;整簇冻结 |
决策 + 门禁:用户已决定暂缓 | 先修「单缓冲包撕裂」「TX 超时拉 DE 未等 TC」→ 接消费者 |
| 第三方送检 | 17 | 自有主站工具往返已通过 | 标定 + 第三方环境 | 标定闭锁解除后送检 |
9.1.2 规模型(无外部依赖,只等排期)
| 条目 | 对应 §2.5.2 | 参考 | 现状 | 差额 |
|---|---|---|---|---|
| 定值铺开 | 1、2 | 249 项 / 23 单元 | 40 项(覆盖参考 35 + 本地 5)/ 5 组 | +214 项 / +18 单元 |
| 映射铺开 | 3 | 107 项 0x8820~0x8891 |
40 项局部 | +67 项 |
| 元件铺开 | 12 | 45 个模块 | 8 个模块 / 9 个实例 | +37 个模块(过流类 6 / 电压类 5 / 重合闸 5 / 方向功率 4 / 涌流故障 5 / 自动控制 5 / 记录 5 / 录波采样 2) |
| 遥测铺开 | 4、5 | 31 点 + 模型 35 行 | 9 点 | +22 点 + 模型表 |
| 录波子系统 | 10、15 | 3 类型 / 6 段 / 65 通道 / RAM 16 个 / COMTRADE 64·64·16 | 最小闭环代码面已交付(2026-10-29):1 kHz / 8 路原始码值 / 单段 320 点 / 轮转段文件 / 手动与保护启动 / 单通道回放页;板级判据一轮未跑 | 仍差 4 kHz 全速与 80 点/周波、多段与 65 通道、COMTRADE、104 文件传输;口径偏离登记见 docs/子系统设计/故障录波设计说明.md §2 |
| 记录体系 | 9、13 | 13 类队列(128/256 条) | 8 类 | +5 类(越限 / 闭锁 / COS / 顺控 / 顺控执行) |
| UI 记录页 | 9、13 | 参考有完整记录页与运行报告 | 六页已绑并纳入像素黄金回归(2026-10-28) | 只剩真机判据(docs/任务规划/登记簿.md §7) |
| 多规约栈 | 17 | 12 种 | 1 种(104) | +11 种(101 / 102 / 103 / CDT / ModBus / Whm_GB / 61850 / CAN + 子站侧 3 类) |
| 国密算法 | 18 | Comm/Ecc/ 全套 |
0 | SM2 / SM3 / ECDSA |
| 软压板铺开 | 11 | 9 面(表容量 32) | 1 面 | +8 面 |
| SNTP 对时 | 17 | 参考对时走 SNTP | 私有 TCP 8888 + 104 C_CS |
SNTP 客户端 |
| 固有参数 | 1 | 8001H~800AH 字符串类参数 |
未实现(无法短浮点上送) | 随送检点表设计 |
| 遥测增强 | 4、5 | k=1~9 谐波方和根 + 4 点平均 | 仅基波轨 | 谐波 / 等周波调频 / 零序自产外接切换 三条算法轨 |
| 屏板链路对齐 | 20 | 串口屏板通道(700000 8N1 / USART1 TTL 直连、无 DE,帧 A 6 B 召唤、帧 B 4208 B 应答:显存 3200 B + 状态灯 4 B 位掩码 + 4 B info)+ 7003 四命令(INIT 16 B,单色口径)+ 续传 / 拒绝握手 / 链路监视 / F1·F2 | 只有 7003 四命令(INIT 8 B);串口通道 0;无状态灯下行;无续传、无 bNeedFlash 拒绝、无 1 分钟监视、键值 6 个 |
串口通道整条(协议已定版)+ 7003 报文口径 6 项(明细见 §9.13) |
一句话:「标定闭锁」是唯一"再排期也没用"的缺口(等标准源);「出口与开入」「三相与同期」 「电度计量」等 V0.2 硬件;「对下采集」等用户决策;其余规模型条目全部可在现有硬件上推进, 只取决于排期。 这张表与
docs/任务规划/登记簿.md一一对应;状态只在登记簿维护, 本节不另建状态。
9.2 推进顺序
顺序唯一权威 →
docs/任务规划/README.md§2.0(本表只是产品视角摘要, 冲突时以该节为准)。
| 顺序 | 工作 | 类别 | 当前状态 | 开始条件 |
|---|---|---|---|---|
| 1 | UI 补齐(记录 5 页 → 运行报告) | 规模型 | 清单已清空(2026-10-28) | 六页已落地;余 4 叶属不做项(手动录波与录波回放两叶已随录波道绑页),重开条件见 docs/任务规划/UI补齐.md §5 |
| 2 | net 层跨上下文收口 | 平台 | 下一顺位(未开工) | UI 清单已清空,切换条件已满足;开工待用户点头 |
| 3 | 其余结构与可靠性评估 | 平台 | 排队 | net 收口后 |
| 4 | 端子/子板变比确认 → 两点标定 | 阻塞型 | 等外部资源 | 子板实物/原理图、标准源到位可插入 |
| 5 | 标准源送检与第三方 104 主站验收 | 阻塞型 | 等标定 | 保护 VALID 置位;送检窗口前 2 日冻结特性 |
| 6 | 定值铺开 / 映射铺开 / 遥测铺开 / 软压板铺开 | 规模型 | 等排期 | 标定后(工程量才有意义) |
| 7 | 元件铺开与遥测增强 | 规模型 | 等标准源/硬件 | 先解除未标定闭锁;三相类等 V0.2 |
| 8 | 录波子系统 → 记录体系 → 多规约栈 | 规模型 | 录波最小闭环已提前插入并交付代码面(用户裁定 2026-10-29 录波先行,见 docs/任务规划/故障录波.md);本行剩下的参考机完整形态(多段 / 65 通道 / COMTRADE / 104 文件传输)仍不排 | 各自重启条件 |
| 9 | 验证窗口事项(CI 远端、PC peer、负向注入) | 平台 | 逢条件顺带 | 条件到位即执行 |
| 10 | 出口与开入 / 三相与同期 / 电度计量 / 对下采集 | 阻塞型 | 不排 | V0.2 硬件 / 用户决策 |
不可颠倒的顺序(一):变比确认 → 两点标定 → 保护解卡 → 送检。未完成标定就送检, 保护表现为不动作;保持该闭锁,不用非标准源走捷径(用户裁定,2026-10-25)。
不可颠倒的顺序(二):点表铺开必须晚于标定——否则铺出去的全是 IV 点, 主站无法区分"没做"与"接线错",比不铺更糟。
9.3 未接线开关说明
| 开关 | 位置 | 现状 |
|---|---|---|
| 功能裁剪开关 | App/app/app_cfg.h(当前无宏) |
没有任何生效的裁剪开关:原三个 APP_*_ENABLE 占位宏因全库零消费点已于 2026-10-22 删除,各模块一律编译进产品——ADC / RS-485 均为必需链路(ADC = 遥测/保护来源,RS-485 = 对下 ModBus RTU 采集)。将来确需裁剪时在真实初始化点接入门控,并同步登记回该文件 |
TEST_SUITE_* |
test/board/test_config.h |
测试套件互斥,一次构建只开一个;全注释 = 正常产品固件 |
rs485_task.c |
App/task/(未建任务、白名单登记) |
唯一的结构白名单缺口:RS-485 整簇冻结期间刻意不接线,随该簇一并出白名单 |
DTU_BENCH |
构建宏(protect_task.c 等) |
台架构建下允许保护判据在未标定时动作(仅测试用);产品构建(#ifndef DTU_BENCH)下保护闭锁 |
9.4 定值复刻明细(参考 249 项 → 本产品 40 项)
参考定值表的每一行固定 21 个字段:标识 ×2 / 类型(数值 | 枚举)/ 所属单元 / 单位组 / 值类型 /
最小值 / 最大值 / 步长 / 两个标志 / 上下限原始值 ×3(0xAA / 0xAAAA / 0xFF)/ 104 地址 /
单位 ×2 / 小数位 / 长度 / 显示名 / 结束标记。
本产品对应物是 App/algo/prot_set.h 的 PS_* 枚举(PS_ID_COUNT = 40)。
40 项的去向必须能对上账,否则"还差多少"无从谈起:
| 去向 | 项数 |
|---|---|
| 覆盖参考定值项 | 35 |
| 本产品本地扩展项(参考无对应行) | 5(PS_RET_OVER / PS_RET_UNDER 返回系数,PS_RET_OF / PS_RET_UF 频率返回系数,PS_GLOBAL_EN 全局软压板) |
| 合计 | 40 |
因此定值差额 = 249 − 35 = 214 项。
9.4.1 23 个定值单元逐单元差额
| 单元 | 语义 | 参考项数 | 本产品覆盖 | 差额 |
|---|---|---|---|---|
WatchDog |
过流三段 / 零序三段 / 过负荷 / 重载 / 过载 / 过频 / 低频 | 63 | 22 | 41 |
SYS3 |
系统参数(零飘、死区、变比、防抖、脉宽、FA 模式…) | 45 | 0 | 45 |
VolTimeRecv |
电压时间型馈线自动化(失电分闸 / 得电合闸 / 联络) | 17 | 0 | 17 |
AutoReCls |
重合闸 | 16 | 0 | 16 |
SYN |
同期(FTU 型) | 13 | 0 | 13 |
OverCurI0 |
接地告警(小电流接地选线) | 13 | 0 | 13 |
VolPro |
电压保护(失压 / 过压 / 零序过压) | 13 | 9 | 4 |
WAVESTART |
录波启动 | 12 | 0 | 12 |
MeaLimit |
遥测越限 | 10 | 0 | 10 |
OverCurSpeed |
过流 / 零序后加速 | 8 | 0 | 8 |
SYS1 |
PT 参数 | 6 | 2 | 4 |
SYS2 |
CT 参数 | 4 | 2 | 2 |
Auto_FG |
延时自动分闸 | 4 | 0 | 4 |
Auto_HH |
延时自动合闸(电池活化) | 4 | 0 | 4 |
InRush |
励磁涌流闭锁 | 3 | 0 | 3 |
OverCur |
短路告警 | 3 | 0 | 3 |
VolQuaRate |
电压合格率 | 3 | 0 | 3 |
FZDDL |
非遮断电流闭锁 | 3 | 0 | 3 |
BHKO |
保护出口展宽 | 2 | 0 | 2 |
MeaRecord |
遥测记录周期 | 2 | 0 | 2 |
PowerSet |
功率电压组 | 2 | 0 | 2 |
PTBreak |
PT / 控回断线告警 | 2 | 0 | 2 |
AutoCtrl |
自动复归 | 1 | 0 | 1 |
| 合计 | 249 | 35 | 214 |
单元名
WatchDog有误导性:它装的是全部保护元件的动作定值(过流 / 零序 / 负荷 / 频率), 不是看门狗参数。移植时不要按名字去找"看门狗定值"。
9.4.2 已覆盖单元的逐项对照(35 项)
过流三段:参考 24 项,本产品 12 项(每段缺 4 项,共缺 12)
| 参考项(Ⅰ/Ⅱ/Ⅲ 段各一份) | 本产品 | 说明 |
|---|---|---|
| 过流 n 段投入 | PS_OCn_EN |
✅ |
| 过流 n 段跳闸投入 | PS_OCn_TRIP |
✅ 语义 = 0 告警 / 1 跳闸 |
| 过流 n 段定值 | PS_OCn_CUR |
✅ 二次值 A |
| 过流 n 段延时 | PS_OCn_DLY |
✅ ms(参考为 S,换算在整定入口) |
| 过流 n 段方向投入 | — | ❌ 无方向元件(DirCell / PowDirJudge 未复刻) |
| 过流 n 段低压投入 | — | ❌ 无复压闭锁(bNOVOpen 无来源) |
| 过流 n 段告警投入 | — | ❌ 参考把"告警投退"与"跳闸投退"拆成两项,本产品只有一项 |
| 过流 n 段低压定值 | — | ❌ 同上 |
这一处差额最容易被低估:本产品的三段过流是"简化版三段",参考的三段每段还带 方向 / 低压 / 告警 三个独立开关和一个低压定值。缺这四项时,三段过流只能做无方向、 无复压闭锁的纯过流保护——在环网或双电源线路上会误动。
零序过流三段:参考 18 项,本产品 0 项
参考在 WatchDog 内另有完整的零序三段(每段 6 项:投退 / 方向 / 告警投入 / 跳闸 / 定值 / 时限)。
本产品 PS_3U0_* 三项是零序过压(属 VolPro),不是零序过流——两者不可混为一谈:
零序过流看 3I0 幅值,零序过压看 3U0 幅值。因此零序过流保护目前完全没有定值载体,
OverCurrent_I0 元件也无从判据。
过负荷 / 重载 / 过载:参考 12 项,本产品 4 项
| 参考项组 | 本产品 | 差额 |
|---|---|---|
| 过负荷报警(投退 / 跳闸 / 定值 / 时限) | PS_OL_* 4 项 |
✅ 齐 |
| 重载报警(同上 4 项) | — | ❌ 缺 4 |
| 过载报警(同上 4 项) | — | ❌ 缺 4 |
参考把"过负荷 / 重载 / 过载"分成三级(默认 150 A / 70 A / 100 A 步长,时限 9000 s / 0 / 0), 对应事件 435 / 436 / 437。本产品只有一级过负荷。三级是同一判据不同门槛, 复刻成本低(元件框架已具备),但需先补
OverLoad的三个实例与三条事件映射。
过频 / 低频:参考 8 项,本产品 6 项 + 2 本地项
| 参考项 | 本产品 | 说明 |
|---|---|---|
| 过频 / 低频 保护投退 | PS_OF_EN / PS_UF_EN |
✅ |
| 过频 / 低频 保护定值 | PS_OF_HZ / PS_UF_HZ |
✅ 参考单位 HZ 存 5000~5500(0.01 Hz),本产品存 Hz 浮点 |
| 过频 / 低频 保护时限 | PS_OF_DLY / PS_UF_DLY |
✅ |
| 过频 / 低频 跳闸投退 | — | ❌ 缺 2:参考区分"保护投入"与"跳闸投入",本产品只有前者 |
电压保护:参考 13 项,本产品 9 项
| 参考项 | 本产品 | 说明 |
|---|---|---|
| 失压保护投退 / 定值 / 时限 | PS_UV_EN / PS_UV_VOL / PS_UV_DLY |
✅ |
| 过压保护投退 / 定值 / 时限 | PS_OV_EN / PS_OV_VOL / PS_OV_DLY |
✅ |
| 零序过压投退 / 定值 / 时限 | PS_3U0_EN / PS_3U0_VOL / PS_3U0_DLY |
✅ |
| 失压 / 过压 / 零压 跳闸投退(3 项) | — | ❌ 缺 3 |
| 零压 告警投退(1 项) | — | ❌ 缺 1 |
PT / CT 参数:参考 10 项,本产品 4 项
| 参考项 | 本产品 | 说明 |
|---|---|---|
| 母线一次额定(kV) | PS_PT_PRI |
✅ 本产品存 V |
| 母线二次额定(线)(V) | PS_PT_SEC |
✅ |
| 额定 TA 一次值(A) | PS_CT_PRI |
✅ |
| 额定 TA 二次值(A) | PS_CT_SEC |
✅ |
| 母线二次额定(相)(V) | — | ❌ 缺:线 / 相两种二次额定的换算关系需显式给出 |
| 零序一次额定(kV) | — | ❌ 缺 |
| 零序二次额定(V) | — | ❌ 缺 |
| 零序一次额定(A) | — | ❌ 缺 |
| 零序二次额定(A) | — | ❌ 缺 |
| PT 接入数目(1~3) | — | ❌ 缺:决定用线电压还是相电压作判据源 |
9.4.3 完全未覆盖单元逐项清单(163 项)
214 项差额中,51 项落在 §9.4.2 已部分覆盖的四个单元里(过流 12 / 零序 18 / 重载与过载 8 / 频率 2 / 电压 4 / PT·CT 6 / 备用控制字 1),余下 163 项落在下面这些一项都没有的单元里。 逐项列出以便排期时按"整单元"认领,不要拆散。
系统参数 SYS3(45 项)——零飘门槛 10 项:额定电压零飘门槛、额定电流零飘门槛、直流电压零飘、
功率零飘、频率零飘、功率因数零飘、相角零飘门槛、备用 ×4;死区 7 项:电流死区、电压死区、
直流电压死区、功率死区、频率死区、功率因数死区、相角死区;开入开出 4 项:开入防抖(1060000 ms)、
分闸脉宽、合闸脉宽、开入手动分合;变比 5 项:PT 变比、相 CT 变比、零序 CT 变比、功率变比、电量变比;
其余 19 项:开关类型、故障遥信保持时间、功率置负、单项接地选线投入、单相接地跳闸时间、FA 模式、
对时切换长延时、断线告警确认时间、事故总判小电流接地告警、加速段保护开放时间、
重合闸检有压等待时间、连续分闸时间、分闸次数、备用参数 0108。
本产品的死区落在运行参数段(
0x8030~0x8038九点,RAM 副本 + 104 可写), 变比落在prot_set的 PT/CT 四项。语义已覆盖、载体不同——复刻SYS3时是把这 两类合并进定值表,不是重新实现。
电压时间型自愈 VolTimeRecv(17 项):就地 FA 模式、LS(0/1,1 = 联络)、
失电分闸投退、失电分闸时限(0100000 s)、得电合闸投退、X 时间(1100 s,默认 7)、
故障电流检测、故障电流定值(110000 A)、Y 时间(1100 s,默认 5)、联络开关合闸、
联络充电时限(01800 s)、联络合闸时限(0300 s)、正方向选择、残压定值(0300 V)、
残压判定时限、停电时间(110 s)、人工闭锁。
这是馈线自动化(FA)的核心:失电分闸 → 得电合闸 → 联络转供。对应元件
NoVolTrip/HaveVolCls/ConnectBrkCls/FaultIsola/FaultRecov五个模块。 无开入(开关位置)与出口(分合闸)时无法闭环,属 X3 依赖项。
重合闸 AutoReCls(16 项):重合闸投退、充电时间(0100000 s)、重合闸次数(03)、
一次 / 二次 / 三次重合闸时间(060000 s)、重合闸闭锁时间(09900 s)、整组复归时间、
大电流闭锁投退、大电流闭锁定值、重合闸检同期、重合闸检无压、同期检无压定值(015000 V)、
同期检角差定值(130°)、过流禁止重合闸、零序禁止重合闸。
参考支持三次重合且每次时间独立可整定,充电时间与整组复归时间分离——这三项 是"重合闸能不能用"的关键(无充电时间 = 每次跳闸都立即重合,会连击)。 依赖出口(合闸)与开入(开关位置),属 X3 依赖项。
同期 SYN(13 项,FTU 型专属):检无压投退、检同期投退、频差 / 角差 / 压差 / 滑差闭锁投退
(4 项)、检无压定值(10009999 V)、检频差定值(0200,0.01 Hz)、检角差定值(1180°)、
检压差定值(09999 V)、检频率滑差值(0200 Hz/s)、开关合闸时限(0200 s)、整组复归时间。
需两路电压同刻(母线侧 + 线路侧)才能算角差与频差——本产品 V0.1 只有一个转换器的 电压通道,属 X3 / H1 依赖项。
录波启动 WAVESTART(12 项):电流启动投退 / 定值(010000 A)、低压启动投退 / 定值
(010000 V)、零压启动投退 / 定值(030000 V)、零流启动投退 / 定值(01000 A)、
零流突变投退 / 定值(0~1000 A)、录波启动延时、保护启动录波。
录波启动是独立于保护判据的触发源:即使保护不动作,只要越启动值也要录波。 本产品无录波子系统,这 12 项无处落地(见 §9.9)。
遥测越限 MeaLimit(10 项):有压鉴别投退 / 线路有压定值(0300 V)、无压鉴别投退 /
线路无压定值(0300 V)、线路有压时限(2100000 s)、电压越上限 / 越下限(0100000 V)、
电流越上限(0~10000 A)、越上限延时 / 越下限延时。
越限记录(
OVER队列,128 条)的判据来源。本产品无越限记录类,故这 10 项也无载体。
过流后加速 OverCurSpeed(8 项):后加速投退、线路 1 前加速投退、过流后加速电流值
(110000 A)、过流后加速时限(010000 s)、零序后加速投退、线路 1 前加速投退(重复项,
参考源码如此)、零序后加速电流值(1~1000 A)、零序后加速时限。
接地告警 OverCurI0(13 项):线路接地告警投退、零序电流反极性、零序电压反极性、
接地备用 02、接地告警投退、接地跳闸投退、接地方向投退、接地定值(010000 A)、接地时限、
接地跳闸时限(0600 s)、零压启动定值(1~10000 V)、接地重合投退、接地后加速投退。
反极性两项是现场接线纠错开关(CT / PT 装反时不必改线,改定值即可), 属"现场可维护性"需求,不是可选项。
其余小单元(合计 29 项):励磁涌流闭锁 3(闭锁投退、涌流制动系数 1100、闭锁复归时间);
短路告警 3(投退 / 时限 / 线路 01 短路电流定值);电压合格率 3(上限 / 下限定值 0200 %、周期类型 04);
非遮断电流闭锁 3(电流闭锁投退、停电跳闸投退、非遮断电流值 110000 A);
出口展宽 2(跳闸出口时间、合闸出口时间,1100000 ms);
遥测记录 2(遥测记录周期 02880、极值记录周期 0360);
功率电压组 2(14 组);PT 断线 2(断线告警、控回断线告警);自动复归 1(自动复归投退);
延时自动分闸 4(延时复归投退、2:时 1:分 0:秒、延时复归时限 ×2);
延时自动合闸 4(自动活化投退、2:分 1:时 0:日、自动活化周期 0360、自动活化时限 023000 s)。
9.5 遥测复刻明细(参考 31 点 → 本产品 9 点)
参考 g_tYcIndexTab 的 31 点是按"两回线 × 三相 + 线电压 + 零序 + 功率"组织的完整电气量集。
本产品 9 点(0x4011~0x4018、0x401D)只覆盖第一回线的相量与频率。
| # | 参考遥测 | 参考枚举 | 本产品 | 差额原因 |
|---|---|---|---|---|
| 1 | 1 回 A 相电流 | EN_YCMEA_IA01 |
0x4015 ✅ |
|
| 2 | 1 回 B 相电流 | EN_YCMEA_IB01 |
0x4016 ✅ |
削顶 → 恒 IV |
| 3 | 1 回 C 相电流 | EN_YCMEA_IC01 |
0x4017 ✅ |
削顶 → 恒 IV |
| 4 | 2 回 A 相电流 | EN_YCMEA_IA02 |
— | ❌ 无第二回线 |
| 5 | 2 回 B 相电流 | EN_YCMEA_IB02 |
— | ❌ |
| 6 | 2 回 C 相电流 | EN_YCMEA_IC02 |
— | ❌ |
| 7 | 1 回 A 相电压 | EN_YCMEA_UA1 |
0x4011 ✅ |
|
| 8 | 1 回 B 相电压 | EN_YCMEA_UB1 |
0x4012 ✅ |
削顶 → 恒 IV |
| 9 | 1 回 C 相电压 | EN_YCMEA_UC1 |
0x4013 ✅ |
削顶 → 恒 IV |
| 10 | 2 回 A 相电压 | EN_YCMEA_UA2 |
— | ❌ |
| 11 | 2 回 B 相电压 | EN_YCMEA_UB2 |
— | ❌ |
| 12 | 2 回 C 相电压 | EN_YCMEA_UC2 |
— | ❌ |
| 13 | 1 回 AB 线电压 | EN_YCMEA_UAB1 |
— | ❌ 需两相相量之差 |
| 14 | 1 回 BC 线电压 | EN_YCMEA_UBC1 |
— | ❌ |
| 15 | 1 回 CA 线电压 | EN_YCMEA_UCA1 |
— | ❌ |
| 16 | 2 回 AB 线电压 | EN_YCMEA_UAB2 |
— | ❌ |
| 17 | 2 回 BC 线电压 | EN_YCMEA_UBC2 |
— | ❌ |
| 18 | 2 回 CA 线电压 | EN_YCMEA_UCA2 |
— | ❌ |
| 19 | 1 回零序电流 | EN_YCMEA_3I01 |
0x4018 ✅ |
近似对齐(本产品为外部零序通道) |
| 20 | 1 回零序电压 | EN_YCMEA_3U01 |
0x4014 ✅ |
近似对齐 |
| 21 | 2 回零序电压 | EN_YCMEA_3U02 |
— | ❌ |
| 22 | 频率 | EN_YCMEA_FR1 |
0x401D ✅ |
|
| 23 | 直流 1 | EN_YCMEA_DC_01 |
— | ❌ 无直流采样通道 |
| 24 | 直流 2 | EN_YCMEA_DC_02 |
— | ❌ |
| 25 | A 相有功 | EN_YCMEA_PA_1 |
— | ❌ 需跨转换器同刻(H1) |
| 26 | B 相有功 | EN_YCMEA_PB_1 |
— | ❌ |
| 27 | C 相有功 | EN_YCMEA_PC_1 |
— | ❌ |
| 28 | 总有功 | EN_YCMEA_P_1 |
— | ❌ |
| 29 | 总无功 | EN_YCMEA_Q_1 |
— | ❌ |
| 30 | 总视在 | EN_YCMEA_S_1 |
— | ❌ |
| 31 | 功率因数 | EN_YCMEA_COS_1 |
— | ❌ |
缺的 22 点按依赖分三批:
| 批次 | 点数 | 内容 | 依赖 |
|---|---|---|---|
| 线电压与功率 | 13 | 6 线电压 + 7 功率/功率因数 | H1:电压在 TPAFE、电流在 STM32 ADC1,无共同触发,功率的 U×I 需同刻 |
| 第二回线 | 7 | 2 回 6 相量 + 3U02 |
采样通道数(V0.2 硬件) |
| 直流 | 2 | DC_01 / DC_02 |
无直流采样通道 |
线电压本身不一定要等 H1:
Uab = Ua − Ub只需同一转换器内的两相相量, 若两相都落在 TPAFE 侧即可算。当前Ub/Uc削顶(在 STM32 侧),所以连带算不出。 先解决"三相电压全落 TPAFE"这一件事,能一次解锁 6 个线电压点。
遥测模型 g_tAnaModelTab(35 行):参考为每个遥测点定义死区、变比、系数、越限档等属性行,
是"点表 + 整定"的合体。本产品的对应物拆成了三处:iec104_pts.c 的 YC 表(地址 + 死区系数)、
run_par.c 的死区九点、adc_cal.c 的 k/b。复刻模型表 = 把这三处收敛成一张可整定的表。
电度 g_tYmIndexTab(8 种,本产品 0):正向有功 Pt1、正向无功 Qt1、Q1 象限、Q4 象限、
反向有功 Pt0、反向无功 Qt0、Q2 象限、Q3 象限。地址段 0x6401~0x6600。
电度 = 功率对时间积分,与功率同批解锁(同一 H1 依赖)。
9.6 开入 / 开出复刻明细(138 + 31 → 本产品 0)
参考把"开入"分成四类,本产品一个都没有(无硬件,不可移植项 X3)。
开入 138 点的构成:
| 类别 | 点数 | 含义 |
|---|---|---|
软遥信 EN_KI_SOFTYX_* |
104 | 由保护元件/逻辑产生的内部状态,不占物理端子(如"过流Ⅰ段动作""重合闸充电完成""FA 投入") |
硬件开入 EN_KI_* / EN_KIA_* |
27 | 物理端子:开关合位 / 分位 / 未储能 / 就地远方 / 接地位置 / 隔离位置 / 停用重合闸 / 保护投入 / 检修压板 / 远方信号 / 就地 FTU 手合手分 / 电源输入 / 活化状态 / 电池欠压 / 活化投入 |
双点遥信 EN_KI_TWIN_YX_* |
6 | 开关位置用双点表达(00 中间态 / 01 分 / 10 合 / 11 无效) |
多态遥信 EN_KI_INT8U_* |
1 | 8 位状态量(如"设备状态"枚举) |
104 点 ≠ 104 个端子。真正要接线的是 27 个硬件开入;104 个软遥信是元件输出, 只要元件复刻出来就自然存在。这个区分决定了工作量估算:不是"买 138 路开入板", 而是"27 路端子 + 104 个元件状态映射"。
开出 31 点的构成:
| 类别 | 点数 | 明细 |
|---|---|---|
| 出口类 | 11 | 保跳 1(BH_TZ1)、保合 1(BH_HZ1)、遥分 1(YT01)、遥合 1(YH01)、遥分 2(YT02)、遥合 2(YH02)、电池活化(DCHH)、活化退出(DCHH_Esc)、信号复归(FG)、开入变位(KICHANGE)、录波启动(WAVE_START) |
| 信号类 | 20 | 事故信号 SignTV、运行 SignRun、通信中断 SignCOMM、硬件故障 SignHW、储能 SignCN、电池欠压 SignBatQY、失电 SignSD、过负荷 SignGL、接地 SignJD、闭锁 SignBM、备用 SignBS、自检 SignCHK、重合 SignCH、备用 3 个 SignBAK1~3、告警 SignALM、保护动作 SignPro、就地 FA SignJDFA、集中 FA SignJZFA |
本产品当前保护动作只体现为遥信 + SOE,没有任何物理出口。这在"保护测控装置"的 定义里是硬缺口:保护判据做得再准,不跳闸就等于没保护。X3 解除前,
YX里的 动作类遥信必须如实标 IV,不能让主站误以为已跳闸。
9.7 动作事件复刻明细(参考 33 条 → 本产品 9 条)
参考 g_tActRecTab 的 33 条动作事件编号 421~453,是"保护动作 → 事件码 → 记录 → 上送"的
中间层。本产品用 App/log/sys_log.h 的七类记录 + SOE,没有事件码表。
| 事件码 | 参考事件 | 本产品 | 说明 |
|---|---|---|---|
| 421 | 线路励磁涌流闭锁 | ❌ | InRushCur 未复刻 |
| 422 | 线路Ⅰ段过流保护动作 | ✅ | PS_OC1_* |
| 423 | 线路Ⅱ段过流保护动作 | ✅ | PS_OC2_* |
| 424 | 线路Ⅲ段过流保护动作 | ✅ | PS_OC3_* |
| 425 | 线路零序Ⅰ段过流保护动作 | ❌ | 无零序过流定值载体 |
| 426 | 线路零序Ⅱ段过流保护动作 | ❌ | 同上 |
| 427 | 线路零序Ⅲ段过流保护动作 | ❌ | 同上 |
| 428 | 线路后加速保护动作(过流) | ❌ | OverCurrent_SpeedUp 未复刻 |
| 429 | 线路后加速保护动作(零序) | ❌ | OverCurrentI0_SpeedUp 未复刻 |
| 430 | 零序过压保护动作 | ✅ | PS_3U0_* |
| 431 | 线路欠压保护动作 | ✅ | PS_UV_* |
| 432 | 线路过压保护动作 | ✅ | PS_OV_* |
| 433 | 高频保护动作(过频) | ✅ | PS_OF_* |
| 434 | 低频保护动作 | ✅ | PS_UF_* |
| 435 | 线路过负荷保护动作 | ✅ | PS_OL_* |
| 436 | 线路重载保护动作 | ❌ | 三级负荷只做了一级 |
| 437 | 线路过载保护动作 | ❌ | 同上 |
| 438 | 线路接地保护动作 | ❌ | OverCurI0 未复刻 |
| 439 | 一次重合动作 | ❌ | 重合闸未复刻 |
| 440 | 二次重合动作 | ❌ | 同上 |
| 441 | 三次重合动作 | ❌ | 同上 |
| 442 | 接地重合动作 | ❌ | 同上 |
| 443 | 接地后加速动作 | ❌ | 同上 |
| 444 | 失电分闸动作 | ❌ | NoVolTrip 未复刻 |
| 445 | 得电合闸动作 | ❌ | HaveVolCls 未复刻 |
| 446 | 闭锁合闸动作 | ❌ | 需开入(闭锁压板) |
| 447 | 闭锁分闸动作 | ❌ | 同上 |
| 448 | 联络开关合闸动作 | ❌ | ConnectBrkCls 未复刻 |
| 449 | 联络开关分闸动作 | ❌ | 同上 |
| 450 | 保护动作备用 02 | — | 参考即备用 |
| 451 | A 相故障 | ❌ | 需分相判别(三相全接) |
| 452 | B 相故障 | ❌ | 同上 |
| 453 | C 相故障 | ❌ | 同上 |
本产品覆盖 9 / 33 条。注意 428 与 429 在参考源码里同名(都叫"线路后加速保护动作"), 靠事件码区分过流与零序——移植时不能按名字去重。
���件码缺失的连带后果:事故报告(
CN_NUM_QUE_REC_RPT队列)无法生成。 参考的事故报告是按事件码索引动作时序的,没有事件码表就没有"保护动作报告"这一页。
9.8 保护元件复刻明细(参考 45 个模块 → 本产品 8 个)
模块级口径:参考 RelayUnit/ 45 个 .c 文件 = 45 个元件模块。本产品覆盖 8 个模块
(7 个判据模块 + 1 个记录模块),以 9 个实例落地(OverCurrent 一个模块出三段实例)。
| 类别 | 参考模块 | 本产品 | 缺 |
|---|---|---|---|
| 过流类 | 8 | 2(OverCurrent、OverLoad) |
6 |
| 电压类 | 8 | 3(OverVol、OverVol_U0、LackVol) |
5 |
| 频率类 | 2 | 2(OverFr、LackFr) |
0 |
| 重合闸 | 5 | 0 | 5 |
| 方向 / 功率 | 4 | 0 | 4 |
| 涌流 / 故障 | 5 | 0 | 5 |
| 自动控制 | 5 | 0 | 5 |
| 记录类 | 6 | 1(SOERecord) |
5 |
| 录波 / 采样 | 2 | 0 | 2 |
| 合计 | 45 | 8 | 37 |
缺的 37 个模块,逐个给出"缺它意味着什么":
| 模块 | 类别 | 判据要点 | 缺它的后果 | 依赖 |
|---|---|---|---|---|
OverCurrent_I0 |
过流 | 零序电流三段 + 方向 | 接地故障无保护 | 定值载体(零序 18 项) |
OverCurrent_SpeedUp |
过流 | 后加速:重合后短延时无选择跳闸 | 重合于故障时靠 Ⅰ 段延时切除,慢一拍 | 重合闸 |
OverCurrentI0_SpeedUp |
过流 | 零序后加速 | 同上(接地) | 重合闸 |
FZDOverCur |
过流 | 非遮断电流闭锁(负荷电流以下不允许跳闸) | 小电流跳闸可能拉弧不熄 | 定值 3 项 |
OverCurWarn |
过流 | 过流告警(只告警不跳闸) | 过流只能跳不能告警 | 定值(告警投入) |
OverCurWarn_I0 |
过流 | 零序过流告警 | 同上 | 定值 |
LineHaveVol |
电压 | 线路有压鉴别 | 无法区分"有压合闸"与"无压合闸" | 定值(MeaLimit 有压鉴别) |
HaveVolCls |
电压 | 得电合闸 | FA 的"来电自动合闸"缺失 | 开入 + 出口 |
NoVolTrip |
电压 | 失电分闸 | FA 的"失电自动分闸"缺失 | 开入 + 出口 |
PTBreak |
电压 | PT 断线(电压消失但电流正常) | 断线时电压类保护可能误动/拒动 | 定值 2 项 |
CTBreak |
电压 | CT 断线 | 同上(电流侧) | 定值 |
AutoReCls |
重合闸 | 充电 → 跳闸 → 延时重合 → 整组复归 | 瞬时故障必须人工合闸 | 开入 + 出口 + 16 项定值 |
AutoReCls_JD |
重合闸 | 接地故障重合 | 同上(接地) | 同上 |
OnceCch |
重合闸 | 一次重合(表内无定值,条件编译) | — | 同上 |
TwiceCch |
重合闸 | 二次重合(表内无定值,条件编译) | — | 同上 |
ConnectBrkCls |
重合闸 | 联络开关合闸(转供) | 环网无法转供 | 开入 + 出口 + 17 项定值 |
DirCell |
方向 / 功率 | 方向元件(功率方向判别) | 双电源/环网会反送电误动 | 三相电压 + 三相电流同刻(H1) |
PowDirJudge |
方向 / 功率 | 功率方向(有功/无功象限) | 同上 | 同上 |
PowerSet |
方向 / 功率 | 功率电压组切换(1~4 组) | 多组 PT/CT 变比无法切换 | 定值 2 项 |
YcOverLimit |
方向 / 功率 | 遥测越限判据 | 越限记录无来源 | 定值(MeaLimit 10 项) |
InRushCur |
涌流 / 故障 | 二次谐波制动(励磁涌流闭锁) | 变压器空投时过流误动 | 谐波算法(见 §9.12 遥测增强) |
FaultIsola |
涌流 / 故障 | 故障隔离 | FA 无法定位故障区段 | 开入 + 出口 |
FaultRecov |
涌流 / 故障 | 故障恢复供电 | 同上 | 同上 |
BusEarthAlm |
涌流 / 故障 | 母线接地告警 | 母线接地无告警 | 零序电压 |
SgzAlarm |
涌流 / 故障 | 事故总告警 | 事故总信号缺失 | 事件码表 |
AutoCtrlTrip |
自动控制 | 自动控制跳闸(电池活化等) | 活化流程无法跳闸 | 出口 |
ManualTrip |
自动控制 | 手动跳闸 | 就地手动分闸缺失 | 开入 + 出口 |
MusterRecov |
自动控制 | 总复归(复归所有保持态) | 动作态只能靠重启清 | 无(可先做) |
ExvRec |
自动控制 | 事故记录 | 事故报告缺失 | 事件码表 |
ExvRecGW |
自动控制 | 事故记录(网关侧) | 同上 | 同上 |
CORecord |
记录 | COS 变位记录 | 开入变位无记录 | 开入 |
FrzRecord |
记录 | 冻结记录(整点冻结电量) | 电度无冻结 | 电度 |
YcMeaRecord |
记录 | 遥测定时记录 | 无遥测历史 | 定值 2 项 |
YcMeaLimitRec |
记录 | 遥测越限记录 | 无越限记录 | 越限判据 |
YcVolQuaRate |
记录 | 电压合格率统计 | 无合格率 | 定值 3 项 |
WaveQdCell |
录波 / 采样 | 录波启动判据 | 录波无触发源 | 录波子系统 |
RlyCommSam |
录波 / 采样 | 保护通信采样(跨装置采样同步) | 多装置差动类保护不可能 | 通信 + 对时 |
唯一"现在就能做"的是
MusterRecov(总复归):它不依赖任何硬件,只把各元件的 保持态与出口标志清一遍。本产品已有prot_elm_request_reset单字请求标志(§3.5), 接上即可。其余 36 个模块都至少依赖定值载体、开入、出口、事件码四者之一。
9.9 故障录波子系统规格(本产品 0)
录波是唯一一个"完全独立的子系统"级缺口:它不在保护链路上,但有独立的采样率、 独立的存储格式、独立的文件传输通道。参考实现的硬指标如下,可直接作为复刻验收判据。
| 指标 | 参考值(APP/EquipCfg/Const_Wave.h) |
说明 |
|---|---|---|
| 录波采样率 | CN_SAM_RATE × CN_WAVE_RATIO = 20 × 4 = 80 点/周波(50 Hz 下 4000 Hz) |
保护计算用 20 点/周波,录波要 4 倍过采样才能看清波形。偏离登记:本装置先按 1 kHz(20 点/周波)立项,理由与二期不返工的结构约束见 docs/子系统设计/故障录波设计说明.md §2 与 §2.1 |
| 录波段数 | CN_WAVE_SECT_NUM = 6 段 |
每段独立缓冲,支持连续多次录波 |
| 启动前缓冲 | CN_WAVE_CYCLE_SUM_REFRE_BUF = 5 周波(100 ms) |
循环刷新,保证故障前有数据 |
| 动作后 | CN_WAVE_CYCLE_SUM_ACTED = 10 周波(200 ms) |
|
| 返回段 | CN_WAVE_CYCLE_SUM_RET = 2 周波 |
返回过程也要录 |
| 手动录波 | CN_WAVE_CYCLE_SUM_HAND = 6 周波 |
|
| 单次最长 | CN_WAVE_MAX_TIME = 9000 ms |
超长故障(如持续性接地)按此截断 |
| RAM 录波个数 | CN_WAVE_RAM_NUM = 16 |
RAM 里最多同时存 16 份,满了转存文件 |
| COMTRADE 保存数 | 动作 64 / 启动 64 / 手动 16 | 三类独立配额,满了循环覆盖 |
| 单份最大开关变位 | CN_WAVE_MAX_RECSWI = 64 |
|
| 布尔量通道 | CN_WAVE_NUM_BOOLFLG = 320 |
全局布尔变量按位录波 |
| 模拟量通道 | 原始 + 计算 = CN_WAVE_ALL_ANA_NUM |
本产品对应 65 通道(g_tMeasureModelTab) |
| 录波类型 | 动作 TYPE_ACT=1 / 启动 TYPE_START=2 / 手动 TYPE_HAND=3 |
|
| 文件格式 | COMTRADE(.cfg + .dat) |
主站侧通用格式,非私有 |
| 上送方式 | 104 文件传输(F_FR_NA_1 目录 / F_SR_NA_1 读文件) |
本产品 104 未实现文件传输 |
复刻所需的四件东西(缺一不可):
- 4 倍过采样缓冲:当前
adcTask以 1000 Hz 出样本,录波要 4000 Hz。要么提高采样率 再抽取给保护(改变整条链节拍),要么在 TPAFE 侧单独开一条 4 倍速通路(改驱动)。 - 环形缓冲 + 触发点定位:5 周波前缓冲 + 10 周波后缓冲,触发时刻要能反算出缓冲内偏移。
- COMTRADE 编码器:
.cfg(通道定义、采样率、时标)+.dat(二进制采样值)+.hdr。 - 文件存储与配额管理:SPI NAND 上按 64/64/16 配额循环覆盖,需与现有 FatFs + dhara 层对接。
排期判断:录波不是"加个功能",是新增一条 4 倍速采样通路 + 一套文件格式 + 一个配额管理器。 它排在定值/元件铺开之后,因为录波通道表(65 路)本身依赖元件输出。
9.10 记录体系复刻明细(参考 13 类 → 本产品 8 类)
参考用 13 个定长队列分类存记录,容量按类分配(GlobalDef/Const_Sys.h):
| 参考队列 | 容量 | 语义 | 本产品 |
|---|---|---|---|
REC_ACT |
128 | 动作记录(保护动作) | ✅ 事故记录 /log/accid.log |
REC_ALM |
128 | 告警记录 | ✅ 保护告警 /log/alarm.log |
REC_OVER |
128 | 越限记录 | ❌ |
REC_START |
128 | 启动记录(元件启动但未动作) | ✅ 保护启动 /log/start.log |
REC_LOCK |
128 | 闭锁记录(保护被闭锁) | ❌ |
REC_SOE |
256 | SOE(带时标的开入变位) | ✅ soe_store(SPSC 深度 8 → 落盘) |
REC_COS |
256 | COS(无时标的状态变位) | ❌ |
REC_CHK |
128 | 自检记录 | ✅ /log/selftest.log |
REC_RUN |
128 | 运行记录(上电/重启) | ✅ /log/run.log |
REC_OPT |
128 | 操作记录(复归/对时/定值保存) | ✅ /log/oper.log |
REC_YK |
128 | 遥控记录 | ✅ /log/yk.log |
REC_SC |
128 | 顺控记录 | ❌ |
REC_SCSTEPINFO |
128 | 顺控执行明细 | ❌ |
缺的 5 类及其依赖:
| 缺的队列 | 依赖 | 能否先做 |
|---|---|---|
| 越限记录 | 越限判据(MeaLimit 10 项定值 + YcOverLimit 元件) |
可先做判据、后做记录 |
| 闭锁记录 | 闭锁源已具备(四源闭锁,§5.12),只缺记录落点 | ✅ 最该先补——现在闭锁发生了但无记录,现场排障靠猜 |
| COS 记录 | 开入(X3) | ❌ |
| 顺控记录 / 顺控执行明细 | 顺控功能(参考 YKRly.c 63 KB 的顺控执行引擎) |
❌ 整功能未立项 |
闭锁记录是本表里性价比最高的一项:闭锁源(未标定 / 采样故障 / 定值校验和 / 软压板退出) 已经全部实现,但闭锁的发生与解除都没有留痕。加一个
REC_LOCK等价队列, 只需在protect_task的闭锁判定处加一条写入,不依赖任何硬件。
格式差异:参考是二进制定长记录 + 独立队列 + 循环覆盖;本产品是文本行(64 B 定长)+ 文件。 文本行的优点是 FTP 直接可读、现场排障友好;缺点是容量利用率低、无结构化解码。 复刻时建议保留文本格式(本产品优势),只补队列分类与配额。
9.11 规约栈复刻明细(参考 12 种 → 本产品 1 种)
| 规约 | 参考源码 | 链路 | 用途 | 工作量特征 |
|---|---|---|---|---|
| IEC 60870-5-104 | Comm/Pub/Rly_IEC104.c |
TCP | 主站接入(本产品已实现) | ✅ 已完成 |
| IEC 60870-5-101 | Rly_IEC101.c、Rly_IEC101_B.c |
串口 | 主站接入(老站) | 与 104 共享 ASDU 层,只换链路层(平衡/非平衡链路、可变帧长) |
| IEC 60870-5-102 | Rly_IEC102.c |
串口 | 电度采集 | 独立 ASDU(电度专用类型),依赖电度 |
| IEC 60870-5-103 | RLY_IEC103.c、RLY_IEC103-tcp.c、Rly_IEC103T.c |
串口 / TCP | 保护装置信息接口 | 三种变体(串口 / TCP / T 型),ASDU 与 101/104 不同族 |
| ModBus | Rly_ModBus.c |
串口 / TCP | 通用工业设备 | 简单,对下采集首选 |
| CDT | Rly_Cdt.c |
串口 | 循环式远动(老国标) | 帧结构简单,无确认机制 |
Whm_GB |
Whm_GB.c |
串口 | 国标电度 | 依赖电度 |
| IEC 61850 | struct61850.h、GlobalUnit/SttnLvlGoose.c |
以太网多播 | MMS / GOOSE / SV | 最大工作量:需 MMS 栈 + ASN.1 + 多播组管理 |
| CAN | Rly_Can.h |
CAN 总线 | 内部总线 | 依赖 CAN 硬件 |
| 子站 IEC 101 | Comm/Mon/Rtu_IEC101*.c(含 ABB / 西门子 / 无优先级变体) |
串口 | 对下接 FTU / 开关 | 对下主站侧,与对上从站侧是不同角色 |
| 子站 IEC 104 | Rtu_IEC104.c、Rtu_Dbg104.c、Rtu_RIS104.c |
TCP | 对下 | 含调试与 RIS 变体 |
| BALA101 / ModBus | Rtu_BALA101*.c、Rtu_ModBus.c |
串口 | 对下 | 与 RS-485 簇同批 |
| 加密 | Comm/Ecc/(SM2 / SM3 / ECDSA) |
— | 安全加固 | 国密算法库,纯软件可移植 |
排期分层:
| 层 | 规约 | 理由 |
|---|---|---|
| 先做 | ModBus(对上 + 对下)、IEC 101 | 与 104 共享 ASDU 或结构简单;对下采集是配网终端必备 |
| 次做 | IEC 103、CDT、BALA101 | 老设备兼容,结构清晰 |
| 后做 | IEC 102、Whm_GB |
依赖电度(H1) |
| 末做 | IEC 61850 | 需 MMS/ASN.1/多播,单核 M4 资源需专项评估 |
| 并行 | SM2 / SM3 / ECDSA | 纯软件,无硬件依赖,可随时插入 |
一个容易漏的点:参考同时有对上(
Comm/Pub,本机作从站)与对下(Comm/Mon,本机作主站) 两套规约。本产品只有对上 104。做"配网终端"时对下那套(101/104/ModBus 主站侧) 是必须的——否则接不了一次开关。
9.12 复刻完成判据(逐缺口可验证)
每一条缺口给出"怎么算做完了",避免"实现了但没验收"。
| 缺口 | 完成判据 |
|---|---|
| 定值铺开 | PS_ID_COUNT = 249(或按单元分批:每批新增项在 104 上可读写、跨复位保持、校验和正确);check 脚本比对参考表逐项一致 |
| 104 定值映射 | 107 个地址(0x8820~0x8891 含 8 空洞)全部可读可写;空洞地址返回"未知信息体地址" |
| 元件铺开 | 45 个模块对应 45 个实例;每个实例有:定值项齐全、启动/动作/返回三态可观测、事件码正确、单测覆盖判据边界 |
| 遥测铺开 | 31 点全部非 IV(除物理不可达点明确标 IV);线电压与相量满足 Uab = Ua − Ub 误差 ≤ 0.5 % |
| 开入开出 | 27 路硬件开入可读、31 路开出可驱动;开入防抖可整定;双点遥信四态正确(00/01/10/11) |
| 录波 | **(二期口径;本波按 1 kHz / 8 路 / 单段 / 无 COMTRADE,对照表见 §9.1 第 10 行)**4000 Hz 采样;三类录波各生成一份 COMTRADE 且被第三方工具打开;配额 64/64/16 循环覆盖正确 |
| 记录体系 | 13 类队列各有落点;每类容量达标;断电不丢已确认记录 |
| 多规约 | 每种规约与对应主站/子站工具完成一次完整交互(连接 / 总召 / 变位 / 遥控 / 断链重连) |
| 国密 | SM2 签名验签、SM3 摘要与标准测试向量一致 |
| 软压板 | 9 面全部可投退且行为可观测(投退后对应功能确实停走/恢复) |
| 出口与开入 | 保护动作 → 出口继电器动作 → 开入回读确认,全链路 ≤ 120 ms |
| 标定解卡 | 8 通道两点标定后 ADC_CAL_F_VALID 全置位;注入标准源,保护动作值与定值误差 ≤ 3 % |
| 屏板链路 | 串口通道:屏板 280 ms 召唤、主机 ≤200 ms 内发完 4208 B(整帧无 2 个字符时间以上的间隙),连续 10 min 主机侧零超时、零 CRC 错帧;显存 3200 B 与 g_ui_fbuf 逐字节一致;7 个物理键(1/2/3/4/7/8/9)动作正确;状态灯位掩码逐位一致、LED 0 恒亮;屏板 ≈5000 s 自复位不误判离线;LOGO 下发后断电重启仍在;网络通道:INIT 应答 16 B 逐字段一致且无颜色字段、LCDMEM 偏移 0 得 3204 B、重复召唤无应答、偏移 ≥3200 无应答、KEEPLIVE 无应答且 1 分钟不掉链、8 键(含 F1|ENT 组合)动作正确(§5.16.10 十五条) |
9.13 屏板链路复刻任务规划
口径:条目一律用语义短语(编号规范 P-8),执行序即表序。 改动范围只含本产品固件与
DTU-RemoteLCD客户端;屏板固件不在本仓库, 其行为以 §5.16 为契约做黑盒验收。两种部署形态,两条通道都要:① 串口直连屏板(参考的形态,第 10
15 条)——屏板直接挂在设备 串口上,无需任何网络设备;② 串口服务器透传 / 网络镜像(第 29 条)——屏板或调试软件经以太网连 7003。 现场用串口服务器把屏板接到网上时,两种形态等价,但固件侧不能只实现后者: 只有 7003 时,设备离开网络就没有任何本地显示,与参考产品不等价。方向相反,别写错:网络通道是"客户端召唤、设备应答";串口通道是"屏板召唤、设备应答"。 两条通道共用同一份显存快照,但帧格式、校验、时序完全不同(网络用
0xAA/0xBB+ XOR, 串口用裸二进制 + CRC-16/MODBUS),不能共用组帧代码。执行细则另立:逐项任务的改动点、判据、代码骨架、台架联调步骤与风险清单在
docs/任务规划/屏板链路.md;本节只保留需求视角的缺口与顺序,不复制执行细节。
| 序 | 任务 | 改动点 | 判据 | 跨端 |
|---|---|---|---|---|
| 1 | 报文口径定版 | 本节 + §5.16 + §6.2 按参考源码成文 | 文档门禁全绿(已完成) | — |
| 2 | INIT 应答补足 16 字节 | ui_net_sink.c 的 remo_send_init() 组帧由 8 B 扩到 16 B:补 8 B 键值表;不加颜色位与 RGB(单色屏不对齐多色协议,§5.16.5) |
16 B 逐字节比对通过,且报文内无颜色字段 | 是 |
| 3 | 键值表补 F1 / F2 | ui_net_sink.h 键值宏补 0x04 / 0x80;ui_net_sink_inject_key() 映射;UI 键处理接受组合键 |
下发 0x04 / 0x80 / 0x24 界面响应正确 |
否 |
| 4 | 显存断点续传 | CMD_LCDMEM 分支去掉"仅偏移 0"限制:按偏移取 g_ui_fbuf + off,长度 min(9800, 3200 − off) |
off=1600 得 4+1600 B,内容与整帧尾部逐字节一致 |
否 |
| 5 | 召唤拒绝握手 | 新增"帧代次 + 已上送"等价状态:新图未就绪时重复召唤不应答;偏移 ≥3200 不应答 | §5.16.10 第 2、3 条通过 | 是 |
| 6 | 链路监视 | 1 分钟通信中断计时(收到帧 / 发送成功即重置);超时置状态位并落一行日志 | 断链 60 s 有明确日志与状态;重连后自动恢复推流 | 否 |
| 7 | KEEPLIVE 静默 | 去掉空帧回显,改为仅重置计时 | §5.16.10 第 4 条通过 | 是 |
| 8 | 发送重试评估 | 对比参考"BUSY + 200 ms 放弃"与现有 net_send 阻塞模型,出结论并回填 §5.16.9 第 7 行 |
结论有实测数据支撑(实现 / 明确不实现) | 否 |
| 9 | 客户端一致性回归 | DTU-RemoteLCD 按 16 B 解析;把 §5.16.10 第 1~7 条做成自动化用例 |
七条判据全 PASS | 是 |
| 10 | 串口物理层落地 | 按 §5.16.2 定版:700000 8N1、BRR = 0x0078(USART1,APB2 84 MHz)、无 DE(TTL 直连,不走收发器)、RX 缓冲 16 B + 空闲中断断帧、发送走 DMA 一次性发完(禁逐块阻塞,DMA2_Stream7 TX / DMA2_Stream2 RX 已在 .ioc 配好但控制台未用) |
环回 + 示波器实测 700 kbaud 分频零误差;屏板能收到帧 A 并回帧 B | 否 |
| 11 | 帧 A 解析 / 帧 B 组帧 | 新增屏板通道模块:识别 6 B 请求(01 03 type key CRC_L CRC_H)、校验 CRC-16/MODBUS(低字节在前,口径见 §5.16.2);组 4208 B 帧 B(3200 显存 + 4 B LED + 4 B info 保留 + 998 B 填充 + 2 B CRC) |
屏板出图与 g_ui_fbuf 逐字节一致;info[0..3] 与下发的 LED 掩码一致 |
否 |
| 12 | 状态灯位映射表 | 定义"业务状态 → 屏板 LED 位"映射(参考源码无此表,须自定);info[0..3] 按 32 位小端填,bit0 恒 0、bit20~31 恒 0 |
§5.16.10 第 11 条通过 | 否 |
| 13 | 串口上行按键 | 帧 A 的 key 字节按屏板 KEY_TYPE 解释——实际可达值只有 1/2/3/4/7/8/9(5/6/10 无物理入口);映射为逻辑键值后与 7003 注入同一入口合并 |
§5.16.10 第 10 条通过;9/10 语义按 §5.16.3 ② 处置 |
否 |
| 14 | 双通道并发 + 自复位容忍 | 两出口各自独立发送上下文;串口 4208 B 阻塞不拖 7003;链路监视按"连续 ≥10 s 无应答"判离线,忽略屏板 ≈5000 s 周期自复位 | §5.16.10 第 12、13、14 条通过 | 否 |
| 15 | LOGO 下发流程 | 一次性下发 LOGO 帧(info[4..5] = 0x89 0x45,宽高大端);放在出厂 / 联调流程,不进常规刷新循环 |
§5.16.10 第 15 条通过;断电重启后 LOGO 仍在 | 否 |
| 16 | 日志口迁移(USART1 → RS-232 通道) | ① console_log.c 的 huart1、USART1_IRQn、__HAL_RCC_USART1_CLK_*、MX_USART1_UART_Init() 收口成一处端口宏,指向 RS232#1(huart5 / UART5);② 不动 UART4 的 g_rs485 绑定 |
日志在 RS-232 侧(CN1)可读且内容与迁移前一致;USART1 完全空出;连续 10 分钟无 [ERR] |
否 |
批次划分:
| 批 | 任务 | 理由 |
|---|---|---|
| 第一批(无跨端风险,可独立发版) | 3、6、8 | 只动本端,旧客户端不受影响 |
| 第二批(跨端,须与客户端同步发版) | 2、4、5、7、9 | 报文口径变更,两端必须同版本 |
| 第三批(独立立项,不随 RS-485 冻结) | 16、10、11、12、13、14、15 | 屏板串口通道是独立需求,与 §5.10 冻结的"对下采集簇"不是一回事。第 16 条必须排在 10 之前:日志不腾出 USART1,屏板链路就没法独占这条通道(两者共用同一个 USART1->DR,同时用就是互相插字节) |
⚠ 唯一破坏性变更:第 2 条把 INIT 应答从 8 B 改成 16 B。旧客户端会把 16 B 的前 8 B 当全部、 把后 8 B 当作下一帧的 TAG 去找,解析状态机会被这 8 B 拖住直到超时——表现为"连上了但不出图"。 因此第 2、5、7、9 条必须同批发布,且发版说明中明确"客户端需升级"。
⚠ 16 B 与参考的 29 B 不可互换:删掉 13 B 颜色字段后,偏移 4 之后全部前移—— 参考的"显存大小在偏移 5、键值表在偏移 21"在本产品变成"偏移 4、偏移 8"。 客户端不得复用参考的 29 B 解析器再截前 16 B(会读出颜色位当显存高位)。
屏板固件边界:本表不覆盖屏板侧固件(帧解析 / 显存写入 / 按键扫描 / 状态灯驱动)。 屏板固件工程在
D:\Code\DTU Code\DTU-LCD,不在本仓库,其契约已按源码逐字节成文(§5.16.2 / §5.16.3)。 本产品只要满足 §5.16.10 的十五条判据即为兼容。第三批的前置阻塞:第 11~15 条需要屏板实物才能验收(无实物只能做到"帧发出去了")。 第 11 条的帧长仍有一处待实测复核——代码实参是 4208 B,屏板 readme 写 3208 B(§5.16.2); 台架抓到第一帧真实报文后立即固化,在此之前以代码实参为准,不得按 readme 实现。
一条物理前置(已完成 2026-10-29)+ 一条实现纪律: ① 台架串口线已挪位——日志口迁到 RS-232 侧后,台架那根线改接 CN1 的 RS232#1 端子 (
CN1.10接适配器 TXD、CN1.12接适配器 RXD、CN1.7或CN1.8接 GND),台架日志口 因此由COM6变为COM3,.serialtest/config.json的portName已同步,@test与serial-assistant不必再手工指端口。这些端子是 RS-232 电平,TTL 的 CH340 直连不了, 用的是 USB 转 RS-232 适配器;接法与端子出处见docs/任务规划/屏板链路.md§3 批 0。 这条要在第 16 条动代码之前完成。 ② RX 要真的读、ORE 要真的清——PA10 一直是接线的(§5.16.2), 但"RX 使能却不读DR"本身就足以让 ORE 永久锁存。第 11 条实现时必须在HAL_UART_ErrorCallback里清 ORE 并重挂接收,否则一次噪声就永久静默。
10. 验收判据
10.1 构建与静态门禁
| 项 | 判据 |
|---|---|
| 构建 | @build → BUILD_OK: 0 errors, 0 warnings(退出码 0) |
| 静态门禁 | pre-commit run --all-files 全部通过(钩子族见 §7.4) |
| 主机侧单测 | 全部套件全绿(看门狗、时钟、配置、相量、采集层、标定、遥测、测频、定值、元件、运行参数、104、SOE 等;套件与断言数随代码演进,以 .pre-commit-config.yaml 与 test/host/ 为准) |
| 栈门禁 | scripts/stack_report.py 9/9 PASS(余量 ≥ max(1024 B, 30%)) |
| 体积门禁 | check_size_gate.py --ci PASS(体积凭证与 git 索引一致) |
| 双端构建 | Keil 与 CMake 均 0 错 0 警 |
| UI 回归 | 菜单行 + 内容页像素黄金 + 导航自检全 PASS |
10.2 上电自检(@test)
| 层 | 判据 |
|---|---|
| Required 标记(基础) | App init OK / Network Init / net init: OK / PHY: 100M FULL |
| Required 标记(采集链,可选启用) | ADC input layer init: OK / phasor(first) / freq(hb)(顺序锚点 App init OK>phasor(first)>phasor(hb)) |
| Required 标记(保护链,可选启用) | protect task start / set=40 elm=9 计数锚 |
| Required 标记(104,可选启用) | [I104] 监听/接入行 |
| Forbidden 标记 | 无 FAIL / ERROR / HardFault / [ERR](四个 Fault 的崩溃日志都以 [ERR] 开头,出现即不通过) |
| 自检记录 | selftest: no fault record |
| 固件身份 | fw build 身份戳匹配 + 烧录后回读 No difference found |
| 退出码 | @test → 0(PASS) |
10.3 现场验收清单
| # | 项目 | 方法 | 通过标准 |
|---|---|---|---|
| 1 | 上电自启动 | 断电上电 + 串口采集 | @test PASS,无 Forbidden 标记 |
| 2 | 网络连通 | PC ping 设备 IP | 通(PHY 100M FULL) |
| 3 | 远程显示 | DTU-RemoteLCD 连 7003 | 出图(160×160 1bpp)+ 远端菜单导航可用 |
| 4 | FTP | FTP 客户端连 :21 | 列目录 / 读写 / 下文件 |
| 5 | UI 功能 | 远端操作 | 菜单 7 项导航、内容页、密码(查看 000 / 修改 123)、网口设置保存后立即生效 |
| 6 | 对时 | PC 推送 8888 | 设备墙钟更新、日志时间戳正确 |
| 7 | 掉电保持 | 写文件 / 改网口配置 / 改定值 → 重启 | 数据仍在(/config.ini、/prot_set.bin 按新值生效) |
| 8 | LED 状态 | 目检 | 6 路 LED 随系统状态变化(低电平点亮) |
| 9 | 104 总召与变位 | PC 主站连 :2404 → STARTDT → 总召 | 四组数据回全、actterm 正常;制造变位后 COT=3 上送 |
| 10 | 104 遥控与定值 | YK12 软压板投退、C_SE 写定值 |
两段式正答、压板行为可观测、定值跨复位保持 |
| 11 | 保护闭锁态 | 未标定状态下观察 YX31 与日志 |
判据停走且明确可见(不得静默不动作) |
| 12 | 记录可追溯 | FTP 下载 /log/soe.log、/log/run.log、/log/selftest.log |
记录连续、时标正确、解码校验通过 |
| 13 | 屏板链路一致性 | 串口屏板 + TCP 客户端同时接入,按 §5.16.10 十五条逐项验证 | 串口侧:275 ms 召唤 / ≤200 ms 回 4208 B、显存 3200 B 逐字节一致、状态灯 4 B 掩码逐位一致、7 键动作正确、自复位不误判离线;网络侧:INIT 16 B、重复召唤 / 越界无应答、KEEPLIVE 静默、8 键(含组合)动作正确 |
10.4 台架验收(已闭环)
| 用例 | 内容 | 结论 |
|---|---|---|
| V2 | 任务饿死 → IWDG 复位 | ✅ 800 ms 声明 stall,≤2.5 s 复位(reset cause: IWDG) |
| V4 | 关中断死循环 → IWDG 复位 | ✅ 每 ~4.9 s 稳定复位(IWDG 独立于中断) |
| V5 | 30 min 真实负载长跑 | ✅ 120/120 FTP PASS,零 IWDG 复位 |
| 堆分配改造 | 配置引擎堆分配改造(真机) | ✅ [CFG] load: OK(经 FreeRTOS 堆);FTP 改 IP 复位即生效 |
| 存储/网络套件 | 16/16 PASS | ✅ |
| 采样节拍与相量 | 帧号 1000 Hz、5 实例产出、双区刷新 | ✅ 2026-10-11 |
| ADC 前端注入 | 已知电压注入:零点 / 线性 / 斜率 / 映射 / 极性 | ✅ 2026-10-27 五项 PASS(斜率偏差 −0.14%,R²=0.9999997) |
| 104 主站往返 | STARTDT / 总召四组 / 变位 / 遥控 / 定值读回 | ✅ 2026-10-12 18/18 PASS |
| 定值与压板持久化 | YK12 投退 + 非默认定值跨复位 |
✅ 2026-10-12 21/21 + 13/13 + 4/4 + 4/4 PASS |
| SOE 落盘 | 自发 M_SP_TB_1 带时标 + FTP 下载解码 |
✅ 2026-10-12 56 条记录全 PASS |