GEM300协议在半导体设备自动化里几乎是绕不过去的一道门槛。只要你的设备想进晶圆厂、想跟Fab的MES(制造执行系统)对接,甲方十有八九会在技术协议里写上"支持GEM300";但真把SEMI标准文档摊开,E30、E37、E5、E4、E84、E87……一整叠规范摆在面前,很多工程师第一反应是懵的。我做过几年的半导体设备软件,跟刻蚀、薄膜、光刻、量测各类设备厂商和MES都联调过,想借这篇文章把GEM300从"是什么"到"怎么调通"完整讲一遍,重点放在标准族关系、消息机制和实战排障上,给准备入行或正在对接的朋友一份接地气的参考资料。
1. GEM300到底是谁:它是一叠SEMI标准,不是一个协议
1.1 先理清标准族谱里的编号
很多人第一次接触GEM300,会以为它是一个像Modbus那样的单一协议。实际上,GEM300是半导体设备通信相关的一整套SEMI标准的统称,日常项目里至少涉及以下几个:
| 标准编号 | 名称 | 管什么 |
|---|---|---|
| SEMI E4 | SECS-I | 串口传输层,RS-232上的数据收发规则 |
| SEMI E5 | SECS-II | 消息格式和内容,定义了Stream/Function和数据项类型 |
| SEMI E30 | GEM | 通用设备模型,规定了设备必须具备的通信行为 |
| SEMI E37 | HSMS | 高速消息服务,基于TCP/IP的传输层协议 |
| SEMI E39 | Object Services | 对象服务,设备数据的面向对象访问方式 |
| SEMI E40 | Process Job Management | 工艺任务(Process Job)的生命周期管理 |
| SEMI E84 | Enhanced Carrier Handoff Parallel I/O | 载具自动交接的并行IO信号与握手时序 |
| SEMI E87 | Carrier Management | 载具(Carrier)状态、ID、位置的跟踪管理 |
| SEMI E90 | Substrate Tracking | 晶圆片级(每片wafer)的追踪 |
| SEMI E94 | Control Job Management | 控制任务管理,把Carrier、Recipe、Process Job绑定在一起调度 |
这里有个很关键的认知: GEM300并不是取代了GEM,而是在GEM的基础上做加法 。核心通信模型仍然是E5(消息)+ E30(行为)+ E37(传输)这三件套,300mm时代新增的E87、E90、E94等,本质上是扩展了SECS-II里定义的消息集合和状态流转方式。所以你跟别人聊GEM300项目,第一时间要确认他说的"GEM300"是指全部标准,还是只是某个设备能力的子集,这直接决定工作量评估。
1.2 为什么是"300":从200mm到300mm的自动化跃迁
200mm(8英寸)产线时代,很多设备是单机运行,靠操作员手工搬运晶圆盒、手工装载Recipe,SECS-I串口加基础GEM功能就够用了。到了300mm(12英寸)产线,自动化程度完全不是一个量级:天车(OHT)自动搬运晶圆盒,设备要自动完成载具交接、自动读取载具ID、自动匹配Recipe,还要让MES实时知道每一片wafer在设备里的位置和状态。
这就倒逼出了一批新标准:E84用并行IO信号跟物料搬运系统做物理交接握手,E87负责管Carrier(晶圆盒)的完整生命周期,E90把追踪粒度从批次细化到单片wafer,E94在高层把"哪批货、用哪个Recipe、在哪个腔体加工"组织成一个可控制的任务单元。可以说,GEM300是300mm大规模自动化倒逼出来的产物,它的核心价值就四个字: 设备联网 ,而且不是简单的网络通,是让设备的所有工艺行为和物料行为都透明化、可控制、可追溯。
1.3 设备厂商、Fab Host、MES,三方眼中的GEM300不一样
同一套GEM300,在不同角色手里,侧重点差别很大。
设备软件工程师关心的是:设备端怎么实现HSMS连接、怎么处理S1F13建立通信、怎么在状态模型里切换、怎么把报警和事件准确上报。Fab的Host(通常指Cell Controller或MES的Equipment Integration层)工程师关心的是:怎么通过S2F33/S2F35动态配置数据采集、怎么下发Remote Command、怎么处理S6F11事件流。而设备现场服务工程师最关心的往往是:协议通了没有、报警有没有重复上报、联调的时候Host为什么收不到数据。
这三个视角几乎是三个专业方向,但都构建在同一套标准之上。这篇文章主要站在设备端和Host端联调的中间视角写,因为大多数踩坑都发生在两边对接的交界处。
2. 协议栈分层解剖:消息是怎么从设备端口跑到Host的
2.1 传输层:HSMS(E37)与SECS-I(E4)的选择题
传输层解决的是字节怎么在两个节点之间可靠流动。SEMI标准里给了两条路,一条是串口,一条是TCP/IP。
| 对比项 | HSMS(E37) | SECS-I(E4) |
|---|---|---|
| 物理介质 | 以太网TCP/IP | RS-232串口 |
| 典型速率 | 10/100/1000Mbps | 9600bps |
| 连接方式 | 一主一备双TCP连接 | 点对点串口 |
| 典型应用 | 300mm及现代化设备 | 200mm老旧设备 |
现在新项目基本无脑选HSMS。但这里有个容易忽略的细节,HSMS不只是"用TCP传输SECS消息"这么简单,它有自己的一套连接管理状态机和控制消息。HSMS定义了Select、Deselect、Linktest、Separate等控制消息,分别用来建立会话、维持链路、检测链路、断开连接。其中Linktest是实际联调里最能暴露问题的东西——如果心跳机制配得不对,会出现两边TCP连接还活着、但逻辑上已经"失联"的情况。
HSMS默认端口是5000,一个设备可以同时维护主备两条TCP连接,平时用主连接,主连接故障时自动切到备连接。会话建立后通过Session ID(也就是Device ID)来区分连接,多个Host连同一个设备时,靠这个ID隔离消息。
2.2 报文层:SECS-II(E5)的数据类型与消息格式
传输层之上是SECS-II,它规定了一条消息长什么样。一条SECS-II消息分两部分: 10字节的消息头 和 消息体 。消息头里最关键的是Stream、Function和W位,这个组合决定了消息的"语义";消息体则由一棵Item树组成,每个Item都有类型和长度。
SECS-II的数据类型不多,但很容易搞混:
- List(L) :容器,里面可以嵌套任意其他Item
- ASCII(A) :字符串,按字节算长度
- Binary(B) :二进制字节块
- Boolean(BOOL) :单字节,0x00为False,0x01为True
- U1/U2/U4/U8 :1/2/4/8字节无符号整数
- I1/I2/I4/I8 :1/2/4/8字节有符号整数
- F4/F8 :4/8字节浮点数
如果你要自己解析消息流,每个Item的格式字节很有讲究: 高2位表示后面长度域的字节数,低5位表示数据类型 。举个例子,0x40开头的Item通常是ASCII(1字节长度域),0x74开头的是U4(1字节长度域)。实际调试时,用十六进制看包,能不能一眼认出0x00开头的List和0x40开头的ASCII,能省很多时间。
为了让人方便阅读,行业内通常用SML(SEMI Message Language)描述消息内容。SML不是传输格式,只是给人看的文本表示法,很多解析库都支持SML导入导出。
2.3 行为层:GEM(E30)定义了设备必须具备的能力清单
如果说SECS-II定义了"怎么说",那GEM(E30)就定义了"说什么、什么时候说"。
E30的核心是一套设备能力模型,任何声称支持GEM的设备必须具备:
- 状态模型 :设备必须实现从关机上电、到连接Host、到在线运行的一套状态流转,在错误状态下的消息要能正确拒绝
- 三类变量 :状态变量(SV,只读,反映设备状态)、数据变量(DV,随事件上报)、设备常量(EC,可配置,比如超时参数)
- 收集事件(Collection Event) :设备内部某个条件满足时,主动向Host上报事件
- 报警管理 :设备异常时上报报警消息,恢复时上报清除消息
- 远程命令(Remote Command) :Host下发指令让设备执行动作,比如启动配方
- Recipe管理 :设备程序的查询、上传、下载、删除
这里想提醒一个认知:E30不是软件库,而是行为规范。设备厂商可以用任何语言实现,但对外表现必须符合E30的状态和消息要求。这也是为什么GEM300项目里,设备端最忌讳"自己发明一套消息流程"——标准里没定义的时序,Host端根本没法配合。
2.4 300mm扩展层:E84、E87、E90、E94各自管什么
扩展层是GEM300的精髓,也是跟传统GEM最大的区别。简单归纳:
- E84 :管的是设备与OHT(天车)/传送系统之间的 物理交接 。它其实不是TCP消息,而是并行IO信号加一套握手时序——设备把载具交给天车时,哪个信号先拉高、哪个信号后拉低、超时怎么处理,都有明确规定。调E84要有PLC和电气背景,跟调SECS消息完全是两码事。
- E87 :管 载具管理 。包括载具到位/离开检测、载具ID读取(RFID或条码)、载具状态的跟踪上报,以及Carrier ID与设备端口的绑定关系。Fab最关心的是"哪个载具在哪个端口、状态是什么",E87就是回答这个问题。
- E90 :管 晶圆片追踪 。把每一片wafer的在设备内的位置(如从Load Port进入、在某个腔体加工完成、返回FOUP)都记录下来。做缺陷追溯和质量分析时,E90数据是核心证据。
- E94 :管 控制任务 。把Carrier、Recipe、腔体资源和工艺条件组合成一个调度单元,MES下发了Control Job,设备按Control Job执行,再把执行结果上报。
这些扩展标准的消息都跑在SECS-II之上,增加了新的Stream/Function,但传输层、消息格式和GEM行为模型是完全复用的。所以技术方案上,只要把E5/E30/E37打牢,扩展层的实现更多是"按标准补消息"的体力活。
3. 消息事务与时序:把一次S6F11完整拆开看
3.1 Stream/Function、W位和消息结构
SECS-II消息的语义由Stream和Function两个数字共同决定。比如S1F1是"你在吗",S1F13是"建立通信请求",S2F41是"下发远程命令",S5F1是"报警上报",S6F11是"事件上报"。日常联调中,翻来覆去就那么十几个S/F,其他多数是扩展标准里新增的。
W位(Wait bit)非常关键。W=1表示这是一条Primary消息,接收方必须在超时时间内回复一条Secondary消息;W=0表示不需要回复,发完即止。比如设备主动上报事件用S6F11 W,Host收到后要回S6F12;如果设备发了S6F11不带W,Host就不用回。
一条HSMS消息在TCP上的完整结构是:4字节长度(包含10字节消息头+消息体总长)+ 10字节消息头 + 消息体。消息头里除了Stream和Function,还有两个容易看漏的字段—— Message ID 和 Session ID 。Message ID用于关联Primary和Secondary消息,一个事务里两者ID必须一致;Session ID用来做多会话隔离。
| 消息头字段 | 字节数 | 说明 |
|---|---|---|
| Message ID | 2 | 事务唯一标识,Primary/Secondary必须一致 |
| Session ID | 2 | 设备ID/会话标识,多Host时靠它区分 |
| Header Byte 2 | 1 | 含W位及系统字节 |
| Stream | 1 | 消息大类 |
| Function | 1 | 消息小类 |
| PType | 1 | 负载类型,0表示SECS-II数据消息 |
| SType | 1 | 0为数据消息,1~9为HSMS控制消息 |
3.2 事务模型与超时定时器
GEM300的通信模型是严格的一问一答(Primary→Secondary),不允许"随便发一条不用管回复"。这套事务模型依赖一组定时器,联调时90%的"假死"问题都跟超时配置有关。
| 定时器 | 常用默认值 | 触发场景 |
|---|---|---|
| T3 | 45秒 | 发出Primary后等待Secondary回复的最长时间 |
| T5 | 10秒 | 与Host断开连接后,重试建立连接的最小间隔 |
| T6 | 5秒 | 控制事务(Select/Linktest等)等待回复的超时 |
| T7 | 10秒 | TCP连接建立的超时时间 |
| Linktest | 10秒 | 心跳发送间隔,无消息流量时测活 |
T3超时是最常见的问题。设备发出S6F11后45秒没等到S6F12,按标准要怎么做?不是重发一遍就完了,而是要往异常方向处理:记录错误日志、可能触发S9F1等通信错误上报。很多现场问题排查困难,就是因为超时后的处理路径没按标准实现,两边各干各的,最后谁都说不清谁先断的。
另外,Host端的配置里经常会看到"T3=45"这个参数,但它必须在两端的参数表里一致吗?严格说并不要求两边配置完全相同,但实际联调时最好拉到一条线上,否则会出现A端还没超时、B端已经重试的错位局面。
3.3 状态模型:能不能回你消息,先看它站在哪一格
GEM标准里最重要的概念之一是状态模型,它规定了设备和Host之间的逻辑关系。设备刚上电时处于 OFF/Equipment Off 状态,设备软件启动后进入 Host Off 状态,此时设备可以本地操作,但不接受Host的远程控制。当双方通过S1F13/S1F14完成通信建立后,设备进入 Host On/Online 状态,才开始处理远程命令、事件上报等业务。
这个模型直接决定了消息的合法性。实际项目中经常遇到一种情况:Host没等S1F14回包成功,就急哄哄发S2F41下远程命令,设备端按状态模型直接回了个错误码,两边一头雾水。这不是消息解析的问题,是状态机没有协调好。排查这类问题,第一步永远是看设备当前处于哪个状态,第二步才是看消息内容。
S1F13/S1F14的回复里有明确的通信建立结果码:0表示接受通信,1表示设备忙,2表示设备离线,3表示已经建立过连接。联调时如果反复连不上,优先看这个结果码,它能告诉你连接请求是被哪个状态拒绝的。
4. 数据采集与报警管理:Fab最关心的两个功能落地
4.1 三种取数方式,别指望一招吃遍天
GEM300提供的数据获取手段不是单一的,而是三套互补:
第一套是 轮询状态变量 ,用S1F3/S1F4读SVID。Host随时可以问"当前温度多少、当前真空度多少",设备回一个当前值。优点是简单直接,缺点是只能拿到"问的那一刻"的值,拿不到变化过程,高频轮询又会增加网络压力。
第二套是 事件报告 ,用S6F11主动推送。设备内部定义了若干个Collection Event,比如"腔体压力超过阈值""Recipe开始执行",事件触发时把关联的数据打包成S6F11发给Host。这是产线上用得最多的方式,因为它只在真正有事情发生时才会传输数据,效率高、语义清楚。
第三套是 Trace采样 ,用S2F23/S2F24配置,S6F1周期上报。Trace适合连续变化的过程量,比如温度曲线、压力曲线,Host可以设置采样周期和采样时长,设备周期性地把采样值推上来。这三套方式在实际项目里通常组合使用:关键状态用事件上报,连续过程用Trace,临时排查用轮询。
4.2 Collection Event与Report的联动配置
事件上报不是设备出厂就配好的,需要Host在联调时动态配置。标准流程是三步:
- Host发 S2F33 定义Report,把若干个需要上报的变量(SVID/DVID)归到一个Report ID(RPTID)下。
- Host发 S2F35 把Collection Event(CEID)跟Report关联起来,告诉设备"这个事件触发时,把那个Report带上"。
- Host发 S2F37 启用指定的事件报告功能,设备才开始上报。
这段配置逻辑我在现场讲了很多遍,还是有不少人绕晕。打个比方:S2F33是在做"报表模板",RPTID就是模板编号;S2F35是给"事件"挂上"该用哪个模板";S2F37是最终按下"开关"。三步缺一不可,而且顺序不能乱。
S6F11的消息体长这样,联调时对着这个结构看,能很快定位问题:
S6F11 W
<L [3]
<U4 1001> // CEID:腔体压力异常事件
<U4 1723456789> // 设备时间戳
<L [1]
<L [2]
<U4 1> // RPTID
<L [1]
<F8 1.0025> // 对应的数据值,这里是压力值
>
>
>
>
.
4.3 报警上报与清除的完整链路
报警管理是最容易出"脏数据"的功能。设备发生故障时,发一条S5F1给Host,消息里带ALCD(报警信息字节)、ALID(报警ID)、ALTX(报警文本)。其中ALCD这个字节,高6位表示报警类别,低2位表示报警状态——是报警发生还是报警解除。
这里有个很多设备厂商容易漏掉的环节: 报警清除也要上报 。设备恢复正常后,必须再发一条S5F1,状态位标记为清除。否则Host端会一直显示这个报警处于激活状态,MES上的设备状态永远都是红叉。我在一个项目里见过设备连续报警30多次、Host端报警列表刷了一整屏,最后排查发现是设备恢复时压根没发清除消息,还把报警ID重复复用了。
Host端还可以通过S5F3/S5F4临时启用或禁用设备的报警通知。这个功能在设备维护时很有用——设备人员做PM保养时,会有大量正常传感器波动触发报警,先在Host端禁用报警,保养完再启用,能避免产生一堆垃圾报警记录。
5. 调试GEM300的真实翻车记录:那些文档没写的坑
5.1 HSMS连接"通而不稳":Active/Passive和心跳的坑
我接手过的GEM300项目里,最开头遇到的往往不是消息解析问题,而是HSMS连接"看起来通了,过一会儿就断"。
第一个坑是 Active/Passive方向配反 。HSMS里,主动发起TCP连接的一端叫Active,被动等待的一端叫Passive。如果设备配置成Active、Host也配成Active,两边都在等对方连,TCP永远建立不起来;反过来两边都主动连,端口冲突、消息错乱都会来。联调第一件事,确认哪端是Server(Passive),哪端是Client(Active),把IP和端口放到同一张表里逐项核对。
第二个坑是 心跳超时没配合适 。HSMS在空闲时靠Linktest维持连接,如果设备10秒发一次心跳,Host端的接收超时却配了5秒,那连接必然周期性断开。反过来说,心跳配得过于频繁,几百台设备同时上线时,空心跳就能把网络打满。经验值是空闲心跳10~30秒,接收超时给心跳间隔的3倍左右。
第三个坑是 Nagle算法 。HSMS消息虽然不大,但如果不把TCP_NODELAY打开,小消息会被Nagle算法积压,消息延迟从毫秒级变成上百毫秒级,表现就是设备反应"迟钝"。做HSMS通信时,请在socket层面把TCP_NODELAY设置为开启,这个操作99%的项目都需要。
5.2 字节序、长度域和SML解析:数据错位的根源
SECS-II里所有多字节整数都用 大端序 (网络字节序),但很多嵌入式工程师习惯小端思维,用手工拼字节流时特别容易出错。我见过一个温控设备上报的温度值,Host端读出来永远是负的,查到最后是I4字节序反了,不是协议问题,是拼包代码的问题。
另一个高频坑是 长度域 。HSMS的4字节长度字段算的是"从消息头开始到消息体结束"的总长,有些实现库则认为长度只算消息体,两边差10个字节,结果就是解析器找不到消息边界。建议第一版就写清楚长度字段的语义,并且用抓包工具抓一条已知消息验证。
还有解析时对 不定长List 的处理。SECS-II的List是嵌套的,子节点的长度各不相同,用一个"读前4字节当整个消息长度"的简单方案去解析嵌套结构,迟早出问题。正确姿势是把Item树解析成一个数据字典结构,再按SML模板去匹配。如果项目允许,尽量用现成的SECS/GEM库,而不是自己造轮子——这个协议细节太多,不是几百行代码能覆盖完的。
5.3 联调阶段的协同:时间同步与日志定位
GEM300联调最磨人的不是单端问题,而是 两边日志对不上 。设备上报了一个事件,Host说没收到;Host下发了命令,设备说没执行。各说各话的时候,能帮你破局的往往不是界面状态,而是两件事:时间同步和事务ID。
SEMI E30里有标准的时间同步消息S2F17/S2F18,联调前一定先把设备和Host的时间拉齐。事件上报、报警恢复、工艺结束这些消息都带时间戳,时间基准不一致,排序和因果分析就全乱了。我在现场的习惯是联调第一天就跑一次S2F17,把两边时间偏差记录在案。
另一个排查利器是 Message ID 。每对Primary/Secondary消息的Message ID必须一致,日志里按Message ID过滤,能完整还原一次事务的来龙去脉:谁先发的、回复是什么、耗时多少。如果出现"设备发了S6F11但没收到S6F12",通过Message ID能在两边日志里精准对上,判断是Host没回、网络丢了还是回复超时。
还需要控制联调时的 消息频率 。有一次我们连续触发设备报警,设备以毫秒级间隔狂发S6F11,Host的消息处理线程直接打满,正常消息反而被饿死。后来在设备端加了事件上报的节流策略(同类型事件最小间隔100ms),同时Host端把消息队列改成有界队列并加丢弃统计,问题才平息。
5.4 别拿Modbus的思路做GEM300:它和通用工业协议的差异
最后聊聊GEM300跟常见工业协议的差异,因为我发现很多做自动化出身、熟悉Modbus、EtherCAT、MQTT的工程师,会把固有思维带进GEM300项目,结果处处碰壁。
Modbus的模型是 寄存器读写 ,你读一个保持寄存器、写一个线圈,语义靠寄存器地址表自己定义,简单粗暴。EtherCAT的强项是 实时运动控制 ,主站和从站之间周期性地交换过程数据。MQTT走的是 发布/订阅 ,消息是松耦合的topic,适合云端和物联网场景。
GEM300完全不是这个路数。它同时规范了传输(HSMS)、报文(SECS-II)和设备行为(E30),而且行为模型是有状态、有事务的。你不能像Modbus那样"发一条读请求拿一个值",因为大部分数据是设备 主动推 上来的;你也不能像MQTT那样"随便订阅一个主题",因为要收到S6F11,必须先完成S2F33/S2F35/S2F37这套配置流程。它的状态模型决定了很多操作有前置条件,它的事务模型决定了消息必须成对出现。用一句话概括: Modbus是"问一句答一句"的简单对话,GEM300是一套有流程、有状态、有审计的商务往来 。调试GEM300之前,先把自己的心态从"协议栈工具人"切换成"业务流程对接人",很多问题就不会走弯路。
最后分享一个我自己的习惯:每次接到新的GEM300项目,不管设备端是自研还是采购SDK,我都会先用SECS/GEM模拟器把S1F13建连、S6F11事件上报、S5F1报警这三条链路跑通,再连真实设备。这个习惯帮我省掉了大量现场蹲守的时间。如果你正在做类似的对接,建议也按这个顺序把基础链路先打通——协议这行,慢就是快。

1013

被折叠的 条评论
为什么被折叠?



