简介:SECS(半导体设备通信标准)开源实现库,面向半导体设备自动化领域的开发者与研究人员,用于简化设备控制器与生产线工具之间的数据交换与通信开发。资源包共11个文件,约39KB,以test测试脚本、tm模块文件、tcl脚本及c源码为主,另含readme说明与copying3许可文件,覆盖SECS消息处理、接口驱动、示例教程、API文档、测试工具与社区支持等模块,可帮助开发者快速搭建I型、II型及HSMS协议通信链路。已有1501人学习下载,适合希望减少从零实现协议成本、专注应用逻辑的中高级开发者参考,也可作为小型企业与研究机构参与半导体设备开发的入门素材。
1. secs-开源:把半导体设备通信协议从黑匣子里拽出来
产线上那台刻蚀机又报通信超时了,设备端日志只有一行S1F1 W,Host 端显示T3 timeout。厂商工程师说“协议栈是黑盒,得换板卡”,报价六位数。这种场景在半导体、面板、光伏设备圈子里太常见了——SECS/GEM 这套协议被少数几家方案商把持,设备厂想自己改一行超时参数都无从下手。secs-开源这个方向要解决的就是这件事:把 SEMI E4/E5/E30/E37 这套设备通信标准用开源方式实现出来,让设备工程师能自己读源码、改参数、抓报文。它适合三类人:做设备端通信的嵌入式工程师、做 EAP/MES 对接的 Host 端开发者、以及被私有协议绑死想换方案的技术负责人。下面按“协议怎么立住 → 最小系统怎么跑 → 坑在哪 → 怎么验证”的顺序拆开讲。
2. SECS/GEM 协议栈的选型与最小可跑架构
2.1 为什么开源实现能替代商业协议栈
商业 SECS/GEM 栈的收费模式通常是按设备台数授权,单台几千到几万不等,而且源码不开放,遇到非标场景只能等厂商排期。开源实现的核心价值不在于“免费”,而在于可审计和可裁剪。半导体设备通信的本质是三层:底层是 HSMS(SEMI E37/E37.1)负责 TCP 连接管理和会话状态机,中间层是 SECS-II(SEMI E5)负责消息编码解码,上层是 GEM(SEMI E30)定义标准状态模型和事件报告机制。商业栈把这三层打包成动态库,开源实现则把每一层拆成独立模块,你可以只替换 HSMS 层来适配非标传输,或者只改 GEM 层的状态机来匹配自家设备的工艺流程。
选型时要盯住三个指标:状态机完整性、消息覆盖度、日志可追溯性。状态机完整性看它是否实现了 HSMS 的 Not Connected / Connected / Selected 三态迁移,以及 GEM 的 Control State 模型(Equipment Offline / Host Offline / Online Local / Online Remote)。消息覆盖度看它支持多少条标准 SECS-II 消息,至少要有 S1F1-S1F14、S2F13-S2F42、S5F1-S5F17、S6F1-S6F19 这些核心集。日志可追溯性看它能不能把每条报文的原始字节流和解析后的结构体同时打出来——这是后面排错的命根子。
2.2 最小可跑系统的四步搭建
先明确目标:让一台模拟设备通过 HSMS 连上 Host,完成 S1F13/S1F14 建立通信,再发一条 S6F11 事件报告。以下用 Python 生态里常见的开源 secs 库举例,其他语言实现逻辑一致。
第一步,装依赖并确认版本。开源 secs 库通常依赖twisted或asyncio做异步 IO,先建虚拟环境隔离。
python3 -m venv secs_env source secs_env/bin/activate pip install secsgem twisted python -c "import secsgem; print(secsgem.__version__)"逻辑说明:虚拟环境避免和系统 Python 冲突,secsgem是常见开源实现之一,twisted提供 reactor 事件循环。参数说明:如果公司内网有 PyPI 镜像,加-i指向内部源,否则装包可能超时。
第二步,写设备端配置。HSMS 连接需要本端 IP、端口、对端 IP、端口、设备 ID、会话 ID。
# equipment_config.py import secsgem.hsms import secsgem.secs settings = secsgem.hsms.HsmsSettings( address="0.0.0.0", # 本端监听所有网卡 port=5000, # 本端 HSMS 端口 connect_to="192.168.1.100", # Host 端 IP connect_port=5000, # Host 端端口 device_id=0, # 设备 ID,Host 侧要对应 session_id=0, # 会话 ID,通常与 device_id 一致 active=True, # True 表示设备主动连 Host timeout=45 # T3 回复超时,单位秒 )逻辑说明:active=True是设备主动发起 TCP 连接,半导体产线里设备端主动连 Host 更常见,因为 Host 通常固定 IP。参数说明:timeout=45对应 SEMI E37 的 T3 定时器,默认 45 秒,如果 Host 处理慢可以调到 60,但别超过 120,否则 Host 侧 T3 先超时。device_id和session_id必须和 Host 配置一致,不一致会卡在 Select 阶段。
第三步,注册 GEM 状态模型和事件。GEM 要求设备维护一套标准状态变量,至少要有 ControlState、EventsEnabled、AlarmsEnabled 这几个。
# gem_model.py from secsgem.gem import GemEquipmentHandler class MyEquipment(GemEquipmentHandler): def __init__(self, settings): super().__init__(settings) # 注册标准状态变量 self.register_state_variable("ControlState", "U1", 1) self.register_state_variable("EventsEnabled", "BOOLEAN", True) # 注册自定义事件 self.register_event("PROCESS_START", 1001) self.register_event("PROCESS_END", 1002) def on_process_start(self): # 触发事件报告,携带两个数据变量 self.trigger_event("PROCESS_START", { "LOTID": "LOT20250101", "RECIPE": "ETCH_01" })逻辑说明:register_state_variable把设备状态暴露给 Host 查询,register_event定义事件 ID,trigger_event在工艺开始时主动上报。参数说明:事件 ID 1001/1002 是自定义区间,标准事件 ID 在 1-999,自定义从 1000 开始避免冲突。数据变量名要和 Host 侧 EAP 配置的别名一致,否则 Host 解析不到。
第四步,启动并抓第一条报文。启动后看日志里有没有S1F13发出和S1F14收到。
python -c " from equipment_config import settings from gem_model import MyEquipment eq = MyEquipment(settings) eq.enable() eq.start() "逻辑说明:enable()激活 HSMS 状态机,start()启动 reactor 事件循环。参数说明:如果日志停在HSMS Connecting,检查 Host 防火墙和端口;如果停在HSMS Selected之前,检查 session_id 是否匹配。
2.3 消息编码解码的实操要点
SECS-II 消息是二进制格式,每个消息项有格式字节、长度字节、数据体。开源实现通常提供SecsStreamFunction基类,你只需要定义消息号和数据结构。
from secsgem.secs import SecsStreamFunction, SecsVarU4, SecsVarList class S6F11(SecsStreamFunction): _stream = 6 _function = 11 _data_format = [ SecsVarU4("DATAID"), SecsVarU4("CEID"), SecsVarList("REPORT", [ SecsVarU4("RPTID"), SecsVarList("V", [ SecsVarU4("VID"), SecsVarU4("VALUE") ]) ]) ]逻辑说明:_data_format定义了 S6F11 的嵌套结构,SecsVarList表示列表项,SecsVarU4表示 4 字节无符号整数。参数说明:DATAID默认填 0,CEID是触发的事件 ID,RPTID是报告 ID,VID是变量 ID。编码时库会自动算长度字节,解码时按同样结构反序列化。如果 Host 报Invalid format,八成是_data_format和 Host 侧定义对不上,用 Wireshark 抓包对比字节流最快。
3. 从零跑通 HSMS 连接:状态机、定时器与日志排查
3.1 HSMS 三态迁移的触发条件
HSMS 连接不是简单的 TCP 连上就能发消息,它有一套独立于 TCP 的状态机。Not Connected是初始态,TCP 连接建立后进入Connected,此时只能发 Select 请求。收到 Select 响应后进入Selected,才能收发 SECS-II 消息。任何一方发 Deselect 或 TCP 断开,都会退回上一态。
设备端主动连接时,流程是:TCP SYN → TCP ACK → 发 Select.req → 收 Select.rsp → Selected。如果卡在 Connected 超过 T6(默认 5 秒),说明 Select 没被响应。常见原因是 Host 侧 session_id 和 device_id 不匹配,或者 Host 的 HSMS 端口没监听。排查方法是在设备端日志里找Select Request和Select Response两行,没有 Response 就是 Host 没回。
3.2 T3/T5/T6/T7/T8 五个定时器的实际取值
SEMI E37 定义了五个关键定时器,开源实现里通常可配。T3 是等待回复超时,默认 45 秒;T5 是连接分离超时,默认 10 秒;T6 是 Select 超时,默认 5 秒;T7 是 Not Selected 超时,默认 10 秒;T8 是网络字符间超时,默认 5 秒。产线环境里最常调的是 T3 和 T8。
T3 调大场景:Host 侧 EAP 处理 S2F41 远程命令时要做数据库查询,超过 45 秒才回 S2F42。这时设备端 T3 要大于 Host 处理时间,否则设备先超时重发,Host 收到重复命令可能执行两次。建议 T3 设为 Host 最大处理时间的 1.5 倍。
T8 调小场景:网络抖动导致报文分片到达,T8 是等待同一报文后续字节的超时。默认 5 秒太宽松,如果网络稳定可以调到 2 秒,让异常报文更快暴露。但别低于 1 秒,否则正常分片也会被误判。
3.3 用日志定位“连上了但发不出消息”
现象:日志显示HSMS Selected,但发 S1F1 后没有 S1F2 回复,也没有报错。这种“静默失败”最坑。排查顺序如下。
先看设备端日志有没有S1F1 Sent。没有就是应用层没调用发送函数,检查代码里send_s1f1()是否在 Selected 回调里执行。有 Sent 但没 Received,去 Host 端日志看有没有S1F1 Received。Host 没收到就是网络层丢包,用tcpdump -i eth0 port 5000 -w secs.pcap抓包,Wireshark 打开看有没有对应 TCP 段。Host 收到了但没回,检查 Host 侧 S1F1 处理函数是否抛异常被吞掉。Host 回了但设备没收到,检查设备端 T3 是否已超时关闭了等待。
提示:抓包时同时抓设备端和 Host 端,对比时间戳。如果设备端显示发出但 Host 端抓不到,中间有交换机或防火墙拦截。
4. 避坑:开源 SECS 实现里最容易翻车的五个地方
4.1 坑一:session_id 和 device_id 混用导致 Select 失败
现象:TCP 连上了,日志停在Connected,反复发 Select.req 但收不到 Select.rsp,T6 超时后断开重连。原因:HSMS 的 Select 请求里携带的是 SessionID,而 SECS-II 消息头里携带的是 DeviceID。很多开源库把这两个参数合并成一个配置项,但 Host 侧可能分开校验。如果 Host 期望 SessionID=1、DeviceID=0,而设备端都填 0,Select 阶段就会被拒。解决:查 Host 侧配置文档,确认两个 ID 的独立取值,在设备端配置里分开设置。如果库只提供一个参数,看源码里它把该参数写进了 Select 请求的哪个字段,必要时改源码。
4.2 坑二:S6F11 事件报告里 VID 和 RPTID 对不上
现象:设备发 S6F11 后 Host 回 S6F12 但带错误码,或者 Host 直接不回。原因:GEM 要求事件报告里的每个变量都要有对应的报告定义(RPTID)和变量定义(VID),Host 侧维护一张映射表。设备端如果自己编了一套 VID,Host 查不到就丢弃。解决:先通过 S2F33 定义报告、S2F35 链接事件和报告,让 Host 确认后再发 S6F11。开源库里通常有define_report和link_event方法,按标准流程走,别跳过。
4.3 坑三:T3 超时后重发导致 Host 重复执行
现象:Host 侧日志显示同一条 S2F41 收到两次,设备执行了两次工艺切换。原因:设备端 T3 设为 45 秒,Host 处理耗时 50 秒,设备超时重发,Host 处理完第一条后又收到第二条。解决:设备端 T3 调到 Host 最大处理时间的 1.5 倍以上;同时 Host 侧对 S2F41 做幂等处理,用 DATAID 去重。开源实现里如果支持消息 ID 跟踪,开启它。
4.4 坑四:字符编码不一致导致中文 Recipe 名乱码
现象:设备端发 S7F19 查询 Recipe 列表,Host 返回的 Recipe 名里中文变成问号或乱码。原因:SECS-II 的 ASCII 项默认按 ISO-8859-1 编码,中文需要 UTF-8 或 GBK。开源库如果不显式指定编码,按默认走就乱。解决:在消息定义里把字符串项标为SecsVarA并指定编码,或者统一用英文 Recipe 名。如果必须用中文,设备端和 Host 端约定同一编码,并在日志里打印原始字节验证。
4.5 坑五:开源库版本升级后 API 不兼容
现象:昨天跑通的代码,今天pip install -U后报AttributeError: 'HsmsSettings' object has no attribute 'timeout'。原因:开源项目迭代快,小版本可能改配置项命名。解决:生产环境锁定版本,用pip freeze > requirements.txt固定依赖。升级前先在测试环境跑一遍 S1F13/S1F14 和 S6F11 全流程,确认 API 没变再上产线。
5. 验证开源 SECS 栈是否达标:三个可量化的测试方法
5.1 用模拟 Host 做回归测试
开源生态里通常有配套的 Host 模拟器,或者你可以用同一套库写一个 Host 端脚本。测试用例至少覆盖:S1F13/S1F14 建立通信、S1F1/S1F2 心跳、S2F33/S2F35 报告定义、S6F11 事件上报、S2F41/S2F42 远程命令、S5F1 报警上报。每个用例断言回复消息号和关键字段值。
# test_host.py from secsgem.hsms import HsmsSettings, HsmsClient from secsgem.secs import SecsStreamFunction def test_s1f13(): settings = HsmsSettings( address="0.0.0.0", port=5000, connect_to="192.168.1.101", connect_port=5000, device_id=0, session_id=0, active=False ) client = HsmsClient(settings) client.enable() # 等待设备连入后发 S1F13 response = client.send_and_wait(S1F13(), timeout=10) assert response.header.stream == 1 assert response.header.function == 14逻辑说明:active=False让 Host 端被动监听,send_and_wait发 S1F13 并等 S1F14。参数说明:timeout=10是测试超时,比 T3 短,快速失败。断言检查回复的流和功能号,确保协议层正确。
5.2 用 Wireshark 做字节级验证
抓包过滤tcp.port == 5000,看 HSMS 报文头。HSMS 头是 4 字节长度 + 10 字节头部(SessionID 2 字节 + HeaderByte2 1 字节 + HeaderByte3 1 字节 + PType 1 字节 + SType 1 字节 + SystemBytes 4 字节)。Select.req 的 SType=1,Select.rsp 的 SType=2,Deselect.req 的 SType=3,数据消息的 SType=0。如果 SType 不对,说明状态机实现有问题。SECS-II 消息体从第 14 字节开始,第一个字节是格式字节,高 6 位是格式码,低 2 位是长度字节数。
5.3 用产线真实设备做灰度验证
模拟器跑通后,找一台非关键设备做灰度。先只开 S1F1 心跳和 S5F1 报警,跑 24 小时看有没有断连。稳定后再开 S6F11 事件上报,对比 Host 侧数据库里的事件记录和设备端日志是否一致。最后开 S2F41 远程命令,但先限制为只读命令,确认无误再放开写命令。灰度期间保留商业栈作为备份,一旦开源栈异常,5 分钟内切回。
注意:灰度验证时设备端和 Host 端的 T3 要设成一致,否则一边超时重发、一边还在处理,日志会对不上。
我自己的习惯是每次改完配置先跑一遍S1F13握手,看到S1F14回来才继续下一步。这个动作花不到 10 秒,但能省掉后面半小时的抓包排查。开源 SECS 栈不是银弹,它把黑匣子打开了,代价是你得自己盯状态机和定时器。但一旦跑通,改一行超时参数不用再等厂商排期,这种掌控感值得前期投入。希望帮到你。
本文还有配套的精品资源,点击获取