본문 바로가기
통신 프로토콜

자동차 통신 프로토콜 2부: LIN (Local Interconnect Network) 완벽 이해

by 버그없는토마토 2025. 12. 24.

자동차 통신 프로토콜 2부: LIN (Local Interconnect Network) 완벽 이해

LIN이란?


 

LIN에 관하여

들어가며

안녕하세요 버그없는토마토입니다

1부에서 자동차는 왜 여러 프로토콜을 써야 하는지 배웠어요.

각각의 역할이 있고 목적이 있기 떄문에, 그리고 비용적인 측면에서도 꼭 필요한 분할이라고 생각하게 되죠.

이제 "그 프로토콜들이 정확히 뭔지" 배워야 할 차례예요.

저번 게시물에서 설명했듯이 옴니버스식 구성의 각각 주인공들이에요 

오늘의 주인공은 린이란 녀석입니다.

첫 번째는 LIN (Local Interconnect Network)이에요.

 

린은 어떨 떄 쓰일까요?

지금 차에서:

운전자: "창문 올려!" (버튼 누름)

↓

바디 ECU: "창문 ECU에게 신호를 보내야 해"

↓

LIN 버스에 신호 전송
[Master Signal] "창문을 올려!"

↓

창문 ECU (LIN Slave): "받았어! 모터를 돌릴게"

↓

창문 모터: 윙 윙 (올라갑니다!)

↓

500ms 후: 창문이 완전히 올라감

결과: "창문이 올라갔어요!"

LIN이 이 모든 과정을 가능하게 했습니다

이 글에서는 LIN이 정확히 뭔지, 어떻게 작동하는지,
메시지는 어떤 구조인지, 실제 차에서는 어떻게 쓰이는지
상세하게 설명해볼게요.


📌 3분 요약

바쁜 당신을 위한 핵심 3줄:

🔌 LIN = 느린 통신 (20 kbps)
🎮 Master-Slave: 한 마스터가 여러 슬레이브를 제어
⏱️ Schedule: 정해진 시간표대로 신호를 보냄

창문, 미러, 좌석 같은 편의 기능용 통신이에요.


LIN이란?

🔌 LIN이란?

LIN의 정의

LIN = Local Interconnect Network

자동차에서 저속, 저비용 통신을 담당하는 프로토콜이에요.

특징:
├─ 속도: 20 kbps (느림!)
├─ 거리: ~40m
├─ 메시지: 최대 8바이트
├─ 구조: Master 1개 + Slave 여러 개
├─ 비용: $ (매우 저가)
└─ 용도: 창문, 미러, 좌석 (편의 기능)

LIN vs CAN

비교:

LIN:
- 느림 (20 kbps)
- 저가 ($1)
- 구조 간단 (Master-Slave)
- 편의용

CAN:
- 빠름 (500 kbps)
- 중가 ($5)
- 구조 복잡 (Broadcast)
- 제어용

선택 기준:
느려도 되고 싼 것? → LIN!
빨라야 하고 신뢰할 수 있어야? → CAN!

왜 LIN은 느릴까?

이유 1: 비용 절감
- 저렴한 칩셋만 필요
- 구현이 간단함
- 배선도 적음 (1개 선으로 충분)

이유 2: 편의 기능용
- 창문이 0.5초 걸려도 괜찮음
- 미러가 1초 걸려도 문제 없음
- 고속일 필요가 없음

이유 3: 비용-성능 트레이드오프
- "충분히 빠르고, 가능한 한 저가"
- 편의 기능의 최적 선택

LIN이란?

🎯 LIN의 특징 (5가지)

특징 1️⃣: Master-Slave 구조

LIN 버스 구조:

┌─────────────────────────────┐
│   Master (바디 ECU)          │
│   (명령을 내림)              │
└──────────────┬──────────────┘
               │ (1개의 LIN 선)
      ┌────────┼────────┐
      ↓        ↓        ↓
┌──────────┐ ┌──────┐ ┌──────┐
│ 창문     │ │ 미러 │ │ 좌석 │
│ Slave   │ │Slave│ │Slave│
│ ECU     │ │ ECU  │ │ ECU  │
└──────────┘ └──────┘ └──────┘

