3. SECS-I 消息格式:数据块结构、长度字节、控制字节、系统字节、消息头解析
SECS-I 定义了 SECS 消息在物理传输层上的具体格式。理解消息格式是进行设备通信适配的基础,它决定了数据如何被封装、识别和传输。本节将深入解析 SECS-I 消息的完整结构,包括数据块、长度字节、控制字节、系统字节以及消息头的详细字段。
3.1 SECS-I 消息整体结构
一个完整的 SECS-I 消息由多个数据块(Block)组成。每个数据块是传输的基本单元,其结构固定,包含长度字节、控制字节、系统字节和消息头。下图展示了消息的整体分层结构:
核心概念: SECS-I 消息 = 消息头 + 数据区。消息头固定 10 字节,数据区长度可变。消息被分割成多个数据块进行传输,每个数据块长度不超过 254 字节(含头)。
3.2 数据块结构详解
每个数据块是 SECS-I 传输的最小单元,其结构固定且紧凑。下表列出了数据块各字段的详细定义:
| 字段 | 字节数 | 描述 | 取值范围 |
|---|---|---|---|
| 长度字节 | 1 | 表示该数据块的总长度(包含长度字节本身) | 0x0A ~ 0xFE (10 ~ 254) |
| 控制字节 | 1 | 控制位,标识消息类型、是否多块、重传标志等 | 0x00 ~ 0xFF |
| 系统字节 | 2 | 系统 ID,用于匹配请求与响应 | 0x0000 ~ 0xFFFF |
| 消息头 | 10 | 包含 Stream、Function、Wbit、设备 ID 等 | 固定 10 字节 |
| 数据区 | 0 ~ 244 | 实际传输的 SECS-II 数据 | 可变长度 |
长度计算: 数据块总长度 = 1 (长度字节) + 1 (控制字节) + 2 (系统字节) + 10 (消息头) + N (数据区)。因此数据区最大长度为 254 - 14 = 240 字节。若消息超过 240 字节,必须拆分为多个数据块传输。
3.3 长度字节解析
长度字节位于每个数据块的第一个字节,其值表示整个数据块的字节数。该字段是接收端判断数据块边界的关键依据。
- 最小值: 0x0A (10),表示只有消息头,无数据区。
- 最大值: 0xFE (254),表示数据块满载。
- 特殊值: 0x00 ~ 0x09 为非法值,接收端应丢弃。
常见陷阱: 长度字节包含自身,因此实际数据区长度 = 长度字节值 - 14。例如长度字节为 0x50 (80),则数据区长度为 80 - 14 = 66 字节。开发时务必注意这个偏移量。
3.4 控制字节解析
控制字节是数据块的控制标志位,其每一位都有特定含义。下表详细说明了各比特位的功能:
| 比特位 | 标志名 | 描述 |
|---|---|---|
| Bit 7 | R (Reply) | 0 = 不需要回复;1 = 需要回复 |
| Bit 6 | E (Error) | 0 = 正常消息;1 = 错误消息 |
| Bit 5 | D (Disconnect) | 0 = 正常;1 = 断开连接请求 |
| Bit 4 | M (Multi-block) | 0 = 单块消息;1 = 多块消息 |
| Bit 3 | B (Block number) | 0 = 第一块或唯一块;1 = 后续块 |
| Bit 2-0 | 保留 | 固定为 0 |
控制字节的典型值示例:
- 0x80 (1000 0000): 需要回复的单块消息。
- 0x90 (1001 0000): 需要回复的多块消息的第一块。
- 0x98 (1001 1000): 需要回复的多块消息的后续块。
- 0x40 (0100 0000): 错误消息。
3.5 系统字节解析
系统字节占用 2 个字节(16 位),用于唯一标识一个消息事务。其核心作用是匹配请求与响应。
- 生成规则: 发送方为每个新消息分配一个递增的系统 ID,范围 0x0001 ~ 0xFFFF。0x0000 通常保留。
- 匹配机制: 响应消息必须使用与请求消息相同的系统 ID,接收方据此将响应与请求关联。
- 超时处理: 若在 T3 超时时间内未收到匹配的响应,发送方应重传或报错。
实战建议: 在多设备通信场景中,系统 ID 的管理至关重要。建议为每个设备维护独立的系统 ID 计数器,避免 ID 冲突。同时,系统 ID 的溢出(从 0xFFFF 回到 0x0001)需要妥善处理。
3.6 消息头解析
消息头是 SECS-I 消息的核心,固定 10 字节,包含设备 ID、Stream、Function、Wbit 等关键字段。下图展示了消息头的详细结构:
3.7 消息头字段详细说明
| 字段 | 字节偏移 | 长度 | 说明 |
|---|---|---|---|
| 设备 ID + Wbit | 0-1 | 2 字节 | Bit 15 为 Wbit,Bit 14-0 为设备 ID。Wbit=1 表示接收方需回复。 |
| Stream 号 | 2 | 1 字节 | 高 7 位有效,范围 0-127。Stream 0 保留,常用 Stream 1-20。 |
| Function 号 | 3 | 1 字节 | 低 7 位有效,范围 0-127。Function 0 保留。 |
| 保留 | 4-5 | 2 字节 | 固定为 0x0000,接收端应忽略。 |
| 数据长度 | 6-9 | 4 字节 | 大端序(Big-Endian)32 位整数,表示数据区字节数。 |
Wbit 的重要性: Wbit 是 SECS/GEM 通信中控制消息流向的关键标志。当主机发送一个 Wbit=1 的消息时,设备必须回复一个响应消息。如果 Wbit=0,设备不需要回复,适用于单向通知场景。
3.8 多块消息传输机制
当消息数据超过 240 字节时,必须拆分为多个数据块传输。多块消息的传输遵循以下规则:
- 第一块: 控制字节的 M 位 = 1,B 位 = 0,系统字节为唯一 ID。
- 中间块: 控制字节的 M 位 = 1,B 位 = 1,系统字节与第一块相同。
- 最后一块: 控制字节的 M 位 = 0,B 位 = 1,系统字节与第一块相同。
下图展示了多块消息的传输流程:
3.9 消息解析实战示例
以下是一个完整的 SECS-I 消息数据块解析示例,帮助理解各字段的实际取值:
原始数据块(十六进制):
0E 90 00 01 01 0D 00 00 00 00 00 05 41 42 43 44 45
字段解析:
长度字节: 0x0E (14) → 数据块总长度 14 字节
控制字节: 0x90 → 1001 0000 → R=1, E=0, D=0, M=1, B=0
系统字节: 0x0001 → 系统 ID = 1
消息头:
设备 ID + Wbit: 0x0101 → Wbit=0, 设备 ID=0x0101
Stream: 0x0D (13)
Function: 0x00 (0)
保留: 0x0000
数据长度: 0x00000005 (5)
数据区: 41 42 43 44 45 → "ABCDE"
解析要点: 该消息为 S13F0,系统 ID=1,需要回复,多块消息的第一块,数据区包含 5 字节的 ASCII 数据。接收方收到后应回复相同系统 ID 的消息。
3.10 常见问题与避坑指南
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 长度字节计算错误 | 未包含长度字节自身 | 始终使用公式:总长度 = 14 + 数据区长度 |
| 系统 ID 冲突 | 多设备共用同一 ID 池 | 为每个设备维护独立 ID 计数器 |
| Wbit 设置错误 | 未按协议要求设置 | 主机消息通常 Wbit=1,设备事件消息 Wbit=0 |
| 多块消息顺序错乱 | 未正确设置 M/B 位 | 严格遵循第一块 M=1,B=0;中间块 M=1,B=1;最后块 M=0,B=1 |
| 数据长度与实际不符 | 大端序解析错误 | 使用大端序(Big-Endian)解析 4 字节数据长度 |