☰
SECS/GEM中文详解:从HSMS连接到GEM状态机的完整指南
2026/10/16 5:07:17 网站建设 项目流程

简介:面向制造业设备集成与自动化工程师的SECS/GEM协议中文详解文档,系统梳理了半导体设备通信标准在工业环境中的应用。该文档共10个章节,从协议价值、消息日志到常用术语均有涉及,并重点讲解Streams and Functions的分类、自定义方式,以及各指令的使用场景和用法,可帮助读者快速定位需要了解的协议细节。针对降低设备集成成本、有效利用网络带宽、数据密度小、无数据翻译、环路保证及安全等关键特性,文档也提供了完整的说明,适合作为设备对接和协议调试时的参考手册。资源包为单个PDF文档,整体约955KB,内容紧凑、便于离线查阅。已有2256人学习使用,适用于半导体、电子制造及其他需要SECS/GEM接口的自动化项目,也适合初学者从零开始系统学习。

1. secs/gem 中文详解:先看清它在解什么,再谈怎么落地

“secs/gem 中文详解”这个标题,看起来像是把一份协议手册翻译成人话,但真去读标准的人会发现,它要解决的远不止“报文格式长什么样”,而是设备怎么跟工厂自动化系统稳定对话。我第一次接触 SECS/GEM 时,对着抓包工具里那串十六进制报文头和数据项看了很久,完全没法把它跟 JSON、Modbus 这类常见协议对应起来——这正是这套标准最反直觉的地方:它不是一个协议,而是一整套标准族,通信靠 E4/E37,消息格式靠 E5,设备行为模型靠 E30。这篇笔记,就是把它拆给设备端工程师、EAP 开发以及设备自动化实施人员看:SECS/GEM 到底是什么、怎么做、坑在哪。

2. SECS/GEM 不是一个协议而是四套标准:先看清标准族的分工

2.1 SEMI E4、E5、E30、E37 各管一段:从物理传输到行为模型

很多新手拿到设备端的协议文档,发现里面既有“SECS-I”,又有“HSMS”,还有一堆 S1F13、S6F11 这样的编号,第一反应是这些是同一个东西的别名。实际上它们分属不同标准,分工非常明确。

标准号标准名层级负责的内容
E4SECS-I传输层基于 RS-232 串口的块传输、块头定义、校验与重试
E5SECS-II消息层Stream/Function 消息格式、数据项类型、编解码规则
E30GEM行为模型层设备状态模型、事件上报、报警、远程命令、时钟同步、配方与进料控制
E37HSMS高速传输层基于 TCP/IP 的高速消息服务,替代 E4 的串口物理传输

E4 是串口时代的东西,速度慢、接线复杂,现在绝大多数新设备已经不走这条路。E37 的 HSMS 用 TCP/IP 传输,是当前设备与 EAP 通信的主流承载层。注意一个容易混淆的点:HSMS 只是“传输管道”,它不负责定义 S1F13 内容本身,S1F13 这条消息长什么样由 E5(SECS-II)定义,而“什么时候该发 S1F13、发完要进哪个状态”由 E30(GEM)定义。

E30 也就是 GEM,是这里面最容易被低估的部分。它不关心字节怎么编,它关心的是设备的行为契约:设备从上电到生产就绪,状态怎么跳;报警来了应该用哪条消息上报;上位机要求同步时间,设备必须用哪个消息回应。我在看很多设备厂商的接入文档时发现,他们往往把 S1F13/S1F14 建连消息讲得很细,但对 GEM 要求的事件上报、远程命令和状态模型一笔带过——这恰恰是后面 EAP 联调时翻车最多的地方。

GEM 里真正绕不开的强制项包括:建连与通信建立(S1F13/S1F14)、事件上报(S6F11/S6F12)、报警(S5F1/S5F2)、远程命令(S2F41/S2F42)、时钟同步(S2F37)、数据收集(S2F33/S2F34)。这些消息不是“可选”,而是 GEM 测试里逐条对账的内容。搞清楚这个标准族的分工之后,再去看设备端的实现,你就知道该往哪一层查问题:连不上看 E37,消息发出去对方看不懂看 E5,连上了但状态不对看 E30。