특징:
- Master는 1개만 (바디 ECU)
- Slave는 여러 개 (창문, 미러, 좌석...)
- Master가 "언제 누가 데이터를 보낼지" 결정
- Slave는 Master의 명령만 따름

비유: 학교 조례
- Master = 교장선생님 (명령)
- Slave = 학생들 (따름)

특징 2️⃣: Schedule (시간표)

LIN Schedule이란?
"정해진 시간표대로 신호를 주고받는다"

예: 현대 쏘나타의 LIN Schedule

시간  │ Master의 명령        │ Slave의 응답
─────┼──────────────────┼─────────────
0ms  │ "창문 신호 줘" → │ 창문 ECU ⟹ 데이터 전송
     │ (Frame ID 0x01)  │
─────┼──────────────────┼─────────────
20ms │ "미러 신호 줘" → │ 미러 ECU ⟹ 데이터 전송
     │ (Frame ID 0x02)  │
─────┼──────────────────┼─────────────
40ms │ "좌석 신호 줘" → │ 좌석 ECU ⟹ 데이터 전송
     │ (Frame ID 0x03)  │
─────┼──────────────────┼─────────────
60ms │ "창문 신호 줘" → │ 창문 ECU ⟹ 데이터 전송
     │ (Frame ID 0x01)  │ (반복!)
─────┴──────────────────┴─────────────

Timeline으로 보면:

0ms ━━━━━ 창문 데이터 전송 ━━━━━
20ms ━━━━━ 미러 데이터 전송 ━━━━━
40ms ━━━━━ 좌석 데이터 전송 ━━━━━
60ms ━━━━━ 창문 데이터 전송 ━━━━━ (반복)

= 시간표처럼 정해진 순서대로!

특징 3️⃣: 간단한 메시지 구조

LIN 메시지 구조:

┌──────────────────────────────┐
│ Break (신호)                  │ ← "시작합니다!"
│ (13비트, 낮은 전압)           │
├──────────────────────────────┤
│ Sync (동기화)                 │ ← "속도 맞춰!"
│ (8비트, 0x55)                │
├──────────────────────────────┤
│ PID (Published ID)            │ ← "메시지 이름"
│ (1바이트, 예: 0x01)          │
├──────────────────────────────┤
│ Data (실제 데이터)            │ ← "데이터는 여기!"
│ (0~8바이트)                  │
├──────────────────────────────┤
│ Checksum (오류 검사)          │ ← "맞나 확인"
│ (1바이트)                    │
└──────────────────────────────┘

비유: 편지
- Break: 편지 시작 신호
- Sync: 받는 사람이 준비
- PID: "누가 보낸 편지인가?" (창문 ECU가 보낸가? 미러 ECU가 보낸가?)
- Data: 편지 내용
- Checksum: "편지가 손상 안 됐나?" 확인

특징 4️⃣: 신뢰성은 중간 수준

LIN의 에러 처리:

에러 감지:
1️⃣ Checksum 오류
   - 데이터가 손상됐나?
   - 계산 결과가 다르면 오류!

2️⃣ Timeout (응답 없음)
   - "어? Slave가 응답이 없네?"
   - Master가 대기

3️⃣ Sync 에러
   - 속도가 맞지 않음
   - 동기화 실패

에러 처리:
- 대부분 재전송
- 일부 무시 (중대하지 않으니까)
- 창문이 안 올라갔으니? 다시 요청!

신뢰성 평가:
CAN: ⭐⭐⭐⭐⭐ (매우 높음)
LIN: ⭐⭐⭐ (중간)
FlexRay: ⭐⭐⭐⭐⭐ (극도로 높음)

특징 5️⃣: 저비용!

LIN의 가격:

칩셋:
- LIN 트랜시버: $0.5~1
- 마이크로컨트롤러: $1~2
- 합계: $1.5~3 (매우 저가!)

CAN과 비교:
- CAN 트랜시버: $2~5
- 마이크로컨트롤러: $3~10
- 합계: $5~15 (훨씬 비쌈)

