Category (Click)
개발보드 덕질하기

[Beepy Likely] 3. 시리얼 터미널 에뮬레이터 구현

 차완기 - @7/13/2024, 7:52:00 PM
Beepy Likely 프로젝트
작고, 키보드 달렸고, 느리고, 그런데 리눅스가 돌아가는!!! 오픈소스 포터블 리눅스 머신인 Beepy를 레퍼런스로 삼아, 나만의 포터블 리눅스 머신을 만드는 프로젝트입니다.
#HW #PCB Design #FW #Pico SDK #RTOS #TinyUSB #HID #u8g2 #LCD #terminal emulation

에이 UART 받아다가 화면에 뿌리면 되겠지 ㅋ

Raspberry Pi - Introducing: Raspberry Pi 5! [링크]
대부분의 SBC들은 키보드나 마우스를 장치에 직접 부착하지 않고도 터미널에 접속할 수 있도록 “시리얼 터미널”을 제공합니다. 가장 대표적으로 라즈베리파이 5의 UART 포트가 있죠.
단순히 문자열을 그대로 화면에 띄우면 되겠지 생각했는데..
가만 상각해 보니 글씨가 지워지고, 색이 바뀌고, 화면이 지워지는 이런 건 문자열을 보낸다고 구현이 되는걸까요..?
어..라..?
대충 이런 느낌이죠

ANSI Escape Code

ANSI라.. ISO metric이 최고 아니었나요? 기계제도를 가끔 하다 보니 단어만 봐도 반감이 생기는데요, 여기서 이야기하는 건 조금 다른 내용입니다.
설명을 위해 나무위키의 내용을 가져와봤습니다.
터미널은 원래 전신타자기라고 불리는 일종의 프린터였고 아주 기본적인 제어 동작만을 가지고 있었는데 커서의 위치를 이동시키는 것은 개행이나 캐리지 리턴 정도만 가능했고 한번 인쇄된 문자를 바꾸는 것은 불가능했다. 이후 디스플레이에 출력되는 전자 제어식 터미널이 보급되면서 더 다양한 동작이 가능해졌는데 출력된 문자를 지우는 것도 가능하고 커서를 임의의 위치로 이동시키는 동작이 가능해졌다. 초기에는 표준이 정해지지 않아 터미널을 설계하는 회사마다 동작이 달랐는데 각 회사의 제품마다 지원되는 기능이 다르고 비슷하거나 같은 기능이여도 사용법이 다르는 등 호환성에 악영향을 끼쳤다. 그래서 터미널의 동작을 통일시켜야 할 필요성이 생겼고 터미널이 가져야 할 기본적인 동작들을 모아 ANSI 이스케이프 시퀀스 표준이 탄생한다.
나무위키 - ANSI 이스케이프 코드 [링크]
요약하자면 롤페이퍼에 결괏값을 출력하던 과거의 터미널이 디스플레이에 담기며 화면을 지우거나, 커서를 옮기는 등의 동작이 가능해졌는데, 이를 구현하기 위한 표준이 바로 ANSI 이스케이프 코드인 것입니다.
ANSI 이스케이프 코드는 ESC 문자(0x1B) 뒤로 여는 대괄호([)가 붙은 CSI로 시작됩니다. 그 뒤로 세미클론(;)으로 구분되는 argument가 옵션으로 붙고, 가장 마지막에는 명령어가 붙습니다.
XTerm Control Sequences [링크]
문제는.. 구현해야 할 이스케이프 코드가 너무 많다는 것이죠.
우선 지금은 기본적인 기능을 위해 필요한 것만 구현하고 오픈소스 터미널 에뮬레이터를 가져다가 붙이던가 해야겠습니다. (그런 게 있을지 모르겠네요)
당장 사용할 수 있는 SBC가 Milk-V 뿐이라(...) Mlik-V의 UART 출력을 RPi Pico의 UART 입력에 붙이고 프로그래밍을 진행했습니다.
이전 포스팅에서 만들어둔 LCD 드라이버에 몇몇 기능을 추가하고, DMA 기반 UART 드라이버를 만들었습니다.
터미널을 처리하는 task를 하나 만들어 UART로 데이터가 들어올 때 마다 파서에 집어넣도록 했습니다.
이제 이스케이프 문자를 처리하는 파서를 만들어야 하는데요, 위 리포지토리의 코드 구조를 많이 참고했습니다.
간단한 state machine을 만들고,
ESC 문자의 여부, CSI(ESC + [)의 시작 여부 등에 따라 이후의 내용을 처리하도록 했습니다.
CSI가 시작된 후에는 이런 식으로 처리됩니다.

테스트

RPi Zero 2 W를 마련해 Ubuntu 22.04를 설치한 후 사진을 찍었습니다.
vi, htop 정도는 잘 먹습니다 ㅎㅎㅎ
아직 구현되지 않은 이스케이프 코드가 너무 많아.. nano, apt 등 조금이라도 화려한(?) 툴은 화면이 날라다니지만 말이죠 ㅋㅋ..
이건 언젠가..언젠가 해결해 보려 합니다.

마무리

터미널을 너무 만만하게 보고 있었던 것 같습니다 ㅋㅋ 그래도 덕분에 ANSI 제어문자를 알게 되어 터미널에 로그를 찍을 일이 생기게 되면 많이 편리해질 것 같습니다.
다음 포스팅에서는 블랙베리 키보드를 연결해 키보드를 처리해 보겠습니다!