본문 바로가기

조금은 전문적인 이야기/자동차 통신

Application Layer #1 - 부정응답


 오늘은 7번 Application Layer 의 첫 번째 순서인 부정응답에 대해 다룰 예정이다. 다른 것들을 모두 제껴두고 이 녀석을 먼저 다루는 이유는 응답패턴 관련 해서 모든 SID 에 공통으로 적용이 되는 부분이기 때문이다. 대부분의 통신 오류의 경우 2번 Data Link Layer 의 문제가 아니라면 이 녀석이 대부분의 문제이기 때문이다. 일반 적인 경우 SID 체계는 UDS(Unified Diagnostic Services) 의 경우 다르지만 이 녀석은 거의 유일하게 동일한 녀석이다. 고로 한번만 제대로 이해를 하고 나면 대부분의 프로토콜에서 동일하게 적용 할 수 있다는 것이다. 예외가 있다면 구형 OBD -I 에서는 부정응답부분도 다른 경우가 왕왕 있는 편이다. 


 사실 이 녀석의 문제는 해결하는 것이 아주 간단하다. 각 PID 별로 어째서 실패가 나는지에 대한 이유를 보여주기 때문인데, 그 부분에 대해 이해를 하고 있다면, 어렵지 않게 해결을 할 수 있으며, 기능이나, 시스템의 개발 당시에도 이 부분에 대한 고려가 이루어지지 않으면, 어떤 차량에서는 되고 어떤 차량에서는 안되는 문제가 발생 할 수 있다. 



 일반적으로 사용하는 SID 들의 리스트 이다.(다시한번 말하지만, UDS 는 SID 리스트 자체가 틀리다.) 굉장히 많이 쓰이는 녀석들도 있고, 거의 쓰지 않는 녀석들도 있는데 사실 ECU 는 기본적으로 여기에 나와있는 명령들은 대부분 지원을 한다. 다만 각 제조사 별로 패턴이 다른 경우가 있고, 명령어 포맷이 틀린 경우가 있어 부정응답의 패턴에 대해서 알아두면 분석을 할 때 굉장히 도움이 된다. 



 전형적인 통신 절차에 대한 그래프 이다. 통신을 시작하고, 메세지 포맷에 대해 체크를 한 뒤에 부정응답 조건에 따라 플로우가 진행이 된다. SID 의 지원 여부부터 컨디션, 세션등의 이유를 모두 표출해 준다. 간단하게 정리된 부정응답의 PID 리스트는 다음과 같다. 



 부정응답은 크게 나누면 6가지의 분류로 나눌 수가 있는데, 간단하게 설명을 하자면 이렇다.


1. 일반적인 부정응답 : SID, PID 혹은 메세지 형식이 틀린 경우

2. 차량의 상태에 따른 부정응답 : 차량의 컨디션이나 ECU의 컨디션에 따른 부정응답. 

3. 세션관련 부정응답 : 진단 세션이 너무 낮거나, Security 가 연관 된 기능들의 부정응답.

4. 프로그래민 관련 부정응답 : ECU Reprogramming 관련 부정응답. - ECU 제조이외에는 거의 볼일이 없다. 

5. 펜딩(지연) : ECU 의 처리대기 부정응답.

6. 제조사 정의 구역 : 일반적으로 사용되지 않는 제조사들이 정의한 부정응답.


 부정응답의 패턴은 굉장히 간단한데, 먼저 0x7F 로 부정응답이라는 것을 알린 뒤에, SID 가 붙어 어떤 명령에 대한 부정응답인지를 보여주고, 이후에 PID가 붙어 어떤 이유인지를 보여준다. 


86 10 F1 3B 00 01 02 03 04 CS

83 F1 10 7F 3B 33 CS


 예를든 코드를 설명 하자면, 0x3B 로 Write를 하는데, 0x00 번지에 0x01, 0x02, 0x03, 0x04 를 Write 를 하라는 명령이다. 그 명령에 대해 0x7F 로 부정응답을 보내왔고, 0x3B 에 대한 응답이며, 0x33 즉 세션이 맞지 않아 실행이 되지 않는 다는 명령을 보내왔다. 패턴에 대해서는 굉장히 직관적이기 때문에, 더 이상의 설명은 아마 필요 없을 것 같다. 


 일반적인 부정응답에 대해 설명을 하자면, 이 부정응답이 온다는 것은 대부분 SID/PID 자체를 지원하지 않는 경우이다. 따라서 이 응답이 오는 경우는 지원하지 않는 기능이기 때문에 다시 시도를 할 필요가 없다. 


