AUTOSAR CanIf 완벽 이해: CAN 메시지 라우팅의 모든 것
CanIf란?

들어가며
지난 게시물에서 Dcm이 어떻게 정비소와 통신하는지 배웠어요.
그렇다면 그 통신은 어떤 방법을 통해 하는걸까요???
그 물음에 대한 대답을 이번 게시물을 통해 해드리겠습니다.
이제 "그 통신 메시지가 정확히 어떤 경로로 이동할까?"에 대해 글을 써보려합니다.
먼저 자동차는 CAN 버스가 1개만 있는 게 아니에요.
실제 자동차:
┌────────────────────────────────────┐
│ CAN-0 (High-speed CAN, 500 kbps) │
│ ├─ 엔진 ECU │
│ ├─ 변속기 ECU │
│ ├─ ABS ECU │
│ └─ 진단 ECU │
└────────────────────────────────────┘
┌────────────────────────────────────┐
│ CAN-1 (Infotainment CAN) │
│ ├─ 헤드유닛 (Radio) │
│ ├─ 내비게이션 │
│ └─ 스마트폰 연동 │
└────────────────────────────────────┘
┌────────────────────────────────────┐
│ LIN 버스 (저속, 선택적) │
│ ├─ 창문 모터 │
│ ├─ 미러 제어 │
│ └─ 좌석 제어 │
└────────────────────────────────────┘
이 모든 통신을 관리하는 게 CanIf!
그런데 엔진 ECU가 변속기 ECU의 메시지를 필요로 하면?
아니면 진단 ECU가 엔진 ECU의 데이터를 필요로 하면?
"어느 메시지를 어느 ECU로 보낼 것인가?"를 결정하는 게 CanIf이에요!
이 글에서는 CanIf의 메시지 라우팅, 필터링, 우선순위 관리를 상세히 설명할 거야.
옛날에 전화 연결해주는 사람 혹시... 아시나요?
너무 옛날인가요...ㅎ

📨 CanIf란?
CanIf의 정의
CanIf = CAN Interface
자동차 ECU에서 CAN 버스와의 통신을 중개하는 시스템이에요.
CanIf의 역할 (4가지)
1️⃣ 메시지 수신 (Message Reception)
└─ CAN 버스에서 메시지 받기
└─ "메시지 0x100이 왔어!"
2️⃣ 메시지 라우팅 (Message Routing)
└─ 받은 메시지를 어디로 보낼 것인가?
└─ Com 모듈로? BSW로? ASW로?
3️⃣ 메시지 필터링 (Message Filtering)
└─ 필요 없는 메시지는 버리기
└─ "이 메시지는 우리 ECU가 필요 없어"
4️⃣ 메시지 전송 (Message Transmission)
└─ CAN 버스로 메시지 내보내기
└─ "메시지 0x200 전송!"
CanIf의 위치 (계층)
┌──────────────────────────────────┐
│ ASW / SWC (응용 소프트웨어) │
│ EngineControlSWC, etc │
└────────────────┬─────────────────┘
│
┌────────────────▼─────────────────┐
│ Com (신호 관리) │
│ 신호 ↔ PDU 변환 │
└────────────────┬─────────────────┘
│
┌────────────────▼─────────────────┐
│ CanIf (CAN 인터페이스) │
│ 메시지 라우팅 & 필터링 │
└────────────────┬─────────────────┘
│
┌────────────────▼─────────────────┐
│ CAN 드라이버 (저수준) │
│ 하드웨어 제어 │
└────────────────┬─────────────────┘
│
┌────────────────▼─────────────────┐
│ CAN 버스 │
│ 물리적 신호 전송 │
└──────────────────────────────────┘
📋 PDU: Protocol Data Unit
PDU란?
PDU = Protocol Data Unit
CAN 버스 상에서 실제로 전송되는 데이터의 기본 단위예요.
대표 사진에 PDU라는 것을 사진만 보고 이해하셨나요?
혹시 "PDU가 뭐야" 라고 했다면 이제부터 공부해봅시다
PDU vs 신호
신호 (Signal):
- SWC가 주고받는 논리적 데이터
- 예: "엔진 RPM = 3000 rpm" (부동소수점)
- 단위: rpm, 도씨, %, A 등
PDU (Protocol Data Unit):
- CAN 버스에서 실제 전송되는 바이트 데이터
- 예: "CAN ID 0x100: [0x0B, 0xB8, 0x5A, ...]" (8바이트)
- 단위: 바이트
변환 과정:
신호 (3000 rpm)
↓
Com (신호 인코딩)
↓
PDU (바이트 배열)
↓
CanIf (라우팅)
↓
CAN 드라이버
↓
CAN 버스 전송
PDU의 구조
CAN 메시지 (PDU):
┌──────────────────────────────────┐
│ CAN ID: 0x100 (메시지 고유번호) │
├──────────────────────────────────┤
│ DLC: 8 (데이터 길이, 0~8 바이트) │
├──────────────────────────────────┤
│ Data[0]: 0x0B (데이터 바이트 0) │
│ Data[1]: 0xB8 (데이터 바이트 1) │
│ Data[2]: 0x5A (데이터 바이트 2) │
│ Data[3]: 0x64 (데이터 바이트 3) │
│ Data[4]: 0x00 (데이터 바이트 4) │
│ Data[5]: 0x00 (데이터 바이트 5) │
│ Data[6]: 0x00 (데이터 바이트 6) │
│ Data[7]: 0x00 (데이터 바이트 7) │
└──────────────────────────────────┘
= 1개 PDU (총 12바이트: ID 4바이트 + DLC 1바이트 + Data 8바이트)

