简介:在半导体等制造业场景中,MES系统与生产设备之间普遍采用SECS II标准通信,通信质量直接影响自动化产线的稳定与追溯。这一调试工具模拟器可切换服务端或客户端模式,用于验证程序发送/接收的数据是否符合客户协议要求,并能辅助排查HSMS与SECS-II联调中的报文格式与交互时序问题。整个资源压缩后约90KB,内部共4个文件:1个exe主程序可直接运行,2个xml提供默认配置与样板数据,1个txt为使用说明,结构简洁,便于快速对照调整。目前已有2819人学习下载,适合需要落实SECS-II报文规范、处于设备对接或MES集成测试阶段的工程师。借助默认配置与样板文件,用户可以缩短环境准备时间,快速验证自身消息编码是否正确,提升联调效率;对刚接触SECS-II的开发者,也能提供直观的模拟联机参考。
1. 这个调试工具要解决什么——先聊场景再聊代码
1.1 没设备就没法联调?这个痛我太熟了
做半导体设备软件或者工厂自动化(EAP)对接的朋友,大概率都经历过这种场景:设备端程序写完了,Signal灯正常,自检没问题,但一到和Host联调就卡壳——要么现场设备排产紧张不能反复测试,要么设备还没进厂,代码只能干瞪眼。尤其是SECS-II/HSMS这类基于TCP/IP的通信协议,联调时看不到对方的报文,错了也不知道错在哪。我最早被这个问题折磨的时候,只能拿两个终端互相报文字,一条一条手敲消息,效率低到让人想转行。
后来我干脆自己整理了一套SECS-II HSMS调试工具,同时兼具模拟器功能,还带了一份可以直接改着用的样板文件。这套工具解决的核心问题就一句话:在没有真实设备、没有真实Host的情况下,让协议链路先跑起来。它是一个可以模拟设备端(Equipment)的模拟器,也是一个可以主动发报文、看报文的调试工具,适合EAP工程师、设备软件工程师、协议对接测试人员,也适合刚入门想搞懂SEMI通信标准的人。
1.2 模拟器在链路里的位置:可模拟设备端也可模拟Host端
很多刚接触SECS通信的人会混淆“模拟器”和“调试工具”的区别。模拟器侧重角色扮演——它把设备端的行为模拟出来,让Host端程序有东西可连;调试工具侧重报文分析和消息构造——你能看到链路上跑了什么,也能手动发一条消息去验证对方行为。这套工具两个角色都占了:
- 设备端模拟模式:工具把自己伪装成一台符合SEMI E5/E30/E37标准的设备,等待Host来连接,响应S1F1/S1F2查询,上报S6F11事件,甚至可以按脚本触发报警。
- Host端调试模式:工具作为客户端主动连接设备,发送S2F17等控制消息,读取设备状态,把收到的消息按SML格式解析成可读文本,方便你一条条核对。
两种模式切换只需要改配置,这在联调场景里非常实用。比如你在写设备端程序,就用Host模式模拟工厂主机来“试探”你的设备;你在写EAP程序,就用设备模式模拟一台“听话的假设备”。一个工具,两条链路,彻底摆脱“每次都要找对方要日志”的被动局面。
1.3 样板文件的价值:不是玩具,是给你改的底稿
标题里特意强调“带样板文件”,我觉得这是整个工具最容易被低估的部分。很多模拟器给你一个空白配置界面,让你自己从头搭消息结构,结果光翻标准文档就要花一晚上。这套工具里附带了一份完整的样板文件,包含设备信息配置、消息模板、事件上报脚本和一个能直接跑通的示例会话。它的设计思路相当于是给你一份“答过题的卷子”,你只需要照着抄、改参数,而不是从白纸开始推导。
样板文件我按真实项目里最常见的设备逻辑组织:一台加热类设备,具备温度采集、配方执行、报警上报三组典型行为。改一改设备ID和消息内容,就能适配大多数场景。下面我会把样板文件里到底有什么、怎么用到自己的项目里,一层一层拆开讲。
2. 底层通信骨架:SECS-II与HSMS长什么样
2.1 SECS-II:消息内容的“语法”
SECS-II(SEMI E5标准)定义了设备与Host之间传输的消息内容格式。你可以把它想象成寄快递时的快递单:HSMS负责“用什么车运、走哪条路”,SECS-II负责“单子上每一项怎么填”。SECS-II的消息由Stream和Function两个编号定位,合起来写成“SxFy”。
- Stream:消息的大类,一共16种。常见的有S1(设备状态)、S2(设备控制)、S5(报警)、S6(数据上报)、S7(配方管理)。
- Function:同类下的具体功能。比如S1F1是“设备是否在线”的询问,S1F2是回复;S6F11是设备主动上报数据,S6F12是Host确认收到。
SECS-II消息里真正承载内容的是一棵“数据树”,节点类型包括List(列表)、ASCII(字符串)、U4/I4(无符号/有符号整数)、F4/F8(浮点数)等。标准里管这个叫Item。一条简单的S1F1消息写成SML(SECS Message Language)长这样:
S1F1 W .这是“查询在线”的请求,没有数据项。对应回复S1F2:
S1F2 W <L <A "Demo Heater"> <A "1.0.0"> > .SML的可读性相当高,对照标准里每个消息的定义,基本能猜个八九不离十。样板文件里的消息模板就是按这种格式组织,你改字符串、改数字,再通过工具构造成真实报文发出去,整个理解门槛就降下来了。
2.2 HSMS:消息的“运输通道”
HSMS(SEMI E37标准)负责把SECS-II消息封装成字节流在TCP/IP上传输。一个HSMS报文由10字节的消息头加上消息体组成。消息头里最关键的是:
- Session ID(也常叫Device ID):标识设备编号,一般由Host分配,设备侧配置好之后固定使用。
- Stream/Function和W位:W位(Wait)表示这条消息是否需要对方回复。W=1时,发送方在超时时间内等待应答消息。
- System Bytes:事务ID,用于把“请求”和“回复”配对。一个请求发出后,回复消息里会带相同的System Bytes。
- PType/SType:区分消息类型。数据消息的SType为0,控制消息(Select、Linktest、Separate等)各有各的值。
HSMS的连接不是一个简单的TCP长连接,它有一个状态机:TCP物理连接建立后,双方需要先交换Select控制消息完成“会话选择”,此时链路才进入Selected状态,允许传输业务数据。之后还要通过Linktest消息维持活性。状态机里的几个状态,我建议你死记硬背,因为90%的联调问题都出在状态切换不对上:
| 状态 | 说明 |
|---|---|
| TCP Not Connected | TCP连接尚未建立 |
| TCP Connected | TCP三次握手已建立,但未完成会话选择 |
| Not Selected | TCP已连上,等待Select.req/Select.rsp交换 |
| Selected | 会话选择完成,可以收发业务消息 |
别忘了TCP连接本身建立后还有个隐患:通信双方必须明确谁是主动连接方(Active)、谁是被动监听方(Passive)。通常设备端配置成Passive,Host端为Active;但有项目正相反,设备主动找Host。样板文件里设备端模型预设为Passive监听模式,你可以直接改成Active模式,配置IP和端口即可,后面我会讲实操。
2.3 必须认识的参数:T3~T8、Device ID、Window Size
SECS通信里有一组超时参数,这组参数如果你不设置对,联调时会被各种莫名断连折磨疯。它们有标准名字,也有推荐值:
| 参数 | 含义 | 推荐值 |
|---|---|---|
| T3 | 等待回复超时 | 45秒 |
| T5 | 连接分离后禁止重连的时间 | 10秒 |
| T6 | 控制事务(如Select)超时 | 5秒 |
| T7 | TCP连接建立超时 | 10秒 |
| T8 | 报文内字符间隔超时 | 5秒 |
设备ID一般在1~32767之间。Window Size表示消息窗口大小,默认够用;如果出现大批量数据分块传输明显变慢的情况,再去调整它。样板文件里给的默认值是我多轮测试后比较稳的组合,新项目可以直接沿用,不用一上来就改。
3. 开箱即用:样板文件与实操跑通
3.1 工具功能一览
这套工具的核心界面大致分四块:
- 连接配置区:设置本地角色(设备/主机)、IP、端口、设备ID、连接模式(Active/Passive)。
- 消息收发区:实时滚动显示已收/已发的原始报文和解析后的SML文本,支持对消息做过滤。
- 消息构造器:选择Stream/Function,填写数据项,工具自动生成SML并发送。
- 脚本控制区:按预先写好的步骤触发消息序列,用于模拟完整业务流。
实际用下来,调试阶段最有用的功能是“手动构造消息”,你能直接看到自己拼出来的消息被解析成什么结构,也可以在消息树里直接改某个Item的值再重发,像调试API一样方便。
3.2 样板文件里有什么
我拿到这套样板文件的第一反应是:它真的在试图教会你怎么做。里面的内容包括:
设备模型定义(JSON格式):描述设备名称、版本、支持的Stream/Function列表、事件列表、报警列表。比如示例设备“Demo Heater”支持S1F1/F2查询、S2F17/F18控制写、S5F1报警、S6F11事件上报。
消息模板库:按编号整理的SML模板,例如:
S5F1 W // 报警上报 <L <U4 1001> // 报警ID <A "Heater Over Temp"> // 报警文本 > .S6F11 W // 事件上报 <L <U4 101> // 事件ID <L <F4 231.8> // 实际温度 <U4 1> // 状态码 </L> > .会话脚本(XML格式):定义一次从连接到收尾的完整流程,比如“连接→Select→收到S1F1后回S1F2→等待10秒→触发S6F11上报”。这是工具在自动模式下执行的动作序列,也是你写自动化测试时最好的参照模板。
README说明:把消息类型、超时参数和几个坑都写清楚了。我强烈建议你把这份README通读一遍再动手,很多联调问题都写在里面。
3.3 实操:5分钟让模拟器与Host完成握手
为了让大家有直观体感,我用样板文件里的示例跑一次最经典的握手流程,整个过程大概5分钟:
第一步,启动设备模拟端。从样板文件夹加载设备模型配置文件,确认连接配置为Passive模式、端口5000,设备ID=1。启动监听,工具状态显示“Listening”。这一步相当于把“假设备”立起来了。
第二步,启动Host测试端。切到Host调试模式,填好对方IP为127.0.0.1,端口5000,角色Active,点击连接。此时你会看到设备端状态从“TCP Not Connected”变成“TCP Connected”,再立刻进入“Selected”。这个瞬间的快感,就像两台机器突然说上了话。
第三步,发一个S1F1测试。在消息构造器里选择S1F1,点击发送。右边消息日志里马上能看到S1F2回复,SML格式化显示设备名“Demo Heater”和版本号。到这一步,链路已经完全通透了。
第四步,主动触发一次事件上报。在脚本控制区选择“Trigger Event 101”,工具自动按脚本发送S6F11,Host端收到后返回S6F12。这一整套流程下来,你就能直观理解“设备主动上报”和“Host应答”之间的因果关系。
如果你写的是设备端代码,把工具切到Host模式,用它去连接你的设备程序,同样能看到设备返回的原始报文,从而快速判断是协议实现问题还是业务逻辑问题。
4. 踩坑实录:常见问题与排查技巧
4.1 连接建立不了,多半是这4个原因
我在联调中遇到最多的问题就是“TCP连不上”或“连上了但Select失败”。根据经验,90%的情况落在下面几个原因里:
角色配置反了。确认谁是Active、谁是Passive。两个都设成Active,没人监听,互连失败;两个都Passive,则一直互相等待。最简单的判断方法:Passive侧必须能看到端口监听的日志输出。
防火墙拦了端口。这个问题最容易忽略。Windows防火墙、服务器安全组策略都可能导致TCP连接被静默丢弃。排查时用telnet ip port直接测一下TCP端口通不通,比反复看应用日志快得多。
设备ID不匹配。Select请求里的设备ID和Host期望的不一致,Host会拒绝进入Selected状态。样板文件里默认设备ID=1,新项目如果有多台设备,一定记得逐个核对。
消息头格式没对齐。这里我要特别强调字节序问题。HSMS消息头里Stream/Function、System Bytes都是大端序,如果你自己实现协议栈,用结构体直接强转小端序的机器,解析出来全是乱的。这类问题在工具里不会遇到,但如果你一边写代码一遍用工具对照抓包,这是在代码里最常踩的坑。
排查连接问题时,我给一个最实用的流程建议:先看TCP三次握手是否成功,再看HSMS控制消息是否交换成功,最后才看业务消息。别一上来就盯着SECS-II报文结构分析半天,那是把问题的层级搞错了。
4.2 连上了又断:心跳与超时的博弈
成功握手后出现不定时断连,这是第二大高频问题。表现为:链路跑得好好的,隔几分钟或几十分钟突然断开,日志里出现Linktest失败或者T3超时。
这里的核心原因通常是心跳超时参数没对齐。HSMS要求双方周期性地发送Linktest消息来确认对方存活,但发送间隔是否和T8(字符间隔超时)及Socket超时时间匹配,完全取决于配置。如果你在一个参数上设了30秒,另一个设了60秒,逻辑上还能凑合;但如果一方根本不开Linktest或者间隔远大于TCP层的KeepAlive时间,链路就会因为静默被系统回收。
我的建议是:先用工具双方默认参数跑24小时不中断,再改到自己工程里。样板文件里默认的T3=45秒、T6=5秒、T7=10秒、T8=5秒是经过长时间稳定性测试的,不要随意改动。真需要调整时,记住一个原则:不同超时参数之间的时序要协调好,T6必须小于T7,T3要大于正常业务应答时间,否则会频繁误判超时。
另外,如果你在工业现场使用,网络存在抖动,可以适当放大T3到60秒,但不能再大,因为过大的T3会导致故障发现延迟,在产线上这是很危险的事。
4.3 消息对不上:字节序、解析和W位
连上以后,真正的硬仗才开始——消息内容对不上。常见现象是:消息发出去了,对方一直不回复;或者收到的SML解析出来完全不是预期结构。
到这里,第一件事就是抓包看原始字节。工具自带的报文日志是带原始Hex的,强烈建议你在调试窗口里开启这条显示。对照SEMI E37标准检查10字节消息头:Session ID、Stream/Function、System Bytes是不是在期望的位置。我遇到过一种很隐蔽的情况:两侧的System Bytes生成算法不一致,导致请求和回复无法配对,对方一直认为这条消息没有对应事务,于是不处理。
还有一个高频误区是W位的使用。S1F1 W表示“等待应答”,发送方会进入T3等待;如果你发了一条W=1的消息,对方却不回,发送方就会持续重发或者超时报错。反过来,如果对方实现里本来应该回执的消息你不带W位,有些严格实现也会拒绝处理。所以构造消息时,先确认标准里定义的那条消息是Require Reply还是No Reply。
对于数据项的格式,记住SECS-II的数据项类型和长度是自描述的,收消息解析时不要硬编码偏移量,一定要按照TAG/LENGTH结构逐层解包。样板文件里的所有模板消息都遵循这个原则,照着写不容易错。
4.4 调试方法推荐:从单条消息到全流程
调试方法上我总结出一个经验:先点对点验证单条消息,再跑业务流程。不要一上来就启动完整脚本跑事件流,那样出了问题根本不知道在哪一步挂的。
正确顺序是:
- 手动发一条S1F1,确认最基本的查询/应答可用。
- 依次验证S1F3/F4(设备列表)、S2F17/F18(变量读)、S5F1/F2(报警上报)这类有代表性的消息类型,每一条都确认解析正确。
- 在脚本控制区组合几条消息,模拟一个短流程,比如“查询设备→上报事件→收到确认”。
- 最后才跑完整的模拟会话脚本。
这套方法论能帮助你把协议调试中的变量隔离到最小。我在样板文件里也沿用了同样的顺序安排消息模板顺序,你使用的时候可以明显感觉到它是按调试路径设计的,而不是随意罗列。
在常见问题上,再补充一个速查表,算是我长期调试半导体通信协议的个人笔记:
| 现象 | 可能原因 | 处理建议 |
|---|---|---|
| TCP连不上 | 防火墙、角色配置错、IP端口错误 | telnet测试端口,核对角色配置 |
| 连上后卡在Not Selected | 设备ID不一致、Select消息格式错 | 抓包查看Select.req内容 |
| 连接稳定但定时断 | Linktest配置不对、T3/T8不匹配 | 检查超时参数,考虑加大T5 |
| 消息发出无回复 | W位设置错误、System Bytes不匹配 | 抓包看请求回复配对情况 |
| 解析乱码 | 字节序错误、数据格式不匹配 | 对比Hex和SML解析,检查Item类型 |
最后再聊一点我个人的使用心得。调试协议这事,很多人觉得是“熬时间”,但我觉得真正提效的方式是让工具把复杂度挡在外面。有了能够双向模拟、带现成模板的调试工具,你面对的不再是一堆裸字节和标准文档,而是一个能随时对话的“假设备”。这套工具我已经在各种联调场合用了很长时间,从实验室验证到产线扩容,还没遇到过它应付不来的场景。如果你也在跟SECS-II/HSMS死磕,不妨按这个思路搭一套自己的调试环境,样板文件直接改着用,能省下大量排查时间。
本文还有配套的精品资源,点击获取