news 2026/9/1 13:39:53

SECS/GEM开源方案选型与实战:从协议栈到设备联调

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SECS/GEM开源方案选型与实战:从协议栈到设备联调

简介:SECS 是半导体制造中设备与工厂系统之间通信的标准协议,定义了设备控制器与工艺设备间的数据交换格式和通信机制,是半导体自动化产线中常用的接口标准。这套开源实现整合了 Tcl 与 C 混合编写的核心库,适合自动化工程师、嵌入式开发者和半导体设备集成人员快速理解 SECS/HSMS 消息交互。压缩包共 11 个文件,以 Tcl 脚本、Tcl 模块、C 源文件、测试用例以及说明文档为主,整体仅 39KB,体量精简易读,适合直接阅读源码和二次修改。包内示例脚本演示了从消息构造到收发的基本流程,底层 C 文件揭示了接口驱动逻辑,多个测试文件可辅助验证协议实现的正确性,便于在开发过程中做回归检查。目前已有 1483 人在 CSDN 学习与查看该资源,适合作为 SECS 协议入门、工业通信调试和产线设备集成的轻量参考,能帮助团队节省从零实现协议的时间。 搞半导体设备自动化这些年,我几乎每天都在跟SECS/GEM打交道。供应商设备要接入MES,通讯协议绕不开它;但市面上成熟的SECS/GEM商业组件授权费不便宜,想快速验证又不想被厂商绑定,开源实现就成了很现实的一条路。你抛出的"secs-开源"这个标题,我理解为:在找能落地的SECS/GEM开源方案,包括协议栈选型、消息解析、设备端与主机端联调,以及怎么避开那些文档里不写、但实际会踩的坑。这篇文章就围绕这些展开,面向设备端软件工程师、CIM/MES开发者和做工厂自动化的集成商,照着做能少走不少弯路。

1. 项目概述:为什么要在半导体自动化里谈SECS开源

1.1 SECS/GEM到底在解决什么问题

SECS是SEMI Equipment Communications Standard的缩写,GEM是Generic Equipment Model。它们是半导体制造领域设备与主机系统(Host)之间通信的事实标准。简单说,就是设备端软件通过一套约定好的“语言”告诉MES:我当前是什么状态、发生了什么事件、完成了一片产品的加工;MES也可以通过这套“语言”下发配方、远程指令,查询设备实时的运行参数。

这套标准被SEMI组织定义成系列标准,比如SEMI E4(SECS-I)、E5(SECS-II)、E37(HSMS)、E30(GEM)。实际项目中,你一听到“SECS/GEM”,指的是整个协议族,而不是某一个单独的文件。

从技术形态上看,SECS/GEM替代的其实是过去每个设备厂商各自为政的私有通讯协议。没有它之前,MES要对接十种设备,就要写十套驱动;有它之后,大家都遵守同一套消息格式和行为模型,对接效率明显提高。这也是为什么半导体行业对SECS/GEM的依赖非常深,晶圆厂里的刻蚀、薄膜、光刻、清洗设备,甚至封测厂的贴片机、测试机,基本都要求支持GEM。

1.2 开源实现解决了什么核心问题

商业化的SECS/GEM开发包,比如Cimetrix的SAPPHIRE,或者国外厂商的SDK,功能很全,文档也规范,但价格通常不低,而且版本授权、技术绑定都是问题。你只是想验证设备样机的通讯逻辑,或者做一个内部工具连一下模拟器,投入那么多成本并不划算。

开源实现的核心价值在于三点。

第一,零授权成本,方便快速验证。你本地起一个设备模拟器,再起一个主机模拟器,用开源库几分钟就能把一条S1F2报文发出来,不用等厂商审批License。

第二,源码可读,便于深度定制。半导体设备的通讯逻辑很多时候要和设备内部状态机联动,比如设备处于“正在加工”状态时不允许接收配方切换指令。商业库的黑盒封装反而不方便,开源库你可以直接改消息处理逻辑,甚至加私有Stream/Function。

第三,社区演进速度并不慢。这个领域看似小众,但这几年半导体设备国产化进程加快,国内做设备自动化的工程师越来越多,不少开源项目在持续迭代,像基于.NET的SecsGem、Python的secsgem、Java的secs4java,都有活跃的提交记录。

我的建议是,不要把开源方案当成一个“玩具”,很多量产设备实际就在用这些库跑通讯。关键是你要理解协议本身的语义,而不能只停留在“把报文发出去”的层面。这也是这篇文章后面要重点展开的部分。