비용 효율:
LIN 하나: $1.5 × 수십 개 창문/미러 ECU
= 전체 비용 $50~100

CAN 하나: $10 × 수십 개 파워트레인 ECU  
= 전체 비용 $300~500

결론: "편의 기능은 LIN으로 비용 절감!" ✓

LIN에 관하여

📊 LIN 메시지 상세 분석

1️⃣ Break (신호 시작)

Break의 역할:
"우리 지금 신호 시작할게!"

물리적 특성:
- 최소 13비트
- Low 전압 (0V)
- 시간: 약 1ms

동작:
Master가 LIN 버스를 Low로 당김
→ 모든 Slave가 "아, 신호 시작이구나!"
→ 깨어남

2️⃣ Sync (동기화)

Sync의 역할:
"다들 이 속도로 맞춰!"

형식:
- 고정값: 0x55 (01010101)
- 목적: Slave의 클록 동기화

동작:
Master: 0x55 전송
Slave: 이 비트 패턴으로 속도 계산
→ "아, 20 kbps로 맞춰야겠다!"

예시:
Master가 0x55를 100ms에 보냈어
→ Slave: "아, 10 kbps인가?" (X)
→ Slave: "아, 속도를 다시 계산해야겠다"

3️⃣ PID (Published ID)

PID의 역할:
"이건 누가 전송할 메시지인가?"

형식:
- 6비트 identifier
- 2비트 parity (오류 검사)
- 총 1바이트

예시:
PID = 0x01: 창문 데이터 (창문 ECU가 보냄)
PID = 0x02: 미러 데이터 (미러 ECU가 보냄)
PID = 0x03: 좌석 데이터 (좌석 ECU가 보냄)

동작:
Master: "0x01 메시지 줘!" (창문 ECU에게)
창문 ECU: "받았어! 내 데이터를 보낼게"
→ Break + Sync + PID(0x01) + Data + Checksum
→ Master: 받음!

4️⃣ Data (실제 데이터)

Data의 역할:
"실제로 주고받는 정보"

크기:
- 0~8바이트 (가변)
- 예: 창문 데이터 = 1바이트

창문 데이터 구조:

Byte 0: 창문 제어 신호
├─ Bit 0-3: 모터 방향 (상향=0, 하향=1)
├─ Bit 4-7: 모터 속도 (0~15)
└─ 예: 0x05 = "위로 천천히"

예시:
Master → Slave: [0x02] "창문을 올려!"
Slave는 이를 해석:
- Bit 0-3 = 0 (상향)
- Bit 4-7 = 2 (천천히)
→ 창문 모터: 천천히 올라갑니다!

5️⃣ Checksum (오류 검사)

Checksum의 역할:
"데이터가 손상되지 않았나?"

계산 방식:
Checksum = 255 - (PID + Data1 + Data2 + ... + DataN) % 256

예시:
PID = 0x01
Data = [0x05, 0x10, ...]
Sum = 0x01 + 0x05 + 0x10 = 0x16
Checksum = 255 - 0x16 = 0xE9

검증:
Master 수신 후: 0x01 + 0x05 + 0x10 + 0xE9 = 0xFF
= 정상! ✓

손상 감지:
만약 Data 받는 중에 오류 발생
→ Checksum 계산 결과 ≠ 받은 값
→ 오류 감지!

🎬 실제 작동: 창문 올리기 시나리오

[상황]
사용자: "왼쪽 창문 올려!" (버튼 누름)

─────────────────────────────────

[시간: 0ms] Master 신호 시작

Master (바디 ECU):
"LIN 버스에 신호를 보낼 거야. 
 창문 ECU에게 창문을 올리도록 명령해야겠다."

→ LIN 버스에 신호 전송 시작

─────────────────────────────────

[시간: 1ms] Break 전송

Master:
LIN 버스를 Low로 당김 (13비트 동안)

모든 Slave (창문, 미러, 좌석 ECU):
"어? 신호가 오는군?"
→ 준비!

─────────────────────────────────

[시간: 2ms] Sync 전송

Master:
0x55 (01010101 패턴) 전송

