SECS/GEM标准规范实战指南:从状态机到报文联调

发布时间:2026/10/31 3:43:42
SECS/GEM标准规范实战指南:从状态机到报文联调

简介:这份PDF文档面向半导体设备自动化领域的工程师与开发人员,系统讲解SECS/GEM(SEMI设备通信标准/通用设备模型)规范及落地实现,帮助解决不同厂商设备与主机系统之间的通信标准化与互操作问题。文档以广州金南瓜科技的SECS/GEM方案为实例,依次展开通信状态模型、控制状态模型与设备处理状态,并逐项说明主机发起场景、事件通知、在线识别、动态事件报告配置、变量与跟踪数据采集、报警管理、远程控制、设备常数、过程程序管理、时钟及终端服务等设备能力,同时给出TCP/IP通讯超时等协议细节与事件、变量、报警的实现清单,目录结构完整,便于按模块查阅与对照实施。资源包共1个PDF文件,约1006KB,轻量易读。目前已有746人学习,适合需要理解SECS/GEM规范、搭建设备通信接口或进行自动化产线集成的技术人员参考。

1. 一份把 SECS/GEM 从“玄学”拉回地面的规格书

半导体设备联机这行有个共识:SECS/GEM 本身不难,难的是把标准条文翻译成能跑通的报文和状态机。很多工程师第一次接 GEM 接口,面对 S1F13、S1F14、S2F33、S6F11 这些编号,感觉像在看天书,调不通的时候只能靠抓包猜。这份《SECS/GEM 标准规范》规格说明书,就是一份把标准落到具体设备实现上的工程文档,覆盖通讯状态模型、控制状态模型、事件报告配置、变量采集、报警管理、远程命令、过程程序管理等 GEM 必备能力,还附了完整的 SECS 场景时序和消息格式字典。它适合两类人:一是刚接手设备端 GEM 接口、需要一份可对照实现的开发;二是主机端(Host)侧要对接不同机台、需要确认对方到底实现了哪些能力的集成工程师。下面按“文档怎么读、状态机怎么落、报文怎么对、坑在哪”的顺序拆。

2. 先读状态模型:通讯与控制两条主线怎么落地

2.1 通讯状态模型:DISABLED / ENABLED 与四个子状态

文档第 2.1 节用 Harel 状态图描述了设备与主机的通讯链路,核心是两层:顶层 DISABLED 和 ENABLED,ENABLED 下再分 COMMUNICATING 和 NOT COMMUNICATING,NOT COMMUNICATING 又拆成 HOST-INITIATED CONNECT 和 EQUIPMENT-INITIATED CONNECT 两个并行子状态。这个结构不是画着好看的,它直接决定了你的代码里要维护几个布尔标志、定时器什么时候启动。

落地时我一般会把它映射成一个枚举加一个定时器:

from enum import Enum class CommState(Enum): DISABLED = 0 NOT_COMM_HOST_INIT = 1 # 等主机发 S1F13 NOT_COMM_EQP_WAIT_CRA = 2 # 设备主动发 S1F13,等 S1F14 NOT_COMM_EQP_WAIT_DELAY = 3 # 连接失败,等 CommDelay 到期重试 COMMUNICATING = 4 # 关键参数:建立通讯超时,文档中对应 ECID=1 ESTABLISH_COMM_TIMEOUT = 10.0 # 秒,按设备实际 ECID 值配置 COMM_DELAY = 5.0 # 重试间隔,秒

逻辑说明:进入 NOT COMMUNICATING 时,设备主动连接分支要立刻把 CommDelay 定时器置为“已过期”,然后发 S1F13;收到 S1F14 且 COMMACK=0 才进 COMMUNICATING。如果连接事务失败,进 WAIT DELAY,清空发送队列(必要时转 spool 缓冲),等定时器到期再回 WAIT CRA 重发。参数上,ESTABLISH_COMM_TIMEOUT对应文档里那个 ECID=1 的“建立通讯超时”,这个值主机和设备两边必须一致,否则一方还在等、另一方已经判超时,日志里就会出现“发了没回”的假象。

