자동차 통신 프로토콜 2부: LIN (Local Interconnect Network) 완벽 이해
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 = 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의 특징 (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 메시지 상세 분석
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이 한동안 자동차를 지배했었답니다.
기대해주세요!
'통신 프로토콜' 카테고리의 다른 글
| ISO-TP : CAN으로 큰 데이터를 보내는 방법 (3) | 2025.12.31 |
|---|---|
| 자동차 통신 프로토콜 4부: CAN (2부) – Arbitration과 에러 처리 완전 이해 (0) | 2025.12.26 |
| 자동차 통신 프로토콜 3부: CAN (1부) - 기초와 메시지 구조 완벽 이해 (0) | 2025.12.23 |
| 자동차 통신 프로토콜 1부: 왜 자동차에는 여러 통신 프로토콜이 필요할까? (0) | 2025.12.21 |
| 📌 CAN 통신과 CAN FD란? 자동차가 데이터를 주고받는 방법 쉽게 정리 (0) | 2025.12.10 |