모든 Slave:
"아, 이 속도군. 20 kbps로 동기화!"
→ 클록 조정

─────────────────────────────────

[시간: 3ms] PID 전송

Master:
PID = 0x01 전송
"이건 창문 데이터야!"

Slave 반응:
- 창문 ECU: "어? 나를 부르는 거네!" → 준비
- 미러 ECU: "아니, 0x02가 아닌가?" → 대기
- 좌석 ECU: "아니, 0x03이 아닌가?" → 대기

─────────────────────────────────

[시간: 4ms] Data 전송

Master (바디 ECU):
창문 데이터 전송

Master: [0x02]
"Bit 0-3 = 0 (상향)"
"Bit 4-7 = 2 (천천히)"
= 0x02

창문 ECU:
수신: 0x02
해석: "상향, 천천히"
→ 모터 구동 신호 전송!

─────────────────────────────────

[시간: 5ms] Checksum 전송

Master:
Checksum 계산 & 전송
Sum = PID(0x01) + Data(0x02) = 0x03
Checksum = 255 - 3 = 252 = 0xFC

─────────────────────────────────

[시간: 6ms] 신호 완료

Master:
"전송 완료!"

창문 ECU:
"Checksum 맞나?" 확인
0x01 + 0x02 + 0xFC = 0xFF ✓
→ "데이터가 정상이다!"

─────────────────────────────────

[시간: 100ms] 모터 작동

창문 모터:
신호: 상향, 천천히
→ 윙 윙 (모터 작동)
→ 창문이 올라가기 시작!

─────────────────────────────────

[시간: 500ms] 창문이 올라감

창문 모터:
계속 작동 (Master가 계속 신호를 보냄)

타이밍:
LIN Schedule (0ms마다 반복):
- 0ms: 창문 신호
- 20ms: 미러 신호
- 40ms: 좌석 신호
- 60ms: 창문 신호 (반복)

= 60ms마다 창문 신호를 다시 확인!

─────────────────────────────────

[시간: 500ms] 창문이 완전히 올라감

센서가 감지:
"창문이 맨 위까지 올라갔어!"
→ 창문 ECU가 Master에게 보고

Master:
"완료했구나!"
→ 신호 중지

결과:
✓ 창문이 올라갔어요!
✓ 사용자가 "창문 올림" 버튼을 누른 후 약 0.5초 소요

📋 LIN Schedule (시간표) 상세

LIN Schedule이란?
"어떤 시간에 어떤 메시지를 보낼지 미리 정해놓는 것"

예: 현대 쏘나타 창문 제어 Schedule

주기: 50ms (모든 신호가 50ms마다 반복)

0ms   : Break + Sync + PID(0x01) + 창문1 데이터 + Checksum
10ms  : Break + Sync + PID(0x01) + 창문1 데이터 + Checksum
20ms  : Break + Sync + PID(0x02) + 창문2 데이터 + Checksum
30ms  : Break + Sync + PID(0x02) + 창문2 데이터 + Checksum
40ms  : Break + Sync + PID(0x03) + 미러 데이터 + Checksum
50ms  : (반복)

타이밍 분석:
- 총 5개 메시지 (PID 0x01, 0x02, 0x03)
- 각 메시지 2ms 정도 소요
- 50ms 주기로 반복
- = 20Hz 주파수

Schedule의 목적:
1️⃣ 타이밍 보장
   - 각 창문이 얼마나 자주 갱신될까?
   - 정확히 정해짐!

2️⃣ 우선순위 관리
   - 어떤 신호가 먼저 나갈까?
   - 미리 정해짐!

3️⃣ 리소스 관리
   - Master 계산 부하 예측 가능
   - Slave의 응답 시간 계획 가능

🛠️ LIN 신호 정의 (DBC 파일)

LIN의 신호를 정의하는 파일: DBC 파일 (또는 LDF 파일)