82 10 F1 13 00 CS

83 F1 10 7F 13 10 CS


 이런 식으로 응답이 올 경우는 0x13 에 대해 지원을 하지 않는 경우 이므로, 다른 명령으로 Request 를 해야 정상적으로 DTC 를 읽어 올 수 있다. 


82 10 F1 18 00 CS

83 F1 10 7F 18 12 CS


 이런 응답일 경우는 0x18 에 대해 지원을 하지만, PID가 틀린 경우이다. 0x18 에 대해 알아보면, 메세지 형식이 조금 차이가 있다는 것을 알 수 있는데, 예를 들어 제대로 된 메세지 형식은 다음과 같다. 


84 10 F1 18 00 FF 00 CS

82 F1 10 58 00 CS


 이런 식으로 패턴이 맞게 되면 제대로 된 응답을 받을 수 있게 되는 것이다. 물론 이 작업은 ECU 의 스펙이 없을 경우 굉장히 지루한 작업이 될 수 있다. 다만, 부정응답에 대해 이해를 하고 있다면, 스펙 없이도 개발을 하는 것이 불가능한 일은 아니라는 점이다. 여기서 좀 특별한 녀석이 있는데 0x80 이라는 녀석이다. 이 녀석의 의미는 진단세션이 없다는 표시인데, 이 녀석이 나오는 이유는 많지는 않지만 일부 ECU의 경우 한개 이상의 프로토콜로 통신진단이 되는 경우다 있다. 예를 들면 CAN으로도 통신이 되고 KWP2000 으로도 통신이 되는 경우인데, 둘중의 한개의 프로토콜로만 정상적인 진단이 될 경우 이 응답이 온다. 만일 이 응답을 보게 된다면, 프로토콜이 틀린 것이다. 다른 프로토콜을 찾아야 한다. 


 그렇다면 상태에 따른 부정응답을 알아보도록 하자. 대표적으로 이 녀석은 0x2X 계열의 부정응답이 온다. 0x21 의 경우 ECU 가 어떠한 이유로 바로 처리를 못할 경우 오게 되는데, 이 경우는 "반드시" 명령어를 반복해서 보내줘야 정상 처리가 가능하다. 이와 비슷한 경우로 0x23 이라는 녀석이 있는데, 그 녀석은 "수행중" 이라는 표시로, 명령이 제대로 들어 갔으며 응답이 올 때까지 끝나지 않았다는 표시다. 이 경우는 정상응답으로 처리를 해도 무방하며, 부정응답이기는 하지만 긍정응답이라고 볼 수 있다. 좀더 깊게 설명을 하자면, 2번에서 타이밍에 대해 설명을 했었는데, ECU 와 Tester 간의 통신 시간에 대해 설명을 했었다. Tester 가 Request 를 보내게 되면 ECU 에서 반드시 P2 이내에 응답을 줘야 하는데, 그 P2 이내에 완료되지 않은 경우 이 부정응답이 오게 된다. 간혹 이것과 0x78 을 헷갈릴 경우가 있는데, 펜딩의 경우 기능이 수행이 되고 있는 것이 아니라 대기열에 들어 있는 것이고 0x23 의 경우는 이미 기능이 수행중이라는 것이다. 


 그리고 0x22 의 경우 차량의 상태가 맞지 않는 다는 부정응답인데, 예를 들면 DPF 재생을 수행 할 경우 Engine coolant temperature 가 80 'C 이상에서만 수행이 되는데, 80 'C 가 되지 않는 경우 이 부정응답이 나오게 된다. 이 경우는 해당 상태를 맞춰주면 바로 해결이 가능하다. 


 다음으로는 세션관련 부정응답인데, 사실 이 녀석은 조금 위험한 녀석이다. Security 에 관련된 부분이 있기 때문에, 연속해서 수행할 경우 Lock 이 걸려버릴 수 있는 위험이 있으므로, 0x35 이상의 숫자까 뜨면, 웬만하면 진행을 중지 하는 편이 좋다. 대부분 Security 코드를 잘못 보낼 경우 해당 명령이 오게 된다. 0x31 의 경우는 Out of range 로, (현재 세션에서) 지원하는 PID 의 범위를 벗어난 경우 해당 부정응답이 나오게 된다. 이 경우는 세션을 올려주면 되는 경우가 많다. 0x33 은 세션이 낮아서 수행 할 수 없다는 부정응답이기 때문에, 세션만 올려주면 간단하게 해결이 가능하다. 


 사실 세션관련해서는 이해가 조금 힘들 수도 있는데, 대부분의 통신에서 일반적인 진단 세션이 있고, 확장진단 세션등의 다른 세션이 필요한 경우가 많다. 일반적인 진단세션에서는 DTC 를 읽거나 센서의 데이터를 읽는 등의 기능은 문제없이 수행이 되나, 강제구동이나 Calibration/Adjustment 등의 Adaptation 기능을 사용하려고 하면 확장 세션이 요구되는 경우가 대부분이다. 확장 세션의 경우는 간단한 명령으로 오픈이 되는 경우도 있지만, 보안코드, 즉 Security logic 이 들어간 경우도 아주 많다. 이 부분은 각 메이커 별로 다르며, 일반적으로는 분석하기가 꽤나 어렵다. 그보다 높은 프로그래밍 세션은 코딩관련 기능을 사용할때 필요하다. 


 이제 문제가 되는 0x35 이상의 부정응답에 대한 의문이 어느정도는 풀렸을 것이다. 이 코드들은 세션을 올리기 위해 Security 를 풀때 틀린 코드를 보내면 나오는 응답인데, 연속해서 수행을 해서 Security 를 풀어버리는 것을 방지하기 위해 존재 하는 것들이다. 예를 들면 1회에 잘못된 응답을 보낼 경우 0x35 가 뜨며, 그 이후 부터는 0x36 이상의 번호가 뜬다. 거기서 0x37 까지 갔다면, ECU가 LOCK 이 걸린 상태가 되어 일정시간을 기다려야 하며, 제조사 별로 다르지만, 그 이상의 코드인 0x38, 0x39 등이 뜨며 ECU 자체가 Freezing 이 걸려버리는 경우도 있다. 만일 Freezing 이 걸렸다면, ECU를 교환해야 하는 불상사가 생길 수도 있다. 


