2. SML语法基础

SML(SECS Message Language)是描述 SECS/GEM 消息的标准化文本格式。掌握 SML 语法是解析和构造 SECS 消息的前提。本节将系统讲解 SML 文件结构、消息头格式、Stream/Function 编号规则以及事务 ID 概念。

2.1 SML 文件整体结构

一个完整的 SML 文件由文件头、消息体列表和可选的注释组成。其顶层结构如下:

SML 文件结构层次图 SML 文件结构层次 SML 文件 文件头 (Header) 消息体列表 版本 / 编码 / 注释 消息 1 消息 2 消息 N 说明 SML 文件通常以 .sml 为扩展名,采用 UTF-8 编码。 每个消息体对应一个完整的 SECS 消息定义。

以下是一个典型的 SML 文件示例:

# SML 文件示例
# 版本: 1.0
# 编码: UTF-8

S1F1
  <L>
    <A "Are you there?">
.
提示:SML 文件中的 # 开头行为注释行,解析器应自动忽略。文件头通常包含版本和编码信息,但并非强制要求。

2.2 消息头格式

每个 SECS 消息在传输时都包含一个固定长度的消息头(Message Header),长度为 10 字节。消息头定义了消息的路由和控制信息。

字节偏移 字段名称 长度(字节) 说明
0 Length 4 消息体长度(不包括消息头自身)
4 Device ID 2 设备标识符,用于多设备场景
6 Stream 1 流编号,范围 0–127
7 Function 1 功能编号,范围 0–255
8 W-bit 1 等待位(0/1),表示是否需要回复
9 Transaction ID 1 事务 ID,用于匹配请求与响应

消息头在 SML 中通常不直接显式写出,而是通过消息的 Stream/Function 编号和 W-bit 隐含定义。但在底层解析时,消息头是必须处理的固定结构。

SECS 消息头 10 字节结构 SECS 消息头 10 字节结构 Length (4 字节) 字节 0–3 Device ID 字节 4–5 Stream 字节 6 Function 字节 7 W-bit 字节 8 Transaction ID 字节 9 消息头总长度固定为 10 字节,所有字段均为大端序(Big-Endian)

2.3 Stream 与 Function 编号规则

SECS/GEM 协议使用 Stream 和 Function 两个维度来唯一标识一个消息类型。其编号规则如下:

  • Stream (S):范围 0–127,用于对消息进行大类分组。例如:
    • S1:设备控制与状态
    • S2:设备诊断与维护
    • S6:数据收集与事件报告
    • S7:设备参数管理
  • Function (F):范围 0–255,用于在 Stream 内细分具体功能。例如:
    • F0:取消(Abort)
    • F1:请求(Request)
    • F2:响应(Response)
    • F3:通知(Notification)

消息的完整标识格式为 S<Stream>F<Function>,例如 S1F1 表示 Stream 1、Function 1 的消息。

消息标识 Stream Function 方向 说明
S1F1 1 1 Host → Equipment Are you there?(请求)
S1F2 1 2 Equipment → Host Are you there?(响应)
S6F11 6 11 Equipment → Host 事件报告发送
S7F19 7 19 Host → Equipment 当前参数请求
关键规则:通常 奇数 Function 表示主叫方发送的请求(Primary Message),偶数 Function 表示被叫方返回的响应(Secondary Message)。例如 S1F1 是请求,S1F2 是响应。
Stream/Function 编号空间示意图 Stream/Function 编号空间 Stream 编号范围: 0 – 127 Function 编号范围: 0 – 255 S1F1 S1F2 S6F11 S7F19 每个 (Stream, Function) 组合唯一确定一个 SECS 消息类型。 奇数 Function 为请求,偶数 Function 为响应。

2.4 事务 ID 概念

事务 ID(Transaction ID) 是 SECS/GEM 协议中用于关联请求消息与响应消息的关键字段。它位于消息头的第 9 字节,取值范围 0–255。

事务 ID 的工作机制如下:

  1. 主叫方(Host 或 Equipment)发送一个请求消息(奇数 Function)时,会分配一个唯一的事务 ID。
  2. 被叫方收到请求后,在处理完成后发送响应消息(偶数 Function),并将响应消息中的事务 ID 设置为与请求消息相同。
  3. 主叫方通过事务 ID 将响应与之前的请求进行匹配,从而完成一次事务。
注意:事务 ID 只在单个会话内保证唯一性。不同会话之间的事务 ID 可以重复。事务 ID 的分配通常采用循环递增的方式,从 0 开始,到达 255 后回绕到 0。
事务 ID 匹配流程 事务 ID 匹配流程 Host Equipment S1F1, Transaction ID = 5 S1F2, Transaction ID = 5 匹配成功:请求与响应的事务 ID 相同 Host 通过 Transaction ID = 5 将 S1F2 与 S1F1 关联

2.5 SML 中的消息定义示例

以下是一个完整的 SML 消息定义示例,展示了 Stream/Function、W-bit 以及数据项的写法:

S1F1 W
  <L>
    <A "Are you there?">
.

其中:

  • S1F1:表示 Stream 1、Function 1 的消息。
  • W:表示 W-bit 置 1,即需要对方回复。
  • <L> ... </L>:表示一个列表(List)数据项。
  • <A "Are you there?">:表示一个 ASCII 字符串数据项。
  • .:表示消息定义结束。
实践建议:在编写 SML 文件时,建议为每个消息添加注释说明其用途。事务 ID 在 SML 中通常不显式写出,而是在运行时由通信层自动分配。

2.6 本章小结

本章涵盖了 SML 语法的基础核心内容:

  • SML 文件由文件头和消息体列表组成,支持注释。
  • 消息头固定 10 字节,包含 Length、Device ID、Stream、Function、W-bit 和 Transaction ID。
  • Stream 范围 0–127,Function 范围 0–255,奇数 Function 为请求,偶数 Function 为响应。
  • 事务 ID 用于匹配请求与响应,范围 0–255,在会话内循环分配。