From 11b4b2af700b7843fb99589131e839f3bafb62c3 Mon Sep 17 00:00:00 2001 From: Wanderingss <1624155937@qq.com> Date: Wed, 28 Oct 2026 09:55:44 +0800 Subject: [PATCH] =?UTF-8?q?docs(=E4=BA=A7=E5=93=81=E9=9C=80=E6=B1=82):=20?= =?UTF-8?q?=E5=8D=95=E8=89=B2=E5=8F=A3=E5=BE=84=E2=80=94=E2=80=94=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=A4=9A=E8=89=B2=E5=8D=8F=E8=AE=AE=EF=BC=8CINIT=20?= =?UTF-8?q?=E5=BA=94=E7=AD=94=2029=20B=20=E6=94=B9=2016=20B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 屏板是单色面板,多色协议不对齐。核查参考源码后确认这不是让步, 而是删死字段,三处证据: - RemoDispBus.h:46 CN_RDISP_TYPE_MONO = TRUE,LCD_TYPE = CN_MODE_GREY_MONO、MEMSIZE = (X>>3)*Y,链路显存本就是 1 bpp。 - RDisp_Form_InitInf 的 CN_RGB_RED/GREEN/BLUE 是编译期常量,不是 逐帧数据,每次召唤都发同样的 12 B。 - RDisp_LcdColor_To_Mono() 对 CN_MODE_GREY_MONO 直接 return TRUE 不转换;RDisp_Lcd16B_To_Mono()(RGB565 转单色)挂在 CN_MODE_COLOR_16B 下,本构建永不进入,是死代码。 改动: - 5.16.5 INIT 表 29 B -> 16 B(宽 2 + 高 2 + 显存 4 + 8 键值表), 删 1 B 颜色位与 12 B RGB,附证据块。 - 6.2 命令集 INIT 行同步,加单色口径注。 - 5.16.6 第 6 条注改为"该函数在参考单色构建下就是空转"。 - 5.16.9 第 1 行改为"补 8 B 键值表 -> 16 B、颜色 13 B 不对齐", 新增约束补单色一条,警示改为 16 B 与 29 B 不可互换。 - 5.16.10 判据第 1 条改 16 B 且不得出现颜色字段。 - 9.13 第 2 条改 16 字节且不加颜色位与 RGB,第 9 条客户端按 16 B 解析,破坏性变更警示改后 8 B。 - 2.4.1 补"多色显示不在不可移植项内"——参考同样单色。 - 8.1 色深行补无灰度无彩色,渲染行改双出口。 - 2.5.2 第 20 项、9.1.2、9.12、10.3 第 13 项同步。 版本 v1.6 -> v1.7。 --- docs/产品需求/产品需求设计文档.md | 93 ++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 27 deletions(-) diff --git a/docs/产品需求/产品需求设计文档.md b/docs/产品需求/产品需求设计文档.md index 930ec2b9..2c50f521 100644 --- a/docs/产品需求/产品需求设计文档.md +++ b/docs/产品需求/产品需求设计文档.md @@ -7,7 +7,7 @@ > 待实现项与路线图、验收判据。 > **事实来源**:本文所有数值与结论均取自仓库内**受管事实源**(代码、`.ioc`、`.map`、网表分析报告与 > 各模块设计文档),凡与其它文档冲突处,以本文标注的权威来源为准。 -> **版本**:v1.6 **日期**:2026-10-28 **状态**:现状基线(含已实现项 + 待实现项) +> **版本**:v1.7 **日期**:2026-10-28 **状态**:现状基线(含已实现项 + 待实现项) > **阅读前提**:建议先读 [`docs/README.md`](../../docs/README.md)(文档索引)与 > [`docs/架构设计/项目架构总览.md`](../../docs/架构设计/项目架构总览.md)(全景架构)。 > **范围口径:1:1 复刻**——本产品是参考产品 **CLS100**(`Scatter_P_HV03.01_SV01.01`,OMAP-L138 @@ -186,6 +186,12 @@ flowchart LR > `Key_Rs485_Process()`(注释"轮询从485传来的按键值");屏板插槽号 `CN_SLOT_DISP = 0` > (注释"显示板插槽号固定为0")。即:**参考的屏和键同样在一独立板件上、同样靠链路传输**。 > 本产品与参考**同构**,不是替代;落在范围外的只有那块**屏板硬件本身**。完整复刻规格见 §5.16。 +> +> **多色显示不在本表内(不是范围外能力)**:参考与本产品**都是单色链路**—— +> 参考 `CN_RDISP_TYPE_MONO = TRUE`、`CN_RDISP_MEMSIZE = (X>>3)*Y`,本产品屏板 1 bpp。 +> 7003 `INIT` 里那 13 B 颜色字段(颜色位 + RGB 三色)是参考遗留的**死常量**, +> `RDisp_LcdColor_To_Mono()` 在单色构建下也是**空转**。本产品**直接删除这 13 B** +> (INIT 由 29 B → **16 B**,§5.16.5),**不属于"决定不做"的能力**。 ### 2.5 1:1 复刻基线(参考源码能力清单) @@ -224,7 +230,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`;屏板侧 `DTU-LCD` | **串口屏板通道**(显存 3200 B + **状态灯 4 B 位掩码**下行 / 键号上行)+ **TCP 7003 镜像** | 7003 四命令已通;**串口屏板通道整条缺失**(协议已按屏板源码定版,见 §5.16.2);INIT 应答 8 B(参考 29 B)、无断点续传、无链路监视、缺 F1/F2 | 🔶 | +| 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~X5 不可移植项上。 > 本表是范围判定的唯一出处,§9 不再重复解释"为什么缺"。 @@ -1277,25 +1283,37 @@ for (i = 1; i < LED_COUNT; i++) /* LE | CMD | 名称 | 客户端请求 | 设备应答 | 备注 | |---|---|---|---|---| | 0 | `KEEPLIVE` | 空 | **不应答** | 源码 `return`,注释"无 keep alive 报文";仅重置 1 分钟通信计时 | -| 1 | `INIT` | 空 | **29 B**(见下表) | 工具召唤屏幕参数 | +| 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 应答数据段(29 B,`RDisp_Form_InitInf`)**: +**INIT 应答数据段(16 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` | +| 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 RGB 三色 `CN_RGB_RED/GREEN/BLUE`)。 +> 三处源码证据表明**这 13 B 在参考自己的构建里就是死字段**: +> +> 1. `RemoDispBus.h:46` `CN_RDISP_TYPE_MONO = TRUE` → `CN_RDISP_LCD_TYPE = CN_MODE_GREY_MONO`、 +> `CN_RDISP_MEMSIZE = (X>>3)*Y`,即**链路显存本身就是 1 bpp**,不是彩色显存。 +> 2. `RDisp_Form_InitInf` 里三个 RGB 值是**编译期常量** `CN_RGB_RED/GREEN/BLUE`, +> **不是逐帧数据**,每次召唤都发同样的 12 B。 +> 3. `RDisp_LcdColor_To_Mono()` 对 `CN_MODE_GREY_MONO` **直接 `return TRUE`**,不做任何转换; +> 真正干活的 `RDisp_Lcd16B_To_Mono()`(RGB565 → 单色)挂在 `CN_MODE_COLOR_16B` 分支, +> 本构建**永不进入**,是死代码。 +> +> 本产品的屏板同样是**单色 1 bpp**(`DTU-LCD` 的 `ScreenPrintf()` 只吃 1 bpp 点阵), +> 所以这 13 B **既无接收方、也无语义**。**整段删除,不对齐多色协议**:29 − 13 = **16 B**。 +> 这不是"少实现"——**参考能力全集里的多色分支连参考自己都没启用**(§2.4.1)。 **键值是位掩码,不是枚举**——可组合下发:`CN_KEY_F1|CN_KEY_ENT = 0x24`(`Key.c` 物理键号 `10` 即此值)。 `CN_KEY_ADD=0x82`、`CN_KEY_SUB=0x84` 只在 RS-485 通道使用,不进 7003 键值表。 @@ -1316,6 +1334,12 @@ for (i = 1; i < LED_COUNT; i++) /* LE 6. **刷新来源**:`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 行)。 @@ -1359,7 +1383,7 @@ for (i = 1; i < LED_COUNT; i++) /* LE | # | 项 | 参考 | 本产品 | 处置 | |---|---|---|---|---| -| 1 | INIT 应答长度 | **29 B**(含颜色位 / 显存大小 / RGB 三色 / 8 键值表) | **8 B**(宽 2 + 高 2 + 帧字节 4) | **补 21 B**,客户端按 29 B 解析 | +| 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` 不发 | 无 | 补(防撕裂帧) | @@ -1381,9 +1405,13 @@ for (i = 1; i < LED_COUNT; i++) /* LE - **700000 8N1**,软件 DE;主机侧 DE 极性由本板收发器决定,**不可照抄屏板**。 - **屏板每 ≈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 实现, -> 补 29 B 后**客户端必须同步改**,否则会错位解析。这是本项复刻唯一的跨端风险点。 +> 补到 **16 B** 后**客户端必须同步改**,否则会错位解析。这是本项复刻唯一的跨端风险点。 +> 注意:**16 B 与参考的 29 B 不是同一口径**——13 B 颜色字段被有意删掉, +> 客户端**不得**按 29 B 预留缓冲再截取前 16 B 使用(**从偏移 4 起含义即不同**: +> 参考偏移 4 是颜色位,本产品偏移 4 是显存大小的高字节)。 > > 第 11 / 12 / 13 条是**整条链路缺失**,不是报文细节差异——它决定了本产品能否脱离 PC 独立带屏运行。 > @@ -1391,7 +1419,8 @@ for (i = 1; i < LED_COUNT; i++) /* LE #### 5.16.10 复刻完成判据 -1. 任意 TCP 客户端连 7003 → 发 `INIT` → 收到 **29 B**,字段值与上表逐字节一致。 +1. 任意 TCP 客户端连 7003 → 发 `INIT` → 收到 **16 B**(宽 2 + 高 2 + 显存 4 + 8 键值表), + 字段值与 §5.16.5 逐字节一致;**不得**出现颜色位或 RGB 字段。 2. 发 `LCDMEM(0)` → 收到 `3204 B`;**再次**发 `LCDMEM(0)`(新图未就绪)→ **无应答**(对应参考 `-1`)。 3. 发 `LCDMEM(3200)` → **无应答**(对应参考 `-2`)。注:该分支在 `bNeedFlash` 为真时先被 `-1` 截住, 只能在"新图已拷贝、尚未上送"的窗口内触发,属**边角路径**,判据以"无应答且不越界读"为准。 @@ -1462,11 +1491,16 @@ for (i = 1; i < LED_COUNT; i++) /* LE | CMD | 名称 | 请求数据段 | 应答数据段 | |---|---|---|---| | 0 | KEEPLIVE | 无 | **无应答**(仅重置 1 分钟通信计时) | -| 1 | INIT | 无 | `[宽u16][高u16][颜色位u8][显存u32][R u32][G u32][B u32][8 键值]`(**29 B**) | +| 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(含 29 B 逐字段偏移)。 +**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`)。 @@ -1748,8 +1782,8 @@ pre-commit run --all-files | 项 | 值 | |---|---| | 屏幕尺寸 | 160 × 160 px | -| 色深 | 1bpp 单色(MSB 优先),帧缓冲 3200 B | -| 渲染 | LVGL 离屏渲染到 `g_ui_fbuf`;MCU 无物理屏,经 TCP 7003 推流 | +| 色深 | **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 循环 | @@ -1880,7 +1914,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 | **串口屏板通道**(**700000 8N1 / 软件 DE**,帧 A 6 B 召唤、帧 B **4208 B** 应答:显存 3200 B + **状态灯 4 B 位掩码** + 4 B info)+ **7003 四命令**(INIT 29 B)+ 续传 / 拒绝握手 / 链路监视 / F1·F2 | 只有 7003 四命令(INIT **8 B**);**串口通道 0**;无状态灯下行;无续传、无 `bNeedFlash` 拒绝、无 1 分钟监视、键值 6 个 | 串口通道整条(协议已定版)+ 7003 报文口径 6 项(明细见 §9.13) | +| **屏板链路对齐** | 20 | **串口屏板通道**(**700000 8N1 / 软件 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 硬件;「对下采集」等用户决策;其余规模型条目**全部可在现有硬件上推进**, @@ -2454,7 +2488,7 @@ pre-commit run --all-files | 软压板 | 9 面全部可投退且行为可观测(投退后对应功能确实停走/恢复) | | 出口与开入 | 保护动作 → 出口继电器动作 → 开入回读确认,全链路 ≤ 120 ms | | 标定解卡 | 8 通道两点标定后 `ADC_CAL_F_VALID` 全置位;注入标准源,保护动作值与定值误差 ≤ 3 % | -| 屏板链路 | **串口通道**:屏板 275 ms 召唤、主机 ≤200 ms 回 **4208 B**,连续 10 min 无超时;显存 3200 B 与 `g_ui_fbuf` 逐字节一致;7 个物理键(`1/2/3/4/7/8/9`)动作正确;**状态灯位掩码逐位一致、LED 0 恒亮**;屏板 ≈5000 s 自复位不误判离线;LOGO 下发后断电重启仍在;**网络通道**:INIT 应答 29 B 逐字段一致、`LCDMEM` 偏移 0 得 3204 B、重复召唤无应答、偏移 ≥3200 无应答、`KEEPLIVE` 无应答且 1 分钟不掉链、8 键(含 `F1\|ENT` 组合)动作正确(§5.16.10 十五条) | +| 屏板链路 | **串口通道**:屏板 275 ms 召唤、主机 ≤200 ms 回 **4208 B**,连续 10 min 无超时;显存 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 十五条) | --- @@ -2476,14 +2510,14 @@ pre-commit run --all-files | 序 | 任务 | 改动点 | 判据 | 跨端 | |---|---|---|---|---| | 1 | **报文口径定版** | 本节 + §5.16 + §6.2 按参考源码成文 | 文档门禁全绿(已完成) | — | -| 2 | **INIT 应答补足 29 字节** | `ui_net_sink.c` 的 `remo_send_init()` 组帧由 8 B 扩到 29 B:补颜色位、显存大小、RGB 三色、8 键值表 | 29 B 逐字节比对通过 | **是** | +| 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` 按 29 B 解析;把 §5.16.10 第 1~7 条做成自动化用例 | 七条判据全 PASS | **是** | +| 9 | **客户端一致性回归** | `DTU-RemoteLCD` 按 **16 B** 解析;把 §5.16.10 第 1~7 条做成自动化用例 | 七条判据全 PASS | **是** | | 10 | **串口物理层落地** | 按 §5.16.2 定版:**700000 8N1**、软件 DE(默认 **USART3 PB10/PB11** + 一个空闲 GPIO 作 DE)、RX 缓冲 ≥4208 B + 空闲中断断帧、发送走 **DMA 一次性发完**(禁逐块阻塞) | 环回 + 示波器实测 700 kbaud 分频零误差;屏板能收到帧 A 并回帧 B | 否 | | 11 | **帧 A 解析 / 帧 B 组帧** | 新增屏板通道模块:识别 6 B 请求(`01 03 type key CRC_H CRC_L`)、校验 CRC-16/MODBUS(**高字节在前**);组 **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 条通过 | 否 | @@ -2499,10 +2533,14 @@ pre-commit run --all-files | 第二批(跨端,须与客户端同步发版) | 2、4、5、7、9 | 报文口径变更,两端必须同版本 | | 第三批(**独立立项**,不随 RS-485 冻结) | 10、11、12、13、14、15 | 屏板串口通道是**独立需求**,与 §5.10 冻结的"对下采集簇"不是一回事;物理层已按屏板源码定版(**700000 8N1 / 软件 DE**),默认走 USART3 另配 DE GPIO,**不必解冻 UART4** | -> ⚠ **唯一破坏性变更**:第 2 条把 INIT 应答从 8 B 改成 29 B。**旧客户端会把 29 B 的前 8 B 当全部、 -> 把后 21 B 当作下一帧的 TAG 去找**,解析状态机会被这 21 B 拖住直到超时——表现为"连上了但不出图"。 +> ⚠ **唯一破坏性变更**:第 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 的十五条判据即为兼容。 @@ -2559,7 +2597,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 客户端同时接入,按 §5.16.10 **十五条**逐项验证 | 串口侧:275 ms 召唤 / ≤200 ms 回 4208 B、显存 3200 B 逐字节一致、**状态灯 4 B 掩码逐位一致**、7 键动作正确、自复位不误判离线;网络侧:INIT 29 B、重复召唤 / 越界无应答、KEEPLIVE 静默、8 键(含组合)动作正确 | +| 13 | 屏板链路一致性 | 串口屏板 + TCP 客户端同时接入,按 §5.16.10 **十五条**逐项验证 | 串口侧:275 ms 召唤 / ≤200 ms 回 4208 B、显存 3200 B 逐字节一致、**状态灯 4 B 掩码逐位一致**、7 键动作正确、自复位不误判离线;网络侧:INIT **16 B**、重复召唤 / 越界无应答、KEEPLIVE 静默、8 键(含组合)动作正确 | ### 10.4 台架验收(已闭环) @@ -2632,3 +2670,4 @@ pre-commit run --all-files | 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.9 给出 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 项。**本次只改本文件** | | 2026-10-28 | **v1.5 补串口屏板通道(显示信息不只走网络)** | ① **口径再更正**:v1.4 把串口通道写成"链路 A,随 RS-485 簇冻结",等于把它降级成可选——**错**。参考的架构是**一份显存、两个出口**:**串口屏板通道是主通道**(`LCD_LED_Update(显存 3200 B, LED 4 B)` 变化驱动 + `WriteScreenByByte` 500 ms 兜底),**TCP 7003 是镜像**;上行同理(`getRs485Key()` 物理键号 1~10 为主,`g_tRemoteKey` 为镜像,两者在 `Key_Read()` 汇合且**本地优先**)。§5.16 标题改为「**屏板链路:串口主通道 + 网络镜像**」并重写开篇;② **§5.16.1 重写为「一份显存、两个出口」**:显存物理基址 `CN_VIDEO_ADDRESS_BASE = 0xC1F00000`(非 cache 区)、三条下行路径与两条上行路径的归属任务 / 调用 / 载荷 / 节拍对照表;③ 新增 **§5.16.2「本产品的串口通道(待建)」**:V0.1 串口资源盘点(USART1 调试占用 / UART4 被冻结 RS-485 占用 / **UART5、USART2、USART3 空闲**),默认选 **USART3(PB10/PB11)**,若屏板为 RS-485 半双工则改 UART4 并先解冻该簇;④ 新增 **§5.16.3「参考实现的屏板侧接口一览」**,并**明确列出交付源码推不出的四项**(波特率与数据格式 / 帧头与校验 / 半双工方向控制 / 3200 B 是否分片与应答)——在拿到实测前不得声称"按参考协议实现";⑤ **§5.16.9 差异表由 10 行扩到 14 行**,新增「串口屏板通道整条缺失」「双出口并发缺失」「面板指示灯语义不同」「背光对比度」四项,并注明第 11/12 条是**整条链路缺失**而非报文细节;⑥ **§5.16.10 判据由 7 条扩到 12 条**,新增串口侧 5 条(键号注入 / 500 ms 内出帧 / 双通道并发不丢帧不串帧 / 拔插恢复 / 背光);⑦ **§9.13 任务由 10 条扩到 13 条**:原「RS-485 屏板通道」一条拆为「串口通道物理层定版 / 串口下行显存 / 串口上行按键 / 双通道并发回归」四条,批次表第三批改为**独立立项、不随 §5.10 冻结**,并补前置阻塞(需屏板实物验收;拿不到固件或抓包时不得把猜测定成契约);⑧ §5.16.8 `tTimerLCD` 行由"此路不实现"改为"串口通道周期兜底节拍(待建)",§2.5.2 第 20 项、§9.1.2、§9.12、§10.3 同步。**本次只改本文件** | | 2026-10-28 | **v1.6 屏板源码到手:串口通道协议定版 + 状态灯下行** | ① **屏板固件已获得**(`D:\Code\DTU Code\DTU-LCD`,STM32F103ZE + UC1698U 160×160 单色 + **20 路状态指示灯** + 7 个物理按键),v1.5 列的"四项未知"**全部消解**;② **§5.16.2 重写为「串口通道:物理层与帧格式(屏板源码实测)」**:**700000 8N1**(APB1 42 MHz 分频零误差、`BRR = 0x3C0`)、软件 DE、**角色反转(屏板是 Modbus 主站、主机是从站 `0x01`)**、帧 A 6 B 召唤(`01 03 type key CRC_H CRC_L`,`KEY_CMD=0` / `RT_CMD=1`,CRC-16/MODBUS 只覆盖前 4 B、**高字节在前**)、帧 B **4208 B** 图像应答(3200 显存 + 4 B 状态灯 + 4 B info + 998 B 填充 + 2 B CRC,覆盖 `[0, 4205]`)、时序 275 ms / 200 ms / 5 次超时、200 ms 预算下 4208 B 约 60.1 ms(占 30 %)、主机端口默认 **USART3 + 另配 DE GPIO**(**不必解冻 UART4**);③ **§5.16.3 重写为「屏板侧行为:状态灯 / 按键 / 背光 / LOGO」**,新增**状态灯下行**:`info[0..3]` 为 **32 位小端位掩码**、**ID 0 = 电源灯硬件常亮、ID 1~19 对应 bit1~19**,给出 20 路 LED 引脚表,并指出"**位 → 业务状态映射表参考源码没有、须由本产品自定**";键值 `KEY_TYPE` 表(`0` 无键 / `1` ENTER / `2` UP / `3` DOWN / `4` ESC / `5` ADD / `6` DEC / `7` LEFT / `8` RIGHT / `9` RESET / `10` FACTORY),并**指出与参考主机 `getRs485Key()` 的 `9` / `10` 语义冲突**(参考是 `F1` 与 `F1+ENT`)、`key_configs[]` 仅 7 项且无 ADD/DEC 入口;背光自管、LOGO(Flash `0x0803F000`、魔数 `0x89 0x45`)、屏板健壮性(CRC 错 ≥3 仅清计数**不自愈**、**≈5000 s 自复位**、DMA 接收问题未解决);④ **§5.16.9 差异表**第 8 / 11 / 12 / 13 / 14 行按屏板实测重写,并新增"来自屏板固件的新增约束"5 条;⑤ **§5.16.10 判据由 12 条扩到 15 条**(275 ms 召唤 / ≤200 ms 回 4208 B、显存逐字节、7 键、**状态灯逐位**、双通道并发、**自复位容忍**、拔插恢复、**LOGO 下发**);⑥ **§9.13 任务由 13 条改为 15 条**:第 10 条由"物理层定版"改为"**串口物理层落地**"(参数已定)、新增第 12 条"**状态灯位映射表**"与第 15 条"**LOGO 下发流程**"、第 14 条并入"自复位容忍",批次表第三批改 10~15 并注明**不必解冻 UART4**,删除"拿不到固件不得定契约"告警(已消解),保留"**4208 vs 3208 待台架复核**";⑦ **§5.8 补屏板 20 路指示灯与主板 6 路 LED 是两套独立输出**;§5.6 FR-UI-1 改为"**双出口推流**";§6.2 口径注改为"串口通道是 Modbus RTU 风格裸帧、**不能共用组帧代码**";§2.4.1 X3、§2.5.2 第 20 项、§5.16.1、§5.16.8 `tTimerLCD` 行、§9.1.2、§9.12、§10.3 第 13 项同步。**本次只改本文件** | +| 2026-10-28 | **v1.7 单色口径:删除多色协议,INIT 由 29 B 改 16 B** | 用户裁定"屏幕板都是单色的,多色协议可以删除、不必对齐"。**核查后确认这不是让步,而是删死字段**:① **三处源码证据**——`RemoDispBus.h:46` `CN_RDISP_TYPE_MONO = TRUE` → `CN_RDISP_LCD_TYPE = CN_MODE_GREY_MONO`、`CN_RDISP_MEMSIZE = (X>>3)*Y`(链路显存本就是 1 bpp);`RDisp_Form_InitInf` 里 `CN_RGB_RED/GREEN/BLUE` 是**编译期常量**而非逐帧数据;`RDisp_LcdColor_To_Mono()` 对 `CN_MODE_GREY_MONO` **直接 `return TRUE` 不转换**,真正干活的 `RDisp_Lcd16B_To_Mono()`(RGB565→单色)挂在 `CN_MODE_COLOR_16B` 下**本构建永不进入**(死代码);② **§5.16.5 INIT 应答表由 29 B 重写为 16 B**(宽 2 + 高 2 + 显存 4 + 8 键值表),删掉 1 B 颜色位 + 12 B RGB,并补"为什么是 16 B"的证据块;③ **§6.2 命令集 INIT 行**同步改 16 B 并加"单色口径"注(颜色位与 RGB 整段删除、`RDisp_LcdColor_To_Mono()` 不存在);④ **§5.16.6 第 6 条注**改为"该函数在参考单色构建下就是空转",避免误以为本产品漏了一步转换;⑤ **§5.16.9 第 1 行**由"补 21 B"改为"**补 8 B 键值表 → 16 B**,颜色 13 B 不对齐";"新增约束"补"单色"一条;末尾警示改为 **16 B vs 29 B 不可互换**(从偏移 4 起含义即不同,客户端不得复用参考 29 B 解析器截前 16 B);⑥ **§5.16.10 判据第 1 条**改 16 B 且"不得出现颜色位或 RGB";⑦ **§9.13 第 2 条**改"INIT 应答补足 **16** 字节 / 不加颜色位与 RGB"、第 9 条客户端按 16 B 解析、破坏性变更警示改 16 B(后 8 B 而非后 21 B)并补"不可与参考 29 B 互换";⑧ **§2.4.1 补"多色显示不在本表内"**——参考与本产品都是单色链路,删的是死字段,**不属于"决定不做"的能力**;§2.5.2 第 20 项、§9.1.2、§9.12、§10.3 第 13 项同步;⑨ **§8.1 色深行**补"无灰度、无彩色,7003 INIT 颜色字段已删",渲染行改为"串口屏板通道(主)+ TCP 7003(镜像)双出口"。**本次只改本文件** |