예외 응답
예외 응답(exception response)은 서버가 요청을 받았지만 처리하지 않았다는 정상적인 Modbus 응답입니다. PDComm에서 예외를 받은 request나 execute는 성공하며 결과가 다음과 같습니다.
{"ok":true,"result":{"response":[131,2],"source":"wire","status":"exception"}}response[0]은 요청 기능 코드 + 128(0x80)입니다. 131은 기능 03의 예외입니다.response[1]이 예외 코드입니다.- 애플리케이션은
ok만 보지 말고status를 확인합니다.
예외 코드의 정의는 PDU, ADU와 기능 코드에 있습니다.
01 Illegal Function
섹션 제목: “01 Illegal Function”PDComm 서버가 보내는 경우
- 지원하지 않는 기능 코드: 사용자 정의 코드(65
72, 100110), MEI 13, 정의되지 않은 코드. 예:5A→[218,1] - 지원하지 않는 진단 하위 기능(예: 19)이나 MEI 형식
- TCP 서버에 직렬 전용 기능(07, 08, 11, 12, 17)을 보낸 경우. 예:
0800001234→[136,1] - Modbus/TCP Security에서 클라이언트 역할에 허용되지 않은 기능. 예:
reader의 06 →[134,1] - 게이트웨이에 직렬 전용 기능을 보낸 경우
확인할 것
- 장비 매뉴얼이 그 기능 코드를 지원하는지 봅니다. 많은 장비가 03만 지원하고 04나 16은 지원하지 않습니다.
- TCP로 직렬 전용 기능을 쓰고 있지 않은지 봅니다.
- 보안 연결이라면 서버의
roles,null_role에 그 기능이 있는지, 클라이언트 인증서에 기대한 역할이 들어 있는지 봅니다.
02 Illegal Data Address
섹션 제목: “02 Illegal Data Address”PDComm 서버가 보내는 경우
- 시작 주소부터 수량만큼이 서버 모델의 테이블 범위를 벗어난 경우. 기본 모델은 테이블마다 0~1023입니다. 예:
0304000001→[131,2] - 없는 파일 번호나 레코드, 참조 형식이 6이 아닌 파일 요청
- 없는 FIFO 포인터 주소. 예:
1800FF→[152,2] - MEI 14 개별 읽기로 없는 객체를 요청한 경우
확인할 것
- 매뉴얼 주소를 PDU 주소로 바꿀 때 1을 뺐는지, 테이블 접두 숫자를 빼고 넣었는지 확인합니다. 잘못된 주소를 참고합니다.
- 장비는 연속된 주소 가운데 일부만 구현하는 경우가 많습니다. 여러 레지스터를 한 번에 읽다 02가 나면 범위를 나눠 읽어 봅니다.
- PDComm 서버라면
data_get으로 테이블의start와 값 개수를 확인합니다.
03 Illegal Data Value
섹션 제목: “03 Illegal Data Value”PDComm 서버가 보내는 경우
- 수량이 0이거나 최대 수량(읽기 비트 2000, 레지스터 125, 쓰기 비트 1968, 레지스터 123)을 넘은 경우. 예:
0300000000→[131,3] - 바이트 수와 실제 데이터 길이가 다른 경우. 예:
0F0000000101→[143,3] - 기능 05의 값이
FF00이나0000이 아닌 경우. 예:0500000001→[133,3] - PDU 길이가 기능에 맞지 않은 경우. 예:
030000→[131,3] - MEI 14 읽기 코드가 1~4 밖이거나, 개별 접근을 허용하지 않는 모델에 개별 읽기(4)를 보낸 경우
확인할 것
- PDU를 바이트 단위로 다시 셉니다. 16비트 값은 상위 바이트가 먼저입니다.
- 장비가 한 번에 읽을 수 있는 수량이 표준의 최대 수량보다 작을 수 있습니다. 매뉴얼의 최대 수량을 확인합니다.
04 Server Device Failure
섹션 제목: “04 Server Device Failure”서버가 요청을 처리하다 복구할 수 없는 오류를 만났습니다. PDComm 기본 서버는 내부 데이터가 일관되지 않을 때만 보내며, model_set 검사를 통과한 모델에서는 나오지 않습니다. 실제 장비에서 받았다면 장비의 상태와 진단 정보를 확인합니다.
05 Acknowledge, 06 Server Device Busy
섹션 제목: “05 Acknowledge, 06 Server Device Busy”- 05: 장비가 오래 걸리는 요청을 받아들였습니다. 결과는 나중에 다시 조회합니다. PDComm 서버는 보내지 않습니다.
- 06: 장비가 바쁩니다. PDComm 게이트웨이는 대기열(64개)이 가득 차면 06을 보냅니다.
두 경우 모두 쓰기를 무작정 다시 보내지 않습니다. 장비 매뉴얼이 정한 방법으로 상태를 확인한 뒤 애플리케이션이 다시 보낼지 정합니다.
08 Memory Parity Error
섹션 제목: “08 Memory Parity Error”파일 레코드 메모리에서 패리티 오류가 났습니다. PDComm 서버는 보내지 않습니다. 실제 장비라면 장비의 진단이나 수리 절차를 따릅니다.
0A Gateway Path Unavailable
섹션 제목: “0A Gateway Path Unavailable”PDComm이 보내는 경우
- PDComm TCP 서버가 구성의
unit도, 직접 주소 지정 값255(0xFF)나0도 아닌 유닛 식별자를 받은 경우. 예: 유닛 2 →[131,10] - PDComm 게이트웨이의
routes에 그 유닛이 없는 경우
확인할 것
- 클라이언트의 유닛 식별자를 서버의
unit이나 게이트웨이 경로에 맞춥니다. PDComm 서버에 직접 보낼 때는0xFF도 됩니다. 게이트웨이는0xFF를 경로에 넣어야 전달합니다. - 게이트웨이라면 경로 표에 TCP 유닛이 있는지 봅니다.
0B Gateway Target Device Failed to Respond
섹션 제목: “0B Gateway Target Device Failed to Respond”PDComm 게이트웨이가 보내는 경우
- 직렬 장비가 게이트웨이의
timeout_ms안에 응답하지 않았거나, 응답이 손상됐거나, 직렬 포트 오류가 난 경우 - 요청이 대기열에서 기다리는 동안 시간이 다 된 경우
확인할 것
- 경로의 직렬 주소에 실제로 장비가 있는지, 그 장비의 직렬 설정이 게이트웨이와 같은지 봅니다.
- 게이트웨이의
trace에서 그 주소로tx만 있고rx가 없는지 봅니다. - TCP 클라이언트의
timeout_ms를 게이트웨이의 직렬 대기 시간보다 길게 잡아야 0B를 시간 초과 대신 받습니다.
모르는 예외 코드
섹션 제목: “모르는 예외 코드”명세는 예외 코드 01~06, 08, 0A, 0B를 정의합니다. 장비가 그 밖의 코드(예: 옛 사양의 07이나 장비 전용 코드)를 보내도, 기능 코드 + 128 뒤에 코드 1바이트가 온 응답은 예외 응답입니다(Modbus Application Protocol V1.1b3 §7). PDComm 클라이언트는 이 응답도 "status":"exception"으로 돌려주고, response[1]에 받은 코드를 그대로 담습니다. 예: 기능 03에 코드 07 → [131,7]. 코드의 뜻은 장비 매뉴얼에서 확인합니다.