merge: task/screenlink-doc-scope-cleanup 合入 v2-on-ui
任务 screenlink(1 个提交):屏板链路规划只讲屏板通道本身, 删除与本方案无关的其它串口通道对照内容。纯文档改动, 提交期钩子全绿(文档链接 / 新增行编号门禁 / gitlint)。
This commit is contained in:
+20
-43
@@ -33,14 +33,13 @@
|
||||
| 取 3200 B 显存 | `Drivers/BSP/UI/ui_net_sink_backend.h` 的 `ui_net_sink_get_lcdmem()` | **直接复用**,与 7003 通道同一数据源,天然一致 |
|
||||
| 注入按键 | 同上,`ui_net_sink_inject_key(uint8_t)` | **直接复用**,串口与 7003 走同一入口,无需改 `ui_net_sink.c` |
|
||||
| 1bpp 显存 | `g_ui_fbuf`(`ui_port.c`),`UI_FB_SIZE = 3200` | 160×160÷8,与屏板 `Picture[3200]` 逐字节同构 |
|
||||
| 半双工 DE 时序经验 | `Drivers/BSP/RS485/rs485.c`(拉 DE → 等建立 → 发 → 等 TC → 收 DE) | **照思路,不照代码**(长帧限制见 §1.2) |
|
||||
| UART 外设已初始化 | `Src/usart.c`:USART1/2/3、UART4/5 全部 `MX_*_Init()` 已调用(`Src/main.c:130-137`) | 端口是现成的,只需改波特率(USART1 侧**不需要 DE**) |
|
||||
| UART 外设已初始化 | `Src/usart.c`:USART1/2/3、UART4/5 全部 `MX_*_Init()` 已调用(`Src/main.c:130-137`) | 端口是现成的,只需改波特率(USART1 侧 TTL 直连,没有方向切换) |
|
||||
| 静态任务分配 | `Inc/FreeRTOSConfig.h` `configSUPPORT_STATIC_ALLOCATION = 1` | 可用 `xTaskCreateStatic`,**不占 RTOS 堆**(堆已满,见 §1.3) |
|
||||
|
||||
### 1.2 缺什么(要新建)
|
||||
|
||||
1. **协议层**:CRC-16/MODBUS(仓内没有现成的,`App`/`Drivers` 里搜不到)、帧 A 解析、帧 B 组帧。
|
||||
2. **传输层**:USART1 的 700 kbaud 配置、6 B 收 + 4208 B 发的时序(**无 DE**——TTL 直连没有方向控制)。
|
||||
2. **传输层**:USART1 的 700 kbaud 配置、6 B 收 + 4208 B 发的时序(**无方向控制**——TTL 直连是 TX / RX 两根独立线)。
|
||||
3. **状态灯映射表**:19 路业务状态 → 屏板 LED 位的表,**参考源码里没有,必须自己定义**(`docs/产品需求/产品需求设计文档.md` §5.16.3 ①)。
|
||||
4. **一个宿主**:谁来跑这个链路(决策三)。
|
||||
|
||||
@@ -67,20 +66,14 @@
|
||||
|
||||
### 决策一:波特率与物理介质(**已裁定 2026-10-28**)
|
||||
|
||||
用户裁定:**屏板挂 USART1(PA9/PA10),日志迁 RS-232 通道。** 原来那个"250 kbps 收发器"的死结因此消失:
|
||||
用户裁定:**屏板挂 USART1(PA9/PA10),日志迁 RS-232 通道。** 700 kbaud 只有这条 MCU 引脚直出的通道吃得到,原来的速率死结因此消失:
|
||||
|
||||
| 项 | 结论 |
|
||||
|---|---|
|
||||
| 端口 | **USART1**——唯一一条 MCU 引脚直出 TTL、不经收发器的通道,同时引到 U5 子板连接器 |
|
||||
| 波特率 | 700000 8N1,`BRR = 0x0078`(APB2 84 MHz → `84 000 000 / (16 × 700 000) = 7.5`,误差 0 %) |
|
||||
| DE | **不需要**——TTL 直连是两根独立线,没有半双工方向控制 |
|
||||
| 剩余子决策 | **USART1 那端接什么**:① 直连屏板 UART2 的 TTL 侧(PA2/PA3,绕过屏板自己的收发器);② 经一个 ≥1 Mbps 的外部 485 模块接屏板 A/B。**台架先按 ① 做**,产品形态再定 |
|
||||
|
||||
> ⚠ 选 ② 时 DE 由外部模块决定,**不可照抄屏板的"低 = 发送"**——那是屏板自己那套收发器的接法。
|
||||
> 而且模块的速率上限要单独核,别又买回一个 250 kbps 的。
|
||||
|
||||
> 原方案 A(换 `U15`)/ B(屏板降速)**不再需要**:屏板不走板上 485 通道,`TP8485E-SR` 与本项无关。
|
||||
> 若将来又要回到 485 通道,那两条路的代价表还在本文 v1 的历史里,届时重新评估。
|
||||
| 方向控制 | **不需要**——TTL 直连是 TX / RX 两根独立线(全双工),没有方向切换 |
|
||||
| 剩余子决策 | **USART1 那端怎么接**:TTL 直连屏板 UART2 侧(PA2/PA3,绕过屏板自己的收发器)。**台架按这条做**;产品形态的线束长度与隔离需求届时单独评估 |
|
||||
|
||||
### 决策二:用哪个 UART(**已裁定 2026-10-28**)
|
||||
|
||||
@@ -89,20 +82,15 @@
|
||||
| **USART1** | PA9 / PA10 | 调试口 + U5 直连 TTL(ST_TX0/RX0) | ✅ **屏板链路** |
|
||||
| **USART2** | PD5 / PD6 | **RS232#3**(U10 隔离 → U13 TPT3232E → CN1) | ✅ **日志**(默认) |
|
||||
| UART5 | PC12 / PD2 | **RS232#1**(U9 隔离 → U13 → CN1) | 备选日志口 |
|
||||
| UART4 | PC10 / PC11,DE = **PA15** | **RS485#4**(U11 → U15 → A/B → CN1) | 冻结簇,**不碰** |
|
||||
| USART3 | PB10 / PB11 | U5 直连 TTL(ST_TX2/RX2) | 空闲 |
|
||||
|
||||
**日志口选 USART2 还是 UART5**:两者都经隔离器 → `U13` TPT3232E → CN1,能力等价;
|
||||
控制台是**只发不收、寄存器轮询**,DMA 也用不上,所以挑哪个只取决于**现场把 CH340 接到哪个端子**。
|
||||
默认写 **USART2(RS232#3)**;若实际接的是 RS232#1,就换成 `huart5`——**迁移时收口成一处宏,别散改**。
|
||||
|
||||
> ⚠ **UART4 不要动**:`rs485_init(&g_rs485, &huart4, …)` 与 V0.1 网表一致(V0.1 把 RS485#4 轮换到了 UART4),
|
||||
> 摘它等于动冻结簇的验收基线。本文 v1 曾把这里判成"网表自相矛盾",是拿 V0.0 摘要行对 V0.1 代码,
|
||||
> 判断依据错了——见 §0 末尾那条纠正。
|
||||
|
||||
> ⚠ **USART1 交接前必须确认两件事**:① 控制台已不再写 `USART1->DR`(否则两条流互相插字节,
|
||||
> 症状是"屏板偶尔花屏 + 日志偶尔乱码",很容易误判成 CRC 或时序问题);
|
||||
> ② 屏板链路的错误回调里**要清 ORE**(机理见 §0 那条纠正),否则一次噪声就永久锁死。
|
||||
> ② 屏板链路的错误回调里**要清 ORE**(overrun 一旦锁存,接收再也进不来),否则一次噪声就永久锁死。
|
||||
|
||||
### 决策三:谁来跑这个链路(宿主)
|
||||
|
||||
@@ -143,7 +131,7 @@
|
||||
|---|---|---|---|
|
||||
| 0-1 | **台架串口线挪位** | 硬件:CH340 从 USART1 调试口改接 CN1 的 RS-232 端(或 U14) | `serial-assistant` 在 RS-232 侧能收到日志 |
|
||||
| 0-2 | **日志口迁移(USART1 → RS-232)** | ① `console_log.c` 的 `huart1`、`USART1_IRQn`、`__HAL_RCC_USART1_CLK_*`、`MX_USART1_UART_Init()` 收口成**一处端口宏**,指向 `huart2`(RS232#3)或 `huart5`(RS232#1);② 该实例改 **`UART_MODE_TX`**(只发不收,把 RX 从机制上摘掉) | 日志在 RS-232 侧可读、内容与迁移前一致;连续 10 min 无 ORE 锁存、无 `[ERR]`;USART1 完全空出 |
|
||||
| 0-3 | **定 USART1 那端的物理介质** | 直连屏板 TTL 侧,或外部 ≥1 Mbps 485 模块(决策一的剩余子决策) | 结论落纸,含接法与验收方式 |
|
||||
| 0-3 | **落定 USART1 到屏板的接线** | 按决策一:TTL 直连屏板 UART2 侧(PA2/PA3);把线束接法与验收方式写清楚 | 接法落纸;照此接线后屏板发来的 6 B 召唤帧能被收到 |
|
||||
|
||||
> PA10 **不需要动**——用户 2026-10-28 确认一直是接线的,原"接 PA10"那条任务作废(§0 第 2 行)。
|
||||
|
||||
@@ -154,18 +142,17 @@
|
||||
|
||||
> 批 0 期间可以先做**批 1 的第 1 项**(协议层纯软件、不碰硬件),不冲突。
|
||||
|
||||
### 批 1 · 物理层打通(4 项)
|
||||
### 批 1 · 物理层打通(3 项)
|
||||
|
||||
| 序 | 任务 | 改动点 | 判据 |
|
||||
|---|---|---|---|
|
||||
| 1-1 | **协议层模块(纯逻辑,可主机单测)** | 新建 `Drivers/BSP/ScreenLink/sb_proto.c/h`:CRC-16/MODBUS(表与屏板 `auchCRCHi/Lo` 逐字节一致)、帧 A 解析、帧 B 组帧 | 主机单测:给定 6 B 召唤帧能算出屏板同样的 CRC;组出的 4208 B 帧 CRC 自校验通过 |
|
||||
| 1-2 | **波特率与格式落地** | `STM32F407-Demo.ioc` 里把 **USART1** 改 **700000 / 8N1 / 16 倍过采样**(改 `.ioc` 而不是只改 `Src/usart.c`,否则 CubeMX 重生成会丢);`Src/usart.c` 只写 USER CODE | 示波器/逻辑分析仪实测位宽误差 **< 1 %**;理论值 `USARTDIV = 7.5`、`BRR = 0x0078`(APB2 84 MHz),误差 0 % |
|
||||
| 1-3 | **USART1 收中断与全局回调分支** | 开 IDLE 中断接收(缓冲 **16 B**);`HAL_UARTEx_RxEventCallback` 里**加 USART1 分支**(现有回调只认 `g_rs485.huart`,不加分支会静默收不到);`HAL_UART_ErrorCallback` 同样要加,且**必须清 ORE/NE/FE 并重挂接收**(`__HAL_UART_CLEAR_OREFLAG` 或读 SR 再读 DR) | 屏板每 275 ms 发来的 6 B 能稳定收到,`Size == 6`,CRC 通过率 100 %;**拔插一次 TX 线制造噪声后能自动恢复**(不清 ORE 会永久锁死) |
|
||||
| 1-4 | **(条件项)外部 485 模块的 DE** | **仅当** 0-4 选了"经外部模块接 A/B"才做:新建 `sb_link.c/h`,拉 DE → 等建立(**不要用 `HAL_Delay(1)`,用 DWT 忙等 ≤10 µs**)→ 发 → 等 TC → 松 DE | 逻辑分析仪上看 DE 与最后一字节的时序:DE 必须在 TC 之后才翻转,不得截断末字节 |
|
||||
| 1-3 | **USART1 收中断与全局回调分支** | 开 IDLE 中断接收(缓冲 **16 B**);`HAL_UARTEx_RxEventCallback` 里**加 USART1 分支**(现有回调只把事件分发给另一条在用通道的句柄,不加分支会静默收不到);`HAL_UART_ErrorCallback` 同样要加,且**必须清 ORE/NE/FE 并重挂接收**(`__HAL_UART_CLEAR_OREFLAG` 或读 SR 再读 DR) | 屏板每 275 ms 发来的 6 B 能稳定收到,`Size == 6`,CRC 通过率 100 %;**拔插一次 TX 线制造噪声后能自动恢复**(不清 ORE 会永久锁死) |
|
||||
|
||||
> ⚠ **`HAL_UARTEx_RxEventCallback` / `HAL_UART_ErrorCallback` 是全局单例**(`Drivers/BSP/RS485/rs485.c:189/205`),
|
||||
> 现在只判 `huart == g_rs485.huart`。USART1 必须加分支,否则中断进来了但没人处理——
|
||||
> 表象是"屏板一直超时",很容易误判成协议错。
|
||||
> ⚠ **`HAL_UARTEx_RxEventCallback` / `HAL_UART_ErrorCallback` 是全局单例**——全工程只有一处实现,
|
||||
> 现在只按它自己那个 `huart` 句柄分发(定位:全库搜这两个回调名就能找到实现处)。
|
||||
> USART1 必须加自己的分支,否则中断进来了但没人处理——表象是"屏板一直超时",很容易误判成协议错。
|
||||
|
||||
### 批 2 · 协议实现(5 项)
|
||||
|
||||
@@ -208,8 +195,6 @@ Drivers/BSP/ScreenLink/
|
||||
└── sb_link.c/h 传输:USART1、任务宿主、状态灯映射表 ← 依赖 HAL,仅 MCU
|
||||
```
|
||||
|
||||
DE 控制不单独成模块:**只有 0-4 选了"外部 485 模块"才需要**,届时并进 `sb_link.c` 里两个小函数即可。
|
||||
|
||||
**为什么拆两层**:协议层不碰 HAL 才能在 `test/host/` 里跑单测(项目既有做法:原样 include 生产 `.c`,
|
||||
stub 提供 HAL)。屏板侧 CRC 有查表实现,**用同一张表做交叉验证**是最省事的正确性保证。
|
||||
|
||||
@@ -230,7 +215,7 @@ stub 提供 HAL)。屏板侧 CRC 有查表实现,**用同一张表做交叉
|
||||
|
||||
> ⚠ **帧长 4208 而不是 3208**:屏板接收侧实参是 `Check_CRC(DR, UART_RX_LEN)`,`UART_RX_LEN = 4208`,
|
||||
> 即 CRC 取 `DR[4206]/DR[4207]`。只发 3210 B 会让屏板读到陈旧字节 → **CRC 必失败且静默丢弃**
|
||||
> (屏板 `RS485_Process` 里 CRC 错只累加计数,不报错、不回帧,表象就是"屏板不亮")。
|
||||
> (屏板接收侧 CRC 错只累加计数,不报错、不回帧,表象就是"屏板不亮")。
|
||||
> 这是**最容易踩且最难查**的一条,批 2 第一件事就是按 4208 组帧。
|
||||
|
||||
### 4.3 键值映射表
|
||||
@@ -253,14 +238,10 @@ stub 提供 HAL)。屏板侧 CRC 有查表实现,**用同一张表做交叉
|
||||
|
||||
### 4.4 不要做的事
|
||||
|
||||
- ❌ **不要改 `rs485.c` 的常量**(`RS485_RX_BUF_SIZE` / `RS485_TX_MAX_LEN` 改大会牵动冻结的采集簇基线)。
|
||||
长帧走新模块;万一要 DE 时序,照思路自己实现。
|
||||
- ❌ **不要让控制台继续写 `USART1->DR`**——这是本项最容易犯的错。`console_log.c` 是逐字节轮询直写,
|
||||
和屏板链路的 4208 B 共用同一个数据寄存器,两条流一混,症状是"屏板偶尔花屏 + 日志偶尔乱码",
|
||||
查起来会误以为是 CRC 或时序问题。批 0 的 0-3 就是干这个的。
|
||||
查起来会误以为是 CRC 或时序问题。批 0 的 0-2 就是干这个的。
|
||||
- ❌ **不要在 `Src/freertos.c` 里加任务**——那是 CubeMX 生成物,重生成会丢。
|
||||
- ❌ **不要用 `HAL_Delay(1)` 做 DE 建立延时**(`rs485.c` 那样做是为了兼容它自己的场景):
|
||||
700 kbaud 下每帧多 1 ms 无所谓,但任务里阻塞 1 ms 是白给;用 DWT 忙等 ≤10 µs 更干净。
|
||||
- ❌ **不要把 4208 B 缓冲放到栈上**。
|
||||
- ❌ **不要按屏板 readme 的 3208 B 组帧**(见 §4.2 的警示)。
|
||||
|
||||
@@ -277,10 +258,10 @@ stub 提供 HAL)。屏板侧 CRC 有查表实现,**用同一张表做交叉
|
||||
| 2 | PC 串口助手**模拟屏板**:手发 6 B 召唤帧,看主机回的 4208 B | **USB 转 TTL 模块**接 USART1(PA9/PA10)+ 主机板 | 主机侧协议 100 % 可验证 |
|
||||
| 3 | 反向:PC 收主机帧,用脚本核对 4208 B / CRC / 显存内容 | 同上 | 帧内容正确性(与 `g_ui_fbuf` 逐字节比) |
|
||||
| 4 | **接真屏板**(TTL 直连屏板 UART2 的 PA2/PA3 一侧) | 屏板实物 + 屏板 TTL 引出 | 出图 + 按键 + 状态灯全链路 |
|
||||
| 5 | 产品形态:换外部 ≥1 Mbps 485 模块或直连线束 | 模块 + 线束 | 产品形态验证 |
|
||||
| 5 | 产品形态:按最终线束接法定版(距离 / 隔离有要求时另选器件,并单独核器件速率上限) | 线束(必要时加器件) | 产品形态验证 |
|
||||
|
||||
> 第 2、3 步是**性价比最高的两步**:不用屏板、不用改硬件,就能把 90 % 的软件问题挖出来。
|
||||
> 注意这两步用的是 **USB 转 TTL**(不是 USB 转 485)——USART1 侧没有收发器,直连 TTL 就对了。
|
||||
> 注意这两步用的是 **USB 转 TTL**——USART1 侧没有收发器,直连 TTL 就对了。
|
||||
|
||||
---
|
||||
|
||||
@@ -288,13 +269,12 @@ stub 提供 HAL)。屏板侧 CRC 有查表实现,**用同一张表做交叉
|
||||
|
||||
| 风险 | 触发条件 | 影响 | 回退/应对 |
|
||||
|---|---|---|---|
|
||||
| **日志迁移把台架弄瞎** | 先改代码、后挪串口线 | 什么都看不到,误以为固件挂了 | 顺序钉死:0-2 先挪线、0-3 再改代码;改完先跑一次 `@test` |
|
||||
| **控制台与屏板链路抢 `USART1->DR`** | 日志没迁干净就接屏板 | 屏板花屏 + 日志乱码,像 CRC / 时序错 | 0-3 的判据明确要求"USART1 完全空出" |
|
||||
| **日志迁移把台架弄瞎** | 先改代码、后挪串口线 | 什么都看不到,误以为固件挂了 | 顺序钉死:0-1 先挪线、0-2 再改代码;改完先跑一次 `@test` |
|
||||
| **控制台与屏板链路抢 `USART1->DR`** | 日志没迁干净就接屏板 | 屏板花屏 + 日志乱码,像 CRC / 时序错 | 0-2 的判据明确要求"USART1 完全空出" |
|
||||
| **一次噪声后链路永久静默** | 错误回调里不清 ORE | 屏板召唤再也收不到,症状与"协议不对"完全一样 | 1-3 判据含"拔插 TX 线制造噪声后自动恢复" |
|
||||
| **日志口又染上 ORE 锁存** | 新日志口照抄 `UART_MODE_TX_RX` | 控制台静默、看门狗误复位(老病复发) | 新日志口设 `UART_MODE_TX`;判据含"连续 10 min 无 ORE" |
|
||||
| 帧长按 3208 实现 | 照 readme 写 | CRC 全失败、屏板不亮 | 已写进 §4.2 警示;联调第一步就核 4208 |
|
||||
| DE 极性接反(仅外部模块方案) | 照抄屏板 PA1"低=发" | 总线一直被占、屏板收不到 | 极性由那个模块定,逻辑分析仪一看便知 |
|
||||
| 中断回调漏加分支 | 只改自己模块,忘改 `rs485.c` 的全局回调 | 收不到召唤帧,表象像协议错 | 批 1 第 3 项已列为判据 |
|
||||
| 中断回调漏加分支 | 只改自己模块,忘了现有全局 UART 回调里的句柄分发 | 收不到召唤帧,表象像协议错 | 批 1 的 1-3 已列为判据 |
|
||||
| 屏板自复位被误判离线 | 链路监视窗口设得太小 | 每 83 分钟误报一次 | 判据定为"连续 ≥10 s 无帧" |
|
||||
| 状态灯语义返工 | 映射表拍脑袋定的 | 后期改表要重测 | 把表做成一张 `const` 数组,改表不改逻辑 |
|
||||
| RAM 超门禁 | 误把 RX 缓冲也做成 4208 B | `RW_IRAM1` 逼近 92 % | RX 只要 16 B(§1.3) |
|
||||
@@ -319,10 +299,7 @@ stub 提供 HAL)。屏板侧 CRC 有查表实现,**用同一张表做交叉
|
||||
|
||||
## 8. 与其它工作的关系
|
||||
|
||||
- **与 `docs/任务规划/暂缓-RS485.md` 无关**:那条是"对下采集簇"(UART4 + `g_rs485`;V0.1 网表确认
|
||||
RS485#4 就是 UART4),本项是"对上屏板",走 USART1。两者**不共用外设、不共用驱动常量**,
|
||||
本项**不需要解冻** RS-485 采集簇。
|
||||
- **与日志/控制台工作强耦合**:批 0 的 0-3 要改 `App/log/console_log.c`——那是看门狗喂狗节奏的唯一写者
|
||||
- **与日志/控制台工作强耦合**:批 0 的 0-2 要改 `App/log/console_log.c`——那是看门狗喂狗节奏的唯一写者
|
||||
(机制见 `docs/子系统设计/控制台单写者日志设计说明.md`)。这项改动**不能与其它动控制台的活儿并行**,
|
||||
而且必须台架长稳验证过才算完;**它比屏板链路本身风险更高**,建议单独排一轮、单独回滚。
|
||||
- **与 UI 补齐无关**:本项只消费 `ui_net_sink_get_lcdmem()` / `ui_net_sink_inject_key()`,
|
||||
|
||||
Reference in New Issue
Block a user