자동차 제어기(ECU) 소프트웨어는 정해진 시간 안에 반드시 연산을 끝내야 하는 실시간성(Real-Time)과 절대 다운되지 않아야 하는 고신뢰성을 요구합니다. 일반적인 범용 OS(Linux, Windows)는 런타임에 동적으로 프로세스를 생성하고 가상 메모리를 사용하기 때문에 응답 시간을 밀리초(ms) 단위로 엄격히 보장하기 어렵습니다.
AUTOSAR는 이를 위해 차량용 실시간 운영체제 표준인 OSEK/VDX OS를 기반으로 확장한 AUTOSAR OS를 표준 BSW(Basic Software) 계층으로 채택하고 있습니다.
이 글에서는 AUTOSAR OS의 동작 원리, Basic Task와 Extended Task의 차이, SWC 러너블(Runnable)이 실제 OS Task로 매핑되는 과정, 우선순위 체계와 스케줄링, 그리고 Category 1과 Category 2 ISR의 구분까지 실무 관점에서 정리합니다.
1. AUTOSAR OS란 무엇인가
AUTOSAR OS는 정적 설정(Static Configuration) 기반의 실시간 운영체제(RTOS)입니다.
리눅스나 일반 OS와 구분되는 가장 큰 특징은 컴파일 및 빌드 시점에 필요한 모든 Task, 스택 크기, 우선순위, 알람, 이벤트 정보가 XML(ARXML)로 확정된다는 점입니다. 시스템이 켜진 후 동적으로 Task를 생성하거나 메모리를 동적 할당(malloc)하는 작업은 금지됩니다.
이러한 정적 설정 구조는 다음과 같은 장점을 제공합니다.
- 예측 가능성(Predictability): 실행할 Task와 인터럽트의 수가 고정되어 있어 최악의 경우에도 응답 시간(Worst-Case Execution Time)을 수학적으로 계산할 수 있습니다.
- 최소한의 오버헤드: 동적 메모리 관리자나 복잡한 프로세스 관리자가 없으므로 수 킬로바이트(KB) 수준의 작은 RAM과 Flash 메모리를 가진 마이크로컨트롤러(MCU)에서도 가볍고 빠르게 동작합니다.
- 고신뢰성: 런타임 메모리 고갈이나 댕글링 포인터로 인한 OS 크래시를 원천 방지합니다.
2. Task의 종류와 상태 전이
AUTOSAR OS의 실행 단위인 Task는 크게 두 가지 종류로 나뉩니다.
2.1 Basic Task (베이직 태스크)
Basic Task는 가장 단순하고 가벼운 형태의 태스크입니다.
- 상태 종류:
Suspended(휴면),Ready(준비),Running(실행 중) 세 가지만 존재합니다. - 대기 상태 불가: 외부 사건이나 이벤트를 기다리며 스스로 실행을 멈추는
Waiting상태가 없습니다. - 동작 원리: 일단 기동(
ActivateTask)되면 상위 우선순위 태스크에 의해 선점(Preemption)당할 수는 있지만, 스스로 대기하지 않고 끝(TerminateTask)까지 실행을 마칩니다. - 메모리 이점: 모든 Basic Task가 한 번에 하나씩만 실행되므로, OS 설정에 따라 단일 공유 스택(Single Shared Stack)을 사용하여 RAM 사용량을 극단적으로 줄일 수 있습니다.
2.2 Extended Task (익스텐디드 태스크)
Extended Task는 이벤트 기반 처리를 위해 Waiting 상태를 추가로 지원하는 태스크입니다.
- 상태 종류:
Suspended,Ready,Running, 그리고Waiting(대기) 네 가지가 존재합니다. - 이벤트 대기:
WaitEvent()API를 호출하여 특정 이벤트(예: 데이터 수신, 타이머 완료)가 발생할 때까지 스스로 실행을 중단하고 대기 상태로 들어갈 수 있습니다. 다른 곳에서SetEvent()를 호출해 주면 다시Ready상태로 복귀합니다. - 독립 스택 필수: 대기 상태에 들어간 순간의 레지스터와 로컬 변수를 보존해야 하므로, 각 Extended Task마다 반드시 독립된 전용 스택(Private Stack) 메모리를 할당해야 합니다. RAM 소모가 Basic Task보다 훨씬 큽니다.
2.3 Basic Task vs Extended Task 비교
| 구분 항목 | Basic Task (베이직 태스크) | Extended Task (익스텐디드 태스크) |
|---|---|---|
| 지원 상태 | Suspended, Ready, Running | Suspended, Ready, Running, Waiting |
이벤트 대기 (WaitEvent) |
지원하지 않음 | 지원함 |
| 스택 메모리 구조 | Task 간 스택 공유 가능 (RAM 절약) | Task별 독립 스택 필수 (RAM 소모 큼) |
| 컨텍스트 스위칭 비용 | 매우 낮음 | 상대적으로 높음 |
| 대표적인 사용처 | 1ms, 10ms 등 주기적 제어 루프 | 비주기적 이벤트 처리, 진단 통신, 플래시 쓰기 |
실무에서는 메모리 절약과 결정론적 스케줄링을 위해 대부분의 제어 로직을 Basic Task로 구성하고, 백그라운드 통신이나 복잡한 상태 머신 대기가 필요한 일부 기능에만 Extended Task를 선별적으로 적용합니다.
3. 러너블(Runnable)과 OS Task의 매핑 관계
AUTOSAR 개발에서 초심자들이 가장 많이 헷갈리는 부분 중 하나가 SWC의 러너블(Runnable)과 OS Task의 관계입니다.
- 러너블(Runnable Entity): SWC 개발자가 작성하는 순수 C 언어 함수입니다. (예:
void Runnable_CalculateSpeed(void)) - OS Task: RTOS가 CPU 시간을 배분하여 스케줄링하는 실제 실행 주체입니다.
러너블은 스스로 실행될 수 없으며, 반드시 RTE 설정을 통해 특정 OS Task의 본체 내부로 매핑되어야만 CPU에서 돌아갑니다.
3.1 1:1 매핑 vs N:1 매핑
러너블을 태스크에 배치할 때 두 가지 전략이 있습니다.
-
1:1 매핑
- 러너블 하나마다 전용 OS Task를 하나씩 생성하여 연결합니다.
- 단점: Task 개수가 급증하고, 매번 Task 진입/퇴출에 따른 OS 컨텍스트 스위칭 오버헤드가 발생하여 CPU 낭비가 극심합니다.
-
N:1 매핑 (실무 표준 방식)
- 실행 주기가 같거나 성격이 비슷한 여러 개의 러너블을 하나의 OS Task 본체 안에 함수 호출 순서대로 묶어 넣습니다.
- 장점: OS Task는 단 하나만 돌면서 내부에서 C 함수를 차례대로 호출하므로, 불필요한 컨텍스트 스위칭을 없애고 CPU 효율을 극대화할 수 있습니다.
3.2 RTE가 생성하는 실제 Task 코드 예시
예를 들어 SWC_A의 10ms 주기 제어 러너블과 SWC_B의 10ms 필터 러너블을 Task_10ms라는 Basic Task 하나로 묶었다면, RTE 생성기는 대략 다음과 같은 C 코드를 자동으로 만들어 냅니다.
/* RTE가 생성한 OS Task 본체 */
TASK(Task_10ms)
{
/* 1. Implicit 통신인 경우 입력 스냅샷 복사 */
Rte_Task_10ms_StartHook();
/* 2. 매핑된 SWC 러너블들을 순차적으로 실행 */
SWC_A_Runnable_Control_10ms();
SWC_B_Runnable_Filter_10ms();
/* 3. Implicit 통신인 경우 출력 결과 일괄 반영 */
Rte_Task_10ms_EndHook();
/* 4. OS 태스크 정상 종료 */
TerminateTask();
}
SWC 개발자는 OS API를 직접 알 필요 없이 러너블 함수만 작성하면 되고, 아키텍트는 ARXML 도구에서 러너블을 원하는 Task에 드래그 앤 드롭으로 매핑하면 됩니다.
4. 우선순위(Priority) 체계와 스케줄링 원리
AUTOSAR OS는 고정 우선순위 선점형 스케줄링(Fixed-Priority Preemptive Scheduling)을 기본으로 합니다.
4.1 우선순위 숫자의 의미
운영체제마다 우선순위 숫자의 방향이 다릅니다.
- Linux (Nice 값): 숫자가 작을수록 우선순위가 높습니다.
- OSEK / AUTOSAR OS: 숫자가 클수록 높은 우선순위입니다. (0이 최하위 우선순위)
실행 중인 Task보다 더 높은 우선순위 숫자를 가진 Task가 준비(Ready) 상태가 되면, CPU는 현재 Task를 즉시 일시정지(Preempt)시키고 높은 우선순위의 Task를 먼저 실행합니다. 동일한 우선순위를 가진 Task끼리는 FIFO(First-In, First-Out) 순서로 실행됩니다.
4.2 우선순위 역전(Priority Inversion)과 PCP
멀티태스킹 환경에서 공유 자원(뮤텍스, 전역 버퍼)을 사용할 때 우선순위 역전 문제가 발생할 수 있습니다.
- 저우선순위 Task L이 공유 자원을 획득하고 실행 중입니다.
- 고우선순위 Task H가 깨어나 동일한 공유 자원을 요구하지만, 이미 잠겨 있어서 대기 상태가 됩니다.
- 이때 자원과 아무 상관 없는 중간 우선순위 Task M이 깨어나 Task L을 선점해 버립니다.
- 결과적으로 최상위 Task H가 중간 Task M보다 늦게 실행되는 심각한 지연(우선순위 역전)이 발생합니다.
AUTOSAR OS는 이를 방지하기 위해 표준 OSEK 기능인 우선순위 천장 프로토콜(PCP, Priority Ceiling Protocol)을 기본 내장하고 있습니다.
- 원리: 각 공유 자원(OS Resource)에는 해당 자원을 사용할 수 있는 모든 Task 중 가장 높은 우선순위(Ceiling Priority)가 정적으로 부여됩니다.
- 동작: 어떤 Task가 자원을 획득하는 즉시, 그 Task의 우선순위가 일시적으로 Ceiling Priority까지 강제로 올라갑니다. 따라서 중간 우선순위 Task가 끼어들 수 없으며, 작업이 끝나 자원을 반납하면 원래 우선순위로 즉시 복귀합니다.
5. 인터럽트 처리: Category 1 ISR vs Category 2 ISR
차량용 제어기에서는 CAN 메시지 수신, 모터 위치 엔코더 입력, 타이머 오버플로우 등 수많은 하드웨어 인터럽트가 발생합니다. AUTOSAR OS는 인터럽트 서비스 루틴(ISR)을 두 가지 카테고리로 엄격히 분리합니다.
| 구분 항목 | Category 1 ISR (Cat 1) | Category 2 ISR (Cat 2) |
|---|---|---|
| OS 개입 여부 | OS를 전혀 거치지 않음 | OS가 진입/복귀를 래핑하여 제어 |
| 응답 지연 (Latency) | 하드웨어 수준의 초고속 (극최소 지연) | OS 프롤로그/에필로그로 인한 약간의 지연 |
| OS API 호출 | 일체 호출 불가 | OS API 호출 가능 (SetEvent, ActivateTask 등) |
| 컨텍스트 스위칭 | 인터럽트 복귀 시 기존 태스크로 즉시 복귀 | 인터럽트 처리 중 깨어난 고우선순위 태스크로 스위칭 가능 |
| 대표적 용도 | 극도로 빠른 처리가 필요한 모터 PWM 제어, 엔코더 | 일반 통신 수신(CAN/LIN), 타이머 틱, 센서 완료 통지 |
5.1 Category 1 ISR의 특징
MCU의 인터럽트 벡터가 C 함수로 직접 점프합니다. OS 스케줄러가 개입하지 않으므로 인터럽트 진입 오버헤드가 사실상 0에 가깝습니다. 하지만 OS 상태를 변경할 수 없으므로 SetEvent()나 ActivateTask() 같은 OS 함수를 호출할 수 없습니다.
5.2 Category 2 ISR의 특징
인터럽트가 발생하면 OS가 먼저 개입하여 현재 레지스터를 백업하고 ISR 본체를 실행한 뒤 복귀합니다. ISR 내부에서 통신 수신 이벤트를 알리기 위해 SetEvent()를 호출하면, 인터럽트가 끝나는 시점에 OS 스케줄러가 이를 감지하여 해당 이벤트를 기다리던 상위 Task로 즉시 CPU를 전환할 수 있습니다.
6. 시간 관리와 실행 트리거: Counter, Alarm, Schedule Table
주기적인 태스크 실행과 타임아웃 감시를 위해 AUTOSAR OS는 세 가지 시간 요소를 조합하여 사용합니다.
[ 하드웨어 타이머 인터럽트 ]
│
▼
[ OS Counter ] ──> 하드웨어 틱(Tick)을 누적 계수 (예: 1ms마다 +1)
│
├──────────────────────────┐
▼ ▼
[ OS Alarm ] [ Schedule Table ]
정해진 카운터 값에 도달 시 정해진 오프셋 시점마다
단일 Task 기동 또는 이벤트 전달 여러 Task를 정밀하게 분산 기동
-
Counter (카운터)
- 하드웨어 타이머 인터럽트나 소프트웨어 이벤트를 기반으로 틱(Tick)을 1씩 증가시키는 시간 측정기입니다. (예: 1ms 시스템 타이머 카운터)
-
Alarm (알람)
- 카운터가 특정 값에 도달했을 때 지정된 동작을 수행합니다.
- 동작 형태: Task 기동(
ActivateTask), 이벤트 설정(SetEvent), 알람 콜백 실행 등. - 주기적(Cyclic)으로 반복 설정할 수 있어 10ms, 100ms 주기의 주기 Task를 깨우는 데 사용됩니다.
-
Schedule Table (스케줄 테이블)
- 여러 개의 기동 시점을 하나의 테이블에 오프셋(초 단위/밀리초 단위)별로 나열해 둔 정밀 시간표입니다.
- 예를 들어 0ms에 Task A 기동, 2ms에 Task B 기동, 5ms에 Task C 기동처럼 실행 시점을 물리적으로 분산시켜 CPU 사용률이 한순간에 100%로 솟구치는 피크(Peak Load) 현상을 완화합니다.
7. 시스템 보호 기능: OS-Application과 메모리/타이밍 보호
기능 안전(ISO 26262)과 멀티코어 환경을 충족하기 위해 AUTOSAR OS는 표준 OSEK을 넘어선 강력한 하드웨어 보호 메커니즘을 제공합니다.
-
OS-Application
- 관련 있는 Task, ISR, 알람, 자원들을 하나의 그룹(파티션)으로 묶은 단위입니다.
- 신뢰 영역(Trusted OS-Application)과 비신뢰 영역(Non-Trusted OS-Application)으로 나누어, ASIL 등급이 서로 다른 소프트웨어가 같은 MCU 안에서 상호 간섭(Interference) 없이 안전하게 공존하도록 만듭니다.
-
메모리 보호 (Memory Protection)
- MCU 내부의 MPU(Memory Protection Unit)를 사용하여 특정 Task가 다른 Task의 스택이나 비인가된 전역 RAM 영역을 무단으로 읽거나 쓰지 못하도록 하드웨어 레벨에서 차단합니다. 위반 발생 시 즉시 메모리 예외 트랩이 발생합니다.
-
타이밍 보호 (Timing Protection)
- 특정 Task가 무한 루프에 빠져 CPU를 독점하거나, 인터럽트가 너무 자주 발생하여 시스템이 마비되는 것을 막습니다.
- 실행 시간 예산(Execution Time Budget): Task가 정해진 시간 이상 CPU를 점유하면 강제 차단합니다.
- 인터럽트 잠금 시간 제한:
DisableAllInterrupts()를 호출한 뒤 너무 오래 잠그고 있으면 OS가 에러를 감지합니다.
8. 실무 Task 설계 가이드라인 및 요약
실제 차량용 제어기 소프트웨어를 설계할 때 유용한 핵심 체크리스트입니다.
- 동일 주기 러너블은 하나의 Basic Task로 묶어라
- 10ms 주기의 센서 처리, 제어 로직 등은 N:1 매핑을 활용해 단일
Task_10ms안에 배치하여 OS 컨텍스트 스위칭 낭비를 줄입니다.
- 10ms 주기의 센서 처리, 제어 로직 등은 N:1 매핑을 활용해 단일
- Extended Task는 꼭 필요한 곳에만 사용하라
- Extended Task는 개별 스택을 차지하므로 남발하면 RAM이 급격히 고갈됩니다. 단순 주기 연산은 무조건 Basic Task를 기본으로 사용합니다.
- 짧은 주기 Task에 높은 우선순위를 부여하라
- Rate Monotonic Scheduling(RMS) 이론에 따라, 주기가 짧고 실행 빈도가 높은 Task(예: 1ms, 5ms)에 높은 우선순위 숫자를 부여해야 데드라인 준수에 유리합니다.
- Schedule Table로 CPU 부하를 분산하라
- 10ms 태스크와 20ms, 100ms 태스크가 100ms 시점에 동시에 시작되면 순간 부하가 100%를 초과할 수 있습니다. 오프셋을 2ms, 4ms 등으로 어긋나게 배치하여 부하를 평탄화합니다.
AUTOSAR OS는 정적 설정의 엄격함 속에서 극대화된 실시간성과 안전성을 보장하는 전장 소프트웨어의 뼈대입니다. Task의 종류와 러너블 매핑 원리를 정확히 이해하고 설계하면 최적의 성능과 안정성을 갖춘 ECU 아키텍처를 구축할 수 있습니다.