3. SML数据类型详解

SECS/GEM 协议中,所有消息(Message)的载荷(Data Item)都基于一套严格定义的数据类型。SML(SECS Message Language)作为描述这些消息的文本语言,其数据类型直接映射到 SECS-II 的底层编码规则。理解这些类型的定义、取值范围与编码规则,是进行 SML 解析与消息事务处理的基石。

本章将逐一剖析 SML 中的 12 种核心数据类型,涵盖列表、无符号整数、有符号整数、浮点数、布尔值、ASCII 字符串与二进制字节数组。我们将通过对比表格、编码示例与内联 SVG 结构图,帮助您建立清晰的数据类型认知体系。

3.1 数据类型总览

SECS-II 数据类型通过一个字节的 Format Code(格式码) 标识,后跟长度字节与数据体。SML 文本表示则使用类型关键字加括号包裹的值。下表列出了所有 SML 数据类型及其对应的 SECS-II 格式码、字节长度与典型用途。

SML 类型格式码 (十六进制)数据长度 (字节)取值范围典型用途
L0x01可变 (嵌套)子项数量 0~2³²-1消息结构容器
U0x021/2/4/80 ~ 2⁶⁴-1无符号计数器、ID
A0x10可变 (1~n)ASCII 字符 (0x20~0x7E)设备名、文本状态
B0x04可变 (1~n)0x00~0xFF原始二进制数据
BOOLEAN0x0C1TRUE (0xFF) / FALSE (0x00)开关、使能标志
F0x904/8±3.4E±38 / ±1.7E±308浮点测量值 (通用)
I80x208-2⁶³ ~ 2⁶³-1大范围有符号整数
I40x104-2³¹ ~ 2³¹-1标准有符号整数
I20x082-32768 ~ 32767小范围有符号整数
I10x041-128 ~ 127单字节有符号整数
F80xA08±1.7E±308高精度浮点
F40x904±3.4E±38单精度浮点
编码要点: 所有整数类型(U/I1/I2/I4/I8)均采用大端序(Big-Endian)编码。浮点类型(F4/F8)遵循 IEEE 754 标准,同样使用大端序。列表类型 L 的嵌套深度理论上无限制,但实际设备通常限制在 10 层以内。

3.2 列表类型 (L)

列表类型 L 是 SECS-II 消息的骨架,用于将多个数据项组合成一个结构化的树形节点。一个 L 类型可以包含任意数量的子项,每个子项可以是任何 SML 数据类型(包括另一个 L)。

编码规则:

  • 格式码:0x01
  • 长度域:1、2 或 4 字节,表示子项的数量(不是字节数)。
  • 数据体:依次编码每个子项。

SML 示例:

<L [3]>
  <I4 100>
  <A "OK">
  <L [2]>
    <F4 3.14>
    <BOOLEAN TRUE>
  </L>
</L>

上述 SML 描述了一个包含 3 个子项的列表:一个整数、一个字符串和一个嵌套列表。嵌套列表又包含一个浮点数和一个布尔值。

解析关键: 解析器必须递归处理 L 类型。遇到格式码 0x01 时,先读取长度域确定子项数量,然后循环解析每个子项,直到所有子项处理完毕。嵌套深度是解析器栈深度的直接体现。

3.3 无符号整数 (U)

无符号整数类型 U 用于表示非负整数值,如设备 ID、数据长度、计数器等。根据值的大小,编码长度可以是 1、2、4 或 8 字节。

编码规则:

  • 格式码:0x02
  • 长度域:1 字节,表示数据体的字节数(1、2、4 或 8)。
  • 数据体:大端序无符号整数。

值范围与编码长度对应表:

值范围编码长度 (字节)示例值十六进制编码
0 ~ 25511000x64
256 ~ 65535210000x03 0xE8
65536 ~ 2³²-14700000x00 0x01 0x11 0x70
2³² ~ 2⁶⁴-1850000000000x00 0x00 0x00 0x01 0x2A 0x05 0xF2 0x00
避坑提示: 解析 U 类型时,不能仅根据值的大小选择编码长度,必须严格按照发送方指定的长度读取。例如,值 100 可以用 1 字节编码,但发送方也可能用 4 字节编码为 0x00 0x00 0x00 0x64。接收方必须读取长度域指定的字节数,否则会导致后续数据解析错位。

3.4 ASCII 字符串 (A) 与二进制字节数组 (B)

A 类型用于传输可打印的 ASCII 文本,B 类型用于传输任意二进制数据。两者都是可变长度类型,但字符集限制不同。

对比表格:

特性A (ASCII 字符串)B (二进制字节数组)
格式码0x100x04
有效字符0x20~0x7E (空格、数字、字母、标点)0x00~0xFF (所有字节值)
长度编码1~4 字节 (大端序,表示字节数)1~4 字节 (大端序,表示字节数)
SML 表示<A "Hello"><B 0x01 0x02 0xFF>
典型用途设备名称、状态文本、错误消息原始传感器数据、图像、配置文件

编码示例:

// A 类型编码 "ABC"
格式码: 0x10
长度: 0x03
数据: 0x41 0x42 0x43

// B 类型编码 [0x00, 0xFF, 0x7F]
格式码: 0x04
长度: 0x03
数据: 0x00 0xFF 0x7F

3.5 布尔类型 (BOOLEAN)

布尔类型 BOOLEAN 是最简单的数据类型,固定长度为 1 字节。它只有两个有效值:TRUE 和 FALSE。

编码规则:

  • 格式码:0x0C
  • 长度域:固定为 0x01
  • 数据体:TRUE 编码为 0xFF,FALSE 编码为 0x00。
严格性要求: 根据 SEMI 标准,只有 0xFF 被视为 TRUE,0x00 被视为 FALSE。任何其他字节值(如 0x01、0x80)都是非法的。解析器遇到非 0x00/0xFF 的值时,应视为协议错误并拒绝该消息。

3.6 有符号整数 (I8/I4/I2/I1)

有符号整数类型使用补码(Two's Complement)表示,支持负数。根据精度需求,有 4 种固定长度变体。

类型对比:

类型格式码字节长度最小值最大值
I10x041-128127
I20x082-3276832767
I40x104-2³¹2³¹-1
I80x208-2⁶³2⁶³-1

编码示例 (I4 类型,值 -100):

// -100 的补码表示 (4 字节)
// 100 的十六进制: 0x00 0x00 0x00 0x64
// 取反: 0xFF 0xFF 0xFF 0x9B
// 加 1: 0xFF 0xFF 0xFF 0x9C
格式码: 0x10
长度: 0x04
数据: 0xFF 0xFF 0xFF 0x9C

3.7 浮点类型 (F8/F4)

浮点类型遵循 IEEE 754 标准,F4 对应单精度(32 位),F8 对应双精度(64 位)。两者均使用大端序传输。

类型对比:

类型格式码字节长度有效位数指数范围
F40x904约 7 位十进制±3.4E±38
F80xA08约 15 位十进制±1.7E±308

编码示例 (F4 类型,值 3.14):

// 3.14 的 IEEE 754 单精度表示
// 符号位: 0
// 指数: 10000000 (128)
// 尾数: 10010001111010111000011
// 十六进制: 0x40 0x48 0xF5 0xC3
格式码: 0x90
长度: 0x04
数据: 0x40 0x48 0xF5 0xC3

3.8 数据类型编码结构总览

下面的 SVG 图展示了 SECS-II 数据类型的通用编码结构,以及各类型在格式码、长度域和数据体上的差异。

SECS-II 数据类型编码结构总览 通用编码结构 | 格式码 (1 字节) | 长度域 (1~4 字节) | 数据体 (N 字节) | 格式码标识类型,长度域表示数据体字节数(L 类型表示子项数) 整数类型 U (0x02) | I1 (0x04) I2 (0x08) | I4 (0x10) I8 (0x20) 大端序补码/无符号 长度: 1/2/4/8 字节 浮点类型 F4 (0x90) | F8 (0xA0) F (通用, 0x90) IEEE 754 大端序 长度: 4/8 字节 其他类型 L (0x01) | A (0x10) B (0x04) BOOLEAN (0x0C) L: 嵌套容器 A/B: 可变长度 编码关键点 所有多字节数据均使用大端序;L 类型的长度域表示子项数,其余类型表示字节数

3.9 数据类型选择策略

在实际的 SECS/GEM 设备开发中,选择合适的数据类型直接影响消息的解析效率与兼容性。以下是一些实践建议:

  • 优先使用固定长度类型: 对于已知范围的整数,优先选择 I1/I2/I4 而非 U 或可变长度类型,以减少解析复杂度。
  • 避免不必要的嵌套: L 类型虽然灵活,但过度嵌套会增加解析开销。建议将扁平结构作为首选。
  • 浮点精度匹配: 如果数据来自 32 位传感器,使用 F4 即可;只有需要高精度计算时才使用 F8。
  • 字符串编码一致性: A 类型仅支持 ASCII 子集。如果需要传输 Unicode 或其他编码,应使用 B 类型并在应用层约定编码方式。
实战经验: 在编写 SML 解析器时,建议为每种数据类型实现独立的解析函数(如 parse_I4()、parse_A()),并通过格式码分发到对应函数。这种模块化设计便于维护和扩展。

3.10 本章小结

本章详细介绍了 SML 中的 12 种数据类型,包括它们的定义、编码规则、取值范围与典型用途。重点内容总结如下:

  • L 类型 是消息的容器,支持递归嵌套,长度域表示子项数量。
  • U 类型 是无符号整数,编码长度可变(1/2/4/8 字节)。
  • A 与 B 类型 分别用于 ASCII 文本与二进制数据,均为可变长度。
  • BOOLEAN 类型 固定 1 字节,仅接受 0xFF (TRUE) 与 0x00 (FALSE)。
  • I1/I2/I4/I8 是有符号整数,使用补码与大端序编码。
  • F4/F8 是 IEEE 754 浮点数,分别对应单精度与双精度。