주변기기 및 통신 I/O
임베디드 개발에서 시리얼(serial)은 감초와 같은 존재다. 이것이 우유에 말아 먹는 시리얼이 아니라 parallel의 반대 개념이라는 걸 알고 있다면 당신은 이제 임베디드 개발 세계에 익숙해진 것이다~
시리얼이라고 부르지만 정확히는 RS232C를 매체로 사용하는 UART 통신을 말한다. RS232C은 하드웨어적인 케이블 규격이다. 옛날 PC나 랩탑들은 RS232C 포트가 있었는데, 노트북이 날씬해지고 초고속 디지탈 통신방식이 횡횡하는 요즘에는 찾아보기 어려운 옛날 방식이다. 임베디드 개발세계나 일부 옛날 방식 설비에서 여전히 수요가 있어서, 대안으로 아래 오른쪽 그림과 같이 USB 에 꽂을수 있는 Serial-to-USB 타입이 사용되고 있다.
UART(Universal Asynchronous Receiver/Transmitter)는 프로세서에서 RS232C와 같은 물리적인 매체와 함께 사용하는 통신 규격이다. 이것은 실제 임베디드 기기의 통신방법으로는 거의 이제 사용되지 않는다.
왜냐? 느리기 때문이다.
고속 UART통신도 존재하지만 그것은 특정한 기기에서만 쓸수 있는 희귀한 케이스이고 저사양 디바이스가 아닌 왠만한 임베디드 기기에서는 이제 외부와의 통신을 위해 UART를 사용하지 않는 것이 보편적이다. 아날로그적으로도 데이터 손실에도 취약한 단점이 있는 것도 하나의 이유다.
하지만 여전히 UART는 사용된다. 어디에? 실제 임베디드 소프트웨어 개발할 때 사용한다.
위 그림은 SecureCRT라는 상용 터미널 프로그램에서 띄운 임베디드 기기의 동작 콘솔(Console)이다.
콘솔을 시리얼창이라고도 부르기도 한다. 임베디드 기기의 로그메시지(Log message)가 출력되고, 또한 특정한 명령어(CLI, Command Line Interface)를 입력할 수 있는 대화창이라고 보면 된다.
나중에 디버깅을 다루는 챕터에서 다시 살펴보겠지만, 시리얼콘솔은 임베디드 소프트웨어 개발에서 가장 기초적인 디버깅툴(debugging tool)이다. 시스템이 부팅하고 동작하는 과정의 거의 모든 정보들을 볼 수 있다. 그래서 시스템이 동작하는지 여부를 소프트웨어 개발자가 가장 쉽게 알 수 있는 방법이 바로 디바이스에 전원을 연결했을때(즉 부팅했을때) 콘솔에 로그가 출력되는지 여부를 살펴보는 것이다.
PCB 상태의 보드가 맨처음 나오면 하드웨어 엔지니어가 먼저 보드가 정상동작하는지 확인을 한다.
각 직류전원(DC)이 정해진 입력부에 정상으로 들어가는지 여부를 포함해서 하드웨어 개발자가 기본적인 사항들을 확인하고 나면, 그 다음이 소프트웨어 개발자 차례다. 보드 브링업(Board Bringup)에 들어가는 것이다.
보드 브링업은 아무런 반응없는 벽돌과도 같은 프로토타입 (Proto-Type)디바이스에 생명력을 불어넣는 고난하고도 지난한 작업이다.
바로 이때 소프트웨어 개발자가 보드를 받아서 가장 먼저 하는 일이 전원을 연결했을때 시리얼 콘솔에 부팅로그가 찍히는지를 보는 것이다(물론 이는 보드에 이미 기본적인 부팅 펌웨어가 들어가 있다는 것은 전제로 한다). 제대로 동작안해도 전원을 연결했을때 시리얼콘솔에 그럴듯한 단어 하나(예를 들어 boot...)라도 찍힌다면 운이 좋은 경우다. 이 지난하고 고난한 보드 브링업의 세계에 대해서는 추후 디버깅 챕터에서 떠들도록 하겠다.
디버깅 용도로 UART를 사용하기 위해서는, 호스트(PC의 시리얼콘솔)와 클라이언트인 임베디드 기기의 UART를 똑같이 세팅해줘야 한다.
UART 통신은 위 그림에 나온 Baudrate, Databit, Parity, Stop bits를 설정하기만 하면 된다. 설정값들은 개발하는 임베디드 기기에서 사용하는 값을 확인해서 적용하면 된다. 아래 그림은 UART 통신의 데이터포멧이다.
Baudrate는 통신속도다. Databit는 실제 데이터를 표현하는 비트수로 보통 다 8비트를 쓴다. parity bit는 오류검출용도인데, 실질적으로 많이 쓰지 않는다. 그것보다는 상위단의 소프트웨어 코드에서 오류검출을 하는 것이 낫다. 종료비트는 1, 1.5, 2비트 세가지중 하나를 쓴다. 저사양 디바이스일수록 Baudrate는 낮아진다고 생각하면 되고, 통상의 콘솔로그를 위한 세팅은 위 시리얼콘솔의 환경세팅 그림와 같이 하는 것이 일반적이다.
당연히 쌍방 디바이스가 동일한 UART 데이터 포멧으로 맞춰야 정상적인 쌍방 통신이 가능하다.
시리얼콘솔용도가 아닌 다른 기기와의 데이터 통신도 마찬가지다. 시리얼 콘솔을 사용한다 함은 PC의 COM포트라는 기기와 임베디드 기기가 데이터 통신을 하는 것이다. 이미 언급해듯이, UART 통신은 저속인데다가, 실제 케이블로 전송되면서 물리적으로 데이터훼손(corruption)이 일어날 수 있다. 그래서 시리얼통신은 근거리에서 적은 데이터를 교환하는 경우에만 사용하는 것이 좋다. 또한 데이터를 주고 받을때 필히 데이터가 유효한지 여부를 검증하는 로직이 필요하다. 실제 UART통신이 사용되는 보편적인 예는 스마트카드(Smartcard)와 같은 계열이 있다. 이는 일반적인 UART통신과는 좀 다르다. 유사계열이라고 하는 것이 적절할 듯 싶다.
참고로 시리얼로그로 왠만한 디버깅은 다 가능하다. 로그의 양이 너무 많아서 다른 로그 에이전트(안드로이드의 ADB등과 같은)을 쓸수 밖에 없는 상황도 있지만 여하튼 여전히 임베디드 세계에서 시리얼케이블의 활용도는 절대적이라고 봐도 된다.