센서, 모터 등 컴퓨터가 아닌 기기의 상태를 보고 제어하기 위한 프로토콜에는 여러가지가 있다. 하지만 이중 가장 많이 쓰이는 프로토콜로는 Modbus를 꼽을 수 있다. 이번에는 이 사실상 표준(de facto standard) 프로토콜인 Modbus에 대해서 설명하고자 한다.
정의
Modbus는 OSI 7계층 중 응용 계층에서 사용되는 프로토콜로 여러 종류의 버스 혹은 네트워크에 있는 장치들 간 서버-클라이언트 통신을 할 때 쓰이는 프로토콜이다. 여기서 재밌는 점은 Modbus에서는 장치가 서버 역할이라는 점이다. 즉 장치를 제어하는 서버를 개발한다고 해도 Modbus에서는 서버가 클라이언트이고 연결된 장치가 서버이다. 펌웨어(혹은 PLC) 개발자와 소통할 때 헷갈리지 않도록 주의해야 한다.
모델
Modbus에서 다루는 데이터는 크게 네가지(Discretes Input, Coils, Input Registers, Holding Registers)로 나눌 수 있다.
각 항목별로 최대 65536개의 데이터(주소)를 가질 수 있으며 각 주소는 논리적으로 잘 매핑만 되어있으면 물리적으로 연속될 필요도 없다. 이 네가지 데이터는 다시 두가지 방식으로 분류할 수 있다.
우선 데이터의 단위를 기준으로 분류할 수 있다. Discretes Input과 Coils는 단위가 1비트로 참/거짓값을 표현하기 좋다. 반면 Input Registers와 Holding Registers는 단위가 2바이트로 수치값을 표현하기 좋다.
다른 방식으로 데이터의 소스에 따라 분류할 수 있다. Discretes Input과 Input Registers는 센서 등 기기로부터 데이터를 받는다. 여기서 핵심은 데이터를 쓰지 못한다는 것으로, 기기의 조작을 위해 데이터를 쓰기 위해서는 다른 데이터를 조작해야 한다. Coils와 Holding Registers가 바로 그것으로, 장치의 메모리 내 데이터를 의미한다. 해당 데이터는 정의하기에 따라 데이터를 읽고 쓸 수가 있으며 주로 계산된 값 출력이나 장치의 조작을 위해 사용된다.
위의 네가지 데이터를 읽고 쓰는 것이 사실상 프로토콜의 전부이며 나머지는 이를 보조하기 위한 기능이라 봐도 무방하다. 서버는 장치에서 제공하는 데이터 종류와 주소만 알고 있으면 장치의 상태를 읽거나 조작할 수 있다. 이러한 단순함 때문에 Modbus는 40년이라는 세월이 지나도 여전히 많은 장치에서 사용된다.
데이터 구조
Modbus 데이터는 통신 방식에 관계 없이 Modbus 명령을 정의하는 PDU(Protocol Data Unit)와 이를 포함하여 통신에 필요한 필드가 담긴 ADU(Application Data Unit)로 분류할 수 있다. 대략 다음과 같은 형태이다.
PDU
Function code
Function code는 요청을 통해 어떤 작업을 처리할 것인지 알려주는 역할을 한다. PDU의 앞 1바이트를 차지하며 1~127의 값을 갖는다. 몇몇 function code에는 추가적인 동작을 위해 sub-function code가 추가될 수 있다.
Function code 목록은 아래와 같다.
Function code가 많아서 당황스러울 수 있지만 전술했다시피 데이터를 읽고 쓰는 것이 핵심이므로 Bit access와 16 bits access 항목만 숙지하고 있으면 된다. 다른 Function code는 필요할 때만 찾아보면 된다.
Data
function code로 요청한 작업에 필요한 정보들을 제공하는 역할을 한다. 길이는 가변적이며 function code에 따라 생략될 수도 있다.
ADU
PDU와 해당 PDU를 사용할 장치를 특정하는 데에 쓰이는 정보(주소 정보, 에러 체크 비트)로 이루어져 있다. Modbus는 시리얼 통신(Modbus RTU)과 TCP 통신(Modbus TCP)을 모두 지원하며 각 통신 방법에 따라 PDU 외의 ADU 구조가 바뀐다.
마치며
이번에는 개론 같은 느낌으로 Modbus에 대해 다뤄보았다. 최대한 기술적인 명세를 제외하고 설명하다 보니 오히려 막연한 느낌이 드는 것 같다. 하지만 해당 글만 잘 숙지하면 언어에서 지원하는 라이브러리를 사용하는 데에는 큰 문제가 없을 것이다. 심화편에서는 좀 더 기술적인 명세와 세부적인 구조에 대해 설명해보겠다.