3. 数据项(Data Item)基础:SECS-II 标准数据类型编码规则

SECS-II 消息的核心是数据项(Data Item, DI)。每个数据项由数据项标识符(Item ID)、长度(Length)和数据体(Data Body)三部分组成。理解标准数据类型的编码规则,是正确解析和构造 SECS-II 消息的前提。本章将详细拆解 ASCII、BINARY、无符号/有符号整数、浮点数、列表及布尔类型的二进制编码格式。

3.1 数据项通用格式

每个 SECS-II 数据项在字节流中遵循统一的 TLV(Type-Length-Value)结构。其中“Type”字段不仅标识数据类型,还包含格式位和长度位。

字段 字节数 说明
Item ID 1 字节 高 2 位为格式位(00=List, 01=Single, 10=二次编码),低 6 位为数据类型编码
Length 1 或 3 字节 若 Item ID 低 6 位为 0x00 或 0x01,则 Length 为 3 字节(大端序);否则为 1 字节
Data Body Length 指定 按具体数据类型编码的原始字节
关键点:Item ID 的格式位决定了数据项是单个值还是列表。对于列表(List)类型,其 Data Body 包含的是子数据项,而非原始数据。

3.2 标准数据类型编码规则

SECS-II 定义了 11 种标准数据类型。下表列出了每种类型的编码值、字节长度规则及典型用途。

类型 编码值(Hex) 字节长度 编码规则 典型用途
L 0x01 可变 Data Body 包含子数据项,Length 表示子项个数 嵌套结构、参数列表
BINARY 0x00 可变 原始字节序列,无编码转换 原始数据、图像、固件块
BOOLEAN 0x0C 1 字节 0x00=False,非 0x00=True 开关状态、标志位
ASCII 0x02 可变 ASCII 字符序列,无终止符 设备 ID、文本描述、状态名
U1 0x04 1 字节 无符号 8 位整数,范围 0~255 小范围计数、索引
U2 0x08 2 字节 无符号 16 位整数,大端序 模块编号、端口号
U4 0x10 4 字节 无符号 32 位整数,大端序 时间戳、计数器
I1 0x05 1 字节 有符号 8 位整数,补码表示 小范围偏差、状态码
I2 0x09 2 字节 有符号 16 位整数,大端序补码 测量值、偏移量
I4 0x11 4 字节 有符号 32 位整数,大端序补码 主计数器、累计值
F4 0x14 4 字节 IEEE 754 单精度浮点数,大端序 温度、压力、速率
F8 0x18 8 字节 IEEE 754 双精度浮点数,大端序 高精度测量、校准参数
编码值规律:数据类型编码值的高 4 位通常指示字节长度(0x00=1B, 0x08=2B, 0x10=4B, 0x18=8B),低 4 位指示类型族(0x0=BIN, 0x1=LIST, 0x2=ASCII, 0x4=U, 0x5=I, 0x8=F)。例如 U2=0x08,高 4 位 0x0 表示 2 字节,低 4 位 0x8 表示无符号整数族。

3.3 编码示例与字节流解析

以下通过具体示例展示常见数据类型的编码结果。所有示例均采用大端字节序。

3.3.1 ASCII 编码

数据项 "AB"(2 个字符):

Item ID:  0x02  (格式=Single, 类型=ASCII)
Length:   0x02  (2 字节)
Data:     0x41 0x42  ('A' 'B')
完整字节流: 02 02 41 42

3.3.2 U4 编码

数据项 1000(无符号 32 位):

Item ID:  0x10  (格式=Single, 类型=U4)
Length:   0x04  (4 字节)
Data:     0x00 0x00 0x03 0xE8  (1000 的大端表示)
完整字节流: 10 04 00 00 03 E8

3.3.3 F4 编码

数据项 3.14(单精度浮点数):

Item ID:  0x14  (格式=Single, 类型=F4)
Length:   0x04  (4 字节)
Data:     0x40 0x48 0xF5 0xC3  (3.14 的 IEEE 754 大端表示)
完整字节流: 14 04 40 48 F5 C3

3.3.4 BOOLEAN 编码

数据项 True:

Item ID:  0x0C  (格式=Single, 类型=BOOLEAN)
Length:   0x01  (1 字节)
Data:     0x01  (非零表示 True)
完整字节流: 0C 01 01

3.4 列表(L)数据项的嵌套结构

列表类型(L)的 Data Body 不包含原始数据,而是包含一个或多个子数据项。每个子数据项自身又是一个完整的 TLV 结构。列表的 Length 字段表示子数据项的个数,而非字节数。

