SECS-I
SECS-I(SEMI E4)는 RS-232 직렬 회선으로 SECS-II 메시지를 보내는 방법입니다. HSMS보다 오래된 방식이지만 기존 장비에는 아직 많이 남아 있습니다. 회선은 두 장치를 일대일로 잇습니다. 메시지는 블록(block)으로 나뉘어 하나씩 전달되고, 블록마다 확인 응답을 받습니다.
블록 구조
섹션 제목: “블록 구조”블록 하나는 길이 바이트, 10바이트 헤더, 최대 244바이트 데이터, 2바이트 체크섬(checksum)으로 이뤄집니다(SEMI E4, 블록 형식).
+--------+-------------------------------+------------------+----------+| length | header (10 bytes) | data (0..244) | checksum || 1 byte | | | 2 bytes |+--------+-------------------------------+------------------+----------+
header byte 1 2 3 4 5 6 7..10 R-bit + device ID W-bit + function E-bit + block no. system bytes device ID (low 8) stream block no. (low 8) (high 7) (high 7)- 길이 바이트는 헤더와 데이터의 바이트 수입니다. 10–254 범위입니다.
- R 비트(reverse bit)는 메시지 방향입니다. 1이면 장비에서 호스트로, 0이면 호스트에서 장비로 가는 메시지입니다.
- E 비트(end bit)는 메시지의 마지막 블록에 켜집니다.
- 블록 번호(block number)는 여러 블록으로 나뉜 메시지에서 1부터 차례로 붙습니다.
- 체크섬은 헤더와 데이터 바이트를 모두 더한 16비트 값입니다.
244바이트보다 큰 메시지는 여러 블록으로 나뉩니다(multi-block message). 받는 쪽은 블록을 순서대로 모아 하나의 메시지로 다시 조립합니다.
회선 제어
섹션 제목: “회선 제어”SECS-I는 네 개의 제어 문자로 회선 사용권을 주고받습니다.
| 문자 | 값 | 의미 |
|---|---|---|
| ENQ | 05h |
보낼 블록이 있다는 요청 |
| EOT | 04h |
받을 준비가 됐다는 응답 |
| ACK | 06h |
블록을 정상적으로 받음 |
| NAK | 15h |
블록에 오류가 있음 |
블록 하나는 다음 순서로 전달됩니다.
Sender Receiver | ------------ ENQ --------------> | | <----------- EOT --------------- | within T2 | ---- length, header, data, ----> | characters within T1 | checksum | | <----------- ACK (or NAK) ------ | within T2- 송신자는 NAK를 받거나 T2 안에 응답이 없으면 같은 블록을 다시 보냅니다. 재시도 한도(retry limit, RTY)를 넘으면 전송이 실패합니다.
- 양쪽이 동시에 ENQ를 보내면 경합(contention)입니다. 마스터(master) 쪽은 계속 보내고, 슬레이브(slave) 쪽은 양보하고 먼저 받습니다. E4의 배치는 장비가 마스터, 호스트가 슬레이브입니다.
타이머
섹션 제목: “타이머”| 타이머 | 이름 | 의미 |
|---|---|---|
| T1 | 문자 간 타임아웃(intercharacter timeout) | 블록을 받는 동안 문자 사이의 최대 간격 |
| T2 | 프로토콜 타임아웃(protocol timeout) | ENQ 뒤 EOT, 블록 뒤 ACK/NAK를 기다리는 시간 |
| T3 | 응답 타임아웃(reply timeout) | W 비트 메시지의 응답 메시지를 기다리는 시간 |
| T4 | 블록 간 타임아웃(interblock timeout) | 여러 블록 메시지에서 다음 블록을 기다리는 시간 |
PDComm의 SECS-I 끝점
섹션 제목: “PDComm의 SECS-I 끝점”PDComm의 SECS-I 끝점은 직렬 포트를 직접 열지 않습니다. 애플리케이션이 읽기(read)와 쓰기(write) 콜백(callback)을 제공하고, 끝점은 그 콜백으로 바이트를 주고받습니다. 그래서 같은 코드로 실제 COM 포트, 가상 직렬 포트, 메모리 안의 시험 회선을 모두 다룰 수 있습니다.
- 콜백은 막히지 않아야(non-blocking) 합니다. 읽을 데이터가 없으면
PDCOMM_SECS1_IO_WOULD_BLOCK을 돌려줍니다. - 콜백은
poll안에서만 동기적으로 호출됩니다. 끝점의 모든 함수는 끝점을 만든 스레드에서 호출해야 하며, 콜백 안에서 끝점 함수를 다시 호출하면PDCOMM_INVALID_STATE가 됩니다. - 시간은 애플리케이션이
poll에 넘기는 틱(tick) 값입니다. 타이머 옵션도 같은 틱 단위입니다. .NET 작업자는 밀리초를 틱으로 씁니다. - 결과는 이벤트로 나옵니다. 메시지 수신(
INBOUND), 송신 완료(OUTBOUND_COMPLETE), 송신 실패(OUTBOUND_FAILED), 회선 오류(FAULT)입니다.
PdcommSecs1Options의 타이머 필드는 E4 타이머에 다음처럼 대응합니다.
| PDComm 필드 | E4 | 설명 |
|---|---|---|
priority |
마스터/슬레이브 | 경합 때 누가 양보할지 정합니다(PDCOMM_SECS1_MASTER, PDCOMM_SECS1_SLAVE). |
retry_limit |
RTY | 블록 재전송 한도 |
grant_wait_ticks |
T2 | 보낸 ENQ에 대한 EOT를 기다리는 시간 |
ack_wait_ticks |
T2 | 보낸 블록에 대한 ACK/NAK, 보낸 EOT 뒤 길이 바이트를 기다리는 시간 |
inbound_progress_ticks |
T1 | 블록을 받는 동안 문자 사이 간격 |
inter_block_ticks |
T4 | 여러 블록 메시지에서 다음 블록까지 간격 |
SECS-I 끝점은 블록 전송을 처리하고 메시지를 전달합니다. 요청과 응답은 애플리케이션이 시스템 바이트로 짝짓고, W 비트 메시지의 응답 타임아웃(T3)도 애플리케이션이 잽니다.
메시지를 보낼 때는 장치 ID, 방향(PDCOMM_SECS1_TO_HOST 또는 PDCOMM_SECS1_TO_EQUIPMENT), 스트림, 펑션, W 비트, 시스템 바이트, 본문을 지정해 pdcomm_secs1_submit를 호출합니다. 본문이 옵션의 본문 크기 한도(max_outbound_body_bytes, max_body_bytes)나 블록 수 한도(max_outbound_blocks, max_blocks)를 넘으면 PDCOMM_LIMIT_EXCEEDED가 돌아옵니다. E4는 ENQ/EOT/ACK/NAK가 아닌 바이트를 회선 제어에서 무시하도록 정합니다. PDComm은 이런 바이트를 세고 선택형 진단 로그에 남깁니다.
언어별 API
섹션 제목: “언어별 API”- C:
pdcomm_secs1_create로 끝점을 만들고pdcomm_secs1_poll로 진행시킵니다. 만들기와 시작에는secs-gem모듈 라이선스가 필요합니다(라이선스 설치와 확인). - C++:
Secs1Endpoint는 콜백을 타입 안전하게 감싸고, C 함수 포인터 밖으로 예외가 새지 않게 막습니다. - .NET:
Secs1Worker는 전용 스레드에서 끝점을 만들고poll을 반복합니다.StartAsync,SubmitAsync,ReadEventsAsync,StopAsync,ResetAsync,DisposeAsync를 제공합니다. 작업자는 직렬 포트를 열거나 닫지 않습니다. 콜백은 빨리 반환해야 하고 작업자 메서드를 다시 호출하면 안 됩니다.
가상 회선으로 시험하기
섹션 제목: “가상 회선으로 시험하기”실제 직렬 장비가 없어도 SECS-I를 시험할 수 있습니다.
- 메모리 가상 쌍(virtual pair): 시뮬레이터는 호스트 쪽(슬레이브)과 장비 쪽(마스터) SECS-I 끝점을 메모리 안의 회선으로 연결합니다. GUI 시뮬레이터의 SECS-I 작업 공간, MCP 서버, headless 시뮬레이터의
secs1-virtual-pair시나리오가 이 쌍을 씁니다. 블록 분할, 재조립, 회선 오류 주입(fault injection)을 직렬 포트 없이 확인합니다. - 가상 직렬 포트: 실제 COM 포트처럼 동작하는 포트 쌍이 필요하면 PDComm 도구의 가상 직렬 포트를 씁니다. 애플리케이션은 일반 직렬 포트처럼 열고, SECS-I 끝점의 콜백에서 그 포트를 읽고 씁니다.
시뮬레이터 사용법은 SECS/GEM 가이드에서 설명합니다.