跳到主要内容
版本:4.2

HSMS/SECS-II(Semi)

定义

命名空间:
TouchSocket.Semi
安装:
dotnet add package TouchSocket.Semi

一、说明

TouchSocket.Semi 是一个半导体协议功能库,实现了基于 HSMS(SEMI E37) 的 TCP 传输层以及 SECS-II(SEMI E5) 数据项解析与序列化,可用于半导体设备与主机系统之间的标准化通信。

1.1 HSMS 协议概述

HSMS(High Speed Message Services,高速报文服务) 是由 SEMI 组织制定的 E37 标准,定义了设备与主机之间通过 TCP/IP 进行通信的传输层协议。HSMS 使用固定 10 字节的消息头(Header),并在消息体中承载 SECS-II 数据。

HSMS 会话建立流程如下:

  1. 被动端(Passive)启动监听,等待主动端连接。
  2. 主动端(Active)发起 TCP 连接。
  3. TCP 连接建立后,主动端发送 Select.req 消息,被动端回复 Select.rsp 完成 HSMS 握手。
  4. 握手成功后,双方可通过数据消息(SType=0)传递 SECS-II 内容。

1.2 SECS-II 协议概述

SECS-II(SEMI Equipment Communications Standard, Part 2) 是 SEMI E5 标准,定义了设备与主机之间交换数据的消息格式和语义。每条 SECS-II 消息由 Stream(S)Function(F) 编号标识,并携带结构化的数据项(SecsItem)。

SECS-II 数据项(Item)支持以下格式类型:

格式C# 类型说明
ListListSecsItem子数据项列表
BinaryBinarySecsItem二进制字节数组
BooleanBooleanSecsItem布尔值(用 byte 存储)
ASCIIASCIISecsItemASCII 字符串
JIS8JIS8SecsItemJIS8 字符串
I1I1SecsItem1 字节有符号整数数组
I2I2SecsItem2 字节有符号整数数组
I4I4SecsItem4 字节有符号整数数组
I8I8SecsItem8 字节有符号整数数组
U1U1SecsItem1 字节无符号整数数组
U2U2SecsItem2 字节无符号整数数组
U4U4SecsItem4 字节无符号整数数组
U8U8SecsItem8 字节无符号整数数组
F4F4SecsItem4 字节浮点数数组
F8F8SecsItem8 字节浮点数数组

二、HsmsService(被动端/设备端)

HsmsService 是 HSMS 的被动监听端(Passive),通常用于模拟半导体设备端。它基于 TcpServiceBase<HsmsSessionClient> 实现,每个连入的主动端由一个 HsmsSessionClient 实例管理。

2.1 创建 HsmsService

🔄 正在加载代码...

2.2 处理接收到的消息并发送响应

在服务插件中,可以接收来自主动端的 SECS-II 数据消息并发送回复:

🔄 正在加载代码...
提示

SystemBytes 字段相当于消息的"事务 ID",发送响应时需要回填请求消息中的 SystemBytes,使客户端的等待机制能够正确匹配响应。

三、HsmsClient(主动端/主机端)

HsmsClient 是 HSMS 的主动连接端(Active),通常用于主机系统(Host)。连接成功后会自动完成 HSMS Select 握手。

3.1 创建 HsmsClient

🔄 正在加载代码...

3.2 快捷连接方式

使用扩展方法 ConnectAsync(string ipHost) 可以简化配置步骤:

🔄 正在加载代码...

四、发送消息

4.1 发送数据消息(SType=0)

HsmsMessageSF 属性分别表示 Stream 和 Function 编号。ReplyExpectedtrue 时,SendHsmsMessageAsync 将阻塞等待对端响应;为 false 时则直接返回 null

🔄 正在加载代码...

4.2 发送 Linktest

Linktest 用于在空闲期间检测 TCP 链路是否仍然有效。调用 SendLinkTestAsync 扩展方法即可发送 Linktest.req 并等待 Linktest.rsp:

🔄 正在加载代码...

4.3 发送 Separate(主动断开)

向对端发送 Separate.req,通知其断开 HSMS 连接:

await client.SendSeparateAsync();

五、SECS-II 数据项(SecsItem)

5.1 数据项构造

每种 SECS-II 格式对应一个具体的 SecsItem 子类,可直接在构建 HsmsMessage 时将数据项赋予 Body 属性:

🔄 正在加载代码...

5.2 List 嵌套结构

ListSecsItem 可以包含任意数量的子 SecsItem,用于表达 SECS-II 中的 L 格式,从而构造复杂的嵌套结构。

5.3 从消息体解析数据项

当收到一条带 BodyHsmsMessage 时,可通过类型检查获取具体数据:

if (e.Message.Body is ASCIISecsItem ascii)
{
Console.WriteLine(ascii.Value);
}
else if (e.Message.Body is ListSecsItem list)
{
foreach (var item in list.Items.Span)
{
// 处理子项
}
}

六、插件

TouchSocket.Semi 支持以下插件接口:

插件接口触发时机
IHsmsConnectingPlugin连接即将建立时(TCP 握手前)
IHsmsConnectedPluginHSMS 会话建立完成(Select 握手后)
IHsmsClosingPlugin连接即将主动关闭时
IHsmsClosedPlugin连接已关闭时
IHsmsReceivedPlugin收到 SECS-II 数据消息时

6.1 插件使用示例

🔄 正在加载代码...
🔄 正在加载代码...
提示

插件可用于实现连接认证、消息日志记录、心跳检测、访问控制等横切关注点,而无需修改核心业务代码。

七、消息类型说明

HsmsMessageType 枚举定义了 HSMS 所有标准消息类型(SType 字节):

枚举值SType说明
DataMessage0SECS-II 数据消息
SelectRequest1Select.req(选择请求)
SelectResponse2Select.rsp(选择响应)
DeselectRequest3Deselect.req(取消选择请求)
DeselectResponse4Deselect.rsp(取消选择响应)
LinkTestRequest5Linktest.req(链路测试请求)
LinkTestResponse6Linktest.rsp(链路测试响应)
RejectRequest7Reject.req(拒绝请求)
SeparateRequest9Separate.req(分离请求)

八、注意事项

  • HsmsClient.ConnectAsync() 内部会在 TCP 连接建立后自动发送 Select.req,并等待 Select.rsp 返回 Success 状态,若握手失败则抛出 HsmsException
  • 当收到对端发来的 Separate.req 时,HsmsClientHsmsSessionClient 都会自动调用 CloseAsync 断开连接。
  • HsmsService 收到主动端的 Select.req 时,会自动回复 Select.rsp(Success)并完成握手,无需手动处理。
  • SecsItem 继承自 DisposableObject,在不再使用时应调用 Dispose 释放资源(或使用 using 语句)。