SWC와 Runnable이란? : AUTOSAR 소프트웨어의 기본 단위
SWC와 Runnable이란?

[Autosar Series]
1. 2025.12.14 - [AUTOSAR 기초] - 오토사(AUTOSAR)가 정확히 뭔가요? 개념부터 왜 배워야 하는지까지
오토사(AUTOSAR)가 정확히 뭔가요? 개념부터 왜 배워야 하는지까지
AUTOSAR란?AUTOSAR의 정의, 탄생 배경, 왜 배워야 하는지들어가며안녕하세요, 버그없는토마토입니다.여러분, 혹시 채용공고에서 "AUTOSAR 경험자 우대" 같은 문구를 봤나요?현대, LG이노텍, 기아, BMW, 아
jungposco.com
2. 2025.12.14 - [AUTOSAR 기초] - 오토사(AUTOSAR) Classic vs Adaptive: 어떤 차이? 알아야할까?
오토사(AUTOSAR) Classic vs Adaptive: 어떤 차이? 알아야할까?
오토사(AUTOSAR) Classic vs Adaptive: 어떤 차이?오토사(AUTOSAR) Classic이란?오토사(AUTOSAR) Adaptive란? 들어가며안녕하세요, 버그없는토마토입니다.지난 편에서 AUTOSAR가 뭔지 배웠어요.자동차 소프트웨어의
jungposco.com
3. 2025.12.14 - [AUTOSAR 기초] - AUTOSAR 계층 구조: ASW-RTE-BSW 완벽 이해
AUTOSAR 계층 구조: ASW-RTE-BSW 완벽 이해
AUTOSAR 계층 구조: ASW-RTE-BSW 완벽 이해AUTOSAR 계층 구조는?들어가며지난 두 편에서 AUTOSAR가 뭔지, Classic과 Adaptive의 차이가 뭔지 배웠어요. 이제 본격적으로 AUTOSAR의 내부 구조를 파헤칠 차례예요.조
jungposco.com
들어가며
안녕하세요 버그없는토마토입니다.
지난 세 편에서 AUTOSAR의 전체 구조를 배웠어요. Classic과 Adaptive의 차이, ASW-RTE-BSW 계층까지.
기본적인 배경지식과 기초를 쌓았다고 생각하시면 편할거예요
이제 기둥을 세우는 과정을 하게 될거예요
AUTOSAR 소프트웨어가 정확히 '어떻게' 구성되는지 배워볼 차례예요.
이건 오토사 심화에서 다루는 내용들이기 때문에 다뤄본적이 없을 경우 생소해서 이해하기 쉽지 않을 수 있어요..
그래서 최대한 그림과 함께 설명하기 위해 노력했는데..
제 노력이 조금이나마 여러분들의 이해에 도움이 됐으면 좋겠습니다.
ASW (응용 소프트웨어)는 마치 빌딩처럼 여러 개의 작은 모듈들로 이루어져 있어요.
이런 모듈을 'SWC (Software Component)'라고 부르고, SWC 안에는 'Runnable'이라는 '실행 함수'가 있어요.
소프트웨어컴포넌트, 러너블에 관련한 내용은 오토사 플랫폼인 모빌진을 사용한다면 쉽게 접할 수 있는데요.
맨날 '컴포넌트, 컴포넌트', '러너블,러너블', 'RTE, RTE' 하지만 추상적인 개념말고 정확한 개념은 모르는 경우가 많죠
오늘 한번 자세히 한번 배워봅시다.
오늘 배울 내용의 큰 틀을 먼저 맛보기로 살펴볼게요:
자동차의 엔진 ECU:
├─ EngineControlSWC (엔진 제어 모듈)
│ ├─ EngineControl_Runnable (10ms마다 실행)
│ └─ FuelInjection_Runnable
├─ DiagnosticSWC (진단 모듈)
│ └─ DTC_Recording_Runnable (100ms마다 실행)
└─ CommunicationSWC (통신 모듈)
└─ SignalSending_Runnable (50ms마다 실행)
이 글에서는 SWC와 Runnable의 정의, 역할, 상호작용을 명확하게 설명할게요.

