Files
DTU-HMI/docs/通信协议设计文档.md

265 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DTU-HMI 通信协议设计文档
## 1. 文档说明
- 文档名称:`DTU-HMI` 通信协议设计文档
- 协议名称RemoDispBus项目内实现
- 适用范围:`DTU-HMI` 与远程显示上位机(如 `remo_disp_server.py`)之间的 TCP 通信
- 对应实现:`src/remoteDisplay.c``src/remoteDisplay.h`
## 2. 协议目标
本协议用于实现以下能力:
- 上位机与设备端建立会话并获取显示参数
- 上位机按需读取 LCD 显存内容用于渲染
- 上位机向设备端下发按键事件
- 维持连接活性(保活)
## 3. 传输层与连接模型
- 传输层TCP
- 服务器角色:`DTU-HMI`(设备端)
- 客户端角色:远程显示上位机
- 默认监听端口:`7003`
- 连接模式:单连接处理(当前连接断开后继续接受下一连接)
连接与处理流程(文字图):
```text
[TcpServer_Listen:7003]
|
v
[Accept 客户端连接]
|
v
[接收并累积缓冲区数据]
|
v
[解析完整协议帧]
| 成功 | 不完整/非法
v v
[命令分发与处理] [继续接收数据]
|
v
[发送应答帧]
|
v
[继续处理当前连接,直到断开]
```
## 4. 帧结构定义
### 4.1 通用帧格式
协议帧格式如下:
```text
[TAG][CMD][LEN_H][LEN_L][DATA...][CRC]
```
字段说明:
- `TAG`1 字节,报文方向标记
- `CMD`1 字节,命令码
- `LEN_H` + `LEN_L`2 字节,大端,表示 `DATA` 长度
- `DATA`:可变长,长度由 `LEN` 指定
- `CRC`1 字节,`DATA` 区逐字节异或
### 4.2 TAG 约定
- 客户端 -> 设备端:`0xAA`
- 设备端 -> 客户端:`0xBB`
### 4.3 CRC 算法
- 初值:`0x00`
- 计算范围:仅 `DATA` 字段
- 算法:`crc = data[0] ^ data[1] ^ ... ^ data[n-1]`
- `DATA` 长度为 0 时CRC 结果为 `0x00`
## 5. 命令字定义
当前实现支持 4 个命令:
- `0x00``CMD_KEEPLIVE`
- `0x01``CMD_INIT`
- `0x02``CMD_KEY`
- `0x03``CMD_LCDMEM`
## 6. 命令详细设计
### 6.1 CMD_KEEPLIVE0x00
#### 请求
- `DATA`:空(长度 0
#### 响应
- `CMD``0x00`
- `DATA`:空(长度 0
- 用于连接保活与链路探测
---
### 6.2 CMD_INIT0x01
#### 请求
- `DATA`:空(长度 0
#### 响应
- `DATA` 长度8 字节
- 格式:
```text
[LCD_W_H][LCD_W_L][LCD_H_H][LCD_H_L][MEM_B3][MEM_B2][MEM_B1][MEM_B0]
```
字段含义:
- `LCD_W`:屏幕宽度(当前为 `160`
- `LCD_H`:屏幕高度(当前为 `160`
- `MEM`:显存总字节数(当前为 `160 * 160 = 25600`
字节序:全部为大端编码
---
### 6.3 CMD_KEY0x02
#### 请求
- `DATA`:至少 1 字节
- `DATA[0]`:按键值(如 `KEY_U/KEY_D/KEY_L/KEY_R/KEY_ENT/KEY_ESC`
#### 处理行为
- 设备端将按键写入:
- `g_tRemoteKey.byKeyValid = EN_KEY_FLAG_NEW`
- `g_tRemoteKey.byKeyValue = DATA[0]`
#### 响应
- 当前实现:不发送显式响应帧
- 建议:后续版本增加 ACK以便上位机确认按键注入结果
---
### 6.4 CMD_LCDMEM0x03
#### 请求
- `DATA` 长度:建议 4 字节
- 格式:`[ADDR_B3][ADDR_B2][ADDR_B1][ADDR_B0]`(大端起始地址)
若请求长度小于 4设备端默认起始地址为 0。
#### 响应
- `DATA` 格式:
```text
[ADDR_B3][ADDR_B2][ADDR_B1][ADDR_B0][LCD_MEM_SLICE...]
```
- 前 4 字节回显起始地址
- 后续为显存片段:
-`start_addr < LCD_DISPLAYMEMORYSIZE`,返回从该地址到末尾的全部显存
-`start_addr >= LCD_DISPLAYMEMORYSIZE`,仅返回 4 字节地址(无显存数据)
## 7. 帧解析与容错策略
设备端接收缓冲解析规则:
1. 至少 5 字节才可判定为候选帧(最小帧)
2. 首字节必须是 `TAG_CLIENT(0xAA)`
3. 根据 `LEN` 计算总帧长:`4 + len + 1`
4. 缓冲长度不足总帧长时,继续接收
5. CRC 不匹配则视为非法帧
6. 成功解析后按 `consume` 字节从缓冲区移除
异常处理策略:
- 长时间无法成帧且缓冲接近上限(`4096-256`)时,清空缓冲防止越界
- `recv` 返回 `0``<0`,认为连接结束,关闭当前客户端
- 未知命令:回空应答(同命令码,空 `DATA`
## 8. 协议示例报文
说明:以下示例均为十六进制字节流。
### 8.1 KEEPLIVE 请求/响应
- 请求:`AA 00 00 00 00`
- `CRC=00`(空数据)
- 响应:`BB 00 00 00 00`
### 8.2 INIT 请求/响应(示意)
- 请求:`AA 01 00 00 00`
- 响应头:`BB 01 00 08 ... CRC`
- 响应 `DATA` 示例160x16025600
- `00 A0 00 A0 00 00 64 00`
### 8.3 KEY 请求(上键示例)
- 若上键值为 `0x02`,请求可为:
- `AA 02 00 01 02 02`
- 其中末尾 CRC=`0x02`
### 8.4 LCDMEM 请求(从 0 地址读取)
- 请求:`AA 03 00 04 00 00 00 00 00`
- `DATA` 为 4 字节地址 `0x00000000`
- CRC=`00`
- 响应:`BB 03 LEN_H LEN_L [00 00 00 00][显存数据...] CRC`
## 9. 状态与时序约定
推荐交互顺序:
```text
1) 连接 TCP 7003
2) 发送 CMD_INIT 获取屏幕参数
3) 周期发送 CMD_LCDMEM 拉取显存
4) 有用户操作时发送 CMD_KEY
5) 周期发送 CMD_KEEPLIVE 保活
```
## 10. 安全性与边界约束
当前协议属于内网轻量协议,未设计鉴权与加密机制。建议在生产化场景补充:
- 连接鉴权(口令/Token
- 传输加密TLS 或应用层加密)
- 命令频率限制与异常连接清理
## 11. 兼容性与扩展建议
- 保留 `CMD` 空间用于后续扩展
- 建议新增统一 ACK/NACK 机制(含错误码)
- 建议引入协议版本字段(可放在 `CMD_INIT` 响应或扩展头中)
- 建议为 `CMD_KEY` 增加长度校验(当前默认读取 `DATA[0]`
## 12. 与代码映射关系
- 帧解析:`parse_frame`
- CRC 计算:`calc_crc`
- 应答构造发送:`send_reply`
- 命令处理:`handle_cmd_keeplive` / `handle_cmd_init` / `handle_cmd_key` / `handle_cmd_lcdmem`
- 线程入口:`tcp_server_thread_fn`
- 服务启动:`StartTcpServerThread`
## 13. 测试建议(协议方向)
建议将以下场景纳入自动化测试:
- 正常帧4 类命令全部覆盖
- 异常帧:错误 TAG、错误 CRC、截断帧、超长无效数据
- 边界值:`LEN=0``start_addr=0``start_addr=LCD_DISPLAYMEMORYSIZE-1``start_addr>=LCD_DISPLAYMEMORYSIZE`
- 连接稳定性:频繁重连、并发请求(若后续支持)