82 10 F1 21 0A CS

83 F1 10 7F 21 31 CS   -> Out of range


82 10 F1 10 85 CS

82 10 F1 50 85 CS       -> Session up


82 10 F1 21 0A CS

86 F1 10 61 0A 01 02 03 04 CS  -> Positive answer


 0x31 의 문제에 대한 예이다. 여기서 주의를 해야 하는 부분은, 0x31 응답에 대해서 인데, 이는 0x12 의 의미일 수도 있기 때문이다. PID 자체가 지원을 하지 않을 수 있다는 것이다. 대부분의 경우는 0x12 로 지원하지 않는 경우 오지만, 일부 저가 ECU 의 경우는 그렇지 않은 경우도 있다. 


82 10 F1 31 0A CS

83 F1 10 7F 31 33 CS            -> Session problem


82 10 F1 27 01 CS

84 F1 10 67 01 AB CD CS      -> Request security seed


84 10 F1 27 02 01 02 CS       -> Send security key

83 F1 10 67 02 34 CS


82 10 F1 31 0A CS               -> Positive answer

83 F1 10 71 0A 01 CS


 이런식으로 0x33 에 대한 예를 들 수가 있는데, 대부분의 경우 Security 관련 문제일 가능성이 크다. Seed 를 요청하고 정해진 룰대로 변환을 해서 Key 를 보내줘야만 해당 세션이 열리게 되는 것이다. 


82 10 F1 27 01 CS                   -> Request security seed

84 F1 10 67 01 AB CD CS


84 10 F1 27 01 00 01 CS

