統一診斷服務 (Unified diagnostic services , UDS) (二)
UDS定義的診斷服務從邏輯來說分為以下幾類:
- Diagnostic and Communication Management (診斷和通信管理)
- Data Transmission (數據傳輸)
- Stored Data Transmission (存儲數據傳輸,用於操作DTC)
- InputOutput Control (IO控制)
- Routine Control (不知如何翻譯好,作用是調用ECU內部的預置函數)
- Upload Download (上傳下載)
UDS規定使用1個byte來表示診斷服務,即所謂的Service ID,簡稱SID。本文介紹一下Diagnostic and Communication Management 這一類診斷服務中的一部分。
DiagnosticSessionControl (0x10)
DiagnosticSessionControl這個服務的SID是0x10,request固定為2個byte,第一個byte是SID,第二個byte的低7bit是sub-function,用於指示ECU將進入的session。UDS定義的session包括:
0x00 ISOSAEReserved(保留)
0x01 defaultSession
0x02 ProgrammingSession
0x03 extendedDiagnosticSession
0x04 safetySystemDiagnosticSession
0x05 – 0x3F ISOSAEReserved(保留)
0x40 – 0x5F vehicleManufacturerSpecific(由整車廠自定義使用)
0x60 – 0x7E systemSupplierSpecific(由ECU供應商自定義使用)
0x7F ISOSAEReserved(保留)
DiagnosticSessionControl用於控制ECU在不同的session之間進行轉換,session可以看作是ECU所處的一種軟體狀態,在不同的session中診斷服務執行的許可權不同。 ECU上電之後,默認處在defaultSession中,在這個session中很多診斷服務不可以執行,很多診斷相關的數據不能讀取或寫入。一般的診斷儀啟動之後,會給ECU發送10 03,即讓ECU進入 extendedDiagnosticSession中,在這個session中可執行的診斷服務就很多了。而如果要讓ECU保持在non-defaultSession中,則需要診斷儀每隔固定的時間發送0x3E服務,ECU才會知道診斷儀有和自己通信的需求,從而保持在non-defaultSession中。另一個常用的session是ProgrammingSession,在這個session中可以進行軟體刷寫的一系列診斷服務。0x40 – 0x5F 這個範圍中的session由整車廠自定義使用,比如,某些診斷服務或診斷數據的操作需要在生產線上執行,即所謂的End-Of-Line,整車廠可以從這個範圍中選擇一個值來表示EOL session;又或者在開發階段需要某種「超級」session,則也可以從這裡選一個值用來使ECU進入開發模式的session。DiagnosticSessionControl這個服務非常簡單,但是它卻是ECU和診斷通信的第一條診斷命令。
這個診斷服務的response分為三部分,第一部分是0x50,作為SID的echo;第二部分是進入的session,作為sub-function的echo;第三部分是4個位元組,前兩個位元組代表P2Server_max,即ECU在應用層上對診斷命令的響應時間,後兩個位元組代表P2*Server_max
,即ECU在暫時無法處理當前診斷命令(具體表現為發送了NRC 0X78),在應用層上對診斷命令響應的最長時間。
ECUReset (0x11)
ECUReset 這條指令的用途是通過診斷請求使ECU重啟。
ECUReset 這個服務的SID是0x11,request固定為2個byte,第一個byte是SID,第二個byte的低7bit是sub-function,用於指示ECU將模擬哪種方式進行重啟。
常用的sub-function包括(只舉2個例子,UDS還定義了很多其他的值)
0x01 hardReset 模擬KL30的重啟
0x02 keyOffOnReset 模擬KL15的重啟
當我們通過診斷命令改寫了ECU的某些數據,或者對ECU進行了某些設置,只有將ECU重啟才能將這些配置生效,所以就有了這個診斷命令。在ECUReset 執行之後,ECU會從Non-defaultsession回退到defaultsession中。
SecurityAccess (0x27)
廠家可能會為ECU定義某些安全級別稍微高一些的診斷服務,在執行此類服務之前,就需要執行SecurityAccess 這個診斷命令,進行一個簡單的身份驗證。
完成SecurityAccess 有以下步驟:
- 診斷儀向ECU請求「Seed」(通常是一個與時間相關的偽隨機數),
- ECU向診斷儀發送「Seed」,
- 診斷儀向ECU發送「Key」 (根據請求得到的Seed和一個本地的密碼進行計算得來)
- ECU判斷診斷儀發來的「Key」是否有效
根據UDS的定義,0x03, 0x05, 0x07 – 0x41 這個範圍留給用於requestSeed的sub-function;0x04, 0x06, 0x08 – 0x42這個範圍留給用於sendKey的sub-function。具體選擇哪對值,由整車廠自己定義。整車廠也可以選擇多對sub-function,用於不同等級的安全訪問。
下面我舉一個完成SecurityAccess的診斷命令的例子,假設0x05用於requestSeed,0x06用於sendKey。
診斷儀發送 27 05
ECU響應 67 05 01 01 01(seed是 01 01 01)
診斷儀發送 27 06 02 03 04(key值是02 03 04,seed是 01 01 01,假設本地密碼為01 02 03,而演算法就是將密碼與seed相加)
ECU驗證成功 67 06
此時ECU就處於unlocked的狀態了,那些被保護起來的診斷服務和診斷數據可以被操作了。通常來說,如果ECU重啟,或者回到了default session,unlocked狀態就失效了,如果要執行相關診斷服務,則需要再次執行上面描述的過程。
時間有限,這篇文章里就介紹這三個診斷服務,即0x10, 0x11, 0x27,後續有時間我再補充其他的服務,歡迎大家多提寶貴意見。碼字不易,看到這裡的話就點個贊吧。
推薦閱讀: