HMIS 协议:用会话化二进制帧取代 DGUS 串口屏协议

Babel36acl 嵌入式实战 无~ 11 次阅读 预计阅读时间: 9 分钟 发布于 1 天前 最后更新于 1 小时前 1943 字


协议设计 HMI

HMIS 协议:用会话化二进制帧取代 DGUS 串口屏协议

V1.1 版本废弃了 USART1 上的 DGUS 5A A5 变量协议,改为全新的 HMI Session Protocol(HMIS)。这不是简单的帧格式替换——是整个通信模型的升级。

为什么废弃 DGUS

DGUS 变量协议的核心是 VP 地址模型:固件向屏的指定地址(如 0x3000)写数据,屏显示该地址的内容。HMI 上位机通过抓取屏的通信来间接获取设备信息。这个模式存在三个根本问题:

  • HMI 维护两套协议栈(USART1 DGUS + USART3 20B 帧)
  • 参数地址、HMI 配置、固件参数三处耦合——新增参数要改三处
  • 日志、事件共用变量协议语义,扩展成本高

HMIS 帧格式

| SOF(2) | VER(1) | TYPE(1) | SEQ(2) | CMD(1) | FLAGS(1) | LEN(2) | PAYLOAD(N) | CRC16(2) |
| 55 AA  |  0x01  | 0x01    | 小端   | 0x30   |  0x00    |  0+..  |  0..128B   | Modbus   |

SOF:  固定 0x55 0xAA
VER:  协议版本,首版 0x01
TYPE: 0x01=请求 0x02=响应 0x03=事件 0x04=日志 0x05=心跳
SEQ:  会话序号,请求方递增,响应带相同的 SEQ
CMD:  命令码
FLAGS:标志位(bit2=错误)
LEN:  Payload 长度(小端)
CRC16:从 VER 到 Payload 末尾

能力声明机制

HMI 连接后,固件通过 DEVICE_INFO 响应返回能力位图——HMI 据此知道固件支持什么功能:

// 能力位图(16 位)
#define HMI_CAP_SESSION_BASE      0x0001  // 基础会话 (HELLO/DEVICE_INFO/HEARTBEAT)
#define HMI_CAP_PARAM_DIRECTORY   0x0002  // 参数目录 (0x10/0x11)
#define HMI_CAP_PARAM_RW          0x0004  // 参数读写 (0x12/0x13)
#define HMI_CAP_PARAM_PERSIST     0x0008  // 参数持久化 (0x14/0x15/0x16)
#define HMI_CAP_STREAM_SUBSCRIBE  0x0010  // 推送订阅 (0x22/0x23)
#define HMI_CAP_EVENT_PUSH        0x0020  // 事件推送 (0x40)
#define HMI_CAP_LOG_PUSH          0x0040  // 日志推送 (0x41)
#define HMI_CAP_STACK_SNAPSHOT    0x0080  // 栈快照推送 (0x42)
#define HMI_CAP_DEVICE_STATUS     0x0100  // 状态查询 (0x20)
#define HMI_CAP_ALARM_STATUS      0x0200  // 报警查询 (0x21)
#define HMI_CAP_PACKER_FLOW       0x2000  // 20B 协议控制/流程 (0x40-0x44)

命令分类

范围 命令码 说明
Session 0x01 HELLO 连接握手
0x02 DEVICE_INFO 设备信息+能力
0x03 HEARTBEAT 心跳(3 秒间隔)
参数 0x10 GET_GROUP_LIST 参数分组列表
0x11 GET_PARAM_LIST 某组参数定义
0x12 GET_PARAM_VALUES 批量读值
0x13 SET_PARAM_VALUES 批量写值
0x14 SAVE_PARAMS 保存到 EEPROM
0x15 LOAD_PARAMS 从 EEPROM 加载
0x16 LOAD_DEFAULTS 恢复默认
状态 0x20 DEVICE_STATUS 运行状态+阶段码
0x21 ALARM_STATUS 报警状态
订阅 0x22/0x23 订阅/取消推送流
控制 0x30 CONTROL_RUN_STATE 启停
0x31 TRIGGER_BAG 出袋
0x32 TRIGGER_SEAL 封口
0x33 TRIGGER_DELIVER 投料
0x34 CLEAR_FLAG 清标志
0x35 RESET_FAULT 故障复位
0x36 STEPPER_JOG 步进点动
0x37 DC_MOTOR_JOG 直流点动
推送 0x40 EVENT_PUSH 事件上报
0x41 LOG_PUSH 日志推送
0x42 STACK_SNAPSHOT 栈水位快照

控制命令(0x30~0x37)在固件内部桥接到 20B 协议,复用已有的协议处理逻辑:

// packer_hmi_proto.c — 控制命令桥接
static void hmi_handle_control_run_state(const uint8_t *payload, uint8_t len) {
    app_packer_command_t cmd;
    // 构造 20B 协议的内部命令
    cmd.func = 0x40;  // CONTROL
    cmd.arg0 = (len > 0) ? payload[0] : 0;
    // 投递到命令网关,与 USART3 协议同一条路径
    packer_command_gateway_push(&cmd);
}

日志和事件推送

日志不再封装为 DGUS 0x82 写变量帧,而是通过 HMIS 的 TYPE=0x04 日志帧独立推送:

// 日志推送帧 (TYPE=0x04, CMD=0x41)
| SOF | VER | 0x04 | SEQ | 0x41 | FLAGS | LEN | level(1) | text(N) | CRC16 |

// 事件推送帧 (TYPE=0x03, CMD=0x40)
| SOF | VER | 0x03 | SEQ | 0x40 | FLAGS | LEN | event_code(1) | value0(1) | value1(1) | CRC16 |

// HMI 侧通过订阅机制选择感兴趣的数据流
req: TYPE=0x01, CMD=0x22, payload=[stream_mask]
// stream_mask bit0=事件 bit1=日志 bit2=栈快照

与旧 DGUS 协议的对比

维度 DGUS (废弃) HMIS (当前)
帧头 5A A5 55 AA
地址模型 VP 地址空间(0x1000/0x3000) 命令码 + Payload
参数访问 HMI 硬编码地址表 固件提供参数目录(0x10/0x11)
响应匹配 无序号,超时匹配 SEQ 序号匹配
日志 0x82 写 VP 0x3000 变量帧 TYPE=0x04 LOG_PUSH 帧
心跳 TYPE=0x05,3 秒间隔
能力声明 DEVICE_INFO 的能力位图
HMI 维护成本 两套协议栈 同一套会话协议

HMIS 的核心思路:让固件成为参数元数据的唯一真源。HMI 不再硬编码参数地址和含义——启动时拉目录,看到什么就显示什么。参数新增/删除/换分组,HMI 侧零改动。

此作者没有提供个人介绍。
最后更新于 2026-05-30