LDF 파일 예시:
LINCluster {
  LIN_protocol_version = "2.1";
  LIN_language_version = "2.1";

  LINClusterDef {
    LINframe WindowData {
      ID = 0x01;
      DLC = 2;
      cycle_time = 50;
      Slave_response_timeout = 100;

      Signals {
        WindowCommand 0, 4;  // Bit 0-3
        WindowSpeed 4, 4;    // Bit 4-7
      }
    }

    LINframe MirrorData {
      ID = 0x02;
      DLC = 2;
      cycle_time = 50;

      Signals {
        MirrorCommand 0, 4;  // Bit 0-3
        MirrorSpeed 4, 4;    // Bit 4-7
      }
    }
  }

  ScheduleTable {
    BasicSchedule {
      Event 0 : WindowData 0 ms;
      Event 1 : MirrorData 10 ms;
      Event 2 : WindowData 20 ms;
      Event 3 : MirrorData 30 ms;
    }
  }
}

해석:
- WindowData: PID 0x01, 2바이트, 50ms마다
- Signals: 신호1 (0-3비트), 신호2 (4-7비트)
- Schedule: 0ms에 Window, 10ms에 Mirror...

💡 LIN vs CAN vs FlexRay

| 항목 | LIN | CAN | FlexRay |
|------|-----|-----|---------|
| 속도 | 20 kbps | 500 kbps | 10 Mbps |
| 구조 | Master-Slave | Broadcast | Master-Slave |
| 메시지 | 8B | 8B | 256B |
| 신뢰성 | 중 | 높 | 극 |
| 비용 | $ | $$$ | $$$$$ |
| 용도 | 편의 | 제어 | 안전 |
| 복잡도 | 낮 | 중 | 높 |

선택 기준:
- 편의 기능? → LIN
- 파워트레인? → CAN
- 극도의 안전? → FlexRay

🎯 면접 예상 질문

Q1: "LIN이 뭐고, 왜 느릴까요?"
A: "LIN은 저비용 통신 프로토콜입니다. 
   창문, 미러 같은 편의 기능용이라 
   20 kbps 속도도 충분합니다. 
   이렇게 하면 비용을 절감할 수 있어요."

Q2: "LIN의 Master-Slave 구조를 설명해주세요"
A: "Master는 1개 (바디 ECU)이고, 
   Slave는 여러 개 (창문, 미러, 좌석 ECU)예요. 
   Master가 언제 누가 데이터를 보낼지 
   Schedule에 따라 제어합니다."

Q3: "LIN Schedule이 뭐죠?"
A: "정해진 시간표예요. 
   Master가 '0ms에 창문 신호, 10ms에 미러 신호' 
   이렇게 미리 정해놓고 반복합니다."

Q4: "LIN 메시지 구조를 그려주세요"
A: "Break (시작) → Sync (동기화) → PID (메시지 ID) 
    → Data (데이터) → Checksum (오류 검사) 이런 순서예요."

Q5: "LIN과 CAN의 가장 큰 차이는?"
A: "구조가 다릅니다. 
   LIN은 Master-Slave (한 마스터가 제어),
   CAN은 Broadcast (모두가 같은 버스 사용).
   또한 속도도 LIN은 20 kbps, CAN은 500 kbps로 
   25배 차이입니다."

📌 LIN의 핵심

항목 설명
정의 저속, 저가 편의 통신
구조 Master 1개 + Slave 여러 개
속도 20 kbps (느림!)
메시지 Break + Sync + PID + Data + Checksum
Schedule 정해진 시간표 반복
신뢰성 중간 (Checksum 오류 검사)
비용 $ (매우 저가)
용도 창문, 미러, 좌석 (편의)
장점 저가, 간단함
단점 느림, 신뢰성 중간

마치며

다음 게시물에서는 주인공인 CAN을 포스팅해볼거예요

캔은 중요하기 때문에 2부로 나누어서 포스팅할 계획입니다.

첫째는 기초편으로 정의, 특징, 메시지의 구조

ID의 의미랑 Candb에 대해 알아보는 시간을 가질 예정입니다

 

CAN 은 주인공이라고 말씀드렸죠?

표준이기때문이기도 하고 사실 거의 모든 제어기는 CAN으로 작동합니다.

빠르고 정확하고 비싸지 않고 모든게 좋죠.

그래서 CAN이 한동안 자동차를 지배했었답니다.

기대해주세요!