2.2 控制状态模型:OFF-LINE 下为什么还要回 S1F17

第 2.2 节的控制状态模型定义了主机和设备之间的协作级别。文档写得很明确:OFF-LINE 状态下,设备对主机除 S1F13、S1F17 之外的所有 primary message 都回 SxF0,但 S1F13 和 S1F17 要正常处理。这条规则是很多新手翻车的地方——以为离线了就什么都不理,结果主机发 S1F17 请求上线,设备不回,主机侧一直卡在“设备不可控”。

实现上建议把消息分发做成两级判断:

def dispatch(primary_msg): # 第一级:通讯层是否已建立 if comm_state != CommState.COMMUNICATING: if primary_msg.function in (13, 17): return handle_comm_control(primary_msg) return None # 未通讯,直接丢弃,不回 # 第二级:控制状态 if control_state == "OFFLINE": if primary_msg.function in (13, 17): return handle_control(primary_msg) return build_sxf0(primary_msg) # 其余一律 SxF0 return handle_online(primary_msg)

这里有个容易忽略的细节:S1F17 的应答是 S1F18,里面的 ONLACK 取值有约定,0 表示接受,1 表示拒绝(设备未就绪),2 表示已在 ONLINE。主机侧拿到 1 不要立刻重试,先看设备是不是还在初始化,否则会陷入“请求—拒绝—再请求”的循环。文档在 7.10 节的 Control 场景里给了 ON-LINE/OFF-LINE 的完整时序,建议对着时序图把每个分支的应答码抄进代码注释,后面排查时省一半时间。

2.3 设备处理状态与 GEM 适应性清单的用法

文档 1.4 节的 GEM Adaptability 表是一份“能力勾选清单”,把 Fundamental GEM Requirements 和 Additional Capabilities 逐项标了 Yes/No。注意里面 Material Movement 和 Spooling 两项是 No,这意味着这份实现不支持物料搬运管理和消息溢出缓冲。对接前先看这张表,能避免大量无效联调:比如主机侧如果依赖 Spooling 做断线补报,而设备端明确不支持,那断线期间的事件就是丢了,得在主机侧做补偿逻辑。

设备处理状态(Equipment Processing States)在文档目录里出现了但正文页码标注异常,实际实现时按 GEM 标准常见做法是维护 INIT、IDLE、EXECUTING、PAUSE 等状态,并通过 S1F3/S1F4 或状态变量对外暴露。我一般会把处理状态和事件报告绑定:状态迁移时触发对应的 collection event,而不是让主机轮询,这样既省带宽又符合 GEM 的事件驱动模型。

3. 事件报告与数据采集:S2F33/S2F35 配置链路怎么搭

3.1 动态事件报告配置:REPORTID 与 VID 的绑定关系

GEM 的数据采集核心是“主机定义报告、设备按报告上报”。文档 3.4 节和 7.2 节给了动态事件报告配置的完整场景,涉及 S2F33(Define Report)、S2F35(Link Event Report)、S2F37(Enable/Disable Event Report)三条链路。理解它们的关系是落地前提:S2F33 定义“一个 REPORTID 包含哪些 VID”,S2F35 定义“哪个 CEID 触发哪个 REPORTID”,S2F37 控制事件报告开不开。

用 SML 表示一个典型配置大概是这样:

S2F33 W <L [2] <L [1] # 定义 1 个报告 <L [2] <U4 1001> # REPORTID <L [3] # 该报告包含的 VID 列表 <U4 2001> # 温度 <U4 2002> # 压力 <U4 2003> # 设备状态 > > > <L [0]> # 空列表表示不删除已有报告 > S2F35 W <L [2] <L [1] # 链接 1 个事件 <L [2] <U4 5001> # CEID,例如“工艺开始” <L [1] <U4 1001> # 绑定 REPORTID 1001 > > > <L [0]> >

逻辑说明:S2F33 的第二个列表是“要删除的报告列表”,传空表示纯新增;如果主机要重配,常见做法是先发删除再发定义,或者用 S2F33 的删除语义覆盖。参数上,REPORTID 和 CEID 的数值范围由设备端 Data Item Dictionary 约定,文档 6.2.1 节的 Data Item Dictionary 就是查这些 ID 的地方,别自己拍脑袋编号。S2F35 的应答是 S2F36,里面 DRACK/LRACK 为 0 才算成功,非 0 要对照文档里的错误码表定位。

3.2 变量、跟踪、状态三类数据采集的边界

文档把数据采集拆成三块:Variable Data Collection(3.5)、Trace Data Collection(3.6)、Status Data Collection(3.7)。很多对接争议就出在“这个数据该走哪条路”上。我的经验边界是:需要和事件绑定的瞬时值走 Variable Data Collection,通过 S6F11 随事件上报;需要按固定周期连续采样的走 Trace Data Collection,用 S2F23 设采样周期和总数,设备用 S6F1 回传;设备整体运行状态走 Status Data Collection,主机用 S1F3 主动查询。

Trace 采集的参数最容易设错:

S2F23 W <L [5] <U4 1> # TRID,跟踪报告 ID <A "000500"> # DSPER,采样周期,格式 HHMMSS,这里 5 秒 <U4 0> # TOTSMP,总采样数,0 表示无限 <U4 1> # REPGSZ,每个 S6F1 包含的采样组数 <L [2] # 要跟踪的 VID <U4 2001> <U4 2002> > >

DSPER是字符串格式的时分秒,不是秒数,写成"5"或5都会被设备端解析失败;TOTSMP=0表示一直采到主机发 S2F25 停止,如果主机忘了停,设备端缓冲区会一直涨,这是现场常见的资源泄漏点。文档 7.3.4 节的 Host Initiates Trace Report 场景给了停止时序,建议在主机侧加一个“跟踪会话超时自动停”的兜底。

3.3 报警管理与远程命令的消息对

报警管理(3.8)和远程控制(3.9)是主机干预设备的两条手。报警侧,设备用 S5F1 上报报警,主机用 S5F3 做 enable/disable,用 S5F5 查询报警列表;远程控制侧,主机用 S2F41 下发命令,设备用 S2F42 回 ACK,里面 HCACK 取值要严格按文档 6.2.1 的字典来,0 表示命令已执行,1 表示命令存在但参数无效,2 表示命令不存在,3 表示命令不能现在执行。

S2F41 W <L [2] <A "START"> # RCMD,远程命令名 <L [2] # 参数列表 <L [2] <A "LOTID"> <A "LOT2024001"> > <L [2] <A "RECIPE"> <A "RCP_A"> > > >

参数说明:RCMD 的取值必须在设备端“已实现主机命令”清单里,文档 5.6 节 Implemented host commands 就是查这个的;参数名和类型同样受 Data Item Dictionary 约束。HCACK=1 时 S2F42 还会带一个错误参数列表,主机侧要把它解析出来打到日志,否则现场只看到“命令失败”四个字,排查全靠猜。

4. 避坑与排查:联调现场最常见的五个翻车点

4.1 现象:S1F13 发出后一直等不到 S1F14

原因通常有两个:一是 TCP 层没通,HSMS 的 select 流程没走完就发了 SECS-II 消息;二是设备端处于 DISABLED 状态,SECS-II 通信被禁止。解决:先用抓包确认 TCP 连接和 HSMS select 请求/响应是否完成,再看设备端通讯状态标志。文档 2.1 节明确 DISABLED 下“所有 SECS II 通信立即停止”,所以操作员切了 DISABLED 之后,主机侧发什么都没用,别在应用层死磕。

4.2 现象:事件报告配置返回 ACK 非 0,但不知道错在哪

原因多是 REPORTID 或 VID 不在设备端已实现清单里,或者 S2F33 的删除列表和定义列表语义用反了。解决:对照文档 5.1 节 Implemented collection events 和 5.2 节 Implemented data variables 逐项核对 ID;S2F33 第二个列表非空时是“删除这些报告”,不是“保留这些报告”,这个语义反了会导致配置被清空。建议把每次 S2F33/S2F35 的请求和应答原文落盘,出问题直接比对。

4.3 现象:S6F11 上报的数据项数量和主机预期对不上

原因是 REPORTID 绑定的 VID 列表在设备端被重配过,或者主机侧缓存的报告定义过期。解决:主机在建立通讯后先发 S2F33 重新定义,不要假设设备端保留上次配置;如果设备支持 S2F33 的“查询”语义(部分实现支持空定义查询),先查再配。文档 7.2 节的动态配置场景里,配置和上报是分开的两段时序,别把配置应答当成数据上报。

4.4 现象:OFF-LINE 下主机发 S1F17 被回 S1F0

原因是消息分发逻辑把 S1F17 也归到了“非 S1F13 一律 SxF0”的分支。文档 2.2 节写得很清楚,OFF-LINE 下 S1F13 和 S1F17 都要正常处理。解决:按 2.2 节的分发伪代码改判断条件,把 13 和 17 单独放行;改完用 S1F17 单独测一遍,确认 ONLACK 返回符合预期。

4.5 现象:Trace 采集跑一段时间后设备端内存上涨

原因是 TOTSMP 设了 0(无限采样)但主机侧没有发 S2F25 停止,或者 REPGSZ 设得过大导致单条 S6F1 消息超长被分片。解决:主机侧给每个 TRID 维护会话超时,到期自动发 S2F25;REPGSZ 按设备端消息长度上限反推,一般单条 SECS-II 消息控制在几 KB 以内。文档 3.6 节和 7.3.4 节合起来看,能理清启动和停止的对称关系。

5. 用 SML 字典反查报文:把规格书变成可执行的对照表

文档第 6 章是整份规格书里最“工具化”的部分:6.1 节列了 SECS-II 消息子集,6.2 节讲 SML 语言,6.2.1 节是 Data Item Dictionary,6.2.2 节是 Data Format。我的用法是把 Data Item Dictionary 导成一张对照表,联调时按“消息号 → 结构 → 数据项 ID → 类型 → 含义”五列查,比翻 PDF 快得多。

消息方向关键结构常见数据项用途
S1F13/F14双向COMMACK无建立通讯
S1F17/F18主机→设备ONLACK无请求上线
S2F33/F34主机→设备REPORTID、VID 列表DRACK定义报告
S2F35/F36主机→设备CEID、REPORTIDLRACK链接事件报告
S2F37/F38主机→设备CEID 列表、CEEDERACK启停事件报告
S2F41/F42主机→设备RCMD、参数HCACK远程命令
S5F1/F2设备→主机ALCD、ALID无报警上报
S6F11/F12设备→主机CEID、报告列表无事件数据上报

这张表不是让你背,而是让你在写解析代码时有个锚点。比如收到 S6F11,先取 CEID,再按 S2F35 建立的映射找 REPORTID,再按 S2F33 的定义拆 VID 列表,三层解引用下来数据才对得上。SML 语言那节(6.2)值得单独看,它定义了<L>、<A>、<U4>、<BOOLEAN>这些标记的写法,抓包工具和日志里看到的报文基本都是 SML 形式,能直接读 SML 就等于能读现场日志。

一个实操技巧:把文档 7 章的场景时序逐条转成测试用例。比如 7.1.1 的 Host Attempts to Establish Communications,就写一个“主机先发 S1F13、设备回 S1F14”的用例;7.4.1 的 Enable/Disable Alarms,就写“S5F3 使能后 S5F1 才上报”的用例。每条用例跑通打勾,跑不通就回 6.2.1 查数据项定义。这套方法我从一个模拟项目里沿用下来,联调周期从“靠猜”变成“按表推进”。从那以后我每次拿到新的设备规格书,第一件事就是把 Data Item Dictionary 和场景时序抽成对照表和用例清单,再动手写一行代码。希望帮到你。

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