83 F1 10 7F 27 35 CS               -> Wrong key


84 10 F1 27 01 00 02 CS

83 F1 10 7F 27 36 CS                -> Wrong key time delay on


84 10 F1 27 01 00 03 CS

83 F1 10 7F 27 37 CS               -> Need to wait time delay


84 10 F1 27 01 00 04 CS

83 F1 10 7F 27 39 CS                -> Freezing


 0x35 이상의 코드들에 대한 예인데, 코드만 보고는 잘 모르곘지만 굉장히 무시무시한 코드이다. 만일 이쪽의 지식이 조금 있는 분이 이것을 본다면 일단 공포감을 느낄 것이다.(Freezing 을 한번이라도 시켜봤다면...) 요청한 Seed 에대해 잘못된 응답을 반복해서 보내서 ECU 를 Freezing 까지 가게 만든 경우 인데, 이 경우 운이 좋다면 ECU의 Time delay를 기다려서 풀리는 경우도 있지만, 그렇지 않고 ECU 를 교환을 해야 하는 경우도 있다. 대부분 이런식으로 Freezing 이 되어 버릴 경우 ECU 에는 "Internal error" 계열의 DTC 가 뜨게 된다. 


  다음으로 많은 코드들이 차지하고 있는 프로그래밍 관련 부정응답의 경우는 웬만해서는 보기 힘든 코드들이다. 이는 Reprogramming 시에 세션관련으로도 표출이 될 수 있으며, ECU의 이상동작으로 코딩이 중지가 되거나 거부가 될 경우 뜨게 된다. 대부분의 경우 사용하거나 볼일이 없으므로 이런 것이 있다는 것 정도만 알아둬도 충분하다. 


 마지막으로는 펜딩(지연) 관련 부정응답에 대해 알아보자. 사실 가장 많이 접하게 되는 경우인데, 이 부정응답은 Tester 에서 Request를 보낼 때에, ECU 가 어떠한 이유로 바로 수행을 못할 경우 오게 된다. 위에도 설명을 했디만, 이 것은 수행중이라는 메세지가 아니며, Request 가 메모리에 들어 갔으나 수행되지 않았다는 내용이다. 2번의 Timing 에서 이 응답을 받게 되면 5000 ms 까지 기다리라는 부분이 있는데, 5000 ms 까지 기다려도 제대로 되지 않을 경우 다시한번 동일한 응답이 오게 된다. 


82 10 F1 1A 98 CS

83 F1 10 7F 1A 78 CS                   -> 펜딩 시작

.....

83 F1 10 7F 1A 78 CS                   -> 5000 ms 초과

....

86 F1 10 5A 98 01 02 03 04 CS       -> Positive answer


 이런식으로 명령이 이루어 지는 것이다. 사실 이 녀석 때문에 통신 자체가 꼬이는 경우가 많이 발생을 하는데, Test code 를 보내 통신 라인 이나 세션을 유지시켜줘야 할 경우 이 명령 사이에 코드가 끼게 되면 통신 자체가 꼬여버리기 때문에, 주의를 해야 한다. 그 부분만 주의를 한다면, 응답시간이 길어질 뿐 정상 응답이나 마찬가지 이니 따로 신경을 쓸 필요는 없다. 


 이외의 제조사 정의 구역이 있는데, 대부분 사용을 하지 않거나 특별한 부분에서만 사용이 되기 때문에, 알아둘 필요는 없다. 또한 보게 되더라도, 일반적인 거부의 경우가 대부분 이기 때문에 지원하지 않는 명령이라고 생각하면 된다. 


 자 이렇게 부정응답에 대해 살펴봤다. 사실 이녀석이 그렇게 쉬운 녀석은 아니고 그때 그때 상황에 따라 해석을 해야 되는 부분도 존재하기 때문에 한번에 이해를 하기는 힘들다. 그래도 어느정도 알고 있는 상태라면, 분석이나 개발을 할때 이 녀석들과 마추치면 어느정도 해석은 가능 할 것이다. 게다가 이 녀석의 해석이 없이는 제대로 된 분석도 할 수가 없는 녀석도 많으니 굉장히 중요한 녀석이라고 할 수 있다.