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消息长什么样?我画个图你就明白了。
看到没?消息头在最前面,后面跟着数据体。数据体可以是一个简单的数据项,也可以是一个嵌套的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,再看数据体里的数据项,基本就能猜出这条消息在干什么了。