테마
10. ISO-TP와 CAN 기반 UDS 전송
학습 목표
- CAN 기반 UDS에서 ISO-TP가 필요한 이유를 설명할 수 있다.
- Single Frame, First Frame, Consecutive Frame, Flow Control Frame의 역할을 구분할 수 있다.
- Sequence Number가 누락과 순서 오류를 감지하는 방식을 이해할 수 있다.
- Flow Control의 Flow Status, Block Size, STmin 의미를 설명할 수 있다.
- Padding과 CAN FD 기반 전송에서 달라지는 점을 이해할 수 있다.
전체 구조
1. CAN 한 프레임은 작다
Classical CAN의 데이터 영역은 최대 8바이트다.
그런데 UDS 메시지는 8바이트를 넘는 경우가 많다.
예를 들어 Read Data By Identifier(0x22)로 DID 여러 개를 한 번에 요청한다고 하자.
text
0x22 DID1 DID2 DID3 DID4 DID5 ...DID 하나가 2바이트이므로, 여러 개를 넣으면 금방 8바이트를 넘는다.
DTC Snapshot이나 Extended Data 응답은 더 길어질 수 있다.
이 문제를 해결하기 위해 CAN 기반 UDS에서는 **ISO-TP(ISO 15765-2)**를 사용한다.
TP는 Transport Protocol의 약자로, 긴 UDS 메시지를 여러 CAN 프레임으로 나누고 다시 조립하는 역할을 한다.
2. ISO-TP는 UDS와 CAN 사이에 놓인다
계층을 단순화하면 다음처럼 볼 수 있다.
UDS는 "무슨 서비스를 요청하는가"를 정의한다.
ISO-TP는 "그 UDS 메시지를 CAN 프레임 여러 개로 어떻게 실어 나를까"를 정의한다.
따라서 CAN 로그에서 UDS를 해석할 때는 TP 바이트를 먼저 이해해야 한다.
3. Single Frame은 짧은 메시지를 한 번에 보낸다
UDS 메시지가 짧으면 Single Frame 하나로 보낼 수 있다.
Classical CAN에서 Single Frame은 첫 바이트를 TP 정보로 쓰기 때문에 실제 UDS 데이터는 보통 최대 7바이트까지 들어간다.
첫 바이트는 다음처럼 나뉜다.
| 영역 | 의미 |
|---|---|
| 상위 4비트 | Frame Type, Single Frame은 0 |
| 하위 4비트 | UDS 데이터 길이 |
예를 들어 UDS 데이터가 3바이트라면 첫 바이트는 0x03이 된다.
| Byte | 값 예시 | 의미 |
|---|---|---|
| 1 | 0x03 | Single Frame, UDS 길이 3 |
| 2 | 0x22 | UDS SID |
| 3 | 0x00 | DID high |
| 4 | 0x01 | DID low |
| 5~8 | padding 또는 미사용 | 설정에 따라 다름 |
4. First Frame은 긴 메시지의 시작을 알린다
UDS 메시지가 Single Frame에 들어가지 않으면 First Frame으로 시작한다.
First Frame은 전체 UDS 메시지 길이와 앞부분 데이터를 담는다.
First Frame의 앞쪽 구조는 대략 다음과 같다.
| 영역 | 의미 |
|---|---|
| 첫 바이트 상위 4비트 | Frame Type, First Frame은 1 |
| 첫 바이트 하위 4비트 + 둘째 바이트 | 전체 UDS 메시지 길이 |
| 나머지 바이트 | UDS 데이터 앞부분 |
Classical CAN에서는 First Frame이 2바이트를 TP 정보로 쓰므로, 첫 프레임에는 UDS 데이터 6바이트가 들어간다.
5. Consecutive Frame은 남은 데이터를 이어 보낸다
First Frame 이후 남은 UDS 데이터는 Consecutive Frame으로 보낸다.
Consecutive Frame은 첫 바이트에 Frame Type과 Sequence Number를 담고, 나머지 바이트에 UDS 데이터를 담는다.
| 영역 | 의미 |
|---|---|
| 첫 바이트 상위 4비트 | Frame Type, Consecutive Frame은 2 |
| 첫 바이트 하위 4비트 | Sequence Number |
| 나머지 바이트 | 이어지는 UDS 데이터 |
Sequence Number는 보통 1부터 시작해 1씩 증가하고, 4비트 범위를 넘어가면 다시 순환한다.
수신 측은 Sequence Number를 보고 프레임 누락이나 순서 오류를 감지할 수 있다.
6. Flow Control은 수신자가 전송 속도를 제어한다
긴 메시지를 보낼 때 Sender가 Consecutive Frame을 무작정 빠르게 보내면 Receiver가 처리하지 못할 수 있다.
그래서 First Frame을 받은 Receiver는 Flow Control Frame을 보내 Sender에게 전송 조건을 알려준다.
Flow Control의 첫 바이트도 상위 4비트와 하위 4비트로 나뉜다.
| 영역 | 의미 |
|---|---|
| 상위 4비트 | Frame Type, Flow Control은 3 |
| 하위 4비트 | Flow Status |
Flow Status는 다음처럼 해석한다.
| Flow Status | 의미 |
|---|---|
0 | Continue To Send, 계속 전송 가능 |
1 | Wait, 잠시 대기 |
2 | Overflow, 수신 버퍼 부족 또는 처리 불가 |
7. Block Size와 STmin
Flow Control에는 Flow Status 외에도 중요한 값이 들어간다.
| 필드 | 의미 |
|---|---|
| Block Size | 한 번에 연속으로 받을 수 있는 Consecutive Frame 개수 |
| STmin | Consecutive Frame 사이의 최소 간격 |
Block Size가 0이면 보통 "남은 Consecutive Frame을 추가 Flow Control 없이 계속 보내도 된다"는 의미로 쓰인다.
Block Size가 1이면 한 프레임 보낼 때마다 Flow Control을 다시 기다려야 한다.
STmin은 수신 측 처리 속도에 맞춰 Sender가 Consecutive Frame을 너무 빠르게 보내지 않도록 하는 값이다. STmin 바이트는 값 범위에 따라 단위가 다르다. 0x00~0x7F는 0~127ms, 0xF1~0xF9는 100~900us를 뜻한다. 0x80~0xF0, 0xFA~0xFF는 예약 값으로 보고 사용하는 스택과 프로젝트 규칙을 확인해야 한다.
8. 예시: 27바이트 UDS 메시지 분할
UDS 메시지 길이가 27바이트라고 하자.
Classical CAN 기준으로 First Frame에는 6바이트, 각 Consecutive Frame에는 7바이트씩 담을 수 있다.
분할은 다음처럼 된다.
| 프레임 | 담는 UDS 데이터 |
|---|---|
| First Frame | 6바이트 |
| Consecutive Frame 1 | 7바이트 |
| Consecutive Frame 2 | 7바이트 |
| Consecutive Frame 3 | 7바이트 |
총 6 + 7 + 7 + 7 = 27바이트다.
따라서 First Frame 하나와 Consecutive Frame 세 개가 필요하다.
그 사이에 Receiver가 Flow Control을 보내 전송 가능 여부와 속도를 제어한다.
9. Padding은 CAN 메시지 길이를 고정할 때 사용한다
프로젝트에 따라 CAN 메시지의 DLC를 항상 8바이트로 맞추는 규칙을 사용할 수 있다.
이때 실제 데이터가 4바이트뿐이라도 나머지 바이트를 특정 값으로 채운다.
이렇게 채우는 값을 Padding이라고 한다.
예:
| Byte | 값 |
|---|---|
| 1 | TP 정보 |
| 2~4 | UDS 데이터 |
| 5~8 | 0xCC padding |
Padding 값은 프로젝트 사양에서 정한다.
수신 측은 실제 데이터 길이를 TP 정보로 판단하고, padding 영역을 UDS 데이터로 해석하지 않아야 한다.
10. CAN FD에서도 원리는 이어진다
CAN FD는 한 프레임에 최대 64바이트 데이터 영역을 사용할 수 있다.
따라서 같은 UDS 메시지라도 Classical CAN보다 더 적은 프레임으로 전송할 수 있다.
하지만 기본 개념은 이어진다.
- 메시지가 한 프레임에 들어가면 Single Frame으로 처리
- 길면 First Frame과 Consecutive Frame으로 분할
- Receiver가 Flow Control로 Sender를 제어
- Sequence Number로 순서 확인
다만 CAN FD 기반 ISO-TP는 Single Frame 길이, PCI 정보 배치, DLC 매핑 등 세부가 달라질 수 있으므로 사용하는 표준 버전과 프로젝트 사양을 확인해야 한다.
11. 로그를 볼 때는 TP와 UDS를 분리해서 읽는다
CAN 로그에서 UDS를 해석할 때는 한 줄씩 바로 "UDS 서비스"로만 보면 안 된다.
먼저 ISO-TP 프레임인지 확인해야 한다.
읽는 순서는 다음이 좋다.
- CAN ID를 보고 Tester -> ECU 요청인지, ECU -> Tester 응답인지 확인한다.
- 데이터 첫 바이트의 상위 4비트로 TP Frame Type을 확인한다.
- Single Frame이면 길이만큼 UDS 메시지를 바로 읽는다.
- First Frame이면 전체 길이를 보고 Flow Control과 Consecutive Frame을 추적한다.
- UDS 메시지가 완성되면 SID, DID, SubFunction, NRC 등을 해석한다.
핵심 정리
- Classical CAN 한 프레임은 데이터 영역이 최대 8바이트이므로 긴 UDS 메시지를 담기 어렵다.
- ISO-TP는 UDS 메시지를 CAN 프레임 여러 개로 나누고 다시 조립하는 전송 계층 역할을 한다.
- Single Frame은 짧은 메시지, First Frame은 긴 메시지의 시작, Consecutive Frame은 남은 데이터, Flow Control은 수신 측 흐름 제어를 담당한다.
- Sequence Number는 Consecutive Frame의 순서와 누락을 확인하는 데 쓰인다.
- Block Size와 STmin은 Receiver가 Sender의 전송량과 간격을 제어하기 위한 값이다.
- CAN 로그에서 UDS를 읽을 때는 TP 재조립 후 UDS SID와 파라미터를 해석해야 한다.
확인 질문
- Classical CAN에서 Single Frame에 UDS 데이터가 7바이트까지만 들어가는 이유는 무엇인가?
- First Frame 뒤에 Flow Control이 필요한 이유는 무엇인가?
- Sequence Number가 예상과 다르면 수신 측은 어떤 문제를 의심할 수 있는가?
- Block Size가
0,1,2일 때 Consecutive Frame 전송 흐름은 어떻게 달라지는가?