공부저장소
RTOS(Real-Time Operating System) 본문
RTOS는 정해진 시간(Deadline) 안에 반드시 작업을 완료해야 하는 실시간 운영체제이다. MCU 안에서 여러 태스크가 하나의 CPU를 나눠 쓴다. 하지만 CPU는 한 번에 하나의 작업밖에 못 한다. 그래서 RTOS가 "지금 누가 CPU를 쓸지" 를 결정하고 전환시켜 준다.
예시
void CAN_Task(void *arg) {
while (1) {
receive_can_message();
vTaskDelay(10); // 10ms 대기
}
}
void Motor_Task(void *arg) {
while (1) {
update_pwm();
vTaskDelay(1); // 1ms 대기
}
}각 태스크는 무한루프 형태이고, 대기 중일 때는 Delay를 줌으로써 CPU 사용을 안한다.
스케줄러 동작
RTOS 스케줄러는 매우 짧은 주기마다 실행된다.
- 틱: RTOS가 시간을 측정하는 최소 단위
태스크 상태는 4가지 이다.틱마다 스케줄러가 확인: 현재 READY 상태인 태스크 중 → 우선순위 가장 높은 것 → CPU 할당READY → 실행 가능, CPU 기다리는 중 RUNNING → 현재 CPU 사용 중 (한 번에 하나만 가능) BLOCKED → 대기 중 (타이머, 메시지, 세마포어 등 기다림) SUSPENDED → 일시 정지
선점 (Preemption)
낮은 우선순위 태스크가 실행 중일 때, 높은 우선순위 태스크가 READY 상태가 되면 즉시 CPU를 빼앗는다. (숫자 큰게 젤 우선순위 높은거임)
Motor_Task (우선순위 1) 실행 중
↓
CAN 수신 인터럽트 발생 → CAN_Task (우선순위 2) READY
↓
Motor_Task 실행 중단, 레지스터 값 스택에 저장 (Context Save)
↓
CAN_Task 실행
↓
CAN_Task 완료 or 대기 상태 진입
↓
Motor_Task 레지스터 복구 (Context Restore), 이어서 실행Tick과 Deadline
RTOS의 시간 단위는 Tick 이다.
Tick = 하드웨어 타이머 인터럽트 주기
보통 1ms = 1 Tick
vTaskDelay(10) = 10 Tick = 10ms 대기Hard Real-time: Deadline을 1번이라도 넘기면 시스템 오류로 처리
Soft Real-time: Deadline을 가끔 넘겨도 시스템은 동작하지만 성능 저하
세마포어 / 뮤텍스
두 태스크가 같은 자원(메모리, 레지스터, 버퍼 등) 에 동시 접근하면 데이터가 깨진다.
// 뮤텍스로 보호
xSemaphoreTake(mutex, portMAX_DELAY); // 잠금
can_buffer[idx] = data; // 공유 자원 접근
xSemaphoreGive(mutex); // 해제뮤텍스를 잠근 태스크가 끝내기 전까지, 다른 태스크는 BLOCKED 상태로 대기한다.
메시지 큐
태스크 간 데이터를 전달할 때 쓴다.
// CAN 수신 태스크 → 큐에 넣기
xQueueSend(can_queue, &can_msg, 0);
// 처리 태스크 → 큐에서 꺼내기
xQueueReceive(can_queue, &can_msg, portMAX_DELAY);큐가 비어있으면 수신 태스크는 BLOCKED 상태로 자동 대기한다.
정리
Task: 독립적으로 실행되는 함수 단위
Scheduler: 우선순위 기반으로 CPU 할당 결정
Tick: RTOS의 시간 기준 단위
Preemption: 높은 우선순위가 CPU 즉시 선점
Context Switch: CPU 상태 저장/복구 후 태스크 전환
Mutex/Semaphore: 공유 자원 동시 접근 방지
Message Queue: 태스크 간 데이터 전달