Skip to content

20260513_FreeRTOS

Jaedeok Kim edited this page Jun 6, 2026 · 27 revisions

7697893

Overview

해당 Commit은 키보드 키 입력 감지, USB 통신, LCD 화면 출력, 그리고 매크로 관리 등의 기능을 Thread 단위로 나눠 프로젝트의 유지 보수성을 높이고, 병목 현상 없이 각 Thread를 우선 순위에 따라 실시간으로 처리하기 위해 FreeRTOS 커널을 도입한다.

Background

Bare-Metal Programming

CMSIS와 HAL 드라이버에 대해 다시 정리해보자면:

  • CMSIS-Core (/drivers/cmsis-core/)

    1. ARM Cortex-M7 프로세서의 명령어를 어셈블리어 대신 __disable_irq() 같은 C 함수로 실행할 수 있게 해준다.
    2. NVIC와 SysTick 등의 프로세스 주요 기능에 대한 레지스터를 제어할 때, Memory-Mapped 주소를 직접 사용하는 대신 SysTick->CTRL 같은 매크로/변수로 접근할 수 있게 한다.
  • CMSIS-Device (/drivers/cmsis-device/)

    • STM32H7 보드에서 ARM Cortex-M7 프로세서의 주변 장치 (GPIO, 타이머, 파워 서플라이, 플래시 메모리 등)를 Memory-Mapped 주소 대신 GPIOA->MODER 같은 매크로/변수로 제어할 수 있게 한다.
  • HAL (drivers/hal-driver)

    • CMSIS-Core와 CMSIS-Device를 추상화하여, 레지스터 제어가 여러 번 필요한 모든 동작을 HAL_UART_Transmit()처럼 함수로 수행할 수 있게 한다.

CMSIS-Core, CMSIS-Device와 HAL 드라이버만 사용해 펌웨어를 개발하는 것을 Bare-Metal Programming[1]이라고 한다.

Multi-tasking Firmware

다음과 같이 여러 작업을 수행하는 Bare-Metal 펌웨어를 만들었다고 해보자:

/* (...) */

int main(void) {
    ty_setup_hardware();

    for (;;) {
        // 초음파 센서가 감지한 값을 읽는다.
        ty_read_sensors();

        // 센서로부터 읽은 값을 처리한다.
        ty_compute_pid();

        // LED를 켜고 끈다.
        ty_blink_leds();아래와

        // 모터를 제어한다.
        ty_control_motors();
    }

    __builtin_unreachable();
}

/* (...) */

해당 코드의 문제점은 for 문 안에 있는 함수 하나라도 실행이 늦어지면, 나머지 함수가 실행되지 못하고 앞의 함수가 실행을 마칠 때까지 기다려야 한다는 것이다.

그런데 이 문제점을 해결하기 위해 코드를 수정한다고 하면, 센서가 감지한 값을 읽었는지 안 읽었는지를 조건문으로 판단하고, 시스템 부팅 후 경과 시간을 측정하는 변수를 만들어 LED를 제어하고, 이런 식으로 코드를 계속 추가하다 보면 for 문이 매우 복잡해지고 펌웨어의 유지 보수가 까다로워질 것이다.

실시간 운영 체제 (Real-Time Operating System, RTOS)를 사용하는 이유가 바로 여기에 있다.

Kernel Primer

운영 체제 (Operating System, OS)란 아래 3가지 핵심 기능을 수행하는 시스템 소프트웨어를 뜻한다:

  • 하나 이상의 프로그램을 동시에 실행하게 해준다.
  • 여러 개의 프로그램이 물리 메모리를 공유하게 해준다.
  • 프로그램이 CPU와 RAM 외의 주변 장치 (하드 디스크, SSD, 그래픽 카드 등)와 상호 작용하게 해준다.

운영 체제에는 3가지 핵심 기능 외에도 사용자 인터페이스 (데스크탑 환경), '작업 관리자'와 '제어판' 같은 시스템 도구, 방화벽 등의 각종 서비스 같은 여러 기능이 있기도 하지만, 운영 체제의 본질 (커널)은 바로 이 핵심 기능이라고 할 수 있다.


Monolithic Kernel vs. Microkernel

커널이 얼마나 많은 기능을 포함하느냐에 따라, 커널의 구조는 크게 Monolithic Kernel과 Microkernel로 나눌 수 있다.

커널 구조에 대해 자세히 설명하기 전에 반드시 이해해야 하는 내용이 있는데, CPU에는 현재 실행 중인 프로그램이 사용할 수 있는 명령어 집합을 제한하는 특권 레벨 (Privilege Levels)라는 기능이 있다. 컴퓨터가 처음 켜졌을 때는 특권 레벨이라는 개념이 없이 CPU가 cli, hlt, sti처럼 시스템에 악영향을 미칠 수 있는 명령어를 마음대로 실행 가능하지만, 부트로더 실행이 끝나고 운영 체제 커널이 실행되면 특권 레벨 기능이 활성화되고, 시스템에 악영향을 미칠 수 있는 명령어는 사용자가 실행한 프로그램이 아닌 오직 커널만이 사용할 수 있게 된다. 이때, 사용자 프로그램을 실행할 때의 CPU 특권 모드를 User-Mode (Ring 3)라 하고, 커널이 작업을 수행할 때의 CPU 특권 모드를 Kernel-Mode (Ring 0)이라 한다.

Monolithic Kernel (Linux, FreeBSD 등)이란 위 3가지 핵심 기능이 모두 커널에 내장되어 있어 Kernel-Mode로 실행되는 커널을 뜻하고, Microkernel (FreeRTOS, ThreadX, sel4 등) 이란 "프로그램이 주변 장치와 상호 작용하게 해준다"라는 부분, 즉 디스플레이 드라이버, 그래픽 드라이버, 파일 시스템 드라이버 같은 디바이스 드라이버 부분을 커널 밖으로 빼고 사용자 프로그램 형태로 만들어 커널의 크기를 매우 작게 만든 커널을 뜻한다.


What is FreeRTOS?

FreeRTOS는 대표적인 Microkernel 기반의 실시간 운영 체제이다.

FreeRTOS는 운영 체제의 3가지 핵심 기능 중 첫 번째가 가장 중요하다고 보고, 커널에 CPU 스케줄러와 최소한의 메모리 보호 기능만을 넣은 것이 특징이다. Linux, macOS와 Windows 같은 범용 운영 체제에서는 컴퓨터의 성능이 충분히 좋고 CPU 코어에 MMU (Memory Management Unit)가 내장되어 있다는 가정 하에 '가상 메모리'라는 기술을 이용하여 여러 프로그램이 하나의 물리 메모리를 공유하고 물리 메모리 용량보다 더 큰 프로그램도 실행할 수 있게 해주는데, FreeRTOS를 사용하는 임베디드 시스템에서는 CPU의 성능이 낮기 때문에 커널의 대부분 기능은 CPU 스케줄러와 Context Switching이 차지하고 있다.


[1] S. Lyubka, "A bare-metal programming guide," ARM Community, Mar. 15, 2023. [Online].

Clone this wiki locally