4、SECS-II消息格式:数据项、消息头、流与功能

好,咱们今天聊聊SECS-II的消息格式。说实话,很多初学者一上来就被SML、HSMS这些缩写搞懵了,但SECS-II才是真正承载数据的核心。你想想看,设备要告诉主机“我报警了”、“我晶圆加工完了”,这些信息怎么组织?就是靠SECS-II定义的消息格式。

我个人习惯把SECS-II消息拆成三块来看:消息头(Message Header)、数据项(Data Item),以及它们组合成的流(Stream)与功能(Function)。这三块搞明白,SECS-II就算入门了。

4.1 消息头:每一条消息的身份证

每条SECS-II消息都有一个10字节的消息头。我在项目里调试时,第一步永远是看消息头,因为它告诉你这条消息是谁发的、发给谁、是什么类型。

字节偏移 字段名 长度 说明
0 Device ID 2字节 设备标识,低10位有效
2 Stream & Function 2字节 高6位Stream,低10位Function
4 Message Type 1字节 0x01数据消息,0x02控制消息
5 System Bytes 4字节 系统字节,用于请求-应答配对
9 Header Byte 9 1字节 备用/扩展

关键点:System Bytes是消息配对的钥匙。主机发请求时带上一个System ID,设备回复时必须原样带回。我曾经排查过一个通讯超时问题,最后发现是设备端把System Bytes写成了固定值,导致主机永远匹配不上回复。

4.2 数据项:SECS-II的基本积木块

数据项就是SECS-II里最小的数据单元。说白了,它就像乐高积木里的基础块,可以单独用,也可以组合成复杂结构。

SECS-II定义了6种基本数据类型:

  • List(列表):可以包含任意数量的子数据项
  • ASCII(字符串):可打印字符
  • Binary(二进制):1字节无符号整数
  • Boolean(布尔):True/False
  • Unsigned Integer(无符号整数):1/2/4/8字节
  • Signed Integer(有符号整数):1/2/4/8字节
  • Float(浮点数):4/8字节

我的经验:实际项目中90%的数据项都是List、ASCII和U4(4字节无符号整数)。别被那么多类型吓到,先把这三个用熟再说。

每个数据项在传输时都带一个格式头(Format Header),占2-3字节:

格式头结构:
字节0:格式码(高4位)+ 长度类型(低4位)
字节1-2:数据长度(如果长度类型为2字节)

举个例子,传输一个ASCII字符串"OK":

格式码:0x41(ASCII类型)
长度:0x02
数据:0x4F 0x4B('O'和'K'的ASCII码)

4.3 流与功能:消息的“地址”与“动作”

流(Stream)和功能(Function)是SECS-II消息的“门牌号”。Stream决定消息属于哪个类别,Function决定具体做什么事。

标准SECS-II定义了上百个Stream/Function对,我挑几个最常用的:

Stream Function 名称 说明
1 1 Are You There 通信建立时的握手请求
1 2 On Line Data 设备上线通知
2 41 Host Command 主机下发命令
5 1 Alarm Report 设备报警上报
6 11 Equipment Constant 设备参数读写

避坑指南:我曾经在调试时发现设备一直报错,查了半天才发现是Stream和Function的字节序搞反了。标准规定Stream在高6位,Function在低10位,但有些设备厂商的实现是反的。遇到通讯问题,先检查这个。

4.4 消息结构:从数据项到完整消息

一条完整的SECS-II消息长什么样?我画个图你就明白了。

SECS-II 消息结构 消息头(10字节) Device ID S/F Msg Type System Bytes Reserved 数据体(Data Body) 格式头 数据内容 嵌套数据项 完整消息示例:S1F1(Are You There) 消息头(10B) + List(格式头) + ASCII("OK")

看到没?消息头在最前面,后面跟着数据体。数据体可以是一个简单的数据项,也可以是一个嵌套的List。我见过最复杂的消息嵌套了7层List,调试时看得眼花。

4.5 实战:解析一条S1F1消息

咱们来点实际的。假设设备收到一条S1F1(Are You There)请求,需要回复S1F2(On Line Data)。

请求消息(S1F1):

消息头:
Device ID: 0x0001
S/F: 0x0101(Stream 1, Function 1)
Msg Type: 0x01(数据消息)
System Bytes: 0x12345678

数据体:
格式头: 0x41 0x02(ASCII, 长度2)
数据: 0x4F 0x4B("OK")

回复消息(S1F2):

消息头:
Device ID: 0x0001
S/F: 0x0102(Stream 1, Function 2)
Msg Type: 0x01
System Bytes: 0x12345678(必须和请求一致)

数据体:
格式头: 0x41 0x05(ASCII, 长度5)
数据: 0x48 0x45 0x4C 0x4C 0x4F("HELLO")

注意:回复消息的System Bytes必须和请求消息完全一致。这是SECS-II协议的基本规则,也是主机匹配请求和回复的唯一依据。我见过有人把这个写错,结果主机一直收不到匹配的回复,超时断开连接。

4.6 常见Stream/Function分类

标准SECS-II把Stream分成了几个大类,我整理了一下:

Stream范围 用途 常见Function
Stream 0 保留 无
Stream 1 设备状态与通信 S1F1/S1F2(握手)、S1F13/S1F14(通信建立)
Stream 2 设备控制与诊断 S2F41(主机命令)、S2F49(远程控制)
Stream 3 材料管理 S3F1/S3F2(材料状态)
Stream 4 晶圆状态 S4F1/S4F2(晶圆信息)
Stream 5 报警管理 S5F1/S5F2(报警上报)、S5F3/S5F4(报警确认)
Stream 6 数据收集 S6F11/S6F12(设备参数)、S6F15/S6F16(事件报告)
Stream 7-127 用户自定义 各设备厂商自行定义

我的建议:刚开始做SECS/GEM开发,先把Stream 1、5、6这三个搞熟。Stream 1是通信基础,Stream 5是报警,Stream 6是数据收集。这三个搞定了,80%的通讯场景都能覆盖。

嗯,SECS-II的消息格式就这些。消息头是身份证,数据项是积木块,流与功能是门牌号。这三样东西组合起来,就能表达设备通讯中的任何信息。下次你看到一条SECS-II消息,先看消息头里的S/F,再看数据体里的数据项,基本就能猜出这条消息在干什么了。