2. 消息格式基础:SECS-II 消息结构

SECS-II 是 SEMI 标准 E5 定义的消息层协议,它规定了设备与主机之间交换数据的结构化格式。理解 SECS-II 的消息结构是构建高性能解析引擎的基石。本节将深入剖析其核心组成:Stream/Function 标识、消息体结构、数据项类型以及长度编码规则。

2.1 Stream / Function / Message Body 三层结构

SECS-II 消息采用三层逻辑结构,每一层都有明确的职责:

  • Stream (流):消息的主类别,用 0-127 的整数表示。例如,Stream 1 通常用于设备状态与控制,Stream 6 用于数据收集。
  • Function (功能):消息的具体操作,用 0-255 的整数表示。例如,Function 1 通常表示“请求”,Function 2 表示“响应”。
  • Message Body (消息体):承载实际数据的部分,由一系列数据项(Item)组成,遵循 SML (SECS Message Language) 格式。
关键约定: Stream 和 Function 的组合 (S, F) 唯一标识一条消息。例如,S1F1 是“Are You There”请求,S1F2 是“Are You There”响应。W-bit (Wait-bit) 用于指示是否需要回复。
SECS-II 消息三层结构 SECS-II 消息 (Message) Stream (S) : 消息类别 (0-127) 例如: S1=设备状态, S6=数据收集 Function (F) : 具体操作 (0-255) 例如: F1=请求, F2=响应 Message Body : 数据项 (Item) 列表 例如: <L[2]><A "OK"><B 0x01>

2.2 数据项类型 (Item Types)

SECS-II 定义了 7 种基本数据项类型,用于在消息体中编码不同种类的数据。每种类型都有固定的格式标识符和编码规则。

类型名称 格式码 (Format Code) 描述 字节长度
List (L) 0x00 包含多个子项的无序列表 可变
ASCII (A) 0x40 可打印的 ASCII 字符串 1-256 字节
Binary (B) 0x20 原始字节数据 1-256 字节
Unsigned (U) 0xA0 无符号整数 (1/2/4/8 字节) 1/2/4/8
Signed (I) 0x80 有符号整数 (1/2/4/8 字节) 1/2/4/8
Float (F) 0x90 浮点数 (4/8 字节) 4/8
Boolean (BOOLEAN) 0x10 布尔值 (True/False) 1
性能要点: 在解析引擎中,List 类型是递归解析的核心。解析器需要根据 List 的长度字段,动态创建子解析任务。对于 Unsigned 和 Signed 类型,需要根据长度字节数(1/2/4/8)选择正确的字节序转换算法,避免使用通用但低效的循环移位。

2.3 长度编码规则

SECS-II 使用一种紧凑的变长编码规则来表示数据项的长度。长度字段紧跟在格式码之后,其编码方式如下:

  • 短长度 (0-252 字节):长度字段占用 1 个字节,直接表示长度值。
  • 长长度 (253-65535 字节):长度字段的第一个字节为 0xFD (253),后续 2 个字节表示实际长度(大端序)。
  • 超长长度 (65536 字节以上):长度字段的第一个字节为 0xFE (254),后续 4 个字节表示实际长度(大端序)。
SECS-II 长度编码规则决策流程 读取长度字节 值 < 253? 1 字节长度 值 == 253? 2 字节长度 4 字节长度
常见陷阱: 许多初学者会忽略 超长长度 (4 字节) 的情况。在半导体设备中,某些数据收集消息(如 S6F15)的消息体可能包含数千个数据点,长度超过 65535 字节。解析引擎必须支持 4 字节长度编码,否则会导致解析失败或内存溢出。

2.4 消息体编码示例 (SML 格式)

以下是一个典型的 SECS-II 消息体示例,使用 SML 格式表示:

S1F2 W
<L[3]
  <B 0x01>
  <A "MDLN-123">
  <U2 100 200 300>
>

对应的二进制编码解析如下:

字节偏移 值 (Hex) 说明
0 0x00 格式码: List (L)
1 0x03 长度: 3 个子项
2 0x20 格式码: Binary (B)
3 0x01 长度: 1 字节
4 0x01 数据: 0x01
5 0x40 格式码: ASCII (A)
6 0x08 长度: 8 字节
7-14 4D 44 4C 4E 2D 31 32 33 数据: "MDLN-123"
15 0xA2 格式码: Unsigned 2 字节 (U2)
16 0x03 长度: 3 个元素
17-22 00 64 00 C8 01 2C 数据: 100, 200, 300
解析优化技巧: 在 C++ 实现中,可以使用 memcpy 直接读取多字节整数,避免逐字节移位。对于 List 类型,采用迭代器模式而非递归函数,可以减少函数调用开销,提升解析吞吐量。