4. SECS-II 消息结构:Stream 与 Function 概念、Message ID、WBit 与 EBit 详解
SECS-II(SECS-2)是 SEMI 标准 E5 定义的消息层协议,它规定了设备与主机之间交换的 消息格式 和 数据编码规则。理解 SECS-II 的消息结构是开发 SECS/GEM 通信接口的基础,也是实现 MES 与设备数据交互的核心前提。
核心认知: SECS-II 消息由 Stream(流) 和 Function(功能) 两个维度唯一标识。Stream 定义消息的类别(如设备状态、材料处理),Function 定义具体的操作(如请求、数据上报、确认)。这种二维结构使得消息的语义清晰且可扩展。
4.1 Stream 与 Function 的概念
SECS-II 使用 SxFy 的格式来标识一条消息,其中 Sx 表示 Stream 编号,Fy 表示 Function 编号。Stream 和 Function 均为无符号整数。
- Stream(流):消息的类别或主题域。标准定义了 0~255 个 Stream,其中 Stream 0~127 为 SEMI 标准定义,Stream 128~255 保留给用户自定义。
- Function(功能):在特定 Stream 下的具体操作。Function 编号通常为奇数或偶数,奇偶性决定了消息的方向和语义。
记忆技巧: Stream 可以类比为“章节”,Function 可以类比为“段落编号”。例如 S1F1 是“设备状态”章节下的“请求设备列表”段落。
4.1.1 常见 Stream 定义
| Stream 编号 | 类别名称 | 典型用途 |
|---|---|---|
| S1 | 设备状态 | 设备在线/离线、通信建立、状态数据请求 |
| S2 | 设备控制与诊断 | 远程控制、参数设置、诊断命令 |
| S3 | 材料状态 | 晶圆/料盒状态、材料追踪 |
| S4 | 材料控制 | 材料移动、装载/卸载操作 |
| S5 | 异常与报警 | 报警上报、异常通知 |
| S6 | 数据日志与追溯 | 工艺数据、追溯数据、事件报告 |
| S7 | 设备标识与配方 | 设备 ID、配方管理、配方下载 |
| S9 | 系统错误 | 通信错误、格式错误、超时通知 |
4.1.2 Function 的奇偶规则
Function 编号的奇偶性决定了消息的 方向 和 语义,这是 SECS-II 协议的一个关键设计。
- 奇数 Function(Primary Message):通常由 发起方 发送,表示一个请求、命令或通知。例如 S1F1(请求设备列表)、S6F11(事件报告通知)。
- 偶数 Function(Secondary Message):通常由 响应方 发送,表示对奇数 Function 的 确认或回复。例如 S1F2(返回设备列表数据)、S6F12(确认收到事件报告)。
注意: 并非所有偶数 Function 都是确认消息。某些偶数 Function 可能携带数据(如 S1F2 携带设备列表),而某些奇数 Function 也可能不需要确认(如某些广播通知)。但绝大多数标准消息遵循奇偶配对规则。
4.2 Message ID(消息 ID)
Message ID 是 SECS-II 消息头中的一个字段,用于唯一标识一次 消息交互。它由 System Bytes(系统字节) 组成,通常为 4 字节(32 位)无符号整数。
4.2.1 Message ID 的作用
- 请求-响应匹配:当主机发送一个请求(如 S1F1)时,设备回复的响应(S1F2)必须携带与请求相同的 Message ID,以便主机将响应与对应的请求关联。
- 超时与重试管理:发送方可以通过 Message ID 追踪未收到响应的消息,并在超时后重试。
- 多会话支持:在并发通信中,不同的 Message ID 可以区分多个同时进行的消息交互。
4.2.2 Message ID 的生成规则
| 场景 | 生成方式 | 示例 |
|---|---|---|
| 主机发起请求 | 主机生成一个递增或随机的唯一 ID | 0x00000001, 0x00000002 |
| 设备发起请求 | 设备生成一个唯一 ID(通常从 0x80000000 开始) | 0x80000001, 0x80000002 |
| 响应消息 | 直接复制请求消息的 Message ID | 与请求 ID 相同 |
实践建议: 在 MES 集成开发中,建议使用 单调递增计数器 生成 Message ID,并记录每个 ID 对应的请求时间戳和内容,便于调试和问题排查。
4.3 WBit 与 EBit 详解
WBit(Wait Bit)和 EBit(End Bit)是 SECS-II 消息头中的两个 控制位,它们影响消息的传输行为和消息体的解析方式。
4.3.1 WBit(等待位)
WBit 位于消息头的第 2 字节的第 0 位(bit 0)。它指示发送方是否期望接收方返回一个 确认消息。
- WBit = 1:发送方期望接收方在收到消息后,立即返回一个 ACK(确认) 或 NAK(否定确认) 消息。这用于确保消息被对方正确接收。
- WBit = 0:发送方不要求立即确认,消息为“发后即忘”类型。接收方不需要回复确认消息。
典型应用: 对于关键性操作(如配方下载、设备控制命令),通常设置 WBit=1 以确保可靠性。对于周期性状态上报(如 S6F11 事件报告),通常设置 WBit=0 以减少通信开销。
4.3.2 EBit(结束位)
EBit 位于消息头的第 2 字节的第 1 位(bit 1)。它指示当前消息是否为 多块消息 的最后一块。
- EBit = 1:当前消息是最后一块,或者消息本身是单块消息(即消息体完整)。
- EBit = 0:当前消息是中间块,后面还有后续数据块。接收方需要等待所有块接收完毕后,再组装完整的消息体。
注意: 多块消息通常用于传输大数据量(如配方文件、大批量日志)。在 MES 集成中,如果设备上报的数据超过单块消息的最大长度(通常为 4KB~8KB),协议栈会自动分块发送,并在最后一块设置 EBit=1。
4.4 消息头结构总览
SECS-II 消息头固定为 10 字节,包含以下字段:
| 字节偏移 | 字段名称 | 长度 | 说明 |
|---|---|---|---|
| 0 | Length | 4 字节 | 消息体长度(不包括消息头自身) |
| 4 | Stream | 1 字节 | Stream 编号(0-255) |
| 5 | Function | 1 字节 | Function 编号(0-255) |
| 6 | WBit + EBit + 保留位 | 1 字节 | Bit 0: WBit; Bit 1: EBit; Bit 2-7: 保留 |
| 7-9 | System Bytes | 3 字节 | Message ID 的低 24 位(部分实现使用 4 字节) |
开发提示: 在解析 SECS-II 消息时,务必先读取前 4 字节获取消息体长度,然后读取 Stream 和 Function 确定消息类型,再检查 WBit 和 EBit 决定后续处理逻辑。Message ID 用于关联请求和响应,是实现异步通信的关键。
4.5 实战案例:解析一条 S1F1 消息
假设主机发送一条 S1F1(请求设备列表)消息,WBit=1,Message ID=0x00000001。消息体为空(长度为 0)。
消息头字节序列(十六进制):
00 00 00 00 // 消息体长度 = 0
01 // Stream = 1
01 // Function = 1
03 // WBit=1, EBit=1, 保留位=0 (二进制: 0000 0011)
00 00 01 // System Bytes = 0x000001 (Message ID 低24位)
解析步骤:
- 读取前 4 字节
00 00 00 00,得知消息体长度为 0。 - 读取第 5 字节
01,Stream = 1。 - 读取第 6 字节
01,Function = 1。消息类型为 S1F1。 - 读取第 7 字节
03,二进制0000 0011,Bit 0=1(WBit=1),Bit 1=1(EBit=1)。 - 读取第 8-10 字节
00 00 01,Message ID = 0x000001。 - 由于 WBit=1,设备收到后必须回复 S1F2 消息,且 Message ID 必须为 0x000001。
调试技巧: 使用 Wireshark 或 SECS/GEM 模拟器抓包时,重点关注消息头的 WBit 和 EBit 值。如果发现设备未按预期回复确认,首先检查 WBit 是否设置正确。