示例:一个包含两个子项的列表,子项分别为 U1 值 5 和 ASCII 值 "OK"。

L Item ID:   0x01  (格式=List, 类型=L)
L Length:    0x02  (2 个子项)
子项1 ID:    0x04  (U1)
子项1 Length:0x01
子项1 Data:  0x05
子项2 ID:    0x02  (ASCII)
子项2 Length:0x02
子项2 Data:  0x4F 0x4B  ('O' 'K')
完整字节流: 01 02 04 01 05 02 02 4F 4B
常见错误:解析列表时,不能将 Length 当作字节长度。必须根据子项个数循环解析每个子项的 Item ID,再根据子项类型决定其长度字段的字节数。列表可以无限嵌套,但实际协议栈通常限制最大深度为 10 层。

3.5 数据类型编码流程 SVG

下图展示了从原始数据到 SECS-II 字节流的编码过程,以及解码时的逆向流程。

SECS-II 数据类型编码与解码流程 SECS-II 数据类型编码/解码流程 编码方向 原始数据 选择数据类型 应用编码规则 SECS-II 字节流 解码方向 SECS-II 字节流 解析 Item ID/Length 反向编码规则 还原原始数据 编码规则关键点 • 整数类型(U1/U2/U4/I1/I2/I4)使用大端序,有符号类型使用补码 • 浮点数(F4/F8)严格遵循 IEEE 754 标准,字节序为大端 • ASCII 字符串无终止符,Length 精确表示字符数 • BOOLEAN 仅使用 1 字节,0x00=False,任何非零值=True • 列表(L)的 Length 表示子项个数,而非字节长度

3.6 字节序与对齐规则

SECS-II 协议明确规定所有多字节数据(U2、U4、I2、I4、F4、F8)均采用大端序(Big-Endian),即最高有效字节(MSB)存储在最低地址。这与网络字节序一致,便于跨平台通信。

  • U2/I2:高字节在前,低字节在后。例如值 0x1234 编码为 0x12 0x34。
  • U4/I4/F4:字节顺序为 [MSB, ..., LSB]。例如值 0x12345678 编码为 0x12 0x34 0x56 0x78。
  • F8:8 字节顺序同样为 MSB 在前。
  • 对齐:SECS-II 不要求数据项在字节流中对齐到特定边界。每个数据项紧跟前一个数据项的最后一个字节。
移植提示:在 x86/ARM 小端平台上解析 SECS-II 消息时,必须使用 ntohl()、ntohs() 等函数或手动字节交换。对于浮点数,需先将字节序转换为小端后再使用 memcpy 到 float/double 变量。

3.7 数据类型选择策略

在实际协议栈移植中,选择合适的数据类型可以节省带宽并提高解析效率。以下是一些推荐策略:

场景 推荐类型 理由
状态标志、开关量 BOOLEAN 仅 1 字节,语义清晰
小范围计数(0~255) U1 节省带宽,避免 U4 浪费
设备 ID、模块编号 U2 范围 0~65535,足够大多数场景
时间戳、累计产量 U4 支持大范围无符号值
温度、压力测量值 F4 单精度满足一般精度要求
校准参数、高精度数据 F8 双精度保证精度不丢失
文本描述、日志 ASCII 人类可读,易于调试
嵌套参数结构 L 支持复杂层次关系

3.8 常见编码错误与调试方法

在移植过程中,数据项编码错误是导致通信失败的主要原因。以下列出典型错误及排查方法:

  • 字节序错误:多字节数据未进行大端转换,导致数值错误。调试时打印原始字节流与期望值对比。
  • 列表 Length 误解:将列表的 Length 当作字节数解析,导致后续数据项解析错位。务必根据子项个数循环解析。
  • ASCII 无终止符:接收方使用 strlen 或 strcpy 处理 ASCII 数据项可能导致缓冲区溢出。必须使用 Length 字段精确控制拷贝长度。
  • BOOLEAN 非标值:某些设备发送 0x02 或 0xFF 表示 True,接收方应判断非零即为 True,而非仅判断 0x01。
  • 浮点数字节序:IEEE 754 浮点数在小端平台上需先做字节交换,再解释为 float/double。直接强制类型转换会得到错误值。
调试工具:使用 Wireshark 的 SECS-II 解析器或自定义的字节流打印函数(如 hexdump)逐字节比对编码结果。对于浮点数,可先编码为已知值(如 1.0、3.14159)验证字节序是否正确。

掌握以上编码规则后,开发者可以准确构造和解析 SECS-II 消息中的数据项,为后续的事务处理(Transaction)和消息流控制打下坚实基础。