비동기통신 (Universal Asynchronous Receiver/Transmitter)은 1960년대 초부터 사용된 징그럽게 오래된 통신 프로토콜이다.
60년이라는 세월이 흘렀지만 아직도 다양한 분야에서 사용된다.
Allwinner i3/S3 CPU에는 UART 통신 포트가 3개 있으며, 산업 표준으로 여겨지는 16550 칩과 호환되는 IP로 구성되어 있다.
UART0는 시스템 콘솔 포트로 사용되며 CH330N이라는 IC를 통해 USB 인터페이스로 변환되어 개발용 PC에 연결된다.
터미널 콘솔이 필요하지 않다면 u-boot과 boot.cmd를 수정하여 다른 용도로 사용할 수 있지만 시도해보지는 않았다.
UART1과 UART2는 각각 RX,TX,CTS,RTS 4개의 신호선을 가지고 있으며, UART0는 RX,TX만 있다.
CTS와 RTS는 하드웨어 플로우 컨트롤을 위해 사용된다. CTS(Clear to Send)는 입력으로 "0"이면 상대편 기기에 데이터를 보낼 수 있는 상태이며, RTS(Request to Send)는 출력으로 "0"를 만들어 상대편 기기에 데이터를 요청하는 것이다.
오늘은 하드웨어 플로우 컨트롤을 사용하지 않고 간단하게 Rx/Tx 기능만 확인해 보자.
먼저 DeviceTree 소스(dts)에 아래 내용을 추가하여 UART1와 UART2를 활성화 시킨다. UART0는 이미 활성화되어 시리얼 콘솔로 사용하고 있었다.
&uart1 {
pinctrl-0 = <&uart1_pg_pins>;
pinctrl-names = "default";
status = "okay";
};
&uart2 {
pinctrl-0 = <&uart2_pb_pins>;
pinctrl-names = "default";
status = "okay";
};
UART가 사용할 핀은 &pio 항목에 끝 부분에 아래와 같이 추가한다. RTS와 CTS 기능이 필요하다면 pins 항목에 해당 핀 번호를 추가하면 된다. UART는 필요없고 법용 입출력 포트가 필요하다면 일반 포트로 설정하면 된다.
&pio {
.
.
.
.
.
.
.
uart1_pg_pins: uart1-pg-pins {
pins = "PG6", "PG7";
function = "uart1";
};
uart2_pb_pins: uart1-pb-pins {
pins = "PB0", "PB1";
function = "uart2";
};
};
컴파일하고 보드에 전송해서 리눅스 부팅을 한다. UART 0,1,2의 디바이스 노드는 /dev/ttyS0, ttyS1, ttyS2 이다.
# ls -alp /dev/ttyS*
crw------- 1 root tty 4, 64 Jan 10 11:23 /dev/ttyS0
crw-rw---- 1 root dialout 4, 65 Jan 28 2018 /dev/ttyS1
crw-rw---- 1 root dialout 4, 66 Jan 28 2018 /dev/ttyS2
ttyS3 이후에도 더 많은 노드가 보일수도 있는데, 모두 dummy 노드이므로 무시한다.
dummy 노드 여부는 UART 포토의 통신 속도를 설정하는 명령으로 확인 가능하다. 115200bps로 설정해본 결과이다.
# stty 115200 -F /dev/ttyS1
# stty 115200 -F /dev/ttyS2
# stty 115200 -F /dev/ttyS3
stty: /dev/ttyS3: Input/output error
통신 기능 테스트를 위해 UART1의 TX핀을 UART2의 RX핀에 연결하고, UART2의 TX핀은 UART1의 RX핀에 연결하였다.
크로스 루프백 테스트라고 불러도 좋을것 같다.
통신 실험을 위해 시리얼 콘솔과 LCD 콘솔 양쪽 모두 로그인을 한다.
LCD 콘솔은 UART2의 RX 문자열을 받아서 표시할 준비를 한다.
# cat /dev/ttyS2
시리얼 콘솔에서는 아래와 같이 입력하여 UART1의 TX로 문자열을 전송한다.
# echo "Hello from ttyS1" > /dev/ttyS1
그럼 LCD 콘솔에는 수신한 "Hello from ttyS1"이 출력될 것이다.
반대로 ttyS2에서 ttyS1으로의 전송도 잘 되는 것을 확인 하였다.
다음에는 SPI 통신 기능을 확인해 볼 예정이다. SPI까지 끝나면 내가 만든 PCB 뿐만 아니라 커널 드라이버에 대한 기본적인 동작 검사는 거의 완료될것 같다.
추신:
커널 부팅 로그에 보이는 6~7개의 regulator 설정 관련 warning 메시지는 모두 잡았다.
DeviceTree에 전원 장치 설정이 없었기 때문이다.
겸사겸사 defconfig에는 USB-SERIAL 관련 장치 드라이버를 제거했다.
dmesg 출력이 깔끔해져서 속이 다 시원하다.
CPU의 UART 포트를 활성화시키는 패치를 포함해서 모두 github에 올려 놓았다.
https://github.com/foxnux/linux/commit/e156cf277ecd6536d95916667811ebf340f769d1
https://github.com/foxnux/linux/commit/7b74762a343c78317940370a9c3f088d535d7bfa
https://github.com/foxnux/linux/commit/b430b68b1ba4a4c191d364e30273ae060dab0baf
'임베디드' 카테고리의 다른 글
USB 무선랜 드라이버 구동 (0) | 2020.01.11 |
---|---|
SPI 포트 기능 테스트 (3) | 2020.01.11 |
Buildroot 테스트 (0) | 2020.01.06 |
ADC 키패드 입력 테스트 (0) | 2020.01.06 |
카메라 입력 테스트 (0) | 2020.01.03 |