2.2 设备端“支持 SECS/GEM”到底要支持到什么程度

从业者常问的一个问题是:我们设备要对接工厂的 EAP,是不是把 S1F13 和 S1F14 调通就算“支持 SECS/GEM”了?答案是否定的。S1F13/S1F14 只是建连握手,就像 HTTP 的 TCP 三次握手一样,后面真正的业务还没开始。

常见做法是两条路线:一条是买现成的 SECS/GEM 协议栈库,一条是自研精简实现。对于量产设备且团队没有协议经验的情况,我一般建议先评估现成库。选库时重点看四点:是否同时覆盖 HSMS 传输和 SECS-II 编解码、是否内置 GEM 状态机、是否支持在线消息追踪、以及拿到之后能不能过 GEM 标准测试工具的验收。很多库只是把 E5 的编解码做了,状态机要自己搭,这个工作量容易被低估。

如果决定自研,实现上建议分成四层,不要一上来就把逻辑混在一个文件里:

  1. 传输层:TCP Socket 管理、HSMS 的 Select 流程、T3 到 T8 超时处理。
  2. 编解码层:SECS-II 数据项(List、Binary、ASCII、各种整数浮点类型)的编解码。
  3. 状态机层:设备控制状态、设备模型状态、事件状态的管理。
  4. 业务映射层:把设备内部的报警、配方启动、批次完成这类业务事件,映射成 S6F11、S5F1 这些标准消息。

自研的难点不在编解码本身,而在边界条件。比如一个 List 里嵌了多层子 List,数据区长度算错一位,整帧消息就会断;再比如 T3 超时后要不要重发、重发时 SystemBytes 怎么处理,这些细节决定了对端 EAP 能不能稳定收到。很多设备商最终都发现自己实现的栈占用了大量测试时间,反而拖慢了项目进度,这个取舍要在立项最初就想清楚。

3. HSMS 连接建立与参数配置:设备与 EAP 之间的第一道门

3.1 HSMS 的 select 机制与主动/被动角色

HSMS 不是 TCP 连上就能发消息,它有一套自己的会话建立流程。TCP 三次握手完成之后,双方要先交换 HSMS 控制消息,完成 Select 流程,之后才允许传 SECS-II 数据消息。这个细节是新手最先踩的坑:拿 TCP 工具连上了端口,直接往里塞 S1F13 的字节流,对端完全没有反应。

HSMS 控制消息常见的有 Select.req / Select.rsp、Deselect、Separate.req、Linktest.req / Linktest.rsp。其中 Select 流程决定了一个会话 ID,注意这里说的是会话 ID,不是 SECS-II 消息里的 Device ID,别混。Select 超时由 T7 控制,如果 T7 超时还没收到 Select.rsp,连接会被判为无效并断开。

主动/被动角色的配置决定了谁去连谁。常见做法是设备端配置成 Passive,EAP 端配置成 Active,由 EAP 主动发起连接。反过来也可以,但最怕的是两端都配成 Active:两边同时发起连接,TCP 连接会被反复重置,表现为端口明明开着,但消息一直接不上;两端都配成 Passive 则永远不会建立连接。这个问题的排查成本很低,但定位过程很容易绕路,因为看起来像是防火墙或网络问题。

HSMS 的默认端口常见是 5000 和 5001,也有厂商自定义到其他端口,这个没有强制标准,以双方约定为准。调试时要确认的不是端口本身,而是端口两端的角色、IP 和超时参数是否匹配。

3.2 连接参数配置与三条实用调试命令

设备端的 HSMS 配置项翻来覆去就是下面这些,建议一开始就把它们单独抽出来做成可配置文件,不要在代码里写死。

