Skip to content
Go DevBJ
Go back

DoIP Firmware Download에서 갑자기 문제가 터지는 이유

Edit page

작은 UDS 요청만 테스트할 때는 DoIP가 꽤 안정적으로 보입니다.

이 정도는 대부분 잘 됩니다.

그런데 firmware download 들어가는 순간 분위기가 달라집니다.

이런 문제가 갑자기 튀어나옵니다.

이유는 간단합니다.
평소에는 안 보이던 TCP stream 처리와 large payload 문제가 드러나기 시작하기 때문입니다.

시리즈 목차

평소 테스트는 너무 작다

예를 들어 ReadDataByIdentifier:

22 F1 90

몇 바이트 안 됩니다.

반면 firmware transfer는 다릅니다.

36 xx [large data block]

수 KB ~ 수 MB 데이터가 계속 흘러갑니다.

즉:

small request/reply
→ 간단한 parser로도 버팀

large continuous stream
→ transport 문제 드러남

이 흐름입니다.

TCP는 message protocol이 아니다

여기서 많이 무너집니다.

초기 구현에서는 보통 이런 가정을 합니다.

data = sock.recv(4096)
process_one_packet(data)

하지만 TCP는 packet 기반이 아닙니다.

예를 들면:

DoIP Packet A 절반

만 먼저 올 수도 있고,

Packet A + Packet B

가 한 번에 붙어서 올 수도 있습니다.

Firmware transfer에서는 이런 상황이 훨씬 자주 나옵니다.

그래서 parser 구조가 중요하다

안전한 흐름은 보통 이렇습니다.

1. exact header size read
2. payload length parse
3. exact payload read
4. message process

즉:

header = recv_exact(sock, 8)

payload_len = parse_length(header)

payload = recv_exact(sock, payload_len)

이 흐름이 핵심입니다.

중간에:

recv(4096)

결과를 바로 parser에 넣기 시작하면 큰 transfer에서 흔들립니다.

transfer block size도 영향이 있다

UDS TransferData 자체도 block 단위로 움직입니다.

예를 들어:

RequestDownload
→ TransferData #1
→ TransferData #2
→ TransferData #3

이렇게 이어집니다.

문제는 block size가 커질수록:

가 같이 올라간다는 점입니다.

그래서 무조건 큰 block이 좋은 건 아닙니다.

현장에서 자주 보는 문제

1) ECU 응답 대기 중 timeout

예시:

TransferData 송신
→ ECU flash write
→ 응답 지연
→ tester timeout
→ reconnect

실제로는 ECU가 죽은 게 아니라 flash 작업 중일 수 있습니다.

그래서 programming session timeout 정책은 일반 진단보다 길게 잡는 경우가 많습니다.

2) throughput 계산이 비현실적임

이론상 Ethernet은 빠릅니다.

하지만 실제 firmware transfer는:

영향을 다 받습니다.

즉:

Ethernet bandwidth != Flashing speed

입니다.

3) sender만 빠름

PC 쪽은 계속 밀어 넣는데 ECU가 못 따라가는 경우입니다.

예를 들어:

while True:
    sock.sendall(block)

이런 구조는 위험합니다.

반드시:

request
→ response 확인
→ next block

흐름을 지켜야 합니다.

특히 TransferData sequence 관리는 중요합니다.

sequence counter도 자주 꼬인다

Firmware download에서 sequence counter mismatch가 꽤 자주 나옵니다.

예시:

TransferData #15 전송
응답 timeout
재전송
ECU는 이미 #16 기대 중

이 상태가 되면 recovery가 복잡해집니다.

그래서 timeout 발생 시:

정책을 명확히 해야 합니다.

로그는 block 단위로 남기는 게 좋다

Firmware transfer에서는 payload 전체 dump보다 흐름 로그가 더 중요합니다.

예시:

[uds] transfer block=15 size=4096 tx
[uds] transfer block=15 ack rx
[uds] transfer block=16 size=4096 tx

추가로 좋았던 정보:

elapsed time
retry count
current throughput
flash state

이런 것들입니다.

Wireshark만으로 안 잡히는 경우

이것도 자주 겪습니다.

패킷은 정상처럼 보이는데 실제 flashing은 실패합니다.

왜냐하면 문제 원인이:

일 수도 있기 때문입니다.

즉:

network trace 정상
≠ flashing 정상

입니다.

구현 시 추천하는 구조

Firmware download는 상태 머신으로 보는 게 편합니다.

예시:

IDLE
  → REQUEST_DOWNLOAD
  → TRANSFER_DATA
  → TRANSFER_EXIT
  → VERIFY
  → COMPLETE

여기에:

를 추가하는 방식이 유지보수에 좋습니다.

오늘 포인트

DoIP firmware transfer 문제의 핵심은 Ethernet 속도가 아닙니다.

실제로 중요한 건:

입니다.

작은 diagnostic request에서는 괜찮던 코드가 large transfer에서 무너지는 이유도 여기 있습니다.

다음 글에서는 DoIP Gateway 환경에서 ECU routing이 어떻게 동작하는지 이어서 다뤄보겠습니다.

추천 대상

한 줄 요약

DoIP firmware download에서는 단순 packet 송수신보다 TCP stream 처리와 timeout 상태 관리가 훨씬 중요하다.

추천 키워드

doip, firmware download, uds transferdata, automotive ethernet, tcp stream, flashing


DevBJ | No Bio, Just Log #오늘을살자


Edit page
Share this post on:

Previous Post
DoIP Gateway 구조를 이해해야 ECU가 보인다
Next Post
DoIP Negative Acknowledge, UDS 에러랑은 다르다