임베디드를 좋아하는 조금 특이한 개발자?

[RaspberryPI4] Bare metal에서 UART통신을 위한 레지스터 확인 본문

Embedded/Raspberry PI

[RaspberryPI4] Bare metal에서 UART통신을 위한 레지스터 확인

Gordon_ 2025. 7. 18. 01:47

- 개발 환경

개발 보드 : Raspberrypi 4

WSL2 (Ubuntu 22.04 LTS)

toolchain : aarch64-linux-gnu-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0


1. 서론

  지금까지 C언어로 GPIO를 제어하는 간단한 예제까지 진행하였습니다. 하지만, GPIO만으로는 지역변수나 레지스터의 값을 확인하기 힘듭니다. 가장 좋은 방법은 JTAG를 통해 디버깅을 하는 것이지만 장비도 비쌀 뿐더러 추가적인 작업이 힘들기에 취미로 개발을 진행할 때에는 UART로도 충분히다고 생각합니다. 또한, UART로 다른 장치와 통신하기에도 편하기에 앞으로 자주 사용할 것이라고 생각합니다.

2. UART 통신을 하기 위한 레지스터 확인

  라즈베리파이4에서 사용하는 BCM2711 MCU의 경우 UART 통신을 위해 PL011이라는 Peripheral를 사용합니다. 그래서 UART 와 관련된 내용을 확인하려면 PL011의 데이터시트를 확인하여야 합니다. 하지만 BCM2711에서는 친절하게도 PCL011에 대한 사용 방법을 BCM2711 데이터시트에 서술하였습니다. 그래도, 더 자세한 레지스터의 설정 방법은 PL011의 데이터시트를 참고하여야 합니다.

2.1. CR(Control Register) 레지스터

  CR 레지스터는 이름대로 UART를 제어하는 레지스터입니다. 레지스터를 통해 UART을 활성화 하거나  Rx,Tx의 기능을 개별 적으로 활성화 할 수 있습니다. 허나주의 해야할 점은 다른 레지스터와는 다르게 CR레지스터의 값을 변경하려면 다음과 같은 과정을 따라야합니다.

BCM2711의 UART의 초기화 방법 (정확히는 변경된 CR 레지스터를 UART에 적용 방법)

 

2.1.1. UARTEN(UART ENable) bit

 

  해당 비트는 UART의 활성화 여부를 결정하는 가장 중요한 Bit입니다. 아무리 UART의 기능을 설정하더라도 해당 Bit가 0라면 UART가 동작하지 않습니다. 그렇기에 UART에서 가장 중요한 Bit라고 할 수 있습니다.

 

2.1.2. TXE(Transmit Enable) bit

   해당 비트는 UART을 활성화 한 후 Tx 기능을 활성화 하는 Bit입니다. UART를 활성화 하더라도 해당 Bit를 활성화 하지 않는다면, 데이터를 송신(Tx)할수 없게 됩니다. 반대로, 굳이 개발 환경상 데이터를 송신할 필요가 없는 경우 해당 Bit를 0으로 클리어하더라도 상관 없습니다.

 

2.1.3. RXE(Receive Enable) bit

   해당 비트는 UART을 활성화 한 후 Rx 기능을 활성화 하는 Bit입니다. UART를 활성화 하더라도 해당 Bit를 활성화 하지 않는다면, 데이터를 수신(Rx)할수 없게 됩니다. 반대로, 굳이 개발 환경상 데이터를 수신할 필요가 없는 경우 해당 Bit를 0으로 클리어하더라도 상관 없습니다.

 

2.2. IBRD(Integer BaudRate Divisor) Register, FBRD(Fractional BaudRate Divisor) Register

  IBRD Register와 FBRD Register는 UART의 Baudrate를 결정하는 레지스터입니다. 먼저 해당 레지스터를 설정하기 위해서는 알아야하는 하는 것들이 있습니다. 먼저 UART에 입력 되는 UARTCLK를 알아야 하며 또한 IBRD 레지스터와, FBRD 레지스터의 값을 도출하는 공식을 알아야 합니다.

  UART에 입력되는 UARTCLK은 48MHz입니다. 해당 내용은 BCM2711에 명시되어 있지 않지만 다행스럽게도 라즈베리파이 문서에 명시 되어 있습니다. 해당 내용은 아래 포스트를 확인해보세요.