🏗️ SWC: Software Component란?
SWC의 정의
SWC = 소프트웨어 컴포넌트
AUTOSAR에서 재사용 가능한 소프트웨어 기능 단위예요.
마치 레고 블록처럼, 여러 SWC를 조합해서 전체 애플리케이션을 만들어요.
SWC의 특징
1️⃣ 독립적이고 재사용 가능
한 번 만든 SWC를 여러 프로젝트에서 사용할 수 있어요.
예시: EngineControlSWC 만들기
BMW에서 만듦:
- BMW 5시리즈 엔진 ECU
이걸 다시 사용:
- BMW 7시리즈 엔진 ECU
(거의 그대로 사용!)
- Mercedes C-Class 엔진 ECU
(약간 조정하면 사용!)
- Audi A6 엔진 ECU
(약간 조정하면 사용!)
→ 개발 비용 대폭 절감!
2️⃣ 입출력 인터페이스가 명확
SWC는 명확한 입력 (Require Port)과 출력 (Provide Port)을 가져요.
리시브포트로 불리죠 Pport Rport
EngineControlSWC:
입력 (Require Port):
├─ ThrottlePosition (스로틀 위치)
├─ EngineTemperature (엔진 온도)
└─ VehicleSpeed (차량 속도)
출력 (Provide Port):
├─ DesiredTorque (원하는 토크)
├─ FuelInjectionPulse (분사 신호)
└─ IgnitionTiming (점화 타이밍)
이렇게 명확하면, 다른 SWC와 쉽게 연결할 수 있어요!
3️⃣ 다른 SWC와 느슨한 결합
SWC는 직접 다른 SWC를 호출하지 않아요. RTE를 통해서만 통신해요.
❌ 잘못된 방식 (강한 결합):
EngineControlSWC가 직접
TransmissionControlSWC.CalculateGear() 호출
→ 변경 어려움!
✅올바른 방식 (느슨한 결합):
EngineControlSWC: "엔진 RPM = 3000"
↓ (RTE 통신)
TransmissionControlSWC: "RPM 받았어! 기어 선택해야겠다"
→ 수정 용이!
SWC의 구조
┌─────────────────────────────────┐
│ EngineControlSWC │
├─────────────────────────────────┤
│ │
│ Require Ports (입력): │
│ ├─ ThrottlePosition │
│ ├─ EngineTemperature │
│ └─ VehicleSpeed │
│ │
├─────────────────────────────────┤
│ │
│ Runnables (실행 함수): │
│ ├─ EngineControl_10ms │
│ ├─ FuelInjection_10ms │
│ └─ DiagnosticCheck_100ms │
│ │
├─────────────────────────────────┤
│ │
│ Provide Ports (출력): │
│ ├─ DesiredTorque │
│ ├─ FuelInjectionPulse │
│ └─ IgnitionTiming │
│ │
└─────────────────────────────────┘
⚙️ Runnable: 실행 함수
Runnable의 정의
Runnable = SWC 내부의 실행 함수
정해진 시간에 실행되는 코드 블록이에요.
Runnable의 특징
1️⃣ 주기적 또는 이벤트 기반 실행
주기적 실행 (Periodic):
┌──────┐
│ 0ms │ EngineControl_Runnable 시작
│ │ (일부 코드 실행...)
│ │
│ 10ms │ EngineControl_Runnable 시작 (다시!)
│ │
│ 20ms │ EngineControl_Runnable 시작 (또 다시!)
└──────┘
이벤트 기반 실행 (Event-Triggered):
센서에서 신호 들어옴 (예: 문 열림 감지)
↓
DoorOpeningDetected_Runnable 즉시 실행
↓
"문 열렸어! 경고음 울려!" 처리
2️⃣ Runnable의 실행 속성
각 Runnable은 다음을 가져요:
| 속성 | 설명 | 예시 |
|---|---|---|
| 이름 | Runnable의 고유 이름 | EngineControl_10ms |
| 주기 | 얼마나 자주 실행되나? | 10ms (매 10ms마다) |
| 실행 시간 | 실행이 얼마나 오래 걸나? | 5ms (WCET: Worst Case Execution Time) |
| 우선순위 | 여러 Runnable 중 누가 먼저? | 우선순위 10 |
| 트리거 | 뭐가 실행 신호일까? | TimerInterrupt (타이머 인터럽트) |
3️⃣ 원자성 (Atomicity): 중단 없이 실행
한 번 Runnable이 시작되면, 끝날 때까지 중단되지 않아요.
Time 0ms:
┌─────────────────────┐
│ EngineControl_10ms │
│ 시작 │
│ │
│ 3ms 소비 │
│ │
│ 끝 │ ← 중간에 다른 Runnable 못 끼어들어!
└─────────────────────┘
Time 10ms:
다음 EngineControl_10ms 시작 (다시!)
이걸 원자성(Atomicity)이라고 불러요. 데이터 일관성을 보장해요!
Runnable의 실행 사이클
시간: 0ms 10ms 20ms 30ms 40ms 50ms
─────────────────────────────────
10ms 주기: ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐
Run1 Run1 Run1 Run1 Run1
↑
100ms 주기: ┌──────────────────┐ ┌──────
Run2 Run2
↑
50ms 주기: ┌──────────┐ ┌──────────
Run3 Run3
↑
각 Runnable이 정확한 시간에 실행돼요!
🔗 Port: SWC 간 통신
Port란?
Port = SWC 간 통신 채널
두 가지 종류가 있어요:
1️⃣ Require Port (필요 포트)
"다른 SWC의 데이터가 필요해!"
EngineControlSWC:
├─ Require: ThrottlePosition
│ (스로틀 SWC에서 위치 받음)
├─ Require: EngineTemperature
│ (온도 센서 SWC에서 온도 받음)
└─ Require: VehicleSpeed
(속도 SWC에서 속도 받음)
구현:
uint8 throttle = Rte_Read_ThrottlePosition();
float temp = Rte_Read_EngineTemperature();
2️⃣ Provide Port (제공 포트)
"내 데이터를 다른 SWC에 제공할게!"
EngineControlSWC:
├─ Provide: DesiredTorque
│ (변속기 SWC가 받음)
├─ Provide: FuelInjectionPulse
│ (연료 분사 SWC가 받음)
└─ Provide: IgnitionTiming
(점화 시스템 SWC가 받음)
구현:
float torque = CalculateTorque(rpm);
Rte_Write_DesiredTorque(torque);
Port의 커뮤니케이션
┌──────────────────────┐
│ ThrottleSensorSWC │
│ ─────────────────── │
│ Provide: │
│ └─ ThrottlePosition │ (위치 제공)
└──────────┬───────────┘
│
│ (RTE 연결)
▼
┌──────────────────────┐
│ EngineControlSWC │
│ ─────────────────── │
│ Require: │
│ └─ ThrottlePosition │ (위치 필요)
└──────────┬───────────┘
│
│ (RTE 연결)
▼
┌──────────────────────┐
│ TransmissionSWC │
│ ─────────────────── │
│ Provide: │
│ └─ DesiredGear │
└──────────────────────┘
(실제로는 RTE가 모든 신호 라우팅 처리)
Port 타입 (Interface Type)
데이터 포트 (Data Port):
신호를 직접 읽고 쓰는 방식
uint8 rpm = Rte_Read_EngineRPM();
// 최신 값을 그대로 읽음
큐 포트 (Queue Port):
신호를 큐(대기열)에 넣는 방식
// 최근 3개의 신호를 모두 처리
while (Rte_Receive_Signal(&data)) {
Process(data);
}
서버 포트 (Server Port) - Classic은 드물고, Adaptive가 많음:
함수처럼 호출하는 방식
result = Rte_Call_Service(param);
// "이 서비스를 해줘"라고 요청
// 결과를 받음
🚗 실제 자동차 ECU 구성 예시
말 그대로 예시입니다. 가상의 구현!!
예시 1: 현대 so나타 엔진 ECU
EngineECU:
│
├─ EngineControlSWC
│ ├─ Require Ports:
│ │ ├─ CrankshaftPosition (크랭크샤프트 위치, 센서)
│ │ ├─ ThrottlePosition (스로틀 위치, 센서)
│ │ ├─ AirIntakeFlow (흡입 공기량, 센서)
│ │ ├─ CoolantTemperature (냉각수 온도, 센서)
│ │ ├─ BrakeSignal (제동 신호, 제동 ECU)
│ │ └─ VehicleSpeed (차량 속도, ABS ECU)
│ │
│ ├─ Runnables:
│ │ ├─ EngineControl_10ms (10ms 주기)
│ │ │ → 엔진 RPM 읽기
│ │ │ → 분사량 계산
│ │ │ → 분사 명령 내보내기
│ │ │
│ │ └─ FuelInjection_10ms (10ms 주기)
│ │ → 분사 신호 생성
│ │
│ └─ Provide Ports:
│ ├─ EngineRPM (엔진 회전수 → 변속기 ECU)
│ ├─ EngineTorque (엔진 토크 → 변속기 ECU)
│ ├─ EngineLoad (엔진 부하 → OBD 시스템)
│ └─ EmissionLevel (배출가스 수준 → 촉매)
│
├─ DiagnosticSWC
│ ├─ Require Ports:
│ │ ├─ O2SensorVoltage (산소 센서 전압)
│ │ ├─ KnockSignal (노킹 신호)
│ │ └─ ThrottleSignal
│ │
│ ├─ Runnables:
│ │ └─ DiagnosticCheck_100ms (100ms 주기)
│ │ → 센서 고장 검사
│ │ → DTC 기록
│ │
│ └─ Provide Ports:
│ └─ DTC_Data (오류 코드 → 진단 시스템)
│
└─ CommunicationSWC
├─ Require Ports:
│ ├─ EngineRPM (엔진 제어 SWC에서)
│ ├─ EngineTorque
│ └─ DTC_Data (진단 SWC에서)
│
├─ Runnables:
│ └─ CAN_MessagePrepare_10ms (10ms 주기)
│ → CAN 메시지 생성
│
└─ Provide Ports:
├─ CAN_EngineData (CAN ID 0x100)
└─ CAN_DiagnosticData (CAN ID 0x200)
예시 2: 기아 EV10 배터리 관리 시스템 (BMS)
BatteryECU:
│
├─ BatteryStateMonitoringSWC
│ ├─ Require Ports:
│ │ ├─ CellVoltages[96] (96개 셀 전압)
│ │ ├─ PackCurrent (배터리 충방전 전류)
│ │ ├─ CellTemperatures[12] (12개 온도 센서)
│ │ └─ HighVoltageContactorStatus (HV 접점 상태)
│ │
│ ├─ Runnables:
│ │ ├─ StateOfCharge_100ms (100ms 주기)
│ │ │ → SOC (충전 상태) 계산
│ │ │
│ │ ├─ StateOfHealth_1s (1000ms 주기)
│ │ │ → SOH (건강도) 계산
│ │ │
│ │ └─ SafetyCheck_50ms (50ms 주기)
│ │ → 과전압/과전류 감지
│ │
│ └─ Provide Ports:
│ ├─ SOC (충전 상태)
│ ├─ SOH (배터리 건강도)
│ ├─ BatteryReadySignal (충전 준비 신호)
│ └─ BatteryErrorCode (오류 코드)
│
├─ ThermalManagementSWC
│ ├─ Require Ports:
│ │ ├─ CellTemperatures[12]
│ │ ├─ MotorTorque (모터 토크)
│ │ └─ AmbientTemperature (외부 온도)
│ │
│ ├─ Runnables:
│ │ └─ CoolingControl_100ms (100ms 주기)
│ │ → 냉각액 펌프 제어
│ │ → 냉각 팬 속도 결정
│ │
│ └─ Provide Ports:
│ ├─ CoolingPumpCommand (펌프 명령)
│ └─ CoolingFanSpeed (팬 속도)
│
├─ CellBalancingSWC
│ ├─ Require Ports:
│ │ ├─ CellVoltages[96]
│ │ └─ BalancingStatus
│ │
│ ├─ Runnables:
│ │ └─ BalancingControl_500ms (500ms 주기)
│ │ → 각 셀의 전압 차이 계산
│ │ → 불균형 셀 밸런싱
│ │
│ └─ Provide Ports:
│ ├─ BalancingResistorControl[96] (각 셀별)
│ └─ BalancingStatus
│
└─ ChargerCommunicationSWC
├─ Require Ports:
│ ├─ SOC
│ ├─ BatteryReadySignal
│ └─ ChargerInputVoltage (외부 충전기 전압)
│
├─ Runnables:
│ └─ ChargeProtocol_100ms (100ms 주기)
│ → 충전 프로토콜 처리 (CCS, Type2)
│ → 충전 레벨 결정
│
└─ Provide Ports:
├─ ChargePermission (충전 허용)
└─ ChargeCurrentLimit (충전 전류 제한)
📋 SWC 설계 패턴
패턴 1: 센서 SWC
목적: 센서에서 데이터 읽기, 정제, 제공
SensorSWC:
├─ Require Ports: 없음 (센서가 입력)
├─ Runnables:
│ └─ SensorRead_10ms
│ → 아날로그 값 읽기 (ADC)
│ → 필터링 적용
│ → 범위 검사
└─ Provide Ports:
└─ SensorValue (정제된 값)
예: TemperatureSensorSWC
패턴 2: 제어 SWC
목적: 입력받아서 계산, 제어 결정
ControlSWC:
├─ Require Ports: 여러 입력값들
├─ Runnables:
│ └─ Control_10ms
│ → PID 제어 알고리즘
│ → 상태 머신
│ → 의사결정
└─ Provide Ports: 제어 명령값들
예: EngineControlSWC, BrakeControlSWC
패턴 3: 액추에이터 SWC
목적: 제어 명령을 물리 신호로 변환
ActuatorSWC:
├─ Require Ports: 제어 명령값
├─ Runnables:
│ └─ ActuatorCommand_10ms
│ → PWM 신호 생성
│ → 릴레이 제어
│ → 모터 제어
└─ Provide Ports: 없음 (물리 출력)
예: FuelInjectionSWC, FanControlSWC
패턴 4: 진단 SWC
목적: 오류 감지 및 기록
DiagnosticSWC:
├─ Require Ports: 모니터링할 신호들
├─ Runnables:
│ └─ SelfTest_100ms
│ → 센서 범위 검사
│ → 신호 일관성 검사
│ → DTC 기록
└─ Provide Ports:
└─ DTC_Data (오류 코드)
예: DiagnosticMonitorSWC
💡 SWC 설계할 때 고려사항
1️⃣ 단일 책임 원칙 (Single Responsibility)
❌ 나쁜 설계:
SuperControlSWC:
├─ 엔진 제어
├─ 변속 제어
├─ 제동 제어
├─ 진단
└─ 통신
(너무 복잡!)
✅ 좋은 설계:
EngineControlSWC (엔진만!)
TransmissionControlSWC (변속만!)
BrakeControlSWC (제동만!)
DiagnosticSWC (진단만!)
(각자 역할에 집중)
2️⃣ 인터페이스 명확성
좋은 Port 설계:
┌────────────────┐
│ TorqueLimitSWC │
├────────────────┤
│ Require: │
│ └─ MotorTorque │ (명확한 이름)
│ │
│ Provide: │
│ └─ TorqueLimit │
└────────────────┘
vs
나쁜 Port 설계:
├─ data1, data2, data3 (뭐야?)
├─ output_a, output_b, output_c
└─ signal_xyz (매우 모호!)
3️⃣ 재사용성
높은 재사용성:
- 하드웨어 독립적 (GPIO 주소 안 쓰기)
- 파라미터화 가능 (설정값으로 조정)
- 표준 인터페이스 (Port가 명확)
낮은 재사용성:
- 하드웨어 종속적 (특정 칩 가정)
- 고정값 사용 (수정 불가)
- 복잡한 인터페이스
정리: SWC와 Runnable 핵심 정보
| 항목 | SWC | Runnable |
|---|---|---|
| 정의 | 소프트웨어 컴포넌트 | SWC 내 실행 함수 |
| 역할 | 기능의 모듈화 | 주기적/이벤트 실행 |
| 특징 | 재사용 가능, Port로 통신 | 원자성, 타이밍 보장 |
| 상호작용 | RTE를 통해 통신 | RTE가 실행 시간 관리 |
| 예시 | EngineControlSWC | EngineControl_10ms |
마치며
이제 SWC와 Runnable이 어떻게 작동하는지 명확해졌을까요?
지금까지는 취준생과 초급자를 위한 포스팅이었다면.. 이번부터는 초급자부터 실무자 까지로
난이도가 올라간 듯 느껴지죠?
직접 사용할 것이고 사용했던 내용일 거예요
다음 편에서는 이 SWC들이 실제로 어떻게 통신하는지 CAN 메시지가 어떻게 신호로 변환되는지, 신호 매핑은 뭔지...
다음 편에서는 "AUTOSAR 통신 시스템: CAN 버스, 신호, COM 모듈의 관계"를 주제로 해보겠습니다.
신호가 물리적 CAN 메시지로 어떻게 변환되는지, 구체적인 예시를 통해 설명해서 최대한 여러분이 이해하기 쉽도록
만들어 올게요...
'AUTOSAR 심화' 카테고리의 다른 글
| AUTOSAR Dem 완벽 이해: 오류 감지와 DTC 관리의 모든 것 (0) | 2025.12.18 |
|---|---|
| AUTOSAR NvM 완벽 이해: 메모리 관리의 모든 것 (0) | 2025.12.17 |
| 실무자 관점에서 보는 Watchdog – Window 모드, Alive Monitoring, AUTOSAR WdgM 완벽 이해 (0) | 2025.12.17 |
| AUTOSAR 통신 시스템: CAN 버스, 신호, COM 모듈의 관계 (0) | 2025.12.16 |
| 🚨 Watchdog의 실무적 이해 – 내부 동작, 안전 메커니즘, AUTOSAR WdgM까지 완전 정리 (0) | 2025.12.13 |