(转发)详解汽车UDS诊断协议(一)
一.概述
UDS(UnifiedDiagnostic Services,統(tǒng)一診斷服務(wù),有時也稱增強診斷)是ISO-14229定義的基于OSI模型中應(yīng)用層的協(xié)議。其中,ISO 14229-1定義了診斷服務(wù),但不涉及網(wǎng)絡(luò)層及實現(xiàn)手段,只有應(yīng)用層的內(nèi)容,因此可在不同的汽車總線(如CAN, LIN, Flexray, Ethernet和K-line等)上實現(xiàn)。
結(jié)合ISO 15765-3和ISO 14229-1則實現(xiàn)了基于CAN總線的UDS汽車統(tǒng)一診斷服務(wù)。如下圖所示:
ISO15765-4規(guī)定排放相關(guān)的診斷內(nèi)容
| OSI各層 | 汽車制造商的增強診斷 | 法規(guī)要求的排放相關(guān)診斷(OBD) |
| 診斷應(yīng)用 | 用戶定義 | ISO 15031-5 |
| 應(yīng)用層 | ISO 15765-3/ISO 14229-1 | ISO 15031-5 |
| 表示層 | 無 | 無 |
| 會話層 | ISO 15765-3 | ISO 15765-4 |
| 傳輸層 | 無 | 無 |
| 網(wǎng)絡(luò)層 | ISO 15765-2 | ISO 15765-4 |
| 數(shù)據(jù)鏈路層 | ISO 11898-1 | ISO 15765-4 |
| 物理層 | 用戶定義 | ISO 15765-4 |
UDS不是法規(guī)要求的,沒有統(tǒng)一實現(xiàn)標準,其優(yōu)勢在于方便生產(chǎn)線檢測設(shè)備的開發(fā),同時更大的方便了售后維修保養(yǎng)和車聯(lián)網(wǎng)的功能實現(xiàn)。
診斷通信的過程從用戶角度來看非常容易理解,診斷儀發(fā)送診斷請求(request),ECU給出診斷響應(yīng)(response),而UDS就是為不同的診斷功能的request和response定義了統(tǒng)一的內(nèi)容和格式。
二.診斷服務(wù)交互方式
UDS本質(zhì)上是一種定向的通信,是一種交互協(xié)議(Request/Response),即診斷方給ECU發(fā)送指定的請求數(shù)據(jù)(Request),ECU反饋給診斷方信息(Response)。
Diagnostic Request的格式:
DiagnosticRequest的格式可以分為兩類:
一類是擁有sub-function的;
一類是沒有sub-function的;
Service ID(以下簡稱SID)的長度固定為1個字節(jié),代表了這條診斷命令執(zhí)行的什么功能。Sub-function的長度也是1個字節(jié),它通常表示對這個診斷服務(wù)的具體操作,比如是啟動、停止還是查詢這個診斷服務(wù)。而后面的Parameter則根據(jù)各個診斷服務(wù)的不同具有不同的內(nèi)容,長度和格式并沒有統(tǒng)一規(guī)格,它用于限定診斷服務(wù)執(zhí)行的條件,比如某個診斷服務(wù)執(zhí)行的時間等。Parameter的一個重要應(yīng)用是作為標識符,標識診斷請求要讀出的數(shù)據(jù)內(nèi)容。
有一點要補充的是,其實Sub-function嚴格來說是7個bit,而不是1個byte,因為它的最高位bit被用于抑制正響應(yīng)(Suppress Ppositive Response, SPR),如果這個bit被置1,則ECU不會給出正響應(yīng)(PositiveResponse);如果這個bit被置0,則ECU會給出正響應(yīng)。這樣做的目的是可以告訴ECU不要發(fā)不必要的Response,從而節(jié)約通信資源。
Diagnostic Response的格式:
Diagnosticresponse分為positive和negative兩類。
positive response意味著診斷儀發(fā)過來的診斷請求被執(zhí)行了,而negativeresponse則意味著ECU因為某種原因無法執(zhí)行診斷儀發(fā)過來的診斷請求,而無法執(zhí)行的原因則存在于negative response報文中的NRC中
Positive response肯定響應(yīng)的格式是由三部分組成,其中的response SID這個字節(jié)作為診斷請求的echo,回復(fù)[SID+0x40],例如請求10,響應(yīng)50;請求22,響應(yīng)62,回復(fù)的是一組數(shù)據(jù)。后面的兩個字節(jié)分別為子功能及其他,視具體的診斷服務(wù)而定。
Negative response否定響應(yīng)的格式固定為3個字節(jié),回復(fù)[7F+SID+NRC],第一個字節(jié)為0x7F,第二個字節(jié)是被拒絕掉的SID,第三個字節(jié)是NRC否定響應(yīng)碼。比如,若ECU給出7F22 13這個negative response,則說明SID=22這個服務(wù)因為診斷請求數(shù)據(jù)長度不對(NRC=13)的原因而無法執(zhí)行。NRC否定響應(yīng)碼如下圖所示:
舉例來說:
以CAN總線網(wǎng)絡(luò)舉例。八個幀數(shù)據(jù)字節(jié),第一字節(jié)被網(wǎng)絡(luò)層占用(ISO 15765-2)。
診斷端發(fā)送請求(Request):02 10 02 xx xx xx xx xx ; 02是網(wǎng)絡(luò)層單幀SF,代表數(shù)據(jù)域有2個字節(jié),10是SID,02是子功能。
若ECU的肯定響應(yīng)(Positive Response):02 50 02 xx xx xxxx xx;02同上,10+40表示對SID的肯定回復(fù),02是子功能(在下文進行詳解)。
若ECU的否定響應(yīng)(Negative Response):03 7F 10 22 xx xxxx xx;03同上,代表數(shù)據(jù)域有3個字節(jié),7F表示否定響應(yīng),10是SID,22是NRC。
通俗來說,診斷通信的過程就是診斷儀和ECU交換數(shù)據(jù),前者發(fā)的是request,后者發(fā)的是response,而UDS最重要的作用就是定義了這些request和response的格式和內(nèi)容。
三.診斷服務(wù)內(nèi)容
UDS協(xié)議共定義以下26種服務(wù):
本文首先將針對上圖中關(guān)于“診斷和通信管理類”“數(shù)據(jù)傳輸類”“存儲數(shù)據(jù)傳輸”的服務(wù)進行解讀。后續(xù)將在下文進行更新
診斷和通信管理類服務(wù)
1. DiagnosticSessionControl(0x10)
$10用于控制ECU在不同的session之間進行轉(zhuǎn)換,session可以看作是ECU所處的一種軟件狀態(tài),在不同的session中診斷服務(wù)執(zhí)行的權(quán)限不同。其Request請求格式如下所示:
DiagnosticSessionControl診斷request的格式
第一個字節(jié)即SID,這里為0x10。第二個自己即$10服務(wù)的子功能,功能列表如下所示:
ECU上電時,進入的是默認會話0x01(Default)。如果您進入了一個非默認會話的狀態(tài),一個定時器會運轉(zhuǎn),如果一段時間內(nèi)沒有請求,那么到時間后,診斷退回到默認會話01。當然,我們有一個$3E的服務(wù),可以使診斷保持在非默認的狀態(tài)。
ECU上電之后,由于默認處在0x01 defaultSession中,而在這個session中很多診斷服務(wù)不可以執(zhí)行,導致很多診斷相關(guān)的數(shù)據(jù)不能讀取或?qū)懭搿?/p>
一般的診斷儀啟動之后,會給ECU發(fā)送10 03,即讓ECU進入 extendedDiagnosticSession中,在這個session中可執(zhí)行的診斷服務(wù)就很多了。
而如果要讓ECU保持在non-defaultSession中,則需要診斷儀每隔固定的時間發(fā)送0x3E服務(wù),ECU才會知道診斷儀有和自己通信的需求,從而保持在non-defaultSession中。
另一個常用的session是0x02 ProgrammingSession,在這個session中可以進行軟件刷寫的一系列診斷服務(wù)。
0x40 – 0x5F 這個范圍中的session由整車廠自定義使用,比如,某些診斷服務(wù)或診斷數(shù)據(jù)的操作需要在生產(chǎn)線上執(zhí)行,即所謂的End-Of-Line,整車廠可以從這個范圍中選擇一個值來表示EOL session;又或者在開發(fā)階段需要某種“超級”session,則也可以從這里選一個值用來使ECU進入開發(fā)模式的session。
DiagnosticSessionControl這個服務(wù)非常簡單,但是它卻是ECU和診斷通信的第一條診斷命令。
ECUReset (0x11)
ECUReset 這條指令的用途是通過診斷請求使ECU重啟。
ECUReset 診斷request的格式
第一個字節(jié)是SID,即0x11。第二個字節(jié)的低7bit是sub-function,用于指示ECU將模擬哪種方式進行重啟。 常用的sub-function包括(只舉2個例子,UDS還定義了很多其他的值)
0x01 hardReset 模擬KL30的重啟
0x02 keyOffOnReset 模擬KL15的重啟
當我們通過診斷命令改寫了ECU的某些數(shù)據(jù),或者對ECU進行了某些設(shè)置,只有將ECU重啟才能將這些配置生效,所以就有了這個診斷命令。在ECUReset 執(zhí)行之后,ECU會從Non-defaultsession回退到defaultsession中。
SecurityAccess(0x27)
廠家可能會為ECU定義某些安全級別稍微高一些的診斷服務(wù),在執(zhí)行此類服務(wù)之前,就需要執(zhí)行SecurityAccess 這個診斷命令,進行一個簡單的身份驗證。
完成SecurityAccess 有以下步驟:
根據(jù)UDS對$27服務(wù)的定義:
0x03, 0x05, 0x07– 0x41 這個范圍留給用于requestSeed的sub-function;
0x04, 0x06, 0x08– 0x42 這個范圍留給用于sendKey的sub-function。
具體選擇哪對值,由整車廠自己定義。整車廠也可以選擇多對sub-function,用于不同等級的安全訪問。
舉例來說:
假設(shè)0x05用于requestSeed,0x06用于sendKey。
此時ECU就處于unlocked的狀態(tài)了,那些被保護起來的診斷服務(wù)和診斷數(shù)據(jù)可以被操作了。通常來說,如果ECU重啟,或者回到了default session,unlocked狀態(tài)就失效了,如果要執(zhí)行相關(guān)診斷服務(wù),則需要再次執(zhí)行上面描述的過程。
CommunicationControl (0x28)
該服務(wù)用于打開/關(guān)閉某些類別的報文的發(fā)送/接收。它通常在刷寫軟件或大量數(shù)據(jù)的時候使用,因為在刷軟件或參數(shù)的時候并不需要ECU進行與通信相關(guān)的功能,將通信關(guān)閉之后可以把所有通信資源都留給軟件或參數(shù)的下載,當下載過程完成之后再利用該服務(wù)將通信恢復(fù)即可。
0x28服務(wù)的格式如下圖所示
第一部分即SID,一個字節(jié),值為0x28;
第二部分是sub-function,即對ECU的通信進行哪種控制,具體包括 :
第三部分表明這條診斷請求要對哪種報文進行控制,長度為1個字節(jié),定義如下表所示:
這個字節(jié)中最常用的就是低2 bit,0x1代表普通應(yīng)用報文,0x2代表網(wǎng)絡(luò)管理報文,0x3代表普通應(yīng)用報文和網(wǎng)絡(luò)管理報文。
第四部分是optional的,只有當sub-functional等于0x04或0x05時才需要使用。
舉例來說:
28 01 01 表示激活應(yīng)用報文的接收并關(guān)閉應(yīng)用報文的發(fā)送(網(wǎng)絡(luò)管理報文不受影響)。
28 00 01 表示激活應(yīng)用報文的接收和發(fā)送(網(wǎng)絡(luò)管理報文不受影響)。
TesterPresent (0x3E)
這個診斷服務(wù)的用處可以通過它的名字很明顯地得知,即告知ECU診斷儀還在連接著。在$10中提到了關(guān)于session的部分,如果沒有診斷命令的發(fā)送和接收,ECU將從non-default session中回退到default session, 0x3E就是用于使ECU保持在當前session。
這應(yīng)該是UDS中最簡單的一個診斷服務(wù)了,它永遠只有兩個byte,格式如下:
當sub-function是0x00時,ECU要給出response;
當sub-function是0x80時,ECU不需要給出response。
一般來說主機廠會為這個服務(wù)定義兩個時間參數(shù),一個參數(shù)用于規(guī)定自己的診斷儀發(fā)送0x3E服務(wù)的間隔,另一個參數(shù)用于定義ECU收不到0x3E服務(wù)的timeout時間。
ControlDTCSetting (0x85)
該服務(wù)用于控制ECU的DTC(diagnostic trouble code,故障診斷碼)存儲,這個服務(wù)常常和前面提到的28服務(wù)一起使用,比如,在開始寫參數(shù)之前,為了獲得更快的傳輸速度,我們用28服務(wù)把所有ECU的通信關(guān)閉了,但此時因為收到不到相關(guān)的報文,ECU會沒有必要地存儲很多DTC,這時如果我們使用85服務(wù)把ECU存儲DTC的功能暫時性地禁止掉,則不會造成這種麻煩。
0x85服務(wù)請求的格式
第一部分即SID,一個byte,值為0x85;
第二部分是sub-function,即是打開還是關(guān)閉ECU的DTC存儲,包括 :
0x01 on
0x02 off
第三部分是optional的,由各家自己定義,比如,可以用FF FF FF 來表示這條診斷命令針對所有的DTC。
ResponseOnEvent (0x86)
盡管診斷通信過程是問答式的,診斷儀發(fā)請求,ECU給響應(yīng)。0x86服務(wù)算是一個例外,在ECU收到這條0x86服務(wù)之后,當DTC產(chǎn)生時,它會自動地上報DTC及相關(guān)環(huán)境數(shù)據(jù),直到用另一條0x86服務(wù)來關(guān)閉ECU的這個行為。
該功能主要用于ECU的前期開發(fā)階段,在售后和生產(chǎn)中是不會用到的,而且該服務(wù)的格式復(fù)雜(即可變的參數(shù)很多),執(zhí)行它還分為好幾個步驟,在這里就不過多敘述。
LinkControl (0x87)
這個服務(wù)用于轉(zhuǎn)化ECU數(shù)據(jù)鏈路層和物理層的狀態(tài),比如,在高速CAN上的ECU正常通信速率是500kbit/s,但它同時也支持1M bit/s的波特率,如果需要刷寫大量數(shù)據(jù),便可以利用這條診斷服務(wù)讓ECU以1M bit/s的波特率進行通信。
這個診斷服務(wù)的執(zhí)行分為兩個步驟:
驗證ECU是否支持要調(diào)整到的目標波特率
讓ECU的數(shù)據(jù)鏈路層和物理層轉(zhuǎn)到目標波特率的通信狀態(tài)
只有當?shù)谝粋€步驟驗證通過了,第二個步驟才可以成功執(zhí)行。
數(shù)據(jù)傳輸類服務(wù)
在數(shù)據(jù)傳輸類服務(wù),0x22和0x2E成對使用,0x23和0x3D成對使用,這幾個服務(wù)用于診斷數(shù)據(jù)的基本讀寫操作。0x24,0x2A,0x2C是一些特殊操作。
ReadDataByIdentifier (0x22)
$22,即讀數(shù)據(jù)
l Request(請求):22+DID(Data Identifier,通常是兩個字節(jié))
l Response(響應(yīng)):62+DID+Data
DID有一部分已經(jīng)被ISO 14229-1規(guī)定了。比如0xF186就是當前診斷會話數(shù)據(jù)標識符,0xF187就是車廠零件號數(shù)據(jù)標識符,0xF188就是車廠ECU軟件號碼數(shù)據(jù)ID,0xF189就是車廠ECU軟件版本號數(shù)據(jù)標識符。
舉例來說:
22 F1 87 (讀取零件號,DID=F1 87)
62 F1 87 XX YYZZ KK MM NN(給出零件號)
WriteDataByIdentifier (0x2E)
l Request(請求):2E+DID+Data
l Response(響應(yīng)):6E+DID
注意,比如0xF186這個DID不支持直接寫入數(shù)據(jù),需要用$10來進行會話轉(zhuǎn)換。也就是說,對于寫數(shù)據(jù)的請求,一般來說需要在一個非默認會話,和解鎖的狀態(tài)下才能進行。
舉例來說:
2E F1 87 XX YY ZZ KK MM NN(寫入零件號)
6E F1 87(給出positive response)
ReadMemoryByAddress (0x23)
0x23服務(wù)的請求格式
第一部分固定為1個byte, 0x23;
第二部分是格式信息,長度為1個byte,高4 bits用于指示memorySize的長度(字節(jié)數(shù)),低4 bits用于指示memoryAddress的長度(字節(jié)數(shù))。比如,如果這個值為0x46,則后面的memorySize為6個byte,memoryAddress為4個byte。
第三部分是memoryAddress信息,它的長度由第二部分的AddressAndLengthFormatIdentifier指示。
第四部分是memorySize信息,它的長度由第二部分的AddressAndLengthFormatIdentifier指示。
如果這條命令的格式是 23 22 xx yy aa bb,則它的含義就是,讀取xx yy地址的長度為aa bb的數(shù)據(jù)。
WriteMemoryByAddress (0x3D)
了解了0x23的用法,0x3D的用法就很好理解了,它標識memoryAddress和memorySize的方法與0x23相同,只是在診斷命令最后再加上一段需要寫入的數(shù)據(jù)。
存儲數(shù)據(jù)傳輸服務(wù)
存儲數(shù)據(jù)傳輸服務(wù),用于操作DTC(diagnostic trouble code,故障診斷碼)
在 ISO15031-6 中對 DTC 的格式有明確的定義,該規(guī)范中定義了 DTC 共由三個字節(jié)組成,如下圖所示
DTC格式
| 字節(jié)1 | 字節(jié)2 | 字節(jié)3 |
| 診斷故障代碼高字節(jié) | 診斷故障代碼低字節(jié) | 診斷故障代碼失效類型字節(jié) |
在 ISO15031-6 中對 DTC 格式中的字節(jié) 1 與字節(jié) 2 也做了具體的定義,通過這個定義可以很方便確定記錄的 DTC 屬于車上的那種類型。
至此,DTC故障碼的概念解釋完畢,下面將展開關(guān)于存儲傳輸類服務(wù)的解讀:
這類服務(wù)主要涉及到兩條診斷命令,分別是:
0x14:ClearDiagnosticInformation
0x19:ReadDTCInformation
這兩條服務(wù)用于操作存儲在ECU中的DTC,使用頻率很高,而且它們比較好地體現(xiàn)了“診斷”兩個字的含義。
ClearDiagnosticInformation(0x14)
這條診斷命令的格式比較簡單,用法也很好理解,即刪除存儲在ECU中的DTC。
第一個字節(jié)就是SID了,后邊的三個字節(jié)用于標識將要被刪除的DTC種類,UDS規(guī)定用FF FF FF表示所有種類的DTC,由廠家自定義代表Powertrain、Chassis、Body、NetworkCommunication等種類DTC的值。
舉例來說
Request:14+FF+FF+FF;(刪除掉ECU中的所有DTC)
Response:54 ;
ReadDTCInformation(0x19)
這條指令用于讀取存儲在ECU中的DTC,0x19服務(wù)的sub-function代表了各式各樣讀取DTC的方法,UDS給19服務(wù)的sub-function從0x00到0x19進行了明確定義,這里介紹其中常見4種。
- sub-function = 0x01(reportNumberOfDTCByStatusMask)
用于讀取符合DTC狀態(tài)掩碼的DTC的數(shù)量,此時parameter為一個byte的Mask掩碼,用于與DTC的Status進行“與”運算,而ECU返回的則是"與"運算之后結(jié)果不為0的DTC的數(shù)量。
DTC的Status用一個byte表示,其中的8個bit分別代表DTC的不同狀態(tài),比如,bit0 表示這個DTC是active的還是passive的,bit 4表示這個DTC是否已經(jīng)被confirm了,如果DTC的狀態(tài)是confirm,則說明該DTC已經(jīng)被ECU存儲下來了。
比如:19 01 08這個命令的用途,就是讀取所有狀態(tài)為confirm的DTC的數(shù)量。
- sub-function = 0x02(reportDTCByStatusMask)
用于讀取符合特定條件的DTC列表,此時parameter仍然為一個byte的Mask,用于與DTC的Status進行“與”運算,而ECU返回的則是"與"運算之后結(jié)果不為0的DTC列表。
比如19 02 01這個命令的用途,就是讀取所有狀態(tài)為active的DTC的數(shù)量。此時ECU返回的格式應(yīng)該是59 02 01 XX XX XX 01 YY YY YY 09......。返回的DTC列表中的每個條目為4個字節(jié),前三個字節(jié)用于標識DTC,比如 XX XX XX,最后一個字節(jié)用于標識DTC狀態(tài),比如01,表示DTC是active的,09表示DTC是active且confirm的。
- sub-function = 0x06(reportDTCExtDataRecordByDTCNumber)
用于讀取某個DTC及其相關(guān)的環(huán)境數(shù)據(jù),此時parameter為4個byte,前三個byte用于標識我們要讀取的DTC,第四個byte用于標識要讀取的環(huán)境數(shù)據(jù)的范圍,UDS規(guī)定使用FF來表示讀取所有的環(huán)境數(shù)據(jù),各廠家可以要根據(jù)自己的需求定義其他的值來代表要讀取的環(huán)境數(shù)據(jù)的范圍。環(huán)境數(shù)據(jù)包括DTC狀態(tài),優(yōu)先級,發(fā)生次數(shù),老化計數(shù)器,時間戳,里程等,廠家還可以根據(jù)自己的需求定義一些此DTC產(chǎn)生時的測量數(shù)據(jù)。
比如 19 06 XX XX XX FF就表示讀取 XX XXXX這個DTC的所有環(huán)境數(shù)據(jù),ECU的返回值應(yīng)該是59 06 XX XX XX AA BB CC DD.....,其中AA BB CCDD...代表的就是XX XX XX這個DTC產(chǎn)生時所一起存儲的環(huán)境數(shù)據(jù)。
- sub-function = 0x0E(reportMostRecentConfirmedDTC)
sub-function = 0x0E時,不需要parameter。0x0E表示,要求ECU上報最近的一條被置為confirm的DTC。上文介紹過0x86服務(wù),sub-function = 0x0E的19服務(wù)通常被作為參數(shù)傳遞給86指令,要求ECU在發(fā)生DTC存儲的時候進行自動上報,即19 0E這兩個字節(jié)的指令被嵌入到86服務(wù)的命令中。這條命令在開發(fā)階段會用到,比如驗證某個故障路徑是否生效。
本文概述了UDS協(xié)議,交互方式及部分診斷服務(wù)內(nèi)容(包括診斷和通信管理類”“數(shù)據(jù)傳輸類”“存儲數(shù)據(jù)傳輸”)。
后續(xù)將繼續(xù)更新余下的診斷服務(wù)內(nèi)容(包括IO控制,例程控制,上傳與下載)及其他相關(guān)內(nèi)容,敬請期待!
總結(jié)
以上是生活随笔為你收集整理的(转发)详解汽车UDS诊断协议(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【pyqt5学习】——items vie
- 下一篇: 【pyqt5学习】——container