2. 协议栈拆解:看不懂SECS/GEM文档也能抓住主干

2.1 先分清SECS-I、HSMS、SECS-II和GEM

我第一次接触SECS/GEM时,翻SEMI标准文档翻得头大,因为涉及的标准太多了。其实你可以把它们按OSI模型来归类理解,这样就清晰很多。

协议对应层级作用实际场景
SECS-I物理层/链路层基于RS-232串口通讯老设备、低速传输场景
HSMS传输层基于TCP/IP的有连接通讯现代设备几乎都用
SECS-II消息层定义消息格式(Stream/Function、Item格式)所有报文解析
GEM行为模型定义设备状态机、报警、配方、远程命令等设备与MES联动的规则

现在新建的设备,基本不会再用SECS-I走串口,绝大多数场景都在用HSMS。HSMS又分HSMS-SS和HSMS-GS,SS是单会话,通常一个IP端口对应一个设备;GS是多会话,用于多个设备共享连接。设备端实现以SS为主。

SECS-II是消息层的编码规则。一条SECS消息体包含一个Stream和Function编号,比如S1F1就是“Are You There”,S6F11是“Event Report Send”。消息体内是各种Item,Item可以是List、Binary、ASCII、U4、I4等格式。实际调试时,你会看到类似下面这样的报文结构:

S1F1 W . S1F1 是Stream 1 Function 1,含义是查询存在; W表示需要对方回复。

2.2 Stream/Function消息模型,一小时上手

对初学者来说,不需要一开始把上百种消息全背下来,但几个核心的Stream/Function必须掌握,因为日常调试几乎天天用。

S1F1/S1F2,握手和状态查询,设备端上线后第一件事就是响应这条消息。S1F13/S1F14,Establish Communications Request / Acknowledge,一般用于连接建立后的握手确认,主机发S1F13,设备回S1F14。S1F3/S1F4,查询设备状态,S1F3请求设备属性,S1F4回复属性列表。S6F11/S6F12,事件上报,设备主动告诉主机“发生了什么”,比如加工完成、报警发生,这是联调中最常用的一类消息。S2F17/S2F18,时间请求,设备向主机请求当前时间和日期。S7F1/S7F2,配方管理,主机下发配方名或配方体,设备执行。

实际调试中,你可以用一个支持SML格式的编辑器(比如SML中定义的文本格式)来读写报文,这样比直接看十六进制字节流直观很多。不过也要提醒一句,SML格式只是给人看的,真正在网络上传输的是SECS-II编码后的二进制字节,调试工具软件会自动完成字节流和SML文本之间的转换。

2.3 GEM行为模型:设备端和主机端的分工

GEM标准(SEMI E30)定义了一套设备行为模型,核心是“状态机 + 事件报告 + 控制指令”。设备状态主要分为OFFLINE、EQUIPMENT_OFFLINE、ONLINE_LOCAL、ONLINE_REMOTE等。ONLINE_REMOTE代表主机可以远程控制设备,ONLINE_LOCAL意味着设备旁路操作但主机可以监控,OFFLINE就是完全不跟主机交互。

设备端要做的事,是维护这套状态机,在状态切换时上报事件;主机端要做的事,是根据设备的模型定义下发指令、订阅事件、收集数据。GEM还定义了一些标准状态模型,比如Processing、Ready、Idle等。你在设备端实现时,最好先把状态机模型画出来,再映射到GEM的规定里,否则后面联动调试时会出现“设备已经报了完成事件,但主机端状态还停留在待机”的尴尬情况。

这里有一个常见误解:很多工程师以为只要把HSMS连上,SECS/GEM就算通了。其实不然,HSMS连接的建立只是最底层的第一步,GEM状态机和事件上报规范才是真正决定通讯质量的部分。连接明明能通,但主机认为设备不在线,这种问题大多出在GEM状态机没有正确维护。

3. 核心功能实现:搭建一个可运行的最小SECS/GEM系统

3.1 如何选型:Python还是Java还是C#

开源SECS/GEM实现,语言生态差别挺大。我梳理几个我实际用过或者看过源码的项目,供你做技术选型参考。

Python阵营,最常用的是secsgem。这个库实现了SECS-I、HSMS、SECS-II和GEM模型,API相对简洁,适合快速搭建模拟器、测试脚本。它的主要定位是“快速验证协议”,设备端和主机端都支持,文档也比较全。

