3. SML数据类型详解:L/U/A/B/BOOLEAN/F/I8/I4/I2/I1/F8/F4
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 类型 | 格式码 (十六进制) | 数据长度 (字节) | 取值范围 | 典型用途 |
|---|---|---|---|---|
| L | 0x01 | 可变 (嵌套) | 子项数量 0~2³²-1 | 消息结构容器 |
| U | 0x02 | 1/2/4/8 | 0 ~ 2⁶⁴-1 | 无符号计数器、ID |
| A | 0x10 | 可变 (1~n) | ASCII 字符 (0x20~0x7E) | 设备名、文本状态 |
| B | 0x04 | 可变 (1~n) | 0x00~0xFF | 原始二进制数据 |
| BOOLEAN | 0x0C | 1 | TRUE (0xFF) / FALSE (0x00) | 开关、使能标志 |
| F | 0x90 | 4/8 | ±3.4E±38 / ±1.7E±308 | 浮点测量值 (通用) |
| I8 | 0x20 | 8 | -2⁶³ ~ 2⁶³-1 | 大范围有符号整数 |
| I4 | 0x10 | 4 | -2³¹ ~ 2³¹-1 | 标准有符号整数 |
| I2 | 0x08 | 2 | -32768 ~ 32767 | 小范围有符号整数 |
| I1 | 0x04 | 1 | -128 ~ 127 | 单字节有符号整数 |
| F8 | 0xA0 | 8 | ±1.7E±308 | 高精度浮点 |
| F4 | 0x90 | 4 | ±3.4E±38 | 单精度浮点 |
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 个子项的列表:一个整数、一个字符串和一个嵌套列表。嵌套列表又包含一个浮点数和一个布尔值。
3.3 无符号整数 (U)
无符号整数类型 U 用于表示非负整数值,如设备 ID、数据长度、计数器等。根据值的大小,编码长度可以是 1、2、4 或 8 字节。
编码规则:
- 格式码:0x02
- 长度域:1 字节,表示数据体的字节数(1、2、4 或 8)。
- 数据体:大端序无符号整数。
值范围与编码长度对应表:
| 值范围 | 编码长度 (字节) | 示例值 | 十六进制编码 |
|---|---|---|---|
| 0 ~ 255 | 1 | 100 | 0x64 |
| 256 ~ 65535 | 2 | 1000 | 0x03 0xE8 |
| 65536 ~ 2³²-1 | 4 | 70000 | 0x00 0x01 0x11 0x70 |
| 2³² ~ 2⁶⁴-1 | 8 | 5000000000 | 0x00 0x00 0x00 0x01 0x2A 0x05 0xF2 0x00 |
3.4 ASCII 字符串 (A) 与二进制字节数组 (B)
A 类型用于传输可打印的 ASCII 文本,B 类型用于传输任意二进制数据。两者都是可变长度类型,但字符集限制不同。
对比表格:
| 特性 | A (ASCII 字符串) | B (二进制字节数组) |
|---|---|---|
| 格式码 | 0x10 | 0x04 |
| 有效字符 | 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。
3.6 有符号整数 (I8/I4/I2/I1)
有符号整数类型使用补码(Two's Complement)表示,支持负数。根据精度需求,有 4 种固定长度变体。
类型对比:
| 类型 | 格式码 | 字节长度 | 最小值 | 最大值 |
|---|---|---|---|---|
| I1 | 0x04 | 1 | -128 | 127 |
| I2 | 0x08 | 2 | -32768 | 32767 |
| I4 | 0x10 | 4 | -2³¹ | 2³¹-1 |
| I8 | 0x20 | 8 | -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 位)。两者均使用大端序传输。
类型对比:
| 类型 | 格式码 | 字节长度 | 有效位数 | 指数范围 |
|---|---|---|---|---|
| F4 | 0x90 | 4 | 约 7 位十进制 | ±3.4E±38 |
| F8 | 0xA0 | 8 | 约 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 数据类型的通用编码结构,以及各类型在格式码、长度域和数据体上的差异。
3.9 数据类型选择策略
在实际的 SECS/GEM 设备开发中,选择合适的数据类型直接影响消息的解析效率与兼容性。以下是一些实践建议:
- 优先使用固定长度类型: 对于已知范围的整数,优先选择 I1/I2/I4 而非 U 或可变长度类型,以减少解析复杂度。
- 避免不必要的嵌套: L 类型虽然灵活,但过度嵌套会增加解析开销。建议将扁平结构作为首选。
- 浮点精度匹配: 如果数据来自 32 位传感器,使用 F4 即可;只有需要高精度计算时才使用 F8。
- 字符串编码一致性: A 类型仅支持 ASCII 子集。如果需要传输 Unicode 或其他编码,应使用 B 类型并在应用层约定编码方式。
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 浮点数,分别对应单精度与双精度。