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

[RaspberryPI4] Bare metal에서 UART 수신(Rx) 구현 본문

Embedded/Raspberry PI

[RaspberryPI4] Bare metal에서 UART 수신(Rx) 구현

Gordon_ 2025. 7. 27. 11:18

- 개발 환경

개발 보드 : Raspberrypi 4

WSL2 (Ubuntu 22.04 LTS)

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


- 선행 포스트

 UART를 사용하기 위한 레지스터 확인

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

 

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

- 개발 환경개발 보드 : Raspberrypi 4WSL2 (Ubuntu 22.04 LTS)toolchain : aarch64-linux-gnu-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.01. 서론 지금까지 C언어로 GPIO를 제어하는 간단한 예제까지 진행하였습니다. 하지만, GPIO

littlebitodd-developer.tistory.com

 UART에서 데이터 송신 구현

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

 

[RaspberryPI4] Bare metal에서 UART통신 구현

- 개발 환경개발 보드 : Raspberrypi 4WSL2 (Ubuntu 22.04 LTS)toolchain : aarch64-linux-gnu-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0- 선행 포스트 UART를 사용하기 위한 레지스터 확인https://littlebitodd-developer.tistory.com/63 [Raspb

littlebitodd-developer.tistory.com

- 예제 코드

https://github.com/MainForm/RaspberryPI4_Baremetal_Firmware/tree/629806a9fa57f5698632be1e0f7e0701590065e1

 

GitHub - MainForm/RaspberryPI4_Baremetal_Firmware

Contribute to MainForm/RaspberryPI4_Baremetal_Firmware development by creating an account on GitHub.

github.com


1. 서론

  지금까지 라즈베리파이4에서 UART로 "Hello world"를 송신(Tx)하는 기능을 구현하였습니다. 이제는 데이터를 수신(Rx)를 통해 UART의 기능을 테스트할 수 있는 에코 기능을 구현하도록 하겠습니다. 에코는 단순하게 수신 받은 데이터를 그대로 송신하여 데이터가 손실 없이 정상적으로 통신이 이루어지는 지 확인하는 기능입니다.

 

2. 데이터 수신(Rx) 함수 작성

- uart.c 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
uint32_t UART_ReceiveWord(){
    // UART Rx 버퍼 수신 해야할 데이터가 있는 경우
    while(REG_32(BCM2711_UART0_FR) & UART_RXFE);
 
    // UART Rx 버퍼로 부터 word 길이의 데이터 수신
    uint32_t DataRegValue = REG_32(BCM2711_UART0_DR);
    // 만약 해당 데이터를 수신하는 동안 에러가 발생한 경우
    if(DataRegValue & (UART_OE | UART_BE | UART_PE | UART_FE)){
        // 에러 코드 리턴
        return UART_INVALID_DATA;
    }
 
    // 정상적으로 수신된 데이터 리턴
    return DataRegValue & UART_DATA;
}
cs

 

※주의)

UART_ReceiveWord에서 "uint32_t DataRegValue = REG_32(BCM2711_UART0_DR);"을 2번 이상 사용하면 안됩니다. 그이유는 DR 레지스터를 읽어 올 때마다 데이터를 수신하는 것으로 판단하여 DR을 2번 읽었다는 것은 데이터를 2번 수신했다는 의미입니다.

 

3. 에코 기능을 수행하는 main 함수 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "uart.h"
 
int main(void){
    uint32_t recvData;
 
    // UART 초기화
    UART_Initialize();
 
    while(1){
        // UART로 데이터 수신
        recvData = UART_ReceiveWord();
 
        // 데이터 수신 중 에러가 발생하면 다음 데이터 수신
        if(recvData == UART_INVALID_DATA){
            continue;
        }
 
        // 데이터 다시 송신
        UART_SendWord((uint8_t)recvData);
    }
 
    return 0;
}
cs