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

6.3 KiB
Raw Blame History

DTU-HMI 通信协议设计文档

1. 文档说明

  • 文档名称:DTU-HMI 通信协议设计文档
  • 协议名称RemoDispBus项目内实现
  • 适用范围:DTU-HMI 与远程显示上位机(如 remo_disp_server.py)之间的 TCP 通信
  • 对应实现:src/remoteDisplay.csrc/remoteDisplay.h

2. 协议目标

本协议用于实现以下能力:

  • 上位机与设备端建立会话并获取显示参数
  • 上位机按需读取 LCD 显存内容用于渲染
  • 上位机向设备端下发按键事件
  • 维持连接活性(保活)

3. 传输层与连接模型

  • 传输层TCP
  • 服务器角色:DTU-HMI(设备端)
  • 客户端角色:远程显示上位机
  • 默认监听端口:7003
  • 连接模式:单连接处理(当前连接断开后继续接受下一连接)

连接与处理流程(文字图):

[TcpServer_Listen:7003]
        |
        v
[Accept 客户端连接]
        |
        v
[接收并累积缓冲区数据]
        |
        v
[解析完整协议帧]
   | 成功                   | 不完整/非法
   v                        v
[命令分发与处理]       [继续接收数据]
        |
        v
[发送应答帧]
        |
        v
[继续处理当前连接,直到断开]

4. 帧结构定义

4.1 通用帧格式

协议帧格式如下:

[TAG][CMD][LEN_H][LEN_L][DATA...][CRC]

字段说明:

  • TAG1 字节,报文方向标记
  • CMD1 字节,命令码
  • LEN_H + LEN_L2 字节,大端,表示 DATA 长度
  • DATA:可变长,长度由 LEN 指定
  • CRC1 字节,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 个命令:

  • 0x00CMD_KEEPLIVE
  • 0x01CMD_INIT
  • 0x02CMD_KEY
  • 0x03CMD_LCDMEM

6. 命令详细设计

6.1 CMD_KEEPLIVE0x00

请求

  • DATA:空(长度 0

响应

  • CMD0x00
  • DATA:空(长度 0
  • 用于连接保活与链路探测

6.2 CMD_INIT0x01

请求

  • DATA:空(长度 0

响应

  • DATA 长度8 字节
  • 格式:
[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 格式:
[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. 状态与时序约定

推荐交互顺序:

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=0start_addr=0start_addr=LCD_DISPLAYMEMORYSIZE-1start_addr>=LCD_DISPLAYMEMORYSIZE
  • 连接稳定性:频繁重连、并发请求(若后续支持)