Java阵营,secs4java是经典选项,实现了HSMS、SECS-II、GEM的核心功能,性能稳定,被不少设备厂拿来做量产设备端的通讯模块。如果你的设备端软件本身是Java开发的,选它没有明显的短板。另外还有hsms4j,也提供了基础的HSMS连接能力,接口设计更现代化。

.NET/C#阵营,SecsGem比较活跃,在GitHub上可以找到,使用Sematech标准库结构,封装了SECS-II消息解析、HSMS连接和部分GEM行为。很多Windows上位机项目在用它。

选型经验:优先考虑你设备端主程序的开发语言,不要为了“这个库看着更好”而引入异构语言。如果一个Java后端团队选Python库做设备端通讯,后面维护成本会很高。另外,关注项目的License类型,MIT和Apache-2.0比较宽松,LGPL需要留意衍生作品的合规要求。还有一个容易被忽略的指标是最近一年的提交记录,一个半年没更新的项目,说明要么很稳定,要么已停止维护,需要你结合Issue区判断。

3.2 用secsgem快速搭建一个本地设备模拟器

这里我以Python的secsgem库为例,带你从零拉起一个设备端和主机端,跑通一条S1F13/S1F14握手。

第一步,安装依赖:

pip install secsgem

第二步,写设备端代码。secsgem的设备端类叫SecsGemEquipment,你只需要指定一个设备地址和端口,然后启动即可。