https://littlebitodd-developer.tistory.com/59

 

[Raspberrypi4] BCM2711의 UART 입력 주파수(UARTCLK) 초기 설정값

https://www.raspberrypi.com/documentation/computers/legacy_config_txt.html#init_uart_baudconfig.txt options - Raspberry Pi Documentation" data-og-description="The official documentation for Raspberry Pi computers and microcontrollers" data-og-host="www.ras

littlebitodd-developer.tistory.com

  이제 IBRD 레지스터와 FBRD 레지스터의 값을 도출하는 공식을 확인하도록 하겠습니다. 그리고 우리가 목표로 하는 Baudrate는 115200으로 설정하도록 하겠습니다.

https://developer.arm.com/documentation/ddi0183/g/programmers-model/register-descriptions/fractional-baud-rate-register--uartfbrd?lang=en

 

Documentation – Arm Developer

 

developer.arm.com

IBRD 레지스터 및 FBRD 레지스터 값 도출 과정

위 공식 문서의 내용을 정리하면 IBRD 레지스터와 FBRD 레지스터을 도출하는 공식은 다음과 같습니다.

  이제 UARTCLK을 48MHz으로 설정하고자 하는 Baudrate를 115200 설정하고 IBRD 레지스터와 FBRD 레지스터의 값을 도출하도록 하겠습니다.

위 공식을 통해 IBRD 레지스터는 26, FBRD 레지스터는 3을 저장해야한다는 것을 알았습니다.

 

2.3. LCRH(Line Control) Register

  LCRH 레지스터를 통해 통신의 데이터 구조를 설정합니다. 가장 일반적으로 많이 사용하는 데이터 구조는 다음과 같습니다.

  • Word length : 8 bits
  • Parity bit : Disable
  • Stop bit : 1 bit

위 데이터 구조을 설정하기 위한 bit를 소개하겠습니다.

2.3.1. PEN(Parity ENable) bit

  PEN bit를 1로 설정하면 parity bit를 사용합니다. 하지만 저희는 Parity를 사용하지 않을 것이기에 0으로 클리어할 것입니다.

 

2.3.2. STP2(SToP 2) bit

  STP2 bit를 1로 설정하면 Stop bit를 2개 사용할 것입니다. 하지만 저희는 Stop bit를 1개 사용할 것이기에 0으로 클리어 할 것입니다.

 

2.3.3. WLEN(Word LENgth) bits

  WLEN bits을 11로 설정하여야 Word의 길이를 8bit으로 사용할 수 있습니다. 특수한 경우가 아닌 이상 대부분은 8bit를 사용합니다.

 

2.4. DR(Data Register) bits

  DR 레지스터를 통해 우리는 데이터의 송수신을 하게 됩니다. DR 레지스터에 데이터를 저장한다면 데이터를 송신(Tx)를 하게 되며 DR 레지스터에 데이터를 읽게 된다면 데이터를 수신(Rx)하게 됩니다. 그리고 OE,BE,PE,FE 비트를 통해 송수신시 발생한 에러를 확인할 수 있습니다.

2.4.1. DATA bits

7~0 비트를 통해 데이터를 송수신 하게 됩니다.

 

3. 후기

  이제 UART를 통신하기 위한 최소한의 레지스터를 확인하였습니다. 더 많은 레지스터가 존재하지만 단순한 송수신을 하기 위해서는 위에서 소개한 레지스터만 숙지하여도 충분합니다. 이제 다음 포스트에서는 해당 레지스터를 직접 제어하여 UART 통신으로 데이터를 echo 하는 코드를 작성하도록 하겠습니다.