시리얼 통신에서 제가 애용하는 DLE 프로토콜을 소개하려합니다. 원래 전문 용어가 있을 텐데, 알지는 못하고 키 코드 이름이 DLE인 0x10을 이용하여 아스키 데이터 뿐만 아니라 8bit 모두 사용하는 바이너리 데이터를 보낼 수 있는 프로토콜로 구성까지 간단해서 제가 애용하고 있습니다.
DEL 프로토콜
시리얼은 상대방의 수신 상태를 모르기 때문에 자료의 시작과 종료를 상대 편에 알려 주어야 한다는 말씀은 이전에 드렸습니다. 즉, 아래와 같은 문제 때문이죠.
이 문제를 해결하기 위해 STX와 ETX를 이용하여 전송 데이터의 시작과 종료를 알려 줍니다. 그러낟 보니 데이터에서 STX와 ETX코드가 들어가는 것을 막기 위해, 7bit 통신을 하거나 Length를 알려 주는 식으로 처리한다는 것과 각각의 문제점에 대해서 말씀을 드렸습니다.
생각해 보면, 데이터를 7bit를 사용하는 것이나, 길이를 알려 주는 것 모두 STX나 ETX 같은 구분코드를 사용해야 하기 때문에 발생하는 문제점을 피하기 위한 방법입니다.
그래서 나온 것이 DLE(0x10) 코드를 구분 코드 앞에 붙여서, 0x10 0x02 라고 전송해 줌으로써 데이터의 시작을 알려 주고, 0x10 0x03 으로 데이터의 종료임을 알려 주는 방법입니다. 그리고 데이터에 0x10 이 있다면 2번 연속해서 전송합니다.
STX |
DATA |
ETX |
0x10 0x02 | 데이터 중에 0x10 이 있다면 2번 연속해서 전송 | 0x10 0x03 |
수신하는 쪽은 0x10 이 수신되면 구분코드 수신을 준비합니다. 다음 바이트가 0x10이면 데이터로서 0x10으로 처리하고, 다른 값이면 약속된 구분 코드로 판단하여 처리합니다.
전송 예제
예를 들어 아래와 같은 값이 송신되었습니다. 수신하는 측은 다음과 같이 처리하게 됩니다.
수신 데이터 | 0x34 | 0x40 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x03 | 0x10 | 0x03 |
수신 버퍼 |
0x10을 만나기 전 까지의 0x34, 0x40은 아무 의미가 없으므로 버림합니다.
수신 데이터 | 0x34 | 0x40 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x03 | 0x10 | 0x03 |
수신 버퍼 |
0x10 을 수신했기 때문에 다음 수신 데이터를 확인합니다. 데이터의 시작 0x02 이므로 자료 수신을 시작합니다.
- 자료 수신을 시작 -
다음 바이트가 0x00 이므로 수신 버퍼에 넣습니다.
수신 데이터 | 0x34 | 0x40 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x03 | 0x10 | 0x03 |
수신 버퍼 | 0x00 |
다른 바이트가 0x10 이므로 다음 바이트를 확인합니다. 다음 바이트가 중복된 0x10이므로 데이터 0x10으로 판단하여 수신 버퍼에 넣습니다.
수신 데이터 | 0x34 | 0x40 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x03 | 0x10 | 0x03 |
수신 버퍼 | 0x00 | 0x10 |
다음은 0x02, 0x00은 데이터이므로 바로 수신 버퍼에 넣습니다.
수신 데이터 | 0x34 | 0x40 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x03 | 0x10 | 0x03 |
수신 버퍼 | 0x00 | 0x10 | 0x02 | 0x00 |
다음 데이터를 보니 0x10입니다. 역시 다음 데이터를 확인해 봅니다. 역시 0x10 이기 때문에 자료로서의 0x10으로 판단하고 수신 버퍼에 넣습니다.
수신 데이터 | 0x34 | 0x40 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x03 | 0x10 | 0x03 |
수신 버퍼 | 0x00 | 0x10 | 0x02 | 0x00 | 0x10 |
다음 0x03은 데이터이므로 수신 버퍼에 넣습니다.
수신 데이터 | 0x34 | 0x40 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x03 | 0x10 | 0x03 |
수신 버퍼 | 0x00 | 0x10 | 0x02 | 0x00 | 0x10 | 0x03 |
다음 바이트는 0x10 이므로 뒤에 따라오는 바이트를 확인합니다. 0x10이 아니라 0x03 이므로 ETX로 처리하여 자료 수신을 완료합니다.
- 수신 완료 -
수신 데이터 | 0x34 | 0x40 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x02 | 0x00 | 0x10 | 0x10 | 0x03 | 0x10 | 0x03 |
수신 버퍼 | 0x00 | 0x10 | 0x02 | 0x00 | 0x10 | 0x03 |
네, 말씀 하신 것처럼 0x10 0x10 0x02 라고 들어 왔으면 우선 0x10 0x10,
요렇게 중복되어 들어 온 것은 구분코드를 위한 0x10 이 아니라 데이터로서의 0x10으로 판단하여
바로 버퍼에 0x10 을 넣습니다.
그리고 다음 만난 것이 0x02 이므로 역시 데이터입니다. 그러므로 0x02를 버퍼에 넣습니다.
글을 조금 더 보강해서 올리겠습니다.
오늘도 즐거운 하루가 되세요....^^
처음 0x10 뒤에 0x10 이 오면 데이터로(0x10) 인식하고 0x10 0x10 을 0x10 으로 인식했으니
0x10 다음에 0x02 가오면 헤더로 인식되지않을까요? (몰라서물어보는겁니다..)