from secsgem.gem import GemEquipmentHandler from secsgem.hsms import HsmsSettings, HsmsConnectionMode from secsgem.hsms import HsmsProtocol settings = HsmsSettings( device_id=0, address="127.0.0.1", port=5000, connect_mode=HsmsConnectionMode.PASSIVE, # 设备端通常是被动连接 name="eq_simulator" ) handler = GemEquipmentHandler(settings) handler.enable()

注意设备端一般是被动模式(PASSIVE),也就是监听端口,等主机来连接。

第三步,写主机端代码。主机端用主动模式(ACTIVE)去连接设备。

from secsgem.gem import GemHostHandler from secsgem.hsms import HsmsSettings, HsmsConnectionMode settings = HsmsSettings( device_id=0, address="127.0.0.1", port=5000, connect_mode=HsmsConnectionMode.ACTIVE, # 主机端主动连接 name="host_simulator" ) handler = GemHostHandler(settings) handler.enable()

运行设备端脚本后,再运行主机端脚本。正常情况下,主机端会主动发起TCP连接,连接建立后发送S1F13,设备端返回S1F14。如果你看到两端控制台的日志中都出现了S1F13 WS1F14的回包,就说明SECS/GEM通讯链路已经打通。

3.3 自己实现消息解析时必看的数据结构细节

如果你不是直接用现成库,而是要在老系统里自研一台设备的SECS/GEM模块,那最核心的其实是SECS-II消息的字节级解析。我给你整理几个容易出错的细节。

消息头项(Header)共10个字节:第1字节是MessageLength高字节,第2字节是MessageLength低字节;后面依次是DeviceID/Stream、Function、ReplyExpected,以及两字节的SessionID。其中ReplyExpected位表示是否需要回复,置1表示对方收到后要回一条消息。SECS-II的Item编码是TLV结构:Tag(类型标识)、Length(长度)、Value(数据)。不同的数据类型有不同的TypeCode,比如List是0x01,Binary是0x10,ASCII是0x20。

实际报文解析时最容易踩的坑是字节序。SECS-II规定整型数据是多字节且高字节在前(Big-Endian),但很多设备工程师平时写C代码用x86,默认是Little-Endian,直接转换就出错。比如U4类型数值60000,在网络上是0x0000EA60,如果按小端方式读,就变成了0x60EA0000,结果完全不对。

另外还要注意,消息头的长度字段是对“Header之后的完整数据体”的字节计数,计算时不要把Header本身算进去。这个看似简单,在自研时经常搞错。

4. 实操过程与核心环节实现

4.1 设备端实现GEM状态机迁移

光有通讯框架还不够,设备端必须把GEM状态机“跑起来”。我以secsgem为例,看看状态迁移是怎么实现的。secsgem内部定义了状态机的枚举,比如EquipmentStates这类。设备刚启动时处于OFFLINE状态;当设备端脚本检测到HSMS连接建立后,可调用状态切换接口,让它进入ONLINE_REMOTE

# 设备端代码片段 from secsgem.common import EquipmentState handler.equipment_state = EquipmentState.ONLINE_REMOTE

状态迁移的同时,要上报事件。GEM标准里,模型文件定义了设备支持哪些事件、事件对应哪些数据变量。比如“加工完成”这个事件,数据变量可能包括产品的Recipe ID、Process Time等。secsgem里可以通过模型定义或者API直接上报事件。

from secsgem.gem import EquipmentEvent event = EquipmentEvent("PROCESS_COMPLETE") event.data = {"RECIPE_ID": "RT001", "PROCESS_TIME": 123.45} handler.send_event(event)

这段代码在真实设备上对应的动作是:设备加工完一片晶圆后,主动向MES发送S6F11,MES收到后回复S6F12确认。我在最初调试时经常犯一个错误:事件还没上报,就把设备状态切到Online,结果MES端认为设备“在线但无事件”,数据完全对不上。GEM规范里明确要求,状态切换和事件上报需要按顺序来。

4.2 主机端订阅事件与远程命令下发

主机端要做的第一件事是向设备订阅事件。GEM中通过S2F33(Define Report)/S2F35(Link Event Report)等消息来配置数据收集。secsgem里提供了一些高层接口,简化了订阅过程。

简单场景下,主机端可以周期性调用S1F3查询设备状态,也可以实现事件响应回调。下面是一个简单的事件回调示例:

def on_event(event): if event.name == "PROCESS_COMPLETE": print(f"设备上报加工完成,配方: {event.data['RECIPE_ID']}") handler.events = [on_event] handler.enable()

远程命令通过S2F41/S2F42实现。主机下发S2F41(Host Command Send),命令名比如STARTSTOPPAUSE,设备端执行后回S2F42(Host Command Acknowledge)。命令参数按GEM模型定义,通常包含一个CommandName和参数列表。设备端需要维护命令的执行结果状态,分为AcceptedRejectedNot Ready等。

4.3 联调时如何判断消息链路是否正常

联调阶段,我习惯先在设备端和主机端分别打印出完整的消息日志,然后用Wireshark或者tcpdump抓包做交叉比对。这里有几个判断流量的技巧:

第一,检查TCP连接是否正常建立。HSMS是长连接,正常情况下连接不会频繁断开。如果日志里出现反复断开重连,优先检查心跳超时设置。

第二,检查S1F13/S1F14是否成功交换。这是GEM会话的握手层,连接建立后必须先完成这个动作,后续消息才有意义。

第三,检查S6F11的ReplyExpected位是否设置正确。如果设备发送S6F11时没有要求回复,主机端就不会回S6F12,这在调试日志里看起来像“主机没有反应”,但实际上是正常的。

第四,检查消息长度字段与实际字节数是否一致。这个在自研解析时经常出错,如果长度字段多算或少算一个字节,接收端的消息解析就会直接乱掉。

5. 常见问题与排查技巧实录

5.1 HSMS连接不稳定,总是建立后断开

HSMS的TCP连接建立后,设备端和主机端要维持心跳。GEM标准定义了多个计时器,比如T3(Reply timeout)、T5(Connect separation timeout)、T6(Control transaction timeout)等。连接不稳定的常见原因是T3和T6设置太短,消息处理稍微慢一点就被判定超时中断。

一个常见的配置经验:T3设置为45秒,T6设置为5秒,T5设置为10秒。如果你的设备业务逻辑里存在耗时超过5秒的操作(比如收到远程命令后执行了一次较长的校准流程),那么要考虑把T6调大,否则命令执行中就会出问题。

另外,HSMS消息帧有4个字节的消息头长度字段,帧类型分为数据消息和信令消息,某些实现把心跳控制消息当成了数据消息,导致对端解析出错。出现这种情况时,可以先检查对端库是否支持HSMS的控制消息(Separate、Select、Deselect等),很多超轻量实现并不完整支持这些控制消息。

5.2 数据值对不上:字节序和数据类型设错

联调时最经典的一幕:设备上报温度值,MES端解析出来是个天文数字。原因通常就是字节序不一致,或者SECS-II的Item类型定义错了。比如设备把温度当作I4(有符号32位整型)上报,主机端按U4(无符号32位整型)解析,负温度就会变成正的大数。

排查方法:先在设备端打印出Item的TypeCode和原始字节,确认真实编码;再在主机端解析逻辑里检查类型定义。如果两端都用的标准SECS-II库,一般不会出现这种问题;问题常出在“手工解析”的桩代码上。建议任何手工解析从第一步就打印十六进制字节流,不要直接看数值。

另一个容易出错的是ASCII字符串的长度。SECS-II的ASCII Item长度是实际的字符数,不包括结尾空字符。如果从C语言字符串拷贝数据时多带了一个\0,报文长度就会多出一个字节,对端解析就会出问题。

5.3 事件一直没上报,主机端收不到S6F11

事件上报是GEM最核心的功能之一,也是问题最多的环节。收不到S6F11,我总结了四个排查方向。

先检查事件报告配置。GEM有个概念叫“Report”,设备必须先被配置好“什么事件要上报、上报哪些变量”,才能发S6F11。如果设备上电后没有做S2F33/S2F35的配置流程,那很可能连事件都不会触发。再检查设备状态。很多设备只在ONLINE_REMOTE状态下才允许上报事件,OFFLINE状态下事件会被丢弃,或者放在本地队列里不发送。还要检查事件发生时机。有些设备的事件在加工完成后由某个业务线程触发,如果业务线程异常,事件逻辑根本走不到,这时就需要写一条手动触发事件的调试代码来排除业务层的问题。最后检查主机端是否回S6F12。如果设备发了S6F11但主机没回确认,SECS/GEM底层库会在超时后重发,次数超过限制后会直接断连。这时重点排查主机端的消息处理线程是否阻塞。

5.4 自研SECS-II解析的几个建议

如果决定自研协议解析,我给你三个建议。第一,统一封装一个“字节流到Item列表”的解析层,任何Stream/Function的处理都经过这一层,不要在业务代码里直接操作字节,否则一旦字节序出错,所有处理逻辑都要跟着改。第二,对未知类型Item做容错处理,某些设备厂商会在标准里加入扩展Item类型,解析器遇到未知类型时不要直接throw异常,而是打日志跳过,保证其他消息还能正常处理。第三,写一套基于已知报文样本的单元测试,每个消息都配上十六进制样例和SML对照,这样后续代码升级的时候,回归测试能帮你快速发现问题。

根据我个人的经验,早期用开源库做SECS/GEM验证时,最容易出现的问题不是库本身,而是开发者对协议语义理解不够。你让设备发一条S6F11,它确实发了,但事件数据里缺少关键变量,主机端的业务逻辑拿到后只能干瞪眼。建议任何一个设备项目在开发初期就把“事件报告的数据变量清单”和设备业务逻辑放在一起评审,而不是把这个工作丢给联调阶段。

还有一个小技巧,几乎所有SECS/GEM调试工具都支持记录和回放报文。联调时养成“先记录原始报文,再对照曲线分析”的习惯。我在处理现场问题时,经常靠一段完整报文回放就复现问题了,比反复让现场工程师重试高效得多。遇到难缠的问题,也可以把报文发到社区讨论,附上版本信息和复现步骤,这样得到有效回复的可能性会大很多。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 13:34:24

ViT微调实战:pytorch-image-models中让准确率起飞的4组超参

ViT微调实战:pytorch-image-models中让准确率起飞的4组超参 【免费下载链接】pytorch-image-models The largest collection of PyTorch image encoders / backbones. Including train, eval, inference, export scripts, and pretrained weights -- ResNet, ResNeX…

作者头像 李华
网站建设 2026/9/1 13:34:13

图像渲染GPU租用选型指南:从显存到云平台实操

很多做图像渲染、三维动画、视频后期或者 AI 绘画的朋友,都问过我同一个问题:我自己电脑显卡不够用,想租一台 GPU 服务器来渲染,市面上这么多云平台和租用品牌,到底该怎么选?是看价格,还是看型号…

作者头像 李华
网站建设 2026/9/1 13:33:44

AI视频创作工具漫剧工坊:从文生图到动态漫画的完整工作流解析

这次我们来看一个名为“漫剧工坊”的AI视频创作工具,它刚刚在B站AI创造公开赛中正式上线并开放免费试用。这个项目的核心目标很直接:让用户能够利用AI技术,快速、低成本地生成带有漫画风格的动态视频,也就是所谓的“漫剧”。对于内…

作者头像 李华
网站建设 2026/9/1 13:33:17

Mysql知识梳理(数据库的锁梳理,Mysql优化)

Mysql知识梳理Mysql构成存储引擎Mysql隐藏知识mysql中的日志Redo LogRedo Log 的特性:Redo Log 与 Binlog 的区别:undo 的工作Undo Log 的工作原理:Undo Log 的特性:Undo Log 的作用:Undo Log 与 Redo Log 的区别&…

作者头像 李华