Modbus는 자동화 장치 간의 통신을 가능하게 하기 위해 1979년에 개발된 산업용 프로토콜입니다. 원래 직렬 계층을 통해 데이터를 전송하기 위한 애플리케이션 수준 프로토콜로 구현된 Modbus는 직렬, TCP/IP 및 사용자 데이터그램 프로토콜(UDP)을 통한 구현을 포함하도록 확장되었습니다.
Modbus 프로토콜이란?
Modbus는 마스터-슬레이브 관계를 사용하여 구현된 요청-응답 프로토콜입니다. 마스터-슬레이브 관계에서 통신은 항상 쌍으로 발생하며(한 장치는 요청을 시작한 다음 응답을 기다려야 함) 시작 장치(마스터)가 모든 상호 작용을 시작할 책임이 있습니다.
일반적으로 마스터는 HMI(Human Machine Interface) 또는 SCADA(Supervisory Control and Data Acquisition) 시스템이고 슬레이브는 센서, PLC(Programmable Logic Controller) 또는 PAC(Programmable Automation Controller)입니다.
이러한 요청 및 응답의 내용과 이러한 메시지가 전송되는 네트워크 계층은 프로토콜의 여러 계층에 의해 정의됩니다.
그림 1. 마스터-슬레이브 네트워킹 관계
Modbus 프로토콜의 계층
초기 구현에서 Modbus는 직렬 위에 구축된 단일 프로토콜이었기 때문에 여러 계층으로 나눌 수 없었습니다. 시간이 지남에 따라 직렬을 통해 사용되는 패킷 형식을 변경하거나 TCP/IP 및 UDP(사용자 데이터그램 프로토콜) 네트워크를 사용할 수 있도록 하기 위해 다양한 애플리케이션 데이터 단위가 도입되었습니다. 이로 인해 PDU(Protocol Data Unit)를 정의하는 핵심 프로토콜과 ADU(Application Data Unit)를 정의하는 네트워크 계층이 분리되었습니다.
PDU와 이를 처리하는 코드는 Modbus 애플리케이션 프로토콜 사양의 핵심을 구성합니다. 이 사양은 PDU의 형식, 프로토콜에서 사용하는 다양한 데이터 개념, 해당 데이터에 액세스하기 위한 함수 코드 사용, 각 기능 코드의 특정 구현 및 제한 사항을 정의합니다.
Modbus PDU 형식은 함수 코드와 관련 데이터 세트로 정의됩니다. 이 데이터의 크기와 내용은 함수 코드에 의해 정의되며 전체 PDU(함수 코드 및 데이터)의 크기는 253바이트를 초과할 수 없습니다. 모든 함수 코드에는 슬레이브가 원하는 애플리케이션 동작에 따라 유연하게 구현할 수 있는 특정 동작이 있습니다. PDU 사양은 데이터 액세스 및 조작에 대한 핵심 개념을 정의합니다. 그러나 슬레이브는 사양에 명시적으로 정의되지 않은 방식으로 데이터를 처리할 수 있습니다.
Modbus 및 Modbus 데이터 모델의 데이터 액세스
Modbus에서 액세스할 수 있는 데이터는 일반적으로 1개의 데이터 뱅크 또는 주소 범위(코일, 이산 입력, 홀딩 레지스터 및 입력 레지스터) 중 하나에 저장됩니다. 대부분의 사양과 마찬가지로 이름은 산업 또는 응용 프로그램에 따라 다를 수 있습니다.
예를 들어, 홀딩 레지스터는 출력 레지스터로 지칭될 수 있고, 코일은 디지털 또는 이산 출력으로 지칭될 수 있다. 이러한 데이터 뱅크는 포함된 데이터의 유형 및 액세스 권한을 정의합니다. 슬레이브 장치는 장치에서 로컬로 호스팅되는 이 데이터에 직접 액세스할 수 있습니다. Modbus에서 액세스할 수 있는 데이터는 일반적으로 장치 메인 메모리의 하위 집합입니다. 반대로 Modbus 마스터는 다양한 기능 코드를 통해 이 데이터에 대한 액세스를 요청해야 합니다.
메모리 블록 | 데이터 유형 | 마스터 액세스 | 슬레이브 액세스 |
코일 | 부울 | 읽기/쓰기 | 읽기/쓰기 |
이산 입력 | 부울 | 읽기 전용 | 읽기/쓰기 |
레지스터 보유 | 서명되지 않은 단어 | 읽기/쓰기 | 읽기/쓰기 |
입력 레지스터 | 서명되지 않은 단어 | 읽기 전용 | 읽기/쓰기 |
표 1. Modbus 데이터 모델 블록
이러한 블록은 다양한 데이터 요소에 대한 액세스를 제한하거나 허용할 수 있는 기능을 제공하며, 애플리케이션 계층에서 다양한 데이터 유형에 액세스할 수 있는 간소화된 메커니즘을 제공합니다.
지정된 시스템에서 별도의 메모리 주소로 존재할 수 있지만 겹칠 수도 있습니다. 예를 들어, 코일 1은 레지스터 1을 유지함으로써 표현되는 워드의 첫 번째 비트와 메모리에서 동일한 위치에 존재할 수 있다. 주소 지정 체계는 전적으로 슬레이브 장치에 의해 정의되며 각 메모리 블록에 대한 해석은 장치 데이터 모델의 중요한 부분입니다.
데이터 모델 주소 지정
사양은 각 블록을 최대 65,536개(216) 요소에서 찾을 수 있습니다. PDU의 정의 내에서 Modbus는 각 데이터 요소의 주소를 0에서 65,535 사이의 범위로 정의합니다. 그러나 각 데이터 요소는 1에서 n까지 번호가 매겨지며, 여기서 n의 최대값은 65,536입니다. 즉, 코일 1은 어드레스 0의 코일 블록에 있는 반면, 홀딩 레지스터(54)는 슬레이브가 홀딩 레지스터로 정의한 메모리 섹션의 어드레스(53)에 있습니다.
사양에서 허용하는 전체 범위는 지정된 장치에서 구현할 필요가 없습니다. 예를 들어, 장치는 코일, 이산 입력 또는 입력 레지스터를 구현하지 않고 대신 홀딩 레지스터(150 내지 175) 및 200 내지 225만 사용하도록 선택할 수 있다. 이는 완벽하게 허용되며 잘못된 액세스 시도는 예외를 통해 처리됩니다.
데이터 주소 지정 범위
사양은 서로 다른 데이터 유형을 서로 다른 블록에 존재하는 것으로 정의하고 각 유형에 로컬 주소 범위를 할당하지만, 이는 문서화 또는 주어진 장치의 Modbus 액세스 가능 메모리 이해를 위한 직관적인 주소 지정 체계로 반드시 변환되는 것은 아닙니다. 메모리 블록 위치에 대한 논의를 단순화하기 위해 해당 데이터의 주소에 접두사를 추가하는 번호 매기기 체계가 도입되었습니다.
예를 들어, 장치 설명서는 어드레스(14)에서 레지스터(13)를 보유하는 것과 같은 아이템을 언급하는 대신, 어드레스 4,014, 40,014, 또는 400,014에 있는 데이터 아이템을 참조할 것이다. 각각의 경우에 지정된 첫 번째 숫자는 보유 레지스터를 나타내는 4이고 주소는 나머지 숫자를 사용하여 지정됩니다. 4XXX, 4XXXX 및 4XXXXX의 차이는 디바이스에서 사용하는 주소 공간에 따라 다릅니다. 65,536개의 레지스터가 모두 사용 중인 경우 4,400에서 001,465 사이의 범위를 허용하므로 536XXXXX 표기법을 사용해야 합니다. 몇 개의 레지스터만 사용하는 경우 일반적으로 4,001에서 4,999 사이의 범위를 사용합니다.
이 주소 지정 체계에서 각 데이터 유형에는 표 2와 같이 접두사가 할당됩니다.
데이터 블록 | 접두사 |
코일 | 0 |
이산 입력 | 1 |
입력 레지스터 | 3 |
레지스터 보유 | 4 |
표 2. 데이터 범위 접두사
코일은 접두사 0으로 존재합니다. 이는 4001의 기준이 홀딩 레지스터 4001 또는 코일 6을 참조할 수 있음을 의미합니다. 이러한 이유로 모든 새로운 구현은 선행 400이 있는 001자리 주소 지정을 사용하고 설명서에 이를 기록하는 것이 좋습니다. 따라서, 홀딩 레지스터 4001은 004,001로 참조된다.
데이터 주소 시작 값
메모리 주소와 참조 번호 간의 차이는 지정된 응용 프로그램에서 선택한 인덱싱으로 인해 더욱 복잡해집니다. 앞서 언급했듯이 레지스터 400을 유지하는 것은 주소 001에 있습니다. 일반적으로 참조 번호는 00001 인덱스이며, 이는 지정된 범위의 시작 값이 0임을 의미합니다.
표 3에서는 이 개념을 보여 줍니다.
주소 | 등록 번호 | 숫자(1-인덱싱, 표준) | 숫자(0-인덱싱, 대체) |
0 | 1 | 400001 | 400000 |
1 | 2 | 400002 | 400001 |
2 | 3 | 400003 | 400002 |
표 3. 인덱싱 체계 등록Register Indexing Schemes
1 인덱싱된 범위는 일반적이며 강력히 권장됩니다. 두 경우 모두 각 범위의 시작 값을 설명서에 기록해야 합니다.
큰 데이터 형식
Modbus 표준은 부호 없는 단어 및 비트 값 이외의 추가 데이터 유형을 포함하지 않는 비교적 단순한 데이터 모델을 제공합니다. 비트 값이 솔레노이드 및 계전기에 해당하고 워드 값이 스케일링되지 않은 ADC 값에 해당하는 일부 시스템에서는 이 정도면 충분하지만 고급 시스템에서는 충분하지 않습니다. 결과적으로 많은 Modbus 구현에는 레지스터 경계를 교차하는 데이터 유형이 포함됩니다. NI LabVIEW Datalogging and Supervisory Control (DSC) Module과 KEPServerEX는 여러가지 참조 유형을 정의합니다.
예를 들어, 홀딩 레지스터에 저장된 문자열은 표준 형식(400,001)을 따르지만 그 뒤에는 문자열의 400진수, 길이 및 바이트 순서가 옵니다. 이는 각 요청의 크기가 유한하기 때문에 필요하므로 Modbus 마스터는 NULL과 같은 길이나 구분 기호를 검색하는 대신 문자열의 정확한 경계를 알아야 합니다.
비트 액세스
레지스터 경계를 넘는 데이터에 대한 액세스를 허용하는 것 외에도 일부 Modbus 마스터는 레지스터 내의 개별 비트에 대한 참조를 지원합니다. 이는 장치가 이진 데이터를 코일 및 개별 입력 범위로 분할할 필요 없이 동일한 메모리 범위에서 모든 유형의 데이터를 결합할 수 있도록 하기 때문에 유용합니다. 이것은 일반적으로 구현에 따라 소수점과 비트 인덱스 또는 숫자를 사용하여 참조됩니다.
데이터 엔디안
단정밀도 부동 소수점 값과 같은 다중 레지스터 데이터는 데이터를 두 레지스터로 분할하여 Modbus에서 쉽게 전송할 수 있습니다. 이것은 표준에 의해 정의되지 않기 때문에 이 분할의 엔디안(또는 바이트 순서)은 정의되지 않습니다. 부호 없는 각 단어는 표준을 충족하기 위해 네트워크(빅 엔디안) 바이트 순서로 전송되어야 하지만 많은 디바이스는 멀티바이트 데이터의 바이트 순서를 반대로 합니다. 그림 2는 특이하지만 유효한 예를 보여 줍니다.
그림 2. 여러 단어 데이터에 대한 바이트 순서 스왑
슬레이브가 메모리에 정보를 저장하는 방법을 이해하고 올바르게 디코딩하는 것은 마스터의 몫입니다. 설명서는 시스템에서 사용하는 단어 순서를 반영하는 것이 좋습니다. 엔디안은 구현의 유연성이 필요한 경우 기본 인코딩 및 디코딩 기능과 함께 시스템 구성 옵션으로 추가할 수도 있습니다.
문자열
스트링은 Modbus 레지스터에 쉽게 저장할 수 있습니다. 간단히 하기 위해 일부 구현에서는 문자열 길이가 3의 배수여야 하며 추가 공간은 null 값으로 채워야 합니다. 바이트 순서는 문자열 상호 작용의 변수이기도 합니다. 문자열 형식은 최종 값으로 NULL을 포함하거나 포함하지 않을 수 있습니다. 이러한 가변성의 예로, 일부 장치는 그림과 같이 데이터를 저장할 수 있습니다.
그림 3. Modbus 문자열의 바이트 순서 반전
함수 코드 이해
장치마다 크게 다를 수 있는 데이터 모델과 달리 기능 코드와 해당 데이터는 표준에 의해 명시적으로 정의됩니다. 각 함수는 패턴을 따릅니다. 먼저 슬레이브는 함수 코드, 데이터 주소 및 데이터 범위와 같은 입력을 검증합니다. 그런 다음 요청된 작업을 실행하고 코드에 적합한 응답을 보냅니다. 이 프로세스의 단계가 실패하면 요청자에게 예외가 반환됩니다. 이러한 요청에 대한 데이터 전송은 PDU입니다.
Modbus PDU
PDU는 252바이트 함수 코드와 최대 252바이트의 함수별 데이터로 구성됩니다.
그림 4. Modbus PDU
함수 코드는 유효성을 검사할 첫 번째 항목입니다. 요청을 수신하는 장치에서 기능 코드를 인식하지 못하면 예외로 응답합니다. 기능 코드가 승인되면 슬레이브 장치는 함수 정의에 따라 데이터를 분해하기 시작합니다.
패킷 크기가 253바이트로 제한되기 때문에 디바이스는 전송할 수 있는 데이터의 양에 제약을 받습니다. 가장 일반적인 함수 코드는 코드에 따라 슬레이브 데이터 모델에서 240바이트에서 250바이트 사이의 실제 데이터를 전송할 수 있습니다.
슬레이브 함수 실행
데이터 모델에 의해 정의된 바와 같이, 서로 다른 개념적 데이터 블록에 액세스하기 위해 서로 다른 함수가 정의됩니다. 일반적인 구현은 코드가 정적 메모리 위치에 액세스하도록 하는 것이지만 다른 동작을 사용할 수 있습니다. 예를 들어, 기능 코드 1(판독 코일) 및 3(판독 홀딩 레지스터)은 메모리에서 동일한 물리적 위치에 액세스할 수 있다. 대조적으로, 함수 코드 3(읽기 보유 레지스터) 및 16(기록 보유 레지스터)은 메모리에서 완전히 다른 위치에 액세스할 수 있습니다. 따라서 각 함수 코드의 실행은 슬레이브 데이터 모델 정의의 일부로 가장 잘 고려됩니다.
수행된 실제 동작에 관계없이 모든 슬레이브 장치는 각 요청에 대해 간단한 상태 다이어그램을 따라야 합니다. 그림 5는 코드 1, 읽기 코일에 대한 예를 보여줍니다.
그림 5. Modbus 프로토콜 사양에서 코일 상태 다이어그램 읽기
각 슬레이브는 함수 코드, 입력 수, 시작 주소, 전체 범위 및 실제로 읽기를 수행하는 슬레이브 정의 함수의 실행을 검증해야 합니다.
고정 주소 범위는 위의 상태 다이어그램에 표시되지만 실제 시스템의 요구 사항으로 인해 정의된 숫자와 다소 다를 수 있습니다. 경우에 따라 슬레이브 장치는 프로토콜에서 정의한 최대 바이트 수를 전송할 수 없습니다. 즉, 마스터가 0x07D0 입력을 요청할 수 있도록 허용하는 대신 0x0400로만 응답할 수 있습니다. 유사하게, 슬레이브 데이터 모델은 수용 가능한 코일 값들의 범위를 어드레스 0 내지 500으로서 정의할 수 있다. 마스터가 어드레스 125에서 시작하는 0에 대한 요청을 하는 경우, 이는 괜찮지만, 마스터가 어드레스 400에서 시작하는 동일한 요청을 하는 경우, 최종 코일은 어드레스 525에 있을 것이며, 이는 이 디바이스에 대한 범위를 벗어났고, 상태 다이어그램에 의해 정의된 바와 같이 예외 02를 초래할 것이다.
표준 기능 코드
각 표준 기능 코드의 정의는 사양에 있습니다. 가장 일반적인 기능 코드의 경우에도 마스터에서 활성화된 기능과 슬레이브가 처리할 수 있는 기능 사이에는 불가피한 불일치가 있습니다. 이 문제를 해결하기 위해 Modbus TCP 사양의 초기 버전에서는 세 가지 적합성 클래스를 정의했습니다. 공식 Modbus 적합성 테스트 사양은 이러한 클래스를 참조하지 않고 대신 기능별로 적합성을 정의합니다. 그러나 여전히 이해하기에 편리할 수 있습니다. 모든 문서는 테스트 사양을 따르고 레거시 분류가 아닌 지원하는 코드에 따라 적합성을 정의하는 것이 좋습니다.
클래스 0 코드는 마스터에게 데이터 모델에서 읽거나 쓸 수 있는 기능을 제공하기 때문에 일반적으로 유용한 Modbus 장치의 최소값으로 간주됩니다.
코드 | 묘사 |
3 | 다중 레지스터 읽기 |
16 | 여러 레지스터 쓰기 |
표 4. 적합성 클래스 0 코드
클래스 1 함수 코드는 데이터 모델의 모든 유형에 액세스하는 데 필요한 다른 코드로 구성됩니다. 원래 정의에서 이 목록에는 함수 코드 7(예외 읽기)이 포함되었습니다. 그러나 이 코드는 현재 사양에 의해 직렬 전용 코드로 정의됩니다.
코드 | 묘사 |
1 | 코일 읽기 |
2 | 이산 입력 읽기 |
4 | 입력 레지스터 읽기 |
5 | 단일 코일 쓰기 |
6 | 단일 레지스터 쓰기 |
7 | 읽기 예외 상태(직렬 전용) |
표 5. 적합성 클래스 1 코드
클래스 2 함수 코드는 덜 일반적으로 구현되는 보다 전문화된 함수입니다. 예를 들어 읽기/쓰기 다중 레지스터는 총 요청-응답 주기 수를 줄이는 데 도움이 될 수 있지만 클래스 0 코드를 사용하여 동작을 구현할 수 있습니다.
코드 | 묘사 |
15 | 여러 코일 쓰기 |
20 | 파일 레코드 읽기 |
21 | 파일 레코드 쓰기 |
22 | 마스크 쓰기 레지스터 |
23 | 읽기/쓰기 다중 레지스터 |
24 | FIFO 읽기 |
표 6. 적합성 클래스 2 코드
Modbus 캡슐화 인터페이스(MEI) 코드, 기능 43은 Modbus 패킷 내에서 다른 데이터를 캡슐화하는 데 사용됩니다. 현재 13(CANopen)과 14(장치 식별)의 두 가지 MEI 번호를 사용할 수 있습니다.
기능 43/14(장치 식별)는 최대 256개의 고유한 개체를 전송할 수 있다는 점에서 유용합니다. 이러한 개체 중 일부는 공급업체 이름 및 제품 코드와 같이 미리 정의되고 예약되어 있지만 애플리케이션은 일반 데이터 집합으로 전송할 다른 개체를 정의할 수 있습니다.
예외
슬레이브는 잘못된 형식의 요청에서 잘못된 입력에 이르기까지 여러 가지 잘못된 조건을 나타내기 위해 예외를 사용합니다. 그러나 잘못된 요청에 대한 응용 프로그램 수준 응답으로 예외가 생성될 수도 있습니다. 슬레이브는 예외와 함께 발행된 요청에 응답하지 않습니다. 대신 슬레이브는 불완전하거나 손상된 요청을 무시하고 새로운 수신 메시지를 기다리기 시작합니다.
예외는 정의된 패킷 형식으로 보고됩니다. 먼저, 함수 코드는 최상위 비트 세트를 제외하고 원래 함수 코드와 동일한 요청 마스터로 반환됩니다. 이는 원래 함수 코드의 값에 0x80 추가하는 것과 같습니다. 주어진 함수 응답과 관련된 일반 데이터 대신에, 예외 응답은 단일 예외 코드를 포함한다.
표준 내에서 가장 일반적인 네 가지 예외 코드는 01, 02, 03 및 04입니다. 표 7에는 각 함수별 표준 의미와 함께 나와 있습니다.
예외 코드 | 의미 |
01 | 수신된 함수 코드가 지원되지 않습니다. 원래 함수 코드를 확인하려면 반환된 값에서 0x80 뺍니다. |
02 | 요청이 잘못된 주소에 액세스하려고 했습니다. 표준에서는 시작 주소와 요청 된 값 수가 2를 초과하는 경우에만 발생할 수 있습니다16. 그러나 일부 디바이스는 데이터 모델에서 이 주소 공간을 제한할 수 있습니다. |
03 | 요청에 잘못된 데이터가 있습니다. 경우에 따라 이는 전송된 레지스터 수와 "바이트 수" 필드 사이에 매개변수 불일치가 있음을 의미합니다. 더 일반적으로 마스터는 슬레이브 또는 프로토콜이 허용하는 것보다 더 많은 데이터를 요청했습니다. 예를 들어 마스터는 한 번에 125개의 보유 레지스터만 읽을 수 있으며 리소스가 제한된 장치는 이 값을 더 적은 수의 레지스터로 제한할 수 있습니다. |
04 | 요청을 처리하는 동안 복구할 수 없는 오류가 발생했습니다. 이것은 요청이 유효하지만 슬레이브가 실행할 수 없음을 나타내는 포괄적인 예외 코드입니다. |
표 7. 일반적인 Modbus 예외 코드
모든 함수 코드의 상태 다이어그램은 최소한 예외 코드 01을 포함해야 하며 일반적으로 예외 코드 04, 02, 03을 포함하며 기타 정의된 예외 코드는 선택 사항입니다.
응용 프로그램 데이터 단위
Modbus 프로토콜의 PDU 코어에 정의된 기능 외에도 여러 네트워크 프로토콜을 사용할 수 있습니다. 가장 일반적인 프로토콜은 직렬 및 TCP/IP이지만 UDP와 같은 다른 프로토콜도 사용할 수 있습니다. 이러한 계층을 통해 Modbus에 필요한 데이터를 전송하기 위해 Modbus에는 각 네트워크 프로토콜에 맞게 조정된 ADU 변형 세트가 포함되어 있습니다.
공통 기능
Modbus는 안정적인 통신을 제공하기 위해 특정 기능이 필요합니다. 장치 ID 또는 주소는 각 ADU 형식에서 애플리케이션 계층에 라우팅 정보를 제공하는 데 사용됩니다. 각 ADU에는 주어진 요청에 대한 함수 코드 및 관련 데이터를 포함하는 전체 PDU가 함께 제공됩니다. 안정성을 위해 각 메시지에는 오류 검사 정보가 포함됩니다. 마지막으로, 모든 ADU는 요청 프레임의 시작과 끝을 결정하는 메커니즘을 제공하지만 이를 다르게 구현합니다.
표준 형식
세 가지 표준 ADU 형식은 TCP, RTU(원격 터미널 장치) 및 ASCII입니다. RTU 및 ASCII ADU는 전통적으로 직렬 회선을 통해 사용되는 반면 TCP는 최신 TCP/IP 또는 UDP/IP 네트워크에서 사용됩니다.
TCP/IP (영문)TCP ADU는 Modbus PDU와 연결된 MBAP(Modbus Application Protocol) 헤더로 구성됩니다. MBAP는 신뢰할 수 있는 네트워킹 계층에 따라 달라지는 범용 헤더입니다. 헤더를 포함한 이 ADU의 형식은 그림 6에 나와 있습니다.
그림 6. TCP/IP ADU
헤더의 데이터 필드는 해당 사용을 나타냅니다. 먼저, 트랜잭션 식별자를 포함한다. 이는 여러 요청이 동시에 처리될 수 있는 네트워크에서 유용합니다. 즉, 마스터는 요청 1, 2 및 3을 보낼 수 있습니다. 나중에 슬레이브는 2, 1, 3의 순서로 응답할 수 있고 마스터는 요청을 응답과 일치시키고 데이터를 정확하게 구문 분석할 수 있습니다. 이는 이더넷 네트워크에 유용합니다.
프로토콜 식별자는 일반적으로 0이지만 프로토콜의 동작을 확장하는 데 사용할 수 있습니다. 길이 필드는 프로토콜에서 나머지 패킷의 길이를 설명하는 데 사용됩니다. 또한 이 요소의 위치는 신뢰할 수 있는 네트워킹 계층에서 이 헤더 형식의 종속성을 나타냅니다. TCP 패킷에는 오류 검사 기능이 내장되어 있고 데이터 일관성 및 전달을 보장하므로 패킷 길이는 헤더의 아무 곳에나 위치할 수 있습니다.
직렬 네트워크와 같이 본질적으로 안정성이 떨어지는 네트워크에서는 패킷이 손실될 수 있으며, 이로 인해 애플리케이션에서 읽은 데이터 스트림에 유효한 트랜잭션 및 프로토콜 정보가 포함되어 있더라도 길이 정보가 손상되면 헤더가 유효하지 않게 됩니다. TCP는 이러한 상황에 대해 적절한 수준의 보호를 제공합니다.
장치 ID는 일반적으로 TCP/IP 장치에 사용되지 않습니다. 그러나 Modbus는 Modbus 프로토콜을 다른 프로토콜로 변환하는 많은 게이트웨이가 개발될 정도로 일반적인 프로토콜입니다. 원래 의도된 사용 사례에서 Modbus TCP/IP-직렬 게이트웨이를 사용하여 새 TCP/IP 네트워크와 이전 직렬 네트워크 간의 연결을 허용할 수 있습니다. 이러한 환경에서 장치 ID는 PDU가 실제로 의도한 슬레이브 장치의 주소를 결정하는 데 사용됩니다.
마지막으로, ADU는 PDU를 포함한다. 이 PDU의 길이는 표준 프로토콜의 경우 여전히 253바이트로 제한됩니다.
RTU ADU
RTU ADU는 그림 7에서 볼 수 있듯이 훨씬 더 단순해 보입니다.
그림 7. RTU ADU
더 복잡한 TCP/IP ADU와 달리 이 ADU에는 핵심 PDU 외에 두 가지 정보만 포함됩니다. 첫째, 주소는 PDU가 의도한 슬레이브를 정의하는 데 사용됩니다. 대부분의 네트워크에서 주소 0은 "브로드캐스트" 주소를 정의합니다. 즉, 마스터는 주소 0에 출력 명령을 보낼 수 있으며 모든 슬레이브는 요청을 처리해야 하지만 슬레이브는 응답하지 않아야 합니다. 이 주소 외에도 CRC는 데이터의 무결성을 보장하는 데 사용됩니다.
그러나 보다 현대적인 구현에서 상황의 현실은 단순하지 않습니다. 패킷을 브라케팅하는 것은 한 쌍의 무음 시간, 즉 버스에서 통신이 없는 기간입니다. 전송 속도가 9,600인 경우 이 속도는 약 4ms입니다. 이 표준은 전송 속도에 관계없이 최소 소음 길이를 2ms 미만으로 정의합니다.
첫째, 패킷이 처리되기 전에 장치가 유휴 시간이 완료될 때까지 기다려야 하기 때문에 성능상의 단점이 있습니다. 그러나 더 위험한 것은 직렬 전송에 사용되는 다양한 기술의 도입과 표준이 도입되었을 때보다 훨씬 빠른 전송 속도입니다. 예를 들어 USB-직렬 변환기 케이블을 사용하면 데이터의 패킷화 및 전송을 제어할 수 없습니다. 테스트 결과, NI-VISA 드라이버와 함께 USB-시리얼 케이블을 사용하면 데이터 스트림에 다양한 크기의 큰 갭이 생기고, 이러한 갭(침묵 기간)은 스펙 준수 코드를 속여 메시지가 완전하다고 믿게 만듭니다. 메시지가 완전하지 않기 때문에 일반적으로 잘못된 CRC가 발생하고 디바이스가 ADU를 손상된 것으로 해석합니다.
전송 문제 외에도 최신 드라이버 기술은 직렬 통신을 크게 추상화하며 일반적으로 애플리케이션 코드에서 폴링 메커니즘이 필요합니다. 예를 들어, .NET Framework 4.5 SerialPort 클래스나 NI-VISA 드라이버는 포트의 바이트를 폴링하는 경우를 제외하고 시리얼 라인에서 무음을 감지하는 메커니즘을 제공하지 않습니다. 이로 인해 성능 저하(폴링이 너무 느리게 수행되는 경우) 또는 높은 CPU 사용량(폴링이 너무 빨리 수행되는 경우)의 슬라이딩 스케일이 발생합니다.
이러한 문제를 해결하는 일반적인 방법은 Modbus PDU와 네트워킹 계층 간의 추상화 계층을 분리하는 것입니다. 즉, 시리얼 코드는 Modbus PDU 패킷을 조사하여 기능 코드를 결정합니다. 패킷의 다른 데이터와 결합하여 나머지 패킷의 길이를 검색하고 패킷의 끝을 결정하는 데 사용할 수 있습니다. 이 정보를 사용하면 훨씬 더 긴 시간 제한을 사용할 수 있으므로 전송 간격이 허용되고 애플리케이션 수준 폴링이 훨씬 더 느리게 발생할 수 있습니다. 이 메커니즘은 새로운 개발에 권장됩니다. 이를 사용하지 않는 코드에서는 예상보다 많은 수의 "손상된" 패킷이 발생할 수 있습니다
.
그림 8. ASCII ADU
패킷 크기를 결정하는 문제를 해결하기 위해 ASCII ADU에는 각 패킷에 대해 잘 정의되고 고유한 시작과 끝이 있습니다. 즉, 각 패킷은 ":"로 시작하고 CR(캐리지 리턴) 및 LF(줄 바꿈)로 끝납니다. 또한 NI-VISA 및 .NET Framework SerialPort 클래스와 같은 시리얼 API는 CR/LF와 같은 특정 문자가 수신될 때까지 버퍼의 데이터를 쉽게 읽을 수 있습니다. 이러한 기능을 통해 최신 애플리케이션 코드에서 직렬 라인의 데이터 스트림을 효율적으로 쉽게 처리할 수 있습니다.
ASCII ADU의 단점은 모든 데이터가 ASCII로 인코딩된 3진수 문자로 전송된다는 것입니다. 이렇게 하면 사람이 더 쉽게 읽을 수 있을 뿐만 아니라 직렬 네트워크를 통해 두 배의 데이터를 전송해야 하고 송수신 응용 프로그램이 ASCII 값을 구문 분석할 수 있어야 합니다.
Modbus 확장
비교적 단순하고 개방적인 표준인 Modbus는 주어진 애플리케이션의 요구 사항에 맞게 수정할 수 있습니다. 이는 단일 조직이 프로토콜의 두 엔드포인트를 모두 제어할 수 있는 상황이기 때문에 HMI와 PLC 또는 PAC 간의 통신에 가장 일반적입니다. 예를 들어, 센서 개발자는 일반적으로 슬레이브의 구현만 제어하고 상호 운용성이 바람직하기 때문에 서면 표준을 준수할 가능성이 더 큽니다.
일반적으로 프로토콜을 수정하는 것은 권장되지 않습니다. 이 섹션은 다른 사람들이 프로토콜의 동작을 조정하는 데 사용한 메커니즘에 대한 승인으로 제공될 뿐입니다.
새 함수 코드
일부 기능 코드가 정의되어 있지만 Modbus 표준을 사용하면 추가 기능 코드를 개발할 수 있습니다. 특히, 함수 코드 1 내지 64, 73 내지 99 및 111 내지 127은 유보되고 고유하도록 보장되는 공용 코드이다. 나머지 코드(65 - 72 및 100 - 110)는 사용자 정의 용도입니다. 이러한 사용자 정의 코드를 사용하면 모든 데이터 구조를 사용할 수 있습니다. 데이터는 Modbus PDU의 표준 253바이트 제한을 초과할 수도 있지만 PDU가 표준 제한을 초과할 때 다른 레이어가 예상대로 작동하는지 확인하기 위해 전체 애플리케이션의 유효성을 검사해야 합니다. 127 이상의 함수 코드는 예외 응답용으로 예약되어 있습니다.
네트워크 계층
Modbus는 직렬 및 TCP 외에도 많은 네트워크 계층에서 실행할 수 있습니다. UDP는 Modbus 통신 스타일에 적합하기 때문에 잠재적인 구현입니다. Modbus는 기본적으로 메시지 기반 프로토콜이므로 시작 문자나 길이와 같은 추가 애플리케이션 수준 정보 없이 잘 정의된 정보 패킷을 보낼 수 있는 UDP의 기능은 Modbus를 구현하기가 매우 간단합니다.
추가 ADU를 요구하거나 기존 ADU를 재사용하는 대신 표준 UDP API를 사용하여 Modbus PDU 패킷을 전송하고 다른 쪽 끝에서 완전히 형성된 상태로 수신할 수 있습니다. TCP는 승인 시스템이 내장되어 있기 때문에 일부 프로토콜에 유리하지만 Modbus는 애플리케이션 계층에서 승인을 수행합니다. 그러나 이러한 방식으로 UDP를 사용하면 TCP ADU의 트랜잭션 식별자 필드가 제거되므로 여러 개의 동시 미해결 트랜잭션이 발생할 가능성이 없습니다.
따라서 마스터는 동기 마스터이거나 UDP 패킷에 마스터가 요청 및 응답을 구성하는 데 도움이 되는 식별자가 있어야 합니다. UDP 네트워크 계층에서 TCP/IP ADU를 사용하는 것이 좋습니다.
ADU 수정
마지막으로, 애플리케이션은 ADU를 수정하거나 TCP와 같은 기존 ADU의 사용되지 않는 부분을 사용하도록 선택할 수 있습니다. 예를 들어 TCP는 16비트 길이 필드, 16비트 프로토콜 및 8비트 단위 ID를 정의합니다. 가장 큰 Modbus PDU가 253바이트라는 점을 감안할 때 길이 필드의 상위 바이트는 항상 9입니다. Modbus/TCP의 경우 프로토콜 필드와 장치 ID는 항상 0입니다.
그림 9. TCP ADU의 샘플 수정
'데이터계측분석 > 데이터통신 기술자료' 카테고리의 다른 글
시리얼 통신 기본 - RS-232 / RS-422 / RS-485 (0) | 2023.05.10 |
---|---|
모드버스(Modbus) 장단점 (0) | 2023.05.06 |
OPC UA(Unified Architecture) (0) | 2023.05.05 |
시리얼 통신의 루프백 테스트 (0) | 2023.04.18 |
어플리케이션 사이에서 데이터 스트리밍하기 및 명령 전송하기 (0) | 2023.04.13 |