🔄 메시지 라우팅 (Message Routing)
라우팅이란?
라우팅 = "이 메시지는 어디로 보낼 것인가?" 결정
라우팅의 3가지 경우
경우 1: 송신 (TX - Transmit)
────────────────────────────
ASW → CanIf → CAN 버스
예: 엔진 ECU가 RPM을 변속기 ECU에 전송
EngineControlSWC에서 rpm 값 발생
↓
Com이 신호 인코딩 (rpm → 바이트)
↓
CanIf가 CAN 버스로 전송
↓
CAN 버스에 메시지 0x100 나타남
↓
다른 ECU들이 수신!
경우 2: 수신 (RX - Receive)
────────────────────────────
CAN 버스 → CanIf → ASW
예: 변속기 ECU가 엔진 RPM을 받음
CAN 버스에서 메시지 0x100 들어옴
↓
CanIf가 수신 (메시지가 우리 것인가?)
↓
CanIf가 Com으로 라우팅
↓
Com이 신호 디코딩 (바이트 → rpm)
↓
TransmissionControlSWC가 rpm 사용
경우 3: 내부 라우팅 (Internal Routing)
────────────────────────────────────
같은 ECU 내에서 메시지 전달
예: 엔진 ECU 내에서
EngineControlSWC → Com → CanIf → CAN 드라이버
↓ (내부 루프백)
다시 Com으로
↓
DiagnosticSWC가 데이터 사용
라우팅 테이블 (Routing Table)
DBC 파일이나 ARXML에 정의됨:
메시지 ID 0x100 (EngineData):
├─ 송신자 (Sender): EngineECU
├─ 수신자 (Receivers):
│ ├─ TransmissionECU
│ ├─ ABSECU
│ └─ DiagnosticECU
└─ 신호:
├─ EngineSpeed (모든 수신자)
├─ EngineTorque (TransmissionECU만)
└─ EngineLoad (모든 수신자)
메시지 ID 0x200 (TransmissionData):
├─ 송신자: TransmissionECU
├─ 수신자:
│ ├─ EngineECU
│ └─ DiagnosticECU
└─ 신호:
├─ CurrentGear (모든 수신자)
└─ TorqueLimit (EngineECU만)
메시지 라우팅 흐름도
Time 0ms: EngineECU에서 메시지 0x100 송신
┌──────────────────────────────┐
│ EngineControlSWC │
│ rpm = 3000 │
└────────────┬─────────────────┘
│
▼
┌──────────────────────────────┐
│ Com (신호 인코딩) │
│ rpm 3000 → 바이트 변환 │
│ [0x0B, 0xB8, 0x5A, ...] │
└────────────┬─────────────────┘
│
▼
┌──────────────────────────────┐
│ CanIf (메시지 라우팅) │
│ "이건 0x100이고, │
│ 수신자는 TxECU, ABSECU, │
│ DiagnosticECU다!" │
└────────────┬─────────────────┘
│
▼
┌──────────────────────────────┐
│ CAN 드라이버 │
│ CAN 버스로 전송! │
└────────────┬─────────────────┘
│
▼
CAN 버스: 0x100 #0B B8 5A 64 00 00 00 00
↓↓↓ (모든 ECU가 받음)
Time 10ms: 다른 ECU들이 메시지 수신
┌────────────────────────────────────────┐
│ TransmissionECU │
│ CAN 드라이버에서 0x100 수신 │
│ │
│ CanIf: "어? 0x100이 왔어? │
│우리가 필요한 메시지 맞나?" │
│ 라우팅 테이블 확인: │
│ "맞다! 수신자 목록에 TransmissionECU" │
│ │
│ CanIf: Com으로 전달 │
│ │
│ Com: 신호 디코딩 │
│ 바이트 [0x0B, 0xB8] → rpm 3000 │
│ │
│ TransmissionControlSWC: │
│ "엔진이 3000 rpm이네" │
│ 기어 선택 → D 기어로! │
└────────────────────────────────────────┘
┌────────────────────────────────────────┐
│ ABSECU │
│ CAN 드라이버에서 0x100 수신 │
│ │
│ CanIf: "라우팅 테이블 확인" │
│ "맞다! ABSECU도 수신자 목록에" │
│ │
│ CanIf: Com으로 전달 │
│ Com: rpm 3000 디코딩 │
│ │
│ BrakeControlSWC: │
│ "엔진이 3000 rpm이니까 │
│ ABS 감도를 조정해야겠다" │
└────────────────────────────────────────┘
┌────────────────────────────────────────┐
│ OtherECU (필요 없는 ECU) │
│ CAN 드라이버에서 0x100 수신 │
│ │
│ CanIf: "라우팅 테이블 확인" │
│ "어? 우리는 수신자 목록에 없는데?" │
│ │
│ CanIf: 메시지 버림! │
│ (CPU 시간 절약, 불필요한 처리 방지) │
└────────────────────────────────────────┘
🔍 메시지 필터링 (Message Filtering)
필터링이란?
필터링 = "불필요한 메시지는 받지 말자"
자동차는 수백 개의 CAN 메시지가 오갈 수 있어요.
모든 메시지를 처리하면 CPU가 과부하됩니다.
필터링 없으면:
모든 메시지 수신
→ 매번 확인 "우리 메시지인가?"
→ CPU 시간 낭비!
→ 배터리 소비 증가!
필터링 있으면:
필요한 메시지만 수신
→ "우리가 필요한 메시지만!"
→ CPU 시간 절약!
→ 배터리 절약!
필터링의 2가지 방식
1️⃣ 하드웨어 필터링 (CAN 컨트롤러 레벨)
──────────────────────────
CAN 칩 자체에서 필터링
라우팅 테이블:
┌─────────────────────┐
│ 우리가 수신할 ID: │
│ ├─ 0x100 │
│ ├─ 0x200 │
│ ├─ 0x300 │
│ └─ 0x400 │
└─────────────────────┘
CAN 버스에 0x500 메시지 들어옴
→ CAN 칩: "우리 ID 목록에 없네?"
→ 즉시 버림! (CanIf까지 안 올라옴)
장점: CPU 처리 없음 (칩에서 처리)
단점: 필터 규칙이 고정적
2️⃣ 소프트웨어 필터링 (CanIf 레벨)
──────────────────────────
CanIf에서 필터링
CAN 드라이버 → CanIf:
"0x500 메시지 왔습니다"
CanIf: 라우팅 테이블 확인
"어? 이거 우리 메시지 아닌데?"
→ 버림!
장점: 동적으로 필터 변경 가능
단점: CPU 시간 약간 사용
실제 필터링 규칙
허용 ID (Whitelist):
- 0x100 (EngineData): 허용
- 0x200 (TransmissionData): 허용
- 0x300 (BrakeData): 허용
- 0x600 (DiagnosticRequest): 허용 (OBD-II)
거부 ID (Blacklist):
- 나머지 모든 ID: 거부
필터링 규칙:
if (message_id in 허용_ID_목록) {
Process_Message(); // 처리
} else {
Discard_Message(); // 버림
}
⚖️ 우선순위 관리
우선순위 (Priority)란?
우선순위 = "여러 메시지가 동시에 올 때 누가 먼저?"
CAN 버스는 한 번에 1개 메시지만 전송할 수 있어요.
상황: 여러 ECU가 동시에 메시지 전송 원함
엔진 ECU: "나 0x100 보낼 거야!"
변속기 ECU: "나 0x200 보낼 거야!"
ABS ECU: "나 0x300 보낼 거야!"
동시에 3개?
→ 불가능!
CAN 버스의 "Carrier Sense Multiple Access"
우선순위 결정!
CAN ID가 작을수록 높은 우선순위!
0x100 vs 0x200 vs 0x300
→ 0x100이 먼저 전송!
CanIf의 우선순위 큐
송신 큐 (TX Queue):
높은 우선순위:
┌──────────────────────────┐
│ 0x100 (EngineData) │ ← 먼저 전송
│ 0x150 (BrakeData) │
└──────────────────────────┘
중간 우선순위:
┌──────────────────────────┐
│ 0x200 (TransmissionData) │
│ 0x250 (HVAC) │
└──────────────────────────┘
낮은 우선순위:
┌──────────────────────────┐
│ 0x600 (Diagnostic) │
│ 0x650 (Infotainment) │ ← 나중에 전송
└──────────────────────────┘
CAN 드라이버: 큐에서 꺼내면서 우선순위 확인
"0x100이 가장 중요하네?" → 먼저 전송!
"0x200은 그 다음" → 그 다음 전송!
실제 우선순위 예시
자동차 안전성:
최우선 (충돌 회피):
- 0x100: EngineRPM, EngineTorque
- 0x150: BrakePressure
- 0x180: SteeringAngle
높은 우선순위 (안전):
- 0x200: TransmissionGear
- 0x250: AirbagarStatus
- 0x300: LaneKeepingAssist
중간 우선순위 (편의):
- 0x400: WindowControl
- 0x450: MirrorControl
- 0x500: SeatControl
낮은 우선순위 (정보):
- 0x600: DiagnosticData
- 0x650: Infotainment
- 0x700: Statistics
규칙: CAN ID가 작을수록 높은 우선순위!
따라서 높은 우선순위 메시지에 낮은 ID 할당!
📡 CanIf API
주요 API들
1️⃣ CanIf_Init
─────────────────────────
목적: CanIf 초기화
호출 시점: 시스템 부팅 시
역할:
- 라우팅 테이블 로드
- 필터 규칙 설정
- CAN 드라이버와 연결
- 송수신 버퍼 초기화
2️⃣ CanIf_Transmit
─────────────────────────
목적: CAN 메시지 송신
선언:
Std_ReturnType CanIf_Transmit(
PduIdType TxPduId,
const PduInfoType* PduInfoPtr
);
사용 예:
// Com에서 EngineData 전송 요청
uint8 engine_data[8] = {0x0B, 0xB8, 0x5A, ...};
PduInfoType pdu_info;
pdu_info.SduDataPtr = engine_data;
pdu_info.SduLength = 8;
CanIf_Transmit(CanIfPdu_EngineData, &pdu_info);
CanIf의 처리:
1. TxPduId 확인 (EngineData = 0x100)
2. CAN ID 결정
3. 우선순위 큐에 추가
4. CAN 드라이버가 전송!
3️⃣ CanIf_RxIndication
─────────────────────────
목적: CAN 메시지 수신 알림 (콜백)
호출자: CAN 드라이버
선언:
void CanIf_RxIndication(
const Can_HwType* Mailbox,
const PduInfoType* PduInfoPtr
);
의사 코드:
void CanIf_RxIndication(...) {
// 1. 메시지 ID 추출
message_id = GetCanId(); // 0x100
// 2. 라우팅 테이블에서 수신자 확인
if (message_id == 0x100) {
// 3. 필터링 확인
if (should_process) {
// 4. Com으로 라우팅
Com_RxIndication(0x100, data);
}
}
}
4️⃣ CanIf_TxConfirmation
─────────────────────────
목적: 메시지 송신 완료 확인
호출자: CAN 드라이버
역할:
- 메시지 송신 성공 확인
- Com에 송신 완료 알림
- 우선순위 큐에서 제거
5️⃣ CanIf_ControllerModeIndication
─────────────────────────
목적: CAN 컨트롤러 상태 변경 알림
상태:
- CAN_CS_STOPPED: CAN 버스 정지
- CAN_CS_STARTED: CAN 버스 시작
- CAN_CS_SLEEP: 절전 모드
용도:
- CAN 버스 상태 모니터링
- 버스 오류 복구
🔗 CanIf와 다른 모듈의 협력
CanIf ↔ Com (신호 관리)
송신 방향:
ASW (신호) → Com (인코딩) → CanIf (라우팅) → CAN 버스
예: 엔진 RPM 전송
EngineControlSWC: rpm = 3000
↓
Com_Transmit():
"EngineData 신호를 전송해"
↓
Com이 CanIf_Transmit() 호출:
"이거 CanIf로 보내줄래?"
↓
CanIf가 CAN 드라이버로 전송
↓
CAN 버스에 0x100 나타남!
수신 방향:
CAN 버스 → CanIf (라우팅) → Com (디코딩) → ASW (신호)
예: 변속기 데이터 수신
CAN 버스에 0x200 메시지 들어옴
↓
CAN 드라이버가 CanIf_RxIndication() 호출
↓
CanIf: "0x200이고 라우팅 테이블에서 허용됨"
↓
CanIf가 Com_RxIndication() 호출:
"Com아, 0x200 메시지 줄게"
↓
Com이 신호 디코딩:
Data[0:1] = 0x03 → CurrentGear = 3 (D)
↓
TransmissionControlSWC가 gear = 3 사용
CanIf ↔ CAN 드라이버
CanIf (높은 수준):
- 메시지 라우팅
- 필터링
- 우선순위 관리
- PDU 관리
CAN 드라이버 (낮은 수준):
- 하드웨어 제어
- 실제 CAN 버스 전송/수신
- 타이밍 관리
- 오류 처리
협력:
CanIf → CAN 드라이버: "이 메시지 보내줄래?"
CAN 드라이버 → CanIf: "보냈습니다"
CAN 버스 → CAN 드라이버: "메시지 받았어!"
CAN 드라이버 → CanIf: "메시지 받았으니 처리해"
📊 실제 라우팅 시나리오
시나리오: 다중 CAN 버스 관리
[상황]
자동차에 2개 CAN 버스:
- CAN-0: 파워트레인 (엔진, 변속기)
- CAN-1: 인포테인먼트 (라디오, 네비)
각 ECU가 여러 메시지를 송수신
────────────────────────────────────
[라우팅 테이블]
CAN-0 (파워트레인):
┌─────────────────────────────┐
│ 0x100 (EngineData) │
│ ├─ 송신자: EngineECU │
│ ├─ 수신자: TransmissionECU, │
│ │ ABSECU, DiagECU │
│ └─ 신호: RPM, Torque, Load │
│ │
│ 0x200 (TransmissionData) │
│ ├─ 송신자: TransmissionECU │
│ ├─ 수신자: EngineECU, │
│ │ ABSECU, DiagECU │
│ └─ 신호: Gear, Pressure │
│ │
│ 0x600 (DiagnosticRequest) │
│ ├─ 송신자: DiagECU │
│ ├─ 수신자: 모든 ECU │
│ └─ 신호: UDS 서비스 │
└─────────────────────────────┘
CAN-1 (인포테인먼트):
┌─────────────────────────────┐
│ 0x700 (RadioControl) │
│ ├─ 송신자: HeadUnit │
│ ├─ 수신자: Amplifier │
│ └─ 신호: Volume, Frequency │
│ │
│ 0x800 (NavigationData) │
│ ├─ 송신자: Navigator │
│ ├─ 수신자: HeadUnit, Cluster│
│ └─ 신호: Position, Speed │
└─────────────────────────────┘
────────────────────────────────────
[Time 0ms - EngineECU 송신]
EngineControlSWC:
rpm = 3000, torque = 380 Nm, load = 60%
Com_Transmit(EngineData):
신호 인코딩:
- rpm 3000 → 바이트 변환
- torque 380 → 바이트 변환
- load 60 → 바이트 변환
결과: [0x0B, 0xB8, 0x78, 0xFA, 0x64, ...]
CanIf_Transmit(CanIfPdu_EngineData):
1. PduId → CAN ID 변환 (0x100)
2. 라우팅 테이블 확인: "CAN-0로 보내자"
3. 우선순위 큐에 추가 (0x100은 높은 우선순위)
4. CAN-0 드라이버에 전송 요청
CAN 드라이버:
CAN-0 버스에 메시지 0x100 전송!
CAN-0 버스:
ID: 0x100, Data: [0x0B, 0xB8, 0x78, 0xFA, 0x64, ...]
────────────────────────────────────
[Time 10ms - TransmissionECU 수신]
CAN 드라이버:
CAN-0에서 메시지 0x100 수신!
CAN_RxInterrupt:
CanIf_RxIndication() 호출
CanIf 처리:
1. 메시지 ID 0x100 확인
2. 라우팅 테이블에서 검색:
"TransmissionECU가 수신자 목록에 있나?"
→ YES!
3. 필터링 확인:
"이 메시지가 필요한가?"
→ YES!
4. Com_RxIndication() 호출
Com 처리:
1. PDU 0x100 확인
2. 신호 디코딩:
- 바이트 [0x0B, 0xB8] → rpm 3000
- 바이트 [0x78] → torque 380
- 바이트 [0xFA] → load 60
3. 신호 업데이트
TransmissionControlSWC:
"엔진이 3000 rpm, 380 Nm 토크네"
기어 선택 → D 기어로!
────────────────────────────────────
[Time 20ms - ABSECU 수신]
같은 과정:
CAN 드라이버 → CanIf → Com → BrakeControlSWC
"엔진이 3000 rpm이니까
ABS 감도를 이렇게 조정해야겠다"
────────────────────────────────────
[Time 30ms - DiagnosticECU 수신]
같은 과정:
CAN 드라이버 → CanIf → Com → DiagnosticSWC
"엔진 RPM 통계 기록:
2025-01-15 14:30: 3000 rpm"
────────────────────────────────────
[Time 50ms - CAN-1 (인포테인먼트)]
HeadUnit (라디오):
사용자가 볼륨 조정: 50% → 60%
Com_Transmit(RadioControl):
신호 인코딩: volume 60 → 바이트
CanIf_Transmit (CAN-1):
1. CAN ID: 0x700
2. 라우팅: "CAN-1로 보내자"
3. 우선순위: 낮음 (파워트레인보다)
4. 전송
결과:
CAN-1 버스에 0x700 전송!
────────────────────────────────────
[결과]
2개 CAN 버스가 독립적으로 동작:
- CAN-0: 파워트레인 (높은 우선순위)
- CAN-1: 인포테인먼트 (낮은 우선순위)
CanIf가 모든 라우팅을 자동 관리!
⚙️ CanIf 설정 (ARXML)
<?xml version="1.0" encoding="UTF-8"?>
<AUTOSAR xmlns="http://autosar.org/schema/r4.0">
<AR-PACKAGES>
<AR-PACKAGE>
<SHORT-NAME>CanIf</SHORT-NAME>
<ELEMENTS>
<!-- CAN 컨트롤러 설정 -->
<CAN-COMMUNICATION-CONTROLLER>
<SHORT-NAME>CanController_0</SHORT-NAME>
<CAN-CONTROLLER-PHYSICAL-CHANNELS>
<CAN-PHYSICAL-CHANNEL>
<SHORT-NAME>CAN-0</SHORT-NAME>
<FRAME-TRIGGERING>
<!-- TX 메시지 0x100 -->
<CAN-FRAME-TRIGGERING>
<IDENTIFIER>0x100</IDENTIFIER>
<FRAME-PORT-REFS>
<FRAME-PORT-REF>/CanIf/FramePort_EngineData_TX</FRAME-PORT-REF>
</FRAME-PORT-REFS>
</CAN-FRAME-TRIGGERING>
<!-- RX 메시지 0x200 -->
<CAN-FRAME-TRIGGERING>
<IDENTIFIER>0x200</IDENTIFIER>
<FRAME-PORT-REFS>
<FRAME-PORT-REF>/CanIf/FramePort_TransmissionData_RX</FRAME-PORT-REF>
</FRAME-PORT-REFS>
</CAN-FRAME-TRIGGERING>
</FRAME-TRIGGERING>
</CAN-PHYSICAL-CHANNEL>
</CAN-CONTROLLER-PHYSICAL-CHANNELS>
</CAN-COMMUNICATION-CONTROLLER>
<!-- 라우팅 규칙 -->
<CANIF-RXINDICATION-LAYOUT>
<SHORT-NAME>RxIndication_EngineData</SHORT-NAME>
<CAN-ID>0x100</CAN-ID>
<TARGET-L-PDU-REF>/Com/LPdu_EngineData</TARGET-L-PDU-REF>
<ROUTING-TYPE>CAN-TO-COM</ROUTING-TYPE>
</CANIF-RXINDICATION-LAYOUT>
<!-- 필터 규칙 -->
<CANIF-FRAME-FILTERING>
<SHORT-NAME>Filter_Whitelist</SHORT-NAME>
<FILTER-TYPE>WHITELIST</FILTER-TYPE>
<ALLOWED-CAN-IDS>
<CAN-ID>0x100</CAN-ID>
<CAN-ID>0x200</CAN-ID>
<CAN-ID>0x300</CAN-ID>
<CAN-ID>0x600</CAN-ID>
</ALLOWED-CAN-IDS>
</CANIF-FRAME-FILTERING>
<!-- 우선순위 설정 -->
<CANIF-TX-PRIORITY>
<SHORT-NAME>TxPriority_EngineData</SHORT-NAME>
<CAN-ID>0x100</CAN-ID>
<PRIORITY>1</PRIORITY> <!-- 가장 높음 -->
</CANIF-TX-PRIORITY>
<CANIF-TX-PRIORITY>
<SHORT-NAME>TxPriority_DiagnosticData</SHORT-NAME>
<CAN-ID>0x600</CAN-ID>
<PRIORITY>100</PRIORITY> <!-- 가장 낮음 -->
</CANIF-TX-PRIORITY>
</ELEMENTS>
</AR-PACKAGE>
</AR-PACKAGES>
</AUTOSAR>
🎯 면접 예상 질문 10가지
Q1: CanIf가 뭐고, 왜 필요해요?
A: "CanIf는 CAN 버스와의 통신을 중개하는 계층입니다.
메시지 라우팅, 필터링, 우선순위 관리를 담당해서
필요한 메시지만 올바른 대상에 전달합니다."
Q2: PDU가 뭐죠?
A: "Protocol Data Unit의 약자로,
CAN 버스에서 실제 전송되는 바이트 데이터입니다.
신호는 논리적 개념이고, PDU는 물리적 데이터입니다."
Q3: 라우팅과 필터링의 차이는?
A: "라우팅은 '이 메시지를 어디로 보낼 것인가'이고,
필터링은 '이 메시지를 처리할 것인가'입니다.
필터링에서 탈락하면 라우팅도 하지 않습니다."
Q4: 왜 메시지 필터링이 필요한가요?
A: "자동차는 수백 개의 CAN 메시지가 오갑니다.
필요 없는 메시지까지 모두 처리하면
CPU 성능이 낮아지고 배터리가 빨리 소모됩니다."
Q5: CAN 우선순위는 어떻게 정해지나요?
A: "CAN ID가 작을수록 높은 우선순위입니다.
따라서 안전 관련 메시지(엔진, 브레이크)에는
낮은 CAN ID를 할당합니다."
Q6: CanIf와 Com의 관계는?
A: "Com은 신호를 다루고, CanIf는 메시지를 다룹니다.
신호 → Com (인코딩) → CanIf (라우팅) → CAN 버스
이 순서로 데이터가 흐릅니다."
Q7: 메시지가 오면 어떤 순서로 처리되나요?
A: "1. CAN 드라이버가 메시지 수신
2. CanIf_RxIndication() 호출
3. 라우팅 테이블에서 수신자 확인
4. 필터링 규칙 적용
5. Com으로 라우팅
6. Com이 신호 디코딩
이 순서입니다."
Q8: 다중 CAN 버스를 어떻게 관리하나요?
A: "각 메시지가 어느 CAN 버스에 갈 것인지
라우팅 테이블에서 정의합니다.
CanIf가 자동으로 올바른 버스로 라우팅합니다."
Q9: 하드웨어 필터링과 소프트웨어 필터링의 차이는?
A: "하드웨어 필터링은 CAN 칩에서 처리(빠르지만 고정),
소프트웨어 필터링은 CanIf에서 처리(느리지만 유동적)입니다.
둘 다 사용하는 경우가 많습니다."
Q10: CanIf가 없으면 어떻게 되나요?
A: "모든 ECU가 모든 메시지를 받고 처리해야 하니까,
CPU 부하가 크게 증가합니다.
보안도 떨어집니다 (무관한 메시지도 노출됨)."
정리: CanIf의 핵심
| 항목 | 설명 |
|---|---|
| 정의 | CAN 메시지 라우팅 & 필터링 |
| PDU | 실제 전송되는 바이트 데이터 |
| 라우팅 | 메시지를 올바른 대상으로 전달 |
| 필터링 | 불필요한 메시지 제외 |
| 우선순위 | CAN ID가 작을수록 높음 |
| Com과의 관계 | Com이 신호, CanIf가 메시지 |
| CAN 드라이버 | 실제 CAN 버스 제어 |
| 다중 버스 | 여러 CAN 버스 동시 관리 |
마치며며
오늘 CAN 메시지가 어떻게 라우팅되고, 필터링되고,
우선순위가 정해지는지 완벽히 이해하셨나요,,,?
저는 쓰면서도 너무 어려웠는데요
이걸 이렇게 쓴다고 이해하실까? 라는 생각에 썼다 지웠다를 반복했네요...
저희는 NvM, Dem, Dcm, CanIf를 통해
AUTOSAR BSW의 핵심 4개 모듈을 모두 배웠습니다:
메모리 관리 (NvM)
↓
오류 감지 (Dem)
↓
진단 통신 (Dcm)
↓
메시지 라우팅 (CanIf)
이제 AUTOSAR의 기초부터 심화까지 완벽하게 이해하신거예요
짝짝짝~!~!~!~!~!
다음 주제는 제가 조금 충전을 해가지고 다시 오도록 하겠습니다.
읽어 주셔서 감사합니다.
'AUTOSAR 심화' 카테고리의 다른 글
| AUTOSAR Dcm 완벽 이해: 진단 통신의 모든 것 (3) | 2025.12.18 |
|---|---|
| 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 |