参数含义常见取值
Device IDSECS-II 消息里的设备标识0 或工厂分配的值
Local IP / Port本机监听地址与端口0.0.0.0:5000
Remote IP / Port对端 EAP 地址与端口视工厂网络而定
Active / Passive连接发起方角色设备常用 Passive
Connection Timeout建立 TCP 连接的等待时间10 到 30 秒
Reconnect Interval断开后的重连间隔5 到 15 秒
T3等待 SECS-II 响应的超时45 秒
T5独立连接尝试间隔10 秒
T6控制消息响应超时5 秒
T7Select 流程超时10 秒
T8网络消息间隔超时5 秒

T3 是调参频率最高的一个。如果设备端某个远程命令实际执行时间可能超过 45 秒,EAP 端的 T3 就会先超时,这时候要把 T3 调大。但注意 T3 不是越大越好,调太大意味着消息积压的风险也跟着变大,设备端如果长时间不响应,EAP 的请求队列会越堆越长。

联调时我一般会先跑三条命令确认连接状态:

# 查看设备端 5000 端口是否在监听 ss -tnlp | grep 5000 # 查看与 EAP 的 TCP 连接是否建立 netstat -an | grep 5000 # 抓取 HSMS 报文,确认 Select 流程是否完成 tcpdump -i eth0 tcp port 5000 -X -s 0

第一条命令看监听状态,确认设备端服务起来了;第二条看 ESTABLISHED,确认 TCP 是通的;第三条才真正看出问题在哪。抓包时重点看前几个包:如果只有 TCP 握手包而没有 Select.req,说明本端角色配置成了 Passive 在等对方,但对方没来连;如果有 Select.req 但没有 Select.rsp,说明对端收到了请求但拒绝了,要检查会话 ID 和 T7 配置。

4. SECS-II 消息与 SML 定义:把传输内容写清楚

4.1 一条 SECS-II 消息的帧结构:Header 里藏着哪些关键信息

SECS-II 消息承载在 HSMS 的数据消息里,整体结构是:4 字节的 Length 字段,后面跟着 10 字节的 Header,再后面是数据区。Length 字段的取值是“10 字节 Header + 数据区字节数”,不包含 Length 字段自己。这个计算规则是新手最容易错的地方,后文避坑章节会专门展开。

10 字节 Header 的信息分布,实际联调时几乎每天都要对着看:

Header 字节承载信息说明
字节 0Device ID 高位15 位设备 ID 的高字节
字节 1Device ID 低位 + 重试位低 7 位是 ID,最高位是重试标志
字节 2Stream 号消息流编号,如 1、2、5、6
字节 3Function 号功能编号,如 13、14、11
字节 4W 位置 1 表示需要对方回复
字节 5-9SystemBytes4 字节消息配对编号

Stream/Function 组合就是消息的名字。S1F13 是“Stream 1、Function 13”,意思是建立通信请求;S6F11 是事件上报;S2F41 是远程命令。W 位决定这条消息要不要响应,S1F13 W 置 1,对方必须回 S1F14;如果 W 置 0,对方就不需要回。SystemBytes 的作用是配对,类似请求 ID,后面单独讲。

数据区的编码方式和 JSON 完全不一样。SECS-II 没有键名,它完全靠位置和类型推断内容。一个数据项的开头是格式字节,高四位表示类型,低四位表示长度类别。比如 0x01 是 List,0x00 是 NULL,0x11 是 1 字节无符号整数,0x20 是 ASCII 字符串。这种设计非常紧凑,但可读性极差,所以行业里才有了 SML 这种文本描述格式。

4.2 用 SML 定义一条事件上报消息并计算字节数

SML(SECS Message Language)是 SECS-II 消息的文本描述形式,设备厂商在给 EAP 做对接文档时,通常直接给 SML 而不是二进制字节流。设备和 EAP 之间实际传输的仍然是二进制,但人写代码、写文档、评审协议时,大家都用 SML。下面是一条典型的事件上报消息 S6F11:

S6F11 W <L <U4 1> // DATAID:数据收集ID <U4 1001> // CEID:事件ID,对应设备上配置的事件编号 <L // 数据集合,里面每个子List是一组报表 <L <U4 1> // RPTID:报表ID <L <U4 3> // 变量ID:对应S2F33里定义的变量编号 <A "ALARM"> // 变量值,这里是ASCII字符串 > > > >

这段 SML 的含义是:上报事件 1001,携带一组报表数据,报表里包含变量 3,变量值是一个字符串 “ALARM”。理解它的关键是位置语义:第二个 U4 是事件 ID,第三个位置开始是数据集合,这些全靠约定,靠双方在协议表里对好了 RPTID 和变量 ID 的含义。

把这段 SML 转成二进制,数据区的字节数大致是这样累加的:最外层 List 格式字节 1 字节;DATAID 的 U4 是 4 字节;CEID 的 U4 是 4 字节;内层 List 格式字节 1 字节;再内层 List 格式字节 1 字节;RPTID 的 U4 是 4 字节;最内层 List 格式字节 1 字节;变量 ID 的 U4 是 4 字节;ASCII 字符串 1 字节长度头加 5 字节内容。总共约 26 字节左右,那么 Length 字段应该写 10 + 26 = 36。

这个计算过程看着简单,但手算很容易漏掉字符串前面的长度字节,或者把多层 List 的格式字节数错。实际开发时不要手算,直接由协议栈的编码函数生成字节流,再从字节流里反解长度来验证。

4.3 SystemBytes 配对:响应如何找到请求

EAP 端维护着一张等待响应的请求表,表里的 key 就是 SystemBytes。设备端收到一条 W 位置 1 的请求后,回响应时必须把请求 Header 里的 SystemBytes 原样复制过来。EAP 收到响应后根据 SystemBytes 找到挂起的请求,把这次对话闭环。

如果设备端不回填 SystemBytes,或者填了一个新值,EAP 就永远找不到匹配的请求,结果就是 T3 超时。这个问题在自研协议栈里非常常见,因为开发时容易只关注数据区内容,忽略 Header 复制。我的习惯是:在代码里把收到的整条消息 Header 暂存,构造响应时整段复制,只改 Stream/Function 和 W 位,SystemBytes 一个字节都不动。

5. SECS/GEM 常见故障排查:五个高频坑与根因

5.1 连接层:TCP 已连上,消息却一直超时

现象:EAP 端日志报 T7 超时或者提示 no HSMS session,但设备端 netstat 看到 TCP 状态是 ESTABLISHED,端口也通。

原因:TCP 连接虽然是通的,但 HSMS 层的 Select 流程没有成功完成。常见原因有两个:主动/被动角色配错,两端都是 Active 导致连接互相抢占,反复重置;或者 T7 超时设定得太短,设备端响应稍慢就导致 Select 被放弃。

解决:先确认角色矩阵,一个 Active 一个 Passive 是基本前提。然后抓包看有没有 Select.req 和 Select.rsp 的往返,没有 Select.rsp 就检查对端是否收到请求、会话 ID 是否合法。别一上来就调大 T3,T3 解决不了 Select 的问题,只会掩盖症状。

5.2 字节长度:EAP 一直报 Header Length 不匹配

现象:EAP 日志里出现 “invalid message length” 或解析直接失败,设备端明明按 SML 把内容发出来了,对方就是不认。

原因:Length 字段算错了。最常见的是把 4 字节的 Length 字段本身也算了进去,或者只算了数据区、漏掉了 10 字节 Header。ASCII 字符串的中文字符按字符数算而不是按字节数算,也会导致长度对不上。

解决:记住这个规则:HSMS 的 Length = 10 字节 Header + 数据区字节数,跟前面的 4 字节 Length 字段无关。写编码函数时统一用“先编码数据区,再把数据区长度加 10 回填到 Length”,不要手填。

5.3 消息配对:SystemBytes 回填错,EAP 永远等不到响应

现象:设备端显示已经执行了远程命令,但 EAP 端一直等到 T3 超时,日志里看不到那条命令的响应。

原因:响应帧的 SystemBytes 没有复制请求帧的值。设备端自己生成了一个新的 SystemBytes,EAP 在挂起表里找不到匹配项,只能一直等到超时。另一种情况是响应帧的 W 位没有清掉,EAP 认为这条响应本身还需要再回复,逻辑上直接卡死。

解决:把请求帧的 Headers 原样缓存,构造响应时复制整个 SystemBytes 字段,W 位置 0。抓包对比请求和响应的第 5 到 9 字节,一眼就能看出问题。

5.4 状态机翻车:设备明明在生产,EAP 端却显示未就绪

现象:设备已经在正常跑货了,EAP 界面上设备状态却停在 INITIALIZED 或者反复跳回 NOT COMMUNICATING,GEM 测试里的初始化事件一直报 NACK。

原因:设备在 S1F14 之后没有按 E30 的流程上报初始化完成事件,或者初始化事件携带的事件 ID、报告 ID 没有提前在 E2F33/S2F37 阶段配置好。EAP 不认这个事件 ID,就会认为设备没有进入通信就绪状态。

解决:按 E30 的初始化流程走完整条链:S1F13 建连,S1F14 确认,然后上报初始化事件,事件里携带的事件 ID 和报表 ID 必须与 EAP 侧配置的清单一致。联调前先用标准 GEM 测试工具跑一遍初始化用例,不要跳过。

5.5 字符串编码的玄学:ASCII 类型在中文环境下乱码

现象:报警文本或配方名里的中文、特殊字符到了 EAP 端变成乱码,或者整条消息解析错位。

原因:SML 里定义的是 A 类型(ASCII),但设备端实际往数据区里写的是 UTF-8 编码字节。如果内容是纯英文倒还好,一碰上中文,字节数就不等于字符数,长度头跟着错,后面的数据项全部错位。

解决:协议栈统一按字节流处理,长度字段严格按字节数算。能避免中文就尽量避免,变量说明、报警文本在协议层建议用英文缩写。一定要传中文时,双方要对齐字符集,并对帧长度做逐字节校验。

6. GEM 状态机与最小自检序列:从设备上电到生产就绪

6.1 五种设备状态与跳转条件

GEM 定义的状态模型是设备端与 EAP 对话的基础框架,把设备从断电到生产就绪的过程切成了有明确边界的几个状态。实际联调时,EAP 界面显示的就是这些状态。

状态含义进入条件
NOT COMMUNICATING没有与 EAP 建立 HSMS 会话设备上电但未连接,或连接已断开
INITIALIZING正在建立会话TCP 连通且 Select 完成
INITIALIZED已交换 S1F13/S1F14设备发出 S1F14 且被 EAP 确认
COMMUNICATING生产通信就绪初始化事件上报完成
PAUSED暂停处理生产消息收到暂停指令或设备进入暂停状态

状态跳转里最容易出问题的就是 INITIALIZED 到 COMMUNICATING 这一步,很多实现漏了初始化事件。设备明明已经在跑,但 EAP 认为它还没准备好接收远程命令,导致后续的 S2F41 全部被忽略。

6.2 上电后的最小自检消息序列

设备接入工厂前,我习惯先跑一遍最小自检序列,按顺序执行并逐条检查响应。这个序列很短,但能覆盖八成以上的对接问题。

  1. 与 EAP 建立 TCP 连接,完成 HSMS Select。
  2. 发送 S1F13 W,等待 S1F14,检查响应的 SystemBytes 是否回填。
  3. 上报初始化完成事件 S6F11,确认 EAP 返回 S6F12 且 Acknowledge 为 0。
  4. 发送 S2F37 同步时钟,检查 EAP 返回的当前时间与设备是否一致。
  5. 用 S2F33 读取一个测试变量,验证数据收集链路。

每一步失败的排查方向都不同:第一步失败看 Select 和端口,第二步失败看 Device ID 和 Length,第三步失败看事件 ID 配置。我早期做设备端接入时,曾经在一台模拟设备上把 E4 的块头结构和 HSMS 的 Length 规则搞混,对着抓包工具折腾了大半天,最后才发现是两个标准混用了。从那以后,每实现一条消息,我都先抓包对一遍帧结构再往下走。设备自动化联调不玄,静下来按标准一帧帧对,问题都会露出原形。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询