라즈베리파이에서 UART3 시리얼 통신을 이용해 PC에서 Tera Term으로 문자를 출력됨을 확인해보기(minicom이용).(dtoverlay 작성을 해보는 간단한 연습)
예전에 했던 실습인데, 장치를 활성화 할때, menuconfig 설정으로 활성화를 하는 간단한 방법도 있지만,
이렇게 기존 dts 방식을 찾아가 수정하거나, 새로운 오버레이를 작성하는 연습을 했던 이유를 프로젝트 끝나서 느꼈다.
라즈베리파이 처럼 잘 알려지지 않은 타사의 보드에서 원하는 통신 모듈이나, 장치를 이용하고자 할때 호환이 되거나, 테스트된 정보가 없는 경우가 많다. 이럴때에 아래와 같은 dts 디바이스 트리 노드가 있는지 찾아본 후 , 수정하거나 추가함으로써 포팅을 시도하여 쓸 수 있다.
1. uart3 4,5번 핀 → TX,RX

- 핀맵

2. /boot/fimware/config.txt 추가

3. 연결 확인


4. minicom 실행해 연결 확인
sudo minicom -b 115200 -D /dev/ttyAMA3minicom에서 문자 입력하여 tera term 터미널에 출력 확인

5. 프로그램 코드 구현
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define BUFFER_SIZE 1024
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <string to send>\n", argv[0]);
return 1;
}
char *message = argv[1];
// UART3 포트 열기
int fd = open("/dev/ttyAMA3", O_RDWR | O_NOCTTY | O_SYNC);
// 읽기/쓰기 모드로 열며, 제어 터미널로 사용되지 않도록 설정하고, 쓰기 연산이 완료될 때까지 대기하는 동기식 모드로 열겠
if (fd < 0) {
perror("Failed to open /dev/ttyAMA3");
return -1;
}
// (UART3 포트로 보내기)
ssize_t bytes_written = write(fd, message, strlen(message));
if (bytes_written < 0) {
perror("Failed to write to UART3");
close(fd);
return -1;
}
printf("Written %zd bytes: %s\n", bytes_written, message);
// (UART3 포트에서 읽기)
char buffer[BUFFER_SIZE]; // 버퍼 크기
ssize_t bytes_read;
int i = 0;
while ((bytes_read = read(fd, &buffer[i], 1)) > 0) {
if (buffer[i] == '\n' || buffer[i] == '\r') {
break;
}
if(i<BUFFER_SIZE -1){
i++;}
}
if (bytes_read < 0) {
perror("Failed to read from UART3");
close(fd);
return -1;
}
buffer[i] = '\0';
printf("Read %d bytes: %s\n",i+1, buffer);
close(fd);
return 0;
} gcc -o uart3_test uart3_test.c실행 파일 생성

6. .dtbs 작성

기존 .dtsi 참고
bcm2711.dtsi

)

- 첫번째 시도 (/dev/ttyAMA3 장치파일 안뜸)
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2711";
// UART3 포트 활성화 및 하드웨어 설정
uart3: uart@7e201600 {
compatible = "arm,pl011"; // UART3에 대한 호환성 설정
reg = <0x7e201600 0x200>; // UART3의 레지스터 주소와 크기
status = "okay"; // UART3 포트 활성화
};
};기존 .dtbs파일의 status 만 활성화하여 사용해보기
- 두번째 시도 (시리얼 통신 동작함)
*인터럽트, 클럭을 지우고 함(기존 파일 참고해 써볼 수는 있을 것 같다)
/dts-v1/;
/plugin/;
/ {
compatible = "bcm2711,pi17"; // Raspberry Pi 4에 맞는 설정
// fragment 0: UART3 포트 활성화
fragment@0 {
target = <&uart3>;
__overlay__ {
status = "okay"; // UART3 포트 활성화
};
};
// fragment 1: UART3 하드웨어 설정
fragment@1 {
target = <&uart3>;
__overlay__ {
compatible = "arm,pl011"; // UART3에 대한 호환성 설정
reg = <0x7e201600 0x200>; // UART3의 레지스터 주소와 크기
// interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; // 인터럽트 설정
// clocks = <&clocks BCM2835_CLOCK_UART>, <&clocks BCM2835_CLOCK_VPU>; // 클록 설정
// clock-names = "uartclk", "apb_pclk"; // 클록 이름 설정
};
};
};7. .dtbo 빌드
dtc -@ -I dts -O dtb -o uart3-overlay.dtbo uart3-overlay.dts
인터럽트,클럭 관련 지워보고 시도 
warning이 나지만 시도해봄.
8. .dtbo파일 /boot/overlays에 복사
sudo cp uart3-overlay.dtbo /boot/overlays
sudo nano /boot/firmware/config.txtconfig.txt에 추가

9. reboot 후 실행
ls -l /dev/ttyA*로 장치 파일 뜨는지 확인.문자열 helloimpi17 쓰기 pc→teraterm 송신한 출력 결과
teraterm에서 byebye 읽어 출력.
)

확인 완료!
'Linux' 카테고리의 다른 글
| [리눅스 커널과 디바이스 드라이버]애플리케이션->syscall->vfs->디바이스파일open 까지 (2) | 2025.08.17 |
|---|---|
| 리눅스 디바이스 드라이버 - module_init() 모듈 등록부터 사용자 호출까지 (1) | 2025.08.17 |
| syscall번호를 테이블에 넣어 커널에 빌트인하여 사용 (2) | 2025.08.17 |
| U-Boot 부팅 흐름 과정 요약 2 -Linux kernel 로드 (3) | 2025.08.16 |
| U-Boot 빌드 과정 흐름 요약 (1) | 2025.08.16 |