임베디드 세계에 발을 들인지 어연 3개월, 지금의 단계까지 오면서 취업공고나 랩실 설명에서 RTOS라는 키워드를 굉장히 자주 마주쳤다. 그리고 나는 이게 어떠한 종류의 OS라고 생각해왔다. 그리고 드디어 이 RTOS라는게 도대체 어떤 녀석인지 공부할 단계가 되었다. 후하! 그럼 들어가보자.
글을 열심히 적다보니깐, 내용이 막 길어지는 것도 있고 하나의 글에 담기에는 어울리지 않는 내용들이 점차 불어나는 것 같아서, 글을 분리하였다. 이번 글에서는 RTOS와 FreeRTOS가 무엇인지에 대해서 간략하게 살펴보고, FreeRTOS의 구조나 사용 방법, 타고 들어가서 확인할 수 있는 레지스터나 어셈블리 코드의 동작들, 그리고 프로세스 아키텍처까지 정리하면서 다뤄보려고 한다.
RTOS의 두둥등장
우선 RTOS는 Real-Time Operating System 을 의미한다. 이 RTOS가 그래서 어떤 것들을 말하는 건지, 어떤 특징을 가지고 있는 시스템을 말하는건지 한 번 살펴보자.
ㅤ
임베디드 시스템이란?
특정한 목적을 수행하기 위해서 필요한 SW와 HW를 내장하여 모두 가지고 있는 시스템. 임베디드 시스템에서 개발을 한다면 제한된 자원을 최대한 활용하여 주어진 목적을 수행해야함.
ㅤ
그렇다면 임베디드 개발의 미션은 무엇이냐?
- 코드 크기가 줄어야한다 (RAM 용량이 모자랄 수 있어서)
- 실행 속도가 보장되어야한다
- 전력 소비를 아껴야한다
ㅤ
리얼타임은 실시간 처리를 말하는건가?
RTOS에서 말하는 리얼타임이라는 것은 입력 조건이 들어왔을 때, 정해진 시간 내에 처리할 수 있음을 말한다. 즉, 이벤트에 대한 응답 속도가 매우 중요한 (응답 속도 빼면 시체라고 할 수 있는) 시스템이 리얼타임 시스템이고, 이를 위한 운영체제가 RTOS이다.
ㅤ
리얼타임에는 크게 2가지 종류가 있다. 리얼타임이면 좋은가 vs 리얼타임이어야만 하는가.
- Hard Real-time
- 반드시 정해진 시간 내에 처리되어야하는 시스템. 시간이 오버되면 치명적인 오류가 발생.
- 의료기기, 군사장비 등
- Soft Real-time
- 주어진 시간 내에 처리가 되지 않더라도 시스템 전반에 큰 영향이 없는 시스템
- 네트워크 장비 등
ㅤ
왜 RTOS가 제시되었을까?
기존의 펌웨어 방식에서 여러가지 목적의 작업을 동시에 돌리기 위해서 나는 아래와 같은 방식을 선택했었다.
int main(void)
{
... 코드 설정 ...
while(1) {
// 센서 값을 읽고 -> 10ms
read_sensor();
// LCD에 센서값을 기록하고 -> 50ms
update_lcd();
// UART 로 PC로 정보 전달하기 -> 40ms
process_communication();
}
}
ㅤ
위 방식을 사용한다면 센서값을 읽는 시간이 10ms 밖에 안걸림에도 다른 모든 작업들의 처리를 기다리면서 80ms마다 센서 값을 측정하게된다. 또, 급한 Task에 대한 Event가 발생한 상황(에어백을 터뜨려야하는 상황 등)에서도 앞선 LCD 에 대한 처리를 수행하느라 처리 완료 시간이 늦어지게 된다. 만약 정말로 에어백을 터뜨려야 하는 상황이였다면 당장 1ms 안에 에어백을 터뜨려야하는데 LCD 때문에 무려 50ms나 더 기다려서(50배!!) 에어백이 터지는 상황이 만들어질 수도 있다. 아주 문제가 많다.
ㅤ
그래서, 위 상황에서 발생하는 여러 문제들을 해결하기 위해서 RTOS 라는 개념이 등장했다.
- 작업들이 하나의 While 문 안에 하나로 묶여있음 → 각각을 별개의 Task로 분리하기
- 급한 작업이더라도 차례가 올 때 까지 기다려야함 → “우선순위”의 개념을 도입
- 각 작업을 모두 완료해야 차례대로 넘어감 → 스케줄러가 자동으로 Task를 전환
ㅤ
이를 통해 실시간 처리를 만족시키기 어려웠던 기존의 펌웨어 방식에서 나아가서 실시간 제약 조건을 보장하는, 즉 정해진 시간 내에 반드시 응답을 하는 시스템에 대한 요구사항을 충족하고자 한다.
ㅤ
인터럽트를 적극적으로 활용해서 이벤트가 들어왔을 때 우선적으로 처리해내도록 개발을 해보면 안되나?
인터럽트는 그런 용도가 아니다.
- 인터럽트 내에서 처리 시간이 길어지면 전반적인 성능 저하가 발생할 수 있다.
- 지금 당장 처리하지 않으면 소실되는 것만 수행하고, 나머지는 인터럽트 바깥에서 처리하는게 맞다.
ㅤ
그러면 윈도우같은 좋은 OS를 쓰면 안되나?
윈도우나 macOS 같은 녀석들은 범용 OS (General Purpose OS) 라고 부른다. 요런 범용 OS와 임베디드를 위한 RTOS의 목적은 약간 다르다.
ㅤ
General Purpose OS의 목표는 Maximum Throughput!
- 여기에서는 비선점형 커널을 주로 사용한다.
- 자꾸 새로운 Task가 들어와서 Context-Switch 발생하면 오버헤드가 생겨서 산출량이 줄어드니깐.
- 용량이 크다. 수백MB~GB 단위. 그래서 임베디드에 올리기에는 메모리 용량이 상당히 부담스럽다.
- ㅤ
Real-Time OS의 목표는 Minimum Response Time!
- 여기에서는 선점형 커널을 주로 사용함. 그래야 높은 우선순위에 대해서 빠르게 응답할 수 있음.
- Deterministic한 특성을 가진다 (정해진 입력 값 → 정해진 시간 내에 정해진 출력이 나옴)
- 얘는 KB 단위라서 그나마 임베디드에서 덤벼볼만하다.
ㅤ
막간을 활용한 OS가 무엇이냐?
RTOS도 OS의 일종. 범용적인 OS와 임베디드 OS를 논할거라면 OS가 무엇인지도 함께 논하는게 인지상정.
ㅤ
OS는 제한된 시스템 자원을 효율적으로 사용할 수 있도록 관리해주는 프로그램을 말한다. 윈도우나 맥 같은 범용 OS는 CPU나 코어의 메모리를 효율적으로 사용해 최대의 Throughput을 낼 수 있게 하고, 임베디드 OS는 코어를 할당받는 Task를 제어해서 응답 시간을 보장할 수 있게 한다. 또, 컴퓨터의 전반적인 동작을 제어하며, 컴퓨터 시스템과 사용자 (App Program) 간의 인터페이스를 담당해 편의를 제공한다.
ㅤ
사용자와 컴퓨터 시스템 간의 인터페이스 역할을 한다는 것은 요런 의미이다. printf() 함수를 통해서 “Hello World!” 라는 메시지를 출력한다고 해보자.
- 사용자 프로그램에서 printf() 함수를 호출한다.
- printf 함수의 내부에서 write() 함수를 호출한다.
- write() 은 OS 커널에 진입하는 시스템 콜이며, 커널에게 메시지를 표준 출력해달라고 요청한다.
- 시스템 콜에 의해 CPU는 커널 모드로 진입하며, 표준 출력 장치 드라이버로 메시지를 전달한다.
- 디바이스 드라이버는 전달받은 메시지를 자신이 담당하는 디바이스(터미널 에뮬레이터)로 보낸다.
- 커널은 다시 사용자모드로 복귀하고, write 시스템콜은 출력한 byte 수를 반환하며, printf 는 이 값을 전달받으며 다시 사용자 프로그램으로 실행 흐름이 돌아온다.
ㅤ
ㅤ
ARM 3형제 중에서 RTOS와 가장 적합한 프로세서 라인업은 누구일까
임베디드에서 널리 사용되는 ARM 프로세서에는 크게 3가지 라인업이 있다. 그 이름도 A, R, M. 이중에서 리얼타임 시스템에 가장 적합한 프로세서는 누구일까?
ㅤ
Cortex-A
- 이름은 Application 을 의미
- 가상메모리를 지원하는 MMU와 캐시, 높은 성능을 가지고 있음.
- 고성능 덕에 Linux나 Android를 위해 사용된다. (아이폰과 갤럭시)
- 리눅스 같은 범용OS는 응답시간이 아닌 산출량을 목표로 하기 때문에, 물론 성능이 좋긴 하지만 리얼타임 시스템을 위해서 쓰기에는 부적합하다.
ㅤ
Cortex-R
- 이름은 Real Time을 의미
- MPU나 MMU를 이용한 메모리 보호, 안정성을 위한 여러가지 장치들을 가지고 있다.
- Cortex-A 시리즈에서 MMU를 제거한게 Cortex-R 일 정도로 매우 고성능의 장치이다.
- Hard Real-time용 시스템이다. 이를 위한 HW 적인 장치들도 여럿 가지고있다.
ㅤ
Cortex-M
- 이름은 MCU를 의미
- 저전력, NVIC 덕분의 빠른 인터럽트 응답, 단순하고 결정론적인 아키텍처를 가지고 있다.
- 적당히 예측 가능하고 적당한 성능과 저전력 저비용의 시스템으로, 대부분의 RTOS 시스템에 적합하다. (왜냐? 마이컴 시장을 흡수하기 위해 CISC를 많이 참고해서 만든 프로세서이기 때문에. )
- Cortex-M 역시 RTOS를 위해 설계된 프로세서임 😮😮😮
ㅤ
ㅤ
그럴테면 이름을 Cortex-R 이라고 짓지 말았어야지… 확실하게 안전한 RTOS를 위해서는 Cortex-R을 쓰지만, 이게 너무 비싸고 필요 이상으로 고성능이기 때문에 보통은 Cortex-M을 쓴다고한다. 차량을 예로 든다면 에어백 ECU, 브레이크 ECU 같이 안전과 직결되는 곳은 Cortex-R을 이용한 시스템을 사용해야하고, 에어컨이나 엔진 같이 고장에 의한 즉각적인 영향이 오지 않는 곳은 Cortex-M으로도 충분할 것 같다. 왜냐? Cortex-R은 비싸니깐.
ㅤ
혹시 Cortex-M의 성능이 좋아지면 리눅스 같은 일반적인 OS를 올릴 수 있나? 라고 잠깐 상상해봤다. 그런데 찾아보니 Cortex-M과 Cortex-A 의 차이는 가상메모리를 위한 HW인 MMU의 탑재 유무라고한다. 그래서 가상메모리 같은 기법들이 적용되기 어렵기 때문에 일반적인 OS는 Cortex-M에 탑재하기 어렵다고 한다. (불가능하지 않을까?)
ㅤ
ㅤ
이외에도 ARM에서 시스템의 신뢰성을 제공하기 위해서 여러가지 장치들을 달아주었다.
- Fault Exception
- Hard Fault, Usage Fault, Bus Fault, MMF → Exception이 발생하면 처리할 수 있도록 개선
- NMI (Non-Maskable Interrupt)
- NVIC 설정으로 무시할 수 없는 가장 높은 인터럽트
- 예를 들어서 크리스털이 깨져버리면 → 인터럽트로 우선 내부 RC 발진을 사용하도록 변환
- MPU (Memory Protection Unit)
- 메모리 접근에 대한 오류
- 필수는 아님. 펌웨어에서는 딱히 필요는 없고, RTOS로 올라가면 의미가 있음.
- 그런데 완전히 세부적으로 나누지는 못하고, 대략 8개의 공간으로 나눠서 관리함.
ㅤ
ㅤ
FreeRTOS는 RTOS의 카테고리인가?
RTOS와 함께 나오는 키워드가 바로 FreeRTOS이다. 현재 실습으로 사용해보고 있는 RTOS 역시 FreeRTOS. 그렇다면 이 FreeRTOS가 뭐길래 자꾸 언급되는 것일까? 궁금해서 찾아봤다. 앞으로 쓰게될 기술의 이름인데, 모르면 말이 안되지.
ㅤ
우선, FreeRTOS는 가장 널리 사용되고 있는 AWS에서 관리하는 무료 RTOS이다. 즉, FreeRTOS라는 이름은 제품명이라고 보면 된다! FreeRTOS는 초경량으로 구현되어있기에, Cortex-M 에 최적화되어 사용할 수 있다.
ㅤ
FreeRTOS와 다른 RTOS 제품들
FreeRTOS
- 오픈소스이며 무료
- 초경량, 단순한 구조의 모델
- Soft Real-Time과 중간 정도의 Hard Real-Time 시스템에 적용할 수 있다.
- “학습용으로는 최고”
ㅤ
상용 RTOS : ThreadX, VxWorks, QNX, AUTOSAR
- 유료 (← 벌써 타격이 온다)
- 더 엄격한 인증을 받아, Real-Time 성능 우수
- 상용 제품에서 사용하는 모델
- 특히 AUTOSAR는 차량 산업 표준이며 훨씬 복잡한 구조를 가지고 있다.
ㅤ
FreeRTOS는 특히 다음의 상황에서 적용하기에 적합하다.
- 서로 대기나 블로킹이 없는 테스크의 멀티테스킹
- 시간 제약이 있는 작업이 섞여있을 때 스케줄 관리
- 우선순위와 정확한 주기를 지켜서 테스크를 처리해야하는 경우
- 네트워크 스택을 다루어야하는 경우
- 모듈화가 필요한 크기가 큰 프로젝트
'Embedded System > MCU' 카테고리의 다른 글
| [FreeRTOS] RTOS의 System Exception (0) | 2025.11.15 |
|---|---|
| [FreeRTOS] Task의 생성과 관리 (0) | 2025.11.15 |
| [MCU] Independent 워치독 타이머 - IWDG (0) | 2025.11.09 |
| [MCU] General Purpose Timer (0) | 2025.11.09 |
| [MCU] STM32F429ZIT6의 타이머들 (0) | 2025.11.07 |