docs(产品需求): 更正屏板口径并补远端屏与按键逐字节复刻规格

参考工程主机侧无任何屏/键 GPIO:KeyGet、WriteScreenByByte、
LCD_LED_Update、getRs485Key、anyNewKey 全树只有声明无实现;
按键轮询函数名为 Key_Rs485_Process,屏板插槽号 CN_SLOT_DISP=0。
即屏与键都在独立屏板板件上、靠链路传输,本产品与之同构而非替代。

- §2.4.1 X3 由「本地人机」改为「就地屏板(板件本体)」并补更正说明
- §2.5.2 补第 20 项「远端屏与按键链路」,能力计数 19 项 → 20 项
- 新增 §5.16 远端屏与按键链路(FR-HMI):两条链路对照、帧格式、
  INIT 应答 29 B 逐字段偏移、续传与拒绝语义、按键状态机、三个定时器
- §5.16.7 列 10 项与参考的差异(INIT 8 B vs 29 B 为最大一条)
- §6.2 按参考源码重写:INIT 长度、KEEPLIVE 改为不应答、键码补 F1/F2
- 新增 §9.13 屏板链路复刻任务规划:10 条任务 + 三批划分 + 破坏性变更警示
- §9.1.2 / §9.12 / §10.3 同步补条目
This commit is contained in:
2026-10-28 09:24:18 +08:00
parent 15111eaec3
commit 463d7be135
+229 -14
View File
@@ -7,14 +7,14 @@
> 待实现项与路线图、验收判据。
> **事实来源**:本文所有数值与结论均取自仓库内**受管事实源**(代码、`.ioc`、`.map`、网表分析报告与
> 各模块设计文档),凡与其它文档冲突处,以本文标注的权威来源为准。
> **版本**:v1.3 **日期**:2026-10-28 **状态**:现状基线(含已实现项 + 待实现项)
> **版本**:v1.4 **日期**:2026-10-28 **状态**:现状基线(含已实现项 + 待实现项)
> **阅读前提**:建议先读 [`docs/README.md`](../../docs/README.md)(文档索引)与
> [`docs/架构设计/项目架构总览.md`](../../docs/架构设计/项目架构总览.md)(全景架构)。
> **范围口径:1:1 复刻**——本产品是参考产品 **CLS100**(`Scatter_P_HV03.01_SV01.01`,OMAP-L138
> ARM+DSP 双核 + VxWorks 配电保护测控装置)的**逐模块复刻**。产品范围 = 参考源码的能力全集,
> 差异只允许来自物理不可移植项(§2.4.1)。§2.5 以**参考工程源码的常量表与模块文件**为唯一清单,
> 给出 19 项能力对照与复刻进度;§9 的缺口一律表述为"复刻进度"而非"不做",
> 其中 **§9.4~§9.12 是逐项明细**(每个定值 / 每个点 / 每个模块差在哪、怎么算做完)。
> 给出 20 项能力对照与复刻进度;§9 的缺口一律表述为"复刻进度"而非"不做",
> 其中 **§9.4~§9.13 是逐项明细**(每个定值 / 每个点 / 每个模块 / 每条链路的报文差在哪、怎么算做完)。
> 产品定义的技术细化见 [`docs/算法/继电保护功能复现规划.md`](../算法/继电保护功能复现规划.md)。
---
@@ -162,7 +162,7 @@ flowchart LR
| 🔶 **部分对齐** | 骨架、口径、地址编排已对齐,覆盖范围小于参考(通道数 / 元件数 / 点数) | 差额逐条进 §9 |
| ⬜ **未开始** | 参考源码存在、本产品无对应实现 | 逐条进 §9,**不等于"不做"** |
**当前分布**(19 项能力,明细见 §2.5.2):✅ **2 项**(采样节拍、自检类型)、🔶 **9 项**、
**当前分布**(20 项能力,明细见 §2.5.2):✅ **2 项**(采样节拍、自检类型)、🔶 **10 项**、
⬜ **7 项**、— **1 项**(双核分工,不可移植)。
#### 2.4.1 不可移植项(唯一允许落在范围外的部分)
@@ -171,13 +171,21 @@ flowchart LR
|---|---|---|---|---|
| X1 | 双核 ARM + DSP 分工 | OMAP-L138(ARM 跑通信/HMI,DSP 跑保护) | 单核 Cortex-M4F 按任务划分承担 | 芯片形态 |
| X2 | 实时操作系统与工具链 | VxWorks 5.x + CCS | FreeRTOS V10.3.1 + Keil ARMCC | 平台形态 |
| X3 | 本地人机 | 板载 LCD + 按键 | 无屏:160×160 1bpp TCP 推流 + 远端按键(§8) | 硬件形态 |
| X3 | 就地屏板(**板件本体**) | 专用屏板:主机侧**无任何屏 / 键 GPIO**,屏与键全在独立板件上(RS-485 通道 + TCP 7003 镜像,§5.16) | 不产屏板:只实现**主机侧链路**(TCP 7003 推流 + 按键回注);RS-485 屏板通道随 §5.10 冻结 | 交付物形态(屏板非本产品交付范围) |
| X4 | 一次设备接口 | KO / KI 板卡(出口、开入、硬压板) | V0.1 无该硬件(§4.6 H3) | 硬件缺失 |
| X5 | 独立计量通道 | 专用计量芯片(电度) | 无(跨转换器无同刻,§4.6 H1) | 硬件缺失 |
> **X1~X5 是范围外项的全部。** 除此以外**不存在"参考有、我们决定不做"的能力**——
> v1.1 曾把故障录波、开入开出、多规约、SNTP 等列为"非本期/不做",与 1:1 复刻口径冲突,
> 本版已全部改为"未开始"并入 §9。
>
> ⚠ **X3 口径更正(2026-10-28)**:v1.3 及更早把参考写成"**板载** LCD + 按键",据此把本产品的
> 远端推流说成"等价替代"——**这是错的,两处都错**。参考工程源码里主机侧**没有任何屏 / 键的 GPIO 访问**:
> `KeyGet()` / `WriteScreenByByte()` / `LCD_LED_Update()` / `getRs485Key()` / `anyNewKey()`
> 这 5 个"碰硬件"的函数**全树只有声明、没有实现**(由屏板 BSP 库提供);按键轮询函数名就叫
> `Key_Rs485_Process()`(注释"轮询从485传来的按键值");屏板插槽号 `CN_SLOT_DISP = 0`
> (注释"显示板插槽号固定为0")。即:**参考的屏和键同样在一独立板件上、同样靠链路传输**。
> 本产品与参考**同构**,不是替代;落在范围外的只有那块**屏板硬件本身**。完整复刻规格见 §5.16。
### 2.5 1:1 复刻基线(参考源码能力清单)
@@ -216,6 +224,7 @@ flowchart LR
| 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` | 7003 四命令 + RS-485 屏板通道 | 7003 四命令已通;INIT 应答 8 B(参考 29 B)、无断点续传、无链路监视、缺 F1/F2 | 🔶 |
> **读法**:🔶 / ⬜ 行**全部是待办**,逐条对应 §9.1;`—` 只出现在 X1~X5 不可移植项上。
> 本表是范围判定的唯一出处,§9 不再重复解释"为什么缺"。
@@ -334,7 +343,7 @@ tTimer_NoUI 无压无流判据(CN_
| **外部资源**(标准源、端子变比) | 定值标定、保护判据解卡 | 两点标定(§9.2 第 4 步) |
| **硬件缺失**(X4 / X5) | 开入 138、开出 31、电度 8、同期、三相通道 | V0.2 硬件 |
| **立项未排** | 录波、多规约、SNTP、记录 5 页、定值铺开 | 按 §9.2 顺序 |
| **算力 / 形态**(X1~X3) | 双核分工、VxWorks、本地屏 | 不解除(已用等价方案替代) |
| **算力 / 形态**(X1~X3) | 双核分工、VxWorks、屏板本体 | 不解除;其中 **X3 的主机侧链路已 1:1 同构**(§5.16),不属"替代方案" |
> **结论**:本产品与参考产品的差距**全部是"进度"而非"范围"**——没有一项是"参考有而我们不做"。
> 已对齐的是**软件骨架**(采样节拍、相量算法、定值模型、104 上行、SOE 落盘、自检闭锁);
@@ -951,6 +960,162 @@ sequenceDiagram
| 固有参数 `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")。
> 结论:**屏和键都在一块独立的屏板板件上,主机只负责"送帧 + 收键"**。本产品与参考同构,
> 唯一落在范围外的是那块**屏板硬件本身**(§2.4.1 X3)。
#### 5.16.1 参考实现的两条链路
| 链路 | 参考源码 | 承载 | 对端 | 本产品 |
|---|---|---|---|---|
| A 屏板串行通道 | `HMI/Dsp/Key.c`、`HMI/Dsp/Disp_Pub.c` | RS-485(`getRs485Key()` 收键 / `LCD_LED_Update()` 送屏) | 专用屏板(插槽 0) | ⬜ 随 §5.10 RS-485 簇冻结 |
| B 远程显示总线 | `HMI/RemoeDisp/RemoDispBus.c`(796 行) | TCP **7003**(`0xAA` / `0xBB`) | 屏板或调试软件(客户端) | 🔶 骨架已通,报文口径待对齐 |
链路 A 的数据面(源码实测,供将来解冻 RS-485 时照抄):
| 项 | 参考行为 |
|---|---|
| 送屏 | `LCD_LED_Update(显存 3200 B, LED 4 B)`——一次推 160×160 1bpp 显存 + 4 字节 LED 状态;**非周期**,仅当 `anyNewKey() \|\| LCD_UPDATE_FLAG` 时触发 |
| 收键 | `getRs485Key()` 轮询返回物理键号 `1~10`,映射到逻辑键值:`1`=ENT `2`=U `3`=D `4`=ESC `5`=ADD `6`=SUB `7`=L `8`=R `9`=F1 `10`=F1\|ENT |
| 去抖 | `CN_KEY_TIMES_ONE=2`(单击)/ `CN_KEY_TIMES_TWO=12`(连击);状态机 `EN_KEY_FLAG_NULL → SAM → NEW` |
| 背光 | 有键 `MenuProc_Have_Key()` 点亮;空闲 **120 s** `MenuProc_TurnOff_Light()` 熄灭 |
| 任务 | `tKey`(prio 109 / 栈 0x400,只跑 `Key_Rs485_Process` 轮询);`tDisp`(prio 110 / 栈 0x9000,界面 + 推屏) |
#### 5.16.2 链路 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.7 第 10 行),不作退让。
#### 5.16.3 命令集与数据段布局
| CMD | 名称 | 客户端请求 | 设备应答 | 备注 |
|---|---|---|---|---|
| 0 | `KEEPLIVE` | 空 | **不应答** | 源码 `return`,注释"无 keep alive 报文";仅重置 1 分钟通信计时 |
| 1 | `INIT` | 空 | **29 B**(见下表) | 工具召唤屏幕参数 |
| 2 | `KEY` | `[键值 1B]` | 空(LEN=0) | 键值写入 `g_tRemoteKey`,`byKeyValid = EN_KEY_FLAG_NEW` |
| 3 | `LCDMEM` | `[起始偏移 4B 大端]` | `[起始偏移 4B][显存 nB]` | 支持断点续传;拒绝语义见 §5.16.4 |
| 4 | `ACK` | — | — | 参考 `RDisp_Send` 中为空分支,未使用 |
| 5 | `NCK` | — | — | 同上,未使用 |
| `0xFF` | `IDLE` | — | — | 内部空闲码,不上线 |
**INIT 应答数据段(29 B,`RDisp_Form_InitInf`)**:
| 偏移 | 长度 | 字段 | 参考取值 |
|---|---|---|---|
| 0 | 2 | LCD 像素宽(大端) | `CN_LCD_SIZE_X` = 160 |
| 2 | 2 | LCD 像素高(大端) | `CN_LCD_SIZE_Y` = 160 |
| 4 | 1 | 颜色位 `CN_RDISP_LCD_TYPE` | `CN_MODE_GREY_MONO` = 1 |
| 5 | 4 | 显存字节数 `CN_RDISP_MEMSIZE`(大端) | `(160>>3)*160` = **3200** |
| 9 | 4 | `CN_RGB_RED`(大端) | 见 `HMI/Drv/Lcddrv.h` |
| 13 | 4 | `CN_RGB_GREEN`(大端) | 同上 |
| 17 | 4 | `CN_RGB_BLUE`(大端) | 同上 |
| 21 | 8 | 键值表 `F1/F2/U/D/L/R/ENT/ESC` | `0x04/0x80/0x02/0x40/0x10/0x08/0x20/0x01` |
**键值是位掩码,不是枚举**——可组合下发:`CN_KEY_F1|CN_KEY_ENT = 0x24`(`Key.c` 物理键号 `10` 即此值)。
`CN_KEY_ADD=0x82`、`CN_KEY_SUB=0x84` 只在 RS-485 通道使用,不进 7003 键值表。
#### 5.16.4 显存上送的续传与拒绝语义
`RDisp_Form_LcdMem` / `RDisp_Proc_LcdMem` 的完整规则:
1. **分片**:`dwSendBase + 9800 > 3200` 成立 → 本帧发 `3200 - dwSendBase` 字节;否则发 9800 B。
因 `MEMSIZE = 3200 < 9800`,**实际恒为单帧 3204 B**(4 B 偏移 + 3200 B 位图);
分片逻辑为"显存变大"预留,当前不触发。
2. **推进**:发完后 `dwSendBase += dwLen`;若 `>= MEMSIZE` → **`bNeedFlash = TRUE`**、`dwSendBase = 0`。
3. **拒绝**:召唤时若 `bNeedFlash` 为真(上一帧刚发完、新图还没拷贝)→ 返回 **`-1`**,且把
`dwSendBase` 清 0,**不应答**。含义是"**一帧图像只允许被完整上送一次**",客户端要下一帧
必须等主机完成下一次刷新。
4. **越界**:`dwSendBase >= MEMSIZE` → 返回 **`-2`**,不应答。
5. **成功**:返回 `1`,置 `wSendCode = LCDMEM`,由 `RDisp_Send` 组帧发出。
6. **刷新来源**:`RDisp_Main` 每轮检查 `bNeedFlash`,为真则 `memcpy(byLcdMemory, __Lcd_Pub_GetScreenAddr(0), 3200)`
→ `RDisp_LcdColor_To_Mono()` 转单色 → 清 `bNeedFlash`、`dwSendBase = 0`。
> **为什么必须有 `bNeedFlash` 握手**:显存由显示任务异步改写,若允许客户端随时按偏移拉取,
> 跨两次刷新的位图会在客户端拼成**撕裂帧**。参考用"整帧一次性 + 拒绝重拉"消除这个窗口,
> 本产品当前无此保护(§5.16.7 第 4 行)。
#### 5.16.5 按键注入与状态机
| 项 | 规格 |
|---|---|
| 存储 | `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.6 时序、超时与重试
| 定时器 | 周期 | 作用 |
|---|---|---|
| `tTimerLCD` | **500 ms** | 本地屏刷新节拍(`WriteScreenByByte`);本产品无屏板,此路不实现 |
| `tTimerComBrk` | **1 分钟** | 通信中断判定;**每收到任一帧、每次发送成功**都重置 |
| `tTimerAbandon` | **200 ms** | 发送未完成时的放弃窗口 |
**发送状态机**(`RDisp_Send`):
1. `TcpGetSendState(iTcpNo) <= 0` → 直接返回(链路未建或芯片发送忙),不组帧。
2. `wSendFlag == CN_RDISP_SEND_BUSY` → 重发上次缓冲;成功 → `IDLE` + 重置 `tTimerComBrk`;
失败且 `tTimerAbandon` 未到 → 返回;已到 → `IDLE` 后**重新组帧**(宁可丢帧不阻塞)。
3. 组帧:`byCRC = XOR(DATA)`;填 `TAG=0xBB`、`CMD`、`LEN`;`CRC` 写在 `DATA` 之后。
4. `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.7 与参考的差异(本产品当前实现)
| # | 项 | 参考 | 本产品 | 处置 |
|---|---|---|---|---|
| 1 | INIT 应答长度 | **29 B**(含颜色位 / 显存大小 / RGB 三色 / 8 键值表) | **8 B**(宽 2 + 高 2 + 帧字节 4) | **补 21 B**,客户端按 29 B 解析 |
| 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 |
| 9 | 任务模型 | 独立任务 prio 111 / 栈 212 KB | `uiTask` 10 ms 轮询(prio BelowNormal / 16 KB) | **形态差异,不追平**(X1 / X2) |
| 10 | 接收侧 CRC | 仅 LCDMEM / KEY 校验 | 全帧校验 | **本产品更严,保留** |
> 第 1 / 3 / 4 / 5 / 8 条是**客户端可见的报文口径差异**——现有 `DTU-RemoteLCD` 按 8 B INIT 实现,
> 补 29 B 后**客户端必须同步改**,否则会错位解析。这是本项复刻唯一的跨端风险点。
#### 5.16.8 复刻完成判据
1. 任意 TCP 客户端连 7003 → 发 `INIT` → 收到 **29 B**,字段值与上表逐字节一致。
2. 发 `LCDMEM(0)` → 收到 `3204 B`;**再次**发 `LCDMEM(0)`(新图未就绪)→ **无应答**(对应参考 `-1`)。
3. 发 `LCDMEM(3200)` → **无应答**(对应参考 `-2`)。注:该分支在 `bNeedFlash` 为真时先被 `-1` 截住,
只能在"新图已拷贝、尚未上送"的窗口内触发,属**边角路径**,判据以"无应答且不越界读"为准。
4. 发 `KEEPLIVE` → **无应答**,且链路 1 分钟内不被本端主动断开。
5. 发 `KEY(0x24)` → 收到空 KEY 应答,界面表现为 `F1+ENT` 组合键。
6. 断开 TCP 60 s 以上 → 设备侧可观测到"通信中断"(日志 / 状态位),重连后自动恢复推流。
7. 8 键逐个下发 → 界面动作与按键表一致;组合键 `F1|ENT` 生效。
---
## 6. 接口规范
@@ -970,30 +1135,39 @@ sequenceDiagram
![RemoDispBus 帧格式](../images/RemoDispBus帧格式.svg)
> **口径**:本节按**参考源码**(`HMI/RemoeDisp/RemoDispBus.c`)给线上格式;本产品当前实现与该口径的
> 逐项差异、以及为什么会有差异,见 §5.16.7。**以参考为准**,差异项按 §9.13 排期收敛。
| 项目 | 内容 |
|---|---|
| 传输 | TCP,端口 **7003**;单连接(`backlog=1`) |
| 传输 | 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 = **数据段**逐字节异或(低 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 | INIT | 无 | `[宽u16][高u16][帧字节数u32]`(**8 B**) |
| 2 | KEY | `[按键码u8]` | 无(确认) |
| 3 | LCDMEM | `[起始偏移u32]` | `[偏移u32][1bpp位图 3200B]`(3204 B) |
| 0 | KEEPLIVE | 无 | **无应答**(仅重置 1 分钟通信计时) |
| 1 | INIT | 无 | `[宽u16][高u16][颜色位u8][显存u32][R u32][G u32][B u32][8 键值]`(**29 B**) |
| 2 | KEY | `[按键码u8]` | 无(空帧确认,LEN=0) |
| 3 | LCDMEM | `[起始偏移u32]` | `[偏移u32][1bpp位图 3200B]`(3204 B);偏移非 0 时续传,`bNeedFlash` 期间不应答 |
**按键码**:`UP=0x02` / `DOWN=0x40` / `LEFT=0x10` / `RIGHT=0x08` / `ENTER=0x20` / `ESC=0x01`。
**INIT 字段明细与按键码表**:见 §5.16.3(含 29 B 逐字段偏移)。
**按键码**:`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。
**关键常量**:`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`。
@@ -1399,6 +1573,7 @@ pre-commit run --all-files
| **SNTP 对时** | 17 | 参考对时走 SNTP | 私有 TCP 8888 + 104 `C_CS` | SNTP 客户端 |
| **固有参数** | 1 | `8001H~800AH` 字符串类参数 | 未实现(无法短浮点上送) | 随送检点表设计 |
| **遥测增强** | 4、5 | k=1~9 谐波方和根 + 4 点平均 | 仅基波轨 | 谐波 / 等周波调频 / 零序自产外接切换 三条算法轨 |
| **屏板链路对齐** | 20 | 7003 四命令(INIT 29 B)+ 显存续传 / 拒绝握手 / 链路监视 / F1·F2 + RS-485 屏板通道 | 7003 四命令已通(INIT **8 B**);无续传、无 `bNeedFlash` 拒绝、无 1 分钟监视、键值 6 个 | 报文口径 6 项 + RS-485 通道 1 路(明细见 §9.13) |
> **一句话**:**「标定闭锁」是唯一"再排期也没用"的缺口**(等标准源);「出口与开入」「三相与同期」
> 「电度计量」等 V0.2 硬件;「对下采集」等用户决策;其余规模型条目**全部可在现有硬件上推进**,
@@ -1972,6 +2147,44 @@ pre-commit run --all-files
| 软压板 | 9 面全部可投退且行为可观测(投退后对应功能确实停走/恢复) |
| 出口与开入 | 保护动作 → 出口继电器动作 → 开入回读确认,全链路 ≤ 120 ms |
| 标定解卡 | 8 通道两点标定后 `ADC_CAL_F_VALID` 全置位;注入标准源,保护动作值与定值误差 ≤ 3 % |
| 屏板链路 | INIT 应答 29 B 逐字段一致;`LCDMEM` 偏移 0 得 3204 B、重复召唤无应答、偏移 ≥3200 无应答;`KEEPLIVE` 无应答且 1 分钟不掉链;8 键(含 `F1\|ENT` 组合)界面动作正确(§5.16.8) |
---
### 9.13 屏板链路复刻任务规划
> **口径**:条目一律用**语义短语**(编号规范 P-8),执行序即表序。
> 改动范围只含本产品固件与 `DTU-RemoteLCD` 客户端;**屏板固件不在本仓库**,
> 其行为以 §5.16 为契约做黑盒验收。若现场屏板经**串口服务器(串口透传)**接入,
> 7003 即该透传通道的网络侧承载,帧格式与判据不变。
| 序 | 任务 | 改动点 | 判据 | 跨端 |
|---|---|---|---|---|
| 1 | **报文口径定版** | 本节 + §5.16 + §6.2 按参考源码成文 | 文档门禁全绿(已完成) | — |
| 2 | **INIT 应答补足 29 字节** | `ui_net_sink.c` 的 `remo_send_init()` 组帧由 8 B 扩到 29 B:补颜色位、显存大小、RGB 三色、8 键值表 | 29 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.8 第 2、3 条通过 | **是** |
| 6 | **链路监视** | 1 分钟通信中断计时(收到帧 / 发送成功即重置);超时置状态位并落一行日志 | 断链 60 s 有明确日志与状态;重连后自动恢复推流 | 否 |
| 7 | **KEEPLIVE 静默** | 去掉空帧回显,改为仅重置计时 | §5.16.8 第 4 条通过 | **是** |
| 8 | **发送重试评估** | 对比参考"BUSY + 200 ms 放弃"与现有 `net_send` 阻塞模型,出结论并回填 §5.16.7 第 7 行 | 结论有实测数据支撑(实现 / 明确不实现) | 否 |
| 9 | **客户端一致性回归** | `DTU-RemoteLCD` 按 29 B 解析;把 §5.16.8 七条做成自动化用例 | 七条判据全 PASS | **是** |
| 10 | **RS-485 屏板通道** | `rs485` 收键(物理键号 `1~10` → 逻辑键值)+ `LCD_LED_Update(3200, 4)` 送屏;去抖 `2/12`;背光 120 s | 与 7003 通道同屏同键、互不干扰 | 否 |
**批次划分**:
| 批 | 任务 | 理由 |
|---|---|---|
| 第一批(无跨端风险,可独立发版) | 3、6、8 | 只动本端,旧客户端不受影响 |
| 第二批(跨端,须与客户端同步发版) | 2、4、5、7、9 | 报文口径变更,两端必须同版本 |
| 第三批(随 RS-485 簇解冻) | 10 | 依赖 §5.10 的 RS-485 整簇解冻 |
> ⚠ **唯一破坏性变更**:第 2 条把 INIT 应答从 8 B 改成 29 B。**旧客户端会把 29 B 的前 8 B 当全部、
> 把后 21 B 当作下一帧的 TAG 去找**,解析状态机会被这 21 B 拖住直到超时——表现为"连上了但不出图"。
> 因此第 2、5、7、9 条必须**同批发布**,且发版说明中明确"客户端需升级"。
>
> **屏板固件边界**:本表不覆盖屏板侧固件(帧解析 / 显存写入 / 按键扫描)。屏板可用任意实现,
> 只要满足 §5.16.8 的七条黑盒判据即为兼容。
---
@@ -2018,6 +2231,7 @@ pre-commit run --all-files
| 10 | 104 遥控与定值 | `YK12` 软压板投退、`C_SE` 写定值 | 两段式正答、压板行为可观测、定值跨复位保持 |
| 11 | 保护闭锁态 | 未标定状态下观察 `YX31` 与日志 | 判据停走且**明确可见**(不得静默不动作) |
| 12 | 记录可追溯 | FTP 下载 `/log/soe.log`、`/log/run.log`、`/log/selftest.log` | 记录连续、时标正确、解码校验通过 |
| 13 | 屏板链路一致性 | 任意 TCP 客户端连 7003 按 §5.16.8 七条逐项验证 | INIT 29 B 字段一致、重复召唤/越界无应答、KEEPLIVE 静默、8 键(含组合)动作正确 |
### 10.4 台架验收(已闭环)
@@ -2087,3 +2301,4 @@ pre-commit run --all-files
| 2026-10-27 | **v1.1 全面刷新(以参考产品 CLS100 为横向基准)** | ① 新增 §2.5「与参考产品 CLS100 的能力对照」(12 个能力域逐域给出参考实现 / 本产品现状 / 结论),并据此重写 §2.1 现状口径与 §2.4 产品范围(分"已验收 / 已实现但受制约 / 非本期"三档);② 新增 §4.6「V0.1 硬件能力边界」(H1 双转换器无共同采样触发 / H2 无中点偏置 / H3 无出口开入 / H4 无本地屏 / H5 无 SDIO)作为范围裁剪的硬依据;③ 任务模型由 6 任务更正为 **9 任务**(补 `adcTask` / `iec104Task` / `protectTask`,栈配置改为 words/B 双列),事件位补至 bit8,启动时序补配置段注册与 `adc1_disable` 铁律,线程间通信补双区快照 / SPSC 环 / 脏位;④ **功能需求新增五节**:§5.9 ADC 采集与标定(FR-ADC,含标定折算与前端物理口径)、§5.11 遥测与相量(FR-MEAS)、§5.12 保护功能(FR-PROT,9 元件 + 四源闭锁)、§5.13 定值与运行参数(FR-SET)、§5.14 SOE 与动作记录(FR-SOE)、§5.15 IEC 104 上行(FR-IEC104,含点表推荐响应时间);⑤ 新增 §6.8 104 点表摘要,§6.7 对外 API 补 10 个模块;⑥ §7.2 补采样/相量/遥测/保护/上送七项实时指标,§7.3 内存与栈预算全部换为 2026-10-24 受管快照与 2026-10-22 栈快照,§7.4 门禁改为按族描述,§7.6 补 104 与配置面安全边界;⑦ §8 菜单绑定现状(22/33/42)与内容页分组重写;⑧ §9 改为「缺口总表(G1~G10)+ 推进顺序 + 未接线开关」,删除已闭环的 ADC/104 缺口;⑨ §10 验收补栈/体积门禁、采集与 104 锚点、六条现场项与五项台架闭环用例。**本次只改本文件** |
| 2026-10-27 | **v1.2 改为 1:1 复刻口径(以参考工程源码为唯一清单)** | ① **范围口径反转**:产品范围由「按硬件裁剪」改为「参考源码能力全集」,差异只允许来自 5 项物理不可移植项(X1 双核分工 / X2 VxWorks / X3 本地屏 / X4 一次设备接口 / X5 计量通道,§2.4.1);② §2.5 由「12 域能力对照 + 取舍依据」重写为 **「1:1 复刻基线」**,判定依据从参考项目的分析文档改为 **参考工程源码的常量表与模块文件**(§2.5.1 三要素:点表即契约 / 地址即接口 / 模块即元件);③ 新增 **§2.5.2 19 项能力清单**(源码实测):定值 **249 项 / 23 单元**(`g_tSetModelTab`)、104 定值映射 **107 项 `0x8820~0x8891`**(`g_tCommSetParaTab`)、遥测 **31**、遥测模型 35、电度 **8**、开入 **138**、开出 **31**、动作事件 **33**、录波通道 **65**、软压板 **9**、保护元件 **45 模块**、记录队列 **13 类**、自检 3 类型、录波 3 类型 / 6 段、规约 **12 种**、加密 SM2/SM3/ECDSA;④ 新增 **§2.5.3 104 地址空间 8 段表**并 **更正段基址笔误**——参考 `Rly_IEC104.h` 为 1 起编,遥测 `0x4001`、遥控 `0x6001`(v1.1 及更早写 `4000H+` / `6000H+`),§5.15 与 §6.8 同步更正;⑤ 新增 **§2.5.4 定值 23 单元分布表**(WatchDog 63 / SYS3 45 / VolTimeRecv 17 / AutoReCls 16 …,并说明枚举 28 个中 4 个表内无项的原因)与 **§2.5.5 45 元件九类归集表**(含 `PRS_OverCurrent.c` 判据结构对照);⑥ 新增 **§2.5.6 规约全集 13 行表**(对上 9 种 / 对下 3 类 / 加密)与 **§2.5.7 差异归因表**,结论改为「差距全部是进度而非范围」;⑦ **§9 重写为「复刻进度与路线图」**:删除全部「不做」表述,缺口分 **阻塞型**(标定闭锁 / 出口与开入 / 三相与同期 / 电度计量 / 对下采集 / 第三方送检)与 **规模型**(定值 40→249、映射 40→107、元件 9→45、录波子系统、规约 1→12、国密等)两表,条目一律用**语义短语**命名以免与其它文档的 `S`/`A`/`P` 编号族撞名(编号规范 P-8),推进顺序补「点表铺开必须晚于标定」铁律;⑧ §2.1 产品定位补 1:1 复刻目标与三项差距量化(定值 40 vs 249 / 遥测 9 vs 31 / 开入开出 0 vs 138·31);⑨ §6.8 点表摘要逐段补「与参考的差额」说明(遥测缺第二回线与线电压、遥信缺 138 点开入、定值缺整单元)。**本次只改本文件** |
| 2026-10-28 | **v1.3 缺口逐项细化(新增 §9.4~§9.12)** | ① **定值**:给出 40 项去向对账(覆盖参考 35 + 本地扩展 5),差额由「+209」更正为 **+214 项**;新增 23 单元逐单元差额表、已覆盖 35 项逐项对照(过流三段每段缺方向 / 低压 / 告警 / 低压定值 4 项;零序过流三段 18 项全缺,注意 `PS_3U0_*` 是零序**过压**不是过流;三级负荷只做一级;频率缺「跳闸投退」;电压缺 4 项跳闸 / 告警投退;PT·CT 缺 6 项)、完全未覆盖 163 项逐项清单(`SYS3` 45 / `VolTimeRecv` 17 / `AutoReCls` 16 / `SYN` 13 / `WAVESTART` 12 / `MeaLimit` 10 / `OverCurSpeed` 8 / `OverCurI0` 13 / 小单元 29);② **遥测**:31 点逐点对照,缺 22 点按依赖分三批(线电压与功率 13 / 第二回线 7 / 直流 2),指出「三相电压全落 TPAFE」可一次解锁 6 个线电压点;③ **开入开出**:138 = 软遥信 104 + 硬件 27 + 双点 6 + 多态 1,澄清「104 点 ≠ 104 个端子」;31 开出 = 出口 11 + 信号 20;④ **动作事件**:33 条(421~453)逐条对照,覆盖 9 条;记录参考源码 428/429 **同名**需按事件码区分;⑤ **保护元件**:口径改为模块级 45 → 8,37 个缺失模块逐个给出「缺它的后果 + 依赖」,差额由「+35」更正为 **+37**,指出 `MusterRecov` 总复归是唯一无硬件依赖、可立即开工的元件;⑥ **录波**:14 项硬指标(80 点/周波 = 4000 Hz、6 段、前 5 后 10 返回 2 手动 6 周波、9000 ms、RAM 16、COMTRADE 64/64/16、65 通道)与复刻所需四件东西;⑦ **记录体系**:13 类队列容量表,覆盖 8 类,缺越限 / 闭锁 / COS / 顺控 / 顺控执行;指出「闭锁记录」性价比最高(四源闭锁已全实现却无留痕);⑧ **规约栈**:12 种逐种链路 / 用途 / 工作量特征 + 四层排期,指出对上与对下是两套角色;⑨ 新增 **§9.12 复刻完成判据**(12 条可验证判据)。**本次只改本文件** |
| 2026-10-28 | **v1.4 屏板链路口径更正 + 逐字节复刻规格(新增 §5.16、§9.13)** | ① **口径更正**:v1.3 及更早把参考写成"**板载** LCD + 按键"、把本产品远端推流说成"等价替代",**两处都错**。参考源码中主机侧 5 个碰硬件的函数(`KeyGet` / `WriteScreenByByte` / `LCD_LED_Update` / `getRs485Key` / `anyNewKey`)**全树只有声明没有实现**,按键轮询函数名为 `Key_Rs485_Process()`(注释"轮询从485传来的按键值"),屏板插槽号 `CN_SLOT_DISP = 0`(注释"显示板插槽号固定为0")——**参考的屏和键同样在独立板件上、同样靠链路传输**,本产品与之**同构而非替代**;§2.4.1 X3 由「本地人机」改为「**就地屏板(板件本体)**」,并补口径更正说明段;② **§2.5.2 补第 20 项「远端屏与按键链路」**(状态 🔶),能力计数 19 → **20 项**、🔶 9 → **10 项**,§2.5.7 差异归因同步(X3 不再计为"已用等价方案替代");③ **新增 §5.16 远端屏与按键链路(FR-HMI)**:两条链路对照(RS-485 屏板通道 / TCP 7003 总线)、帧格式逐字节、CRC 覆盖范围、接收定界算法、**INIT 应答 29 B 逐字段偏移表**、键值位掩码语义、`bNeedFlash` 续传与拒绝语义(`-1` / `-2`)、按键状态机与合并优先级、三个定时器(500 ms / 1 分钟 / 200 ms)、发送状态机、`0x55`/`0xaa` 刷新互斥、任务参数(prio 111 / 栈 0x35000);④ **§5.16.7 给出 10 项与参考的差异**,其中 5 项为客户端可见的报文口径差(INIT **8 B vs 29 B** 为最大一条);⑤ **§6.2 按参考源码重写**:更正 INIT 应答长度(原写 8 B)、KEEPLIVE 改为**不应答**(原写"原样回显")、补最长帧 9800 B / 收发缓冲 10240 B / 按键码补 `F1`·`F2` 与位掩码可组合说明;⑥ **新增 §9.13 屏板链路复刻任务规划**:10 条语义短语任务 + 三批划分 + 唯一破坏性变更警示(INIT 长度变更必须与客户端同批发版);⑦ §9.1.2 补「屏板链路对齐」行、§9.12 补完成判据、§10.3 补现场验收第 13 项。**本次只改本文件** |