4. SECS-I串行通信与协议转换

SECS-I(SEMI E4)是SECS/GEM体系中最早被标准化的物理层与数据链路层协议,它把SECS-II消息封装成定长块,通过RS-232串行链路在设备与主机之间传输。虽然现代300mm设备普遍采用HSMS(SEMI E37)走TCP/IP,但大量200mm及更早的设备、部分量测机台和特殊工艺设备仍然只提供SECS-I接口。做一致性测试时,必须理解SECS-I的块传输、握手、重试与超时机制,才能判断设备行为是否符合标准,也才能正确设计协议转换网关的测试用例。

块传输与握手信号

SECS-I把一条SECS-II消息切分成若干数据块,每块最大244字节(含10字节块头,实际数据最多234字节)。块头结构固定:设备ID(2字节)、消息ID(4字节,高2位为R-bit,低30位为消息编号)、块号(2字节,最高位为E-bit表示最后一块)。发送方按块号递增发送,接收方逐块确认。

握手采用独立的控制信号线,而不是数据字节:发送方拉低ENQ(请求发送),接收方若准备好则回EOT,否则回NAK;发送方收到EOT后发送数据块,接收方校验后回ACK或NAK。整个过程由RS-232的RTS/CTS/DTR/DSR等信号配合,形成严格的半双工交互。测试时最常观察的异常是:设备在收到EOT后长时间不发数据、收到NAK后不重发、或E-bit置位错误导致接收方一直等待后续块。

SECS-I 块传输与握手时序(单块消息示例) 发送方 (Host) 接收方 (Equipment) ENQ(请求发送) EOT(准备接收) 块头(10B) + 数据(≤234B) [E-bit=1] ACK(校验通过) 重试与超时分支(T1/T2/T3/T4) T1:等待EOT超时 → 重发ENQ(最多RTY次) T2:等待数据块超时 → 发NAK,要求重发 T3:等待ACK/NAK超时 → 重发当前块 T4:块间超时 → 判定链路中断,上报通信错误

重试机制与超时参数

SECS-I定义了四个关键超时参数,它们直接决定通信的鲁棒性,也是一致性测试的重点:

参数含义典型值测试关注点
T1发送ENQ后等待EOT的时间0.5~2 s超时后是否按RTY重发ENQ
T2接收方等待数据块的时间1~5 s超时是否回NAK而非静默
T3发送方等待ACK/NAK的时间1~5 s超时是否重发当前块
T4块与块之间的最大间隔2~10 s超时是否上报链路错误
RTY最大重试次数3~7超过后是否放弃并报错

测试时可以用串口监听工具人为制造超时:例如在设备发出ENQ后不回复EOT,观察主机是否在T1后重发ENQ,并统计重发次数是否等于RTY。若设备在RTY次后仍不报错,说明其重试逻辑不符合E4要求。

SECS-I与HSMS的差异对比

两者最根本的区别在于传输介质与连接模型。SECS-I是点对点串行链路,半双工,靠信号线握手;HSMS是TCP/IP上的全双工协议,用Select/Deslect或Separate模式管理连接,没有ENQ/EOT握手,而是用控制消息(Select.req、Linktest.req等)维持会话。SECS-I的块头包含设备ID和块号,HSMS的消息头包含Session ID、Header Byte 2/3、System Bytes和Status Bytes,字段语义完全不同。

从测试角度看,SECS-I的故障模式更偏物理层:线序错误、波特率不匹配、流控信号未连接都会导致握手失败;HSMS的故障则更多出现在TCP连接建立、Session ID冲突、超时重连等层面。协议转换网关必须同时处理这两套语义,把SECS-I的块重组为完整SECS-II消息,再封装成HSMS消息发送,反之亦然。

协议转换网关的测试要点

网关的核心职责是“块↔消息”和“串口↔TCP”的双向转换。测试时应重点覆盖以下场景:

  • 分块重组:构造一条超过234字节的SECS-II消息,验证网关能否正确按块号重组,E-bit判断是否准确。
  • 消息ID映射:SECS-I的消息ID为30位,HSMS的System Bytes为32位,验证映射后是否保持唯一性和可追溯性。
  • 超时传递:当SECS-I侧发生T3超时,网关应向HSMS侧返回何种错误?通常应生成S9F7(非法数据)或S9F9(事务超时)等错误消息。
  • 并发与缓冲:多台SECS-I设备接入同一网关时,验证串口队列和TCP会话是否隔离,避免消息串扰。
  • 异常恢复:拔掉串口线再插回,观察网关是否自动重建链路并恢复通信。

搭建SECS-I仿真环境并验证基本通信

搭建仿真环境需要三部分:串口物理层、SECS-I协议栈、SECS-II消息构造工具。以下给出一个基于Python的简化示例,使用pyserial模拟设备侧,主机侧用另一进程发送S1F1(Are You There)。

# 设备侧仿真(简化示意)
import serial, time

ser = serial.Serial(
    port='COM3', baudrate=9600,
    bytesize=8, parity='N', stopbits=1,
    timeout=1, rtscts=True
)

def recv_block():
    # 等待ENQ(实际需通过控制线判断,此处简化)
    time.sleep(0.1)
    ser.write(b'\x06')          # EOT
    header = ser.read(10)       # 块头
    if len(header) < 10:
        ser.write(b'\x15')      # NAK
        return None
    dev_id = int.from_bytes(header[0:2], 'big')
    msg_id = int.from_bytes(header[2:6], 'big')
    blk_no = int.from_bytes(header[6:8], 'big')
    e_bit  = (blk_no >> 15) & 1
    data   = ser.read(234)
    ser.write(b'\x06')          # ACK
    return dev_id, msg_id, blk_no, e_bit, data

print("SECS-I device simulator ready")
while True:
    result = recv_block()
    if result:
        print("recv:", result[:4])

主机侧发送S1F1时,消息体为01 01 00 00(Stream 1, Function 1, W-bit=0, 空消息体),加上块头后总长14字节,单块即可传完,E-bit置1。设备侧收到后应回复S1F2,消息体为01 02 00 00。验证时用串口调试助手观察字节流,确认ENQ/EOT/ACK的时序和块头字段是否正确。

判断通信是否成功的三个基本标志:① 主机发出ENQ后能在T1内收到EOT;② 数据块发送后能在T3内收到ACK;③ 设备回复的S1F2消息ID与主机发送的S1F1消息ID一致(SECS-I要求回复消息沿用请求的消息ID)。若三者都满足,说明基本链路和协议栈工作正常。

完成基本通信后,可以进一步注入异常:把设备侧波特率改为4800而主机保持9600,观察是否出现乱码和NAK;或在设备侧故意不回EOT,验证主机的T1重试和RTY上限。这些异常用例正是SECS-I一致性测试的核心内容,也是协议转换网关必须正确透传或转换的关键行为。