HSMS/SECS-II(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 会话建立流程如下:
- 被动端(Passive)启动监听,等待主动端连接。
- 主动端(Active)发起 TCP 连接。
- TCP 连接建立后,主动端发送 Select.req 消息,被动端回复 Select.rsp 完成 HSMS 握手。
- 握手成功后,双方可通过数据消息(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# 类型 | 说明 |
|---|---|---|
List | ListSecsItem | 子数据项列表 |
Binary | BinarySecsItem | 二进制字节数组 |
Boolean | BooleanSecsItem | 布尔值(用 byte 存储) |
ASCII | ASCIISecsItem | ASCII 字符串 |
JIS8 | JIS8SecsItem | JIS8 字符串 |
I1 | I1SecsItem | 1 字节有符号整数数组 |
I2 | I2SecsItem | 2 字节有符号整数数组 |
I4 | I4SecsItem | 4 字节有符号整数数组 |
I8 | I8SecsItem | 8 字节有符号整数数组 |
U1 | U1SecsItem | 1 字节无符号整数数组 |
U2 | U2SecsItem | 2 字节无符号整数数组 |
U4 | U4SecsItem | 4 字节无符号整数数组 |
U8 | U8SecsItem | 8 字节无符号整数数组 |
F4 | F4SecsItem | 4 字节浮点数数组 |
F8 | F8SecsItem | 8 字节浮点数数组 |
二、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)
HsmsMessage 的 S、F 属性分别表示 Stream 和 Function 编号。ReplyExpected 为 true 时,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)
SecsItem 是所有 SECS-II 数据格式的抽象基类,每种格式对应一个具体子类。构造时直接传入初始值,内部按 大端序(Big-Endian) 自动完成序列化。
5.1 数据项概览
各类型数据项均可作为 HsmsMessage.Body 直接发送:
5.2 字符串类型(ASCIISecsItem / JIS8SecsItem)
ASCIISecsItem:传入标准 ASCII 字符串(仅支持 0x20~0x7E 可打印字符)。JIS8SecsItem:使用 UTF-8 编码,可携带中文等多字节字符。
5.3 整数类型(I1 / I2 / I4 / I8 / U1 / U2 / U4 / U8)
所有整数 SecsItem 子类均接受对应元素类型的数组(C# 数组可隐式转换为 ReadOnlyMemory<T>),支持传入单个值或多个值组成的数组。
| 类型 | C# 元素类型 | 字节宽度 |
|---|---|---|
I1 | sbyte | 1 |
I2 | short | 2 |
I4 | int | 4 |
I8 | long | 8 |
U1 | byte | 1 |
U2 | ushort | 2 |
U4 | uint | 4 |
U8 | ulong | 8 |
5.4 浮点类型(F4 / F8)
F4SecsItem:对应 C#float(4 字节单精度)。F8SecsItem:对应 C#double(8 字节双精度)。
5.5 布尔与二进制类型
BooleanSecsItem:以byte[]存储布尔值,0表示false,非0(通常为1)表示true。BinarySecsItem:携带任意原始字节,适合传输不透明二进制数据。
5.6 List 嵌套结构
ListSecsItem 接受子 SecsItem 数组,用于表达 SECS-II 中的 L 格式,可以任意层级嵌套,构造复杂消息体(如 S6F11 事件报告)。
5.7 从消息体解析数据项
当收到带 Body 的 HsmsMessage 时,通过 is 模式匹配获取具体类型,再通过 Values(整数/浮点/布尔)或 Data(二进制)属性读取值:
六、插件
TouchSocket.Semi 支持以下插件接口:
| 插件接口 | 触发时机 |
|---|---|
IHsmsConnectingPlugin | 连接即将建立时(TCP 握手前) |
IHsmsConnectedPlugin | HSMS 会话建立完成(Select 握手后) |
IHsmsClosingPlugin | 连接即将主动关闭时 |
IHsmsClosedPlugin | 连接已关闭时 |
IHsmsReceivedPlugin | 收到 SECS-II 数据消息时 |
6.1 插件使用示例
插件可用于实现连接认证、消息日志记录、心跳检测、访问控制等横切关注点,而无需修改核心业务代码。
七、消息类型说明
HsmsMessageType 枚举定义了 HSMS 所有标准消息类型(SType 字节):
| 枚举值 | SType | 说明 |
|---|---|---|
DataMessage | 0 | SECS-II 数据消息 |
SelectRequest | 1 | Select.req(选择请求) |
SelectResponse | 2 | Select.rsp(选择响应) |
DeselectRequest | 3 | Deselect.req(取消选择请求) |
DeselectResponse | 4 | Deselect.rsp(取消选择响应) |
LinkTestRequest | 5 | Linktest.req(链路测试请求) |
LinkTestResponse | 6 | Linktest.rsp(链路测试响应) |
RejectRequest | 7 | Reject.req(拒绝请求) |
SeparateRequest | 9 | Separate.req(分离请求) |
八、注意事项
HsmsClient.ConnectAsync()内部会在 TCP 连接建立后自动发送 Select.req,并等待 Select.rsp 返回Success状态,若握手失败则抛出HsmsException。- 当收到对端发来的 Separate.req 时,
HsmsClient和HsmsSessionClient都会自动调用CloseAsync断开连接。 HsmsService收到主动端的 Select.req 时,会自动回复 Select.rsp(Success)并完成握手,无需手动处理。