維修技師更換一顆 ECU 後,工作通常不會停在「把接頭插回去」。
診斷工具可能還要確認 ECU 身分與軟體版本,切換到適合的診斷模式,再執行設定、測試或程式更新。
這段互動可以先簡化成:
診斷工具
→ 選擇目標 ECU
→ 進入允許該工作的 Diagnostic Session
→ 視需要完成 SecurityAccess
→ 讀取資料、執行測試或傳送更新資料
→ ECU 回傳結果或拒絕原因
Day 07 的 OBD-II 讓通用 Scan Tool 取得法規要求的標準化診斷資訊。
今天要再往 ECU 裡面走一步,認識維修與工程診斷常見的 UDS(Unified Diagnostic Services,統一診斷服務)。
核心問題是:診斷工具如何告訴 ECU「我要做什麼」,ECU 又如何決定現在能不能做?
讀完這篇文章,你應該能夠:
0x22 ReadDataByIdentifier 解讀一組 DID 請求與回應0x27 SecurityAccess 的 seed/key 流程與安全邊界UDS 是 Unified Diagnostic Services 的縮寫,可以翻成統一診斷服務。
它由 ISO 14229 系列定義,讓診斷工具以一致的服務格式和車內 ECU 進行請求/回應。
ISO 14229-1 把診斷工具稱為 Client(客戶端),把提供診斷功能的 ECU 稱為 Server(伺服端)。
Client 可以提出許多不同類型的要求,例如:
並不是每顆 ECU 都要支援所有服務,也不是支援某項服務就能在任何狀態下執行。
實際能力會依 ECU 功能、車輛狀態、Diagnostic Session、Security Level 與車廠診斷規格而定。
UDS 定義的是診斷服務與訊息語意,不是「接上去就擁有所有權限」的萬用命令集。
兩者都用於車輛診斷,也可能同樣承載在 CAN 上,所以很容易混在一起。
| 比較項目 | 傳統 OBD-II 診斷 | UDS |
|---|---|---|
| 核心目的 | 提供法規要求的排放/動力相關標準資料 | 提供較完整的 ECU 診斷服務架構 |
| 常見資料索引 | Service/Mode 搭配 PID | Service Identifier 搭配 Sub-function、DID 或其他參數 |
| 通用程度 | 適用項目有標準化資料與換算方式 | 服務格式標準化,但許多 DID、Routine 與存取規則依系統定義 |
| 權限概念 | 通用資料多以讀取為主,仍有會改變狀態的服務 | 可依 Session、Security Level 與車輛條件限制操作 |
| 常見用途 | 排放檢驗、故障碼與即時資料 | ECU 維修、設定、測試、程式更新與工程診斷 |
這張表描述的是典型差異,不代表兩套系統完全分離。
Day 07 提過的新一代 OBDonUDS,便是把法規 OBD 資料放進 UDS 架構中。
所以面對一筆診斷紀錄時,不能只因為它出現在 DLC 或 CAN 上,就直接判斷它一定是傳統 OBD PID 或 UDS。
ISO 14229-1 的服務需求不綁定單一 Data Link。
同一套 UDS 診斷概念可以搭配不同下層通訊,其中最常見的路徑之一是 UDS on CAN。

圖 1:UDS 定義診斷服務語意,ISO-TP 負責分段與重組,CAN 負責 Frame 傳送。實際 Gateway 與網路配置依車款而異
| 層次 | 代表規格或概念 | 負責的問題 |
|---|---|---|
| 診斷應用 | ISO 14229-1 UDS | 要求 ECU 執行哪一項診斷服務? |
| Session | ISO 14229-2 | 診斷 Client/Server 如何維持通訊時序與狀態? |
| UDS on CAN Profile | ISO 14229-3 | UDS 用在 CAN 時有哪些實作要求與限制? |
| 傳輸與網路 | ISO 15765-2 ISO-TP/DoCAN | 資料超過單一 CAN Frame 時如何分段與重組? |
| Data Link/Physical | Classical CAN 或 CAN FD | CAN Frame 如何在實體網路傳送? |
這個分層能避免三個常見誤解:
0x22 是 UDS Service Identifier,不是 CAN Identifier到了 Day 09,我們會保留上層的 UDS 概念,再把承載路徑換成 Ethernet/IP 與 DoIP。
UDS 採用 Client 發出 Request、Server 回傳 Response 的模式。
Request 的第一個 byte 通常是 Service Identifier(SID,服務識別碼),後面再接 Sub-function、Data Identifier 或其他服務參數。
常見服務可以先整理成下面幾組:
| SID | 服務名稱 | 典型用途 |
|---|---|---|
0x10 |
DiagnosticSessionControl | 切換 Diagnostic Session |
0x11 |
ECUReset | 要求 ECU 執行支援的重設方式 |
0x14 |
ClearDiagnosticInformation | 清除指定範圍的診斷資訊 |
0x19 |
ReadDTCInformation | 讀取 DTC 與相關狀態 |
0x22 |
ReadDataByIdentifier | 依 DID 讀取資料 |
0x27 |
SecurityAccess | 透過 seed/key 取得指定 Security Level |
0x2E |
WriteDataByIdentifier | 依 DID 寫入資料 |
0x31 |
RoutineControl | 啟動、停止或取得 Routine 結果 |
0x34~0x37 |
Upload/Download/Transfer Services | 建立並完成資料傳輸流程 |
0x3E |
TesterPresent | 表示 Client 仍在進行診斷互動 |
這不是完整的 UDS 服務清單。
它也不代表每個 ECU 都支援表中的全部服務或每一種 Sub-function。
UDS 常見的 Positive Response SID 是 Request SID 加上 0x40。
例如:
Request SID 0x22 ReadDataByIdentifier
Positive SID 0x62 0x22 + 0x40
Positive Response 會再帶回原本的 DID、Sub-function 或服務結果,實際格式依服務而定。
「Positive」表示這次診斷服務在協定層得到肯定回應。
它仍不一定能獨立證明感測器真實值、實體致動結果或維修工作已完整結束。
若 ECU 無法接受 Request,常見格式是:
7F Request SID NRC
NRC 是 Negative Response Code(否定回應碼)。
例如:
7F 22 31
可以分成:
| Byte | 值 | 意義 |
|---|---|---|
| 0 | 0x7F |
Negative Response SID |
| 1 | 0x22 |
被拒絕的 Request 是 ReadDataByIdentifier |
| 2 | 0x31 |
requestOutOfRange |
requestOutOfRange 可能表示要求的 DID 或參數不受支援,也可能表示它在目前 Session 中不可用。
分析時不能只翻譯 NRC 名稱,還要對照 ECU 的診斷規格與當下狀態。
其他常見 NRC 包括:
| NRC | 名稱 | 可以怎麼理解 |
|---|---|---|
0x11 |
serviceNotSupported | ECU 不支援這項 Service |
0x12 |
subFunctionNotSupported | ECU 不支援要求的 Sub-function |
0x13 |
incorrectMessageLengthOrInvalidFormat | 訊息長度或格式不符合要求 |
0x22 |
conditionsNotCorrect | 當下車輛或 ECU 條件不允許操作 |
0x31 |
requestOutOfRange | 參數超出允許範圍,或資料/功能在目前條件下不可用 |
0x33 |
securityAccessDenied | 尚未滿足要求的安全存取條件 |
0x78 |
requestCorrectlyReceived-ResponsePending | Request 已收到,但 Server 還需要處理時間 |
0x78 不是成功結果,也不是要求 Client 立刻重送相同 Request。
它表示 ECU 正在處理,最後仍要等待正式的 Positive 或 Negative Response。
Diagnostic Session 可以理解成 ECU 的診斷操作情境。
不同 Session 能開放的服務、資料與時序條件可能不同。
最常見的三種標準 Session 是:
| Sub-function | Session | 典型定位 |
|---|---|---|
0x01 |
Default Session | ECU 一般運作時的基礎診斷能力 |
0x02 |
Programming Session | 程式更新流程所需的診斷情境 |
0x03 |
Extended Diagnostic Session | 維修或工程診斷所需的延伸能力 |
Session 名稱不能直接當成權限保證。
例如進入 Extended Session,不代表所有寫入、致動或更新服務都已解鎖。
ECU 還可能檢查:
假設 Client 要求進入 Extended Diagnostic Session,UDS payload 可以寫成:
Client → ECU:10 03
ECU → Client:50 03 ...
| 方向 | Byte | 意義 |
|---|---|---|
| Request | 0x10 |
DiagnosticSessionControl |
| Request | 0x03 |
Extended Diagnostic Session |
| Response | 0x50 |
0x10 + 0x40 的 Positive Response |
| Response | 0x03 |
ECU 確認進入要求的 Session |
| Response | 後續 bytes | ECU 提供適用的 P2/P2* 回應時間參數 |
上面的內容只列 UDS payload,沒有放入 ISO-TP 的長度資訊或 CAN Identifier。
實際 CAN 紀錄還要一起確認 addressing、ISO-TP 與 padding 等設定。
非 Default Session 通常具有維持診斷連線的時間條件。
若 Client 長時間沒有診斷互動,ECU 可能在 S3Server timeout 後回到 Default Session。
0x3E TesterPresent 可以用來表示 Client 仍然存在,但它不是「永久保留權限」的心跳包。
Session、Security Level 與 timeout 的實際行為仍要依 ECU 實作及診斷規格確認。
0x22 ReadDataByIdentifier 讓 Client 透過 **Data Identifier(DID,資料識別碼)**要求資料。
DID 由兩個 bytes 表示,資料內容與長度則依該 DID 的定義解碼。
常見 Request 格式可以先看成:
22 DID 高位元組 DID 低位元組
Positive Response 則是:
62 DID 高位元組 DID 低位元組 Data Record
0xF190 是常見的 Vehicle Identification Number(VIN,車輛識別號碼)DID。
若 Client 要求讀取它,UDS payload 是:
Client → ECU:22 F1 90
ECU → Client:62 F1 90 54 45 53 54 56 49 4E 31 32 33 34 35 36 37 38 39 30
假設教學用回應資料轉成 ASCII 後顯示:
TESTVIN1234567890
這裡可以判斷:
0x62 是 0x22 的 Positive Response0xF190 表示回覆的 DID範例字串只用來說明格式,不代表真實車輛或有效 VIN。
還要注意,0x62 + DID + 17 bytes 已超過單一 Classical CAN Frame 能承載的資料量。
如果這筆 UDS 回應走 CAN,ISO-TP 會負責用 First Frame、Flow Control 與 Consecutive Frame 完成分段和重組。
這正好說明 UDS 與 ISO-TP 的分工:
UDS 知道「這是 F190 的 VIN 回應」
ISO-TP 知道「這包資料要拆成多個 CAN Frame」
CAN 負責「把每個 Frame 送上網路」
除了標準化 DID,車廠或供應商也可能定義專案專用 DID。
看到未知 DID 時,不應靠數字外觀猜測語意,而要取得對應版本的診斷規格。
部分診斷資料與服務不會只靠 Session 決定是否開放。
ECU 還可以要求 Client 透過 0x27 SecurityAccess 取得指定的 Security Level。
常見流程採用一組成對的 Sub-function:
以下使用最前面的一組 Sub-function 建立概念:
Client → ECU:27 01
ECU → Client:67 01 A1 B2 C3 D4
Client → ECU:27 02 5A 6B 7C 8D
ECU → Client:67 02
0x01/0x02 只是其中一組 access type。
支援哪些 Security Level、每個 Level 保護哪些服務,以及 seed/key 如何產生,都要由系統設計與診斷規格定義。
上面的 seed 與 key 完全是虛構資料,兩者沒有可供推導的真實演算法關係。

圖 2:切換 Session 不代表自動取得所有權限。ECU 仍會檢查服務、車輛條件與 Security Level,再回傳 Positive 或 Negative Response
| NRC | 名稱 | 常見情境 |
|---|---|---|
0x24 |
requestSequenceError | 沒有先完成正確的 requestSeed,就直接送出 sendKey |
0x35 |
invalidKey | ECU 判定送來的 key 不正確 |
0x36 |
exceedNumberOfAttempts | 失敗次數達到設定門檻 |
0x37 |
requiredTimeDelayNotExpired | 延遲計時尚未結束,現在不能再次嘗試 |
例如:
7F 27 35
表示 0x27 SecurityAccess 因 invalidKey 被拒絕。
遇到 0x36 或 0x37 時,不應反覆重送。
診斷工具要遵守 ECU 的重試與延遲規則,否則可能讓維修工作被鎖定更久,也可能留下異常事件紀錄。
0x27 SecurityAccess 的目的是開啟受限制的 Security Level。
它本身不應被誤解成完整的安全通訊協定。
只看到一次 seed/key 成功,不能直接推論後續所有診斷訊息都具備:
如果 seed 可預測、key 演算法或祕密管理不當,或所有 ECU 共用容易外洩的材料,SecurityAccess 的實際保護力也會下降。
所以資安設計不能只問「有沒有 0x27」,還要問:
UDS 也定義了 0x29 Authentication 等其他機制,但它們不是 0x27 的別名,也不代表所有車輛都已採用。
實際防護要從威脅模型、車輛架構與生命週期需求出發,不能只靠單一 SID。
回到開頭更換 ECU 的情境,一段合理的概念流程可能是:
1. 診斷工具建立到目標 ECU 的通訊
2. 使用 ReadDataByIdentifier 確認 ECU 身分與軟體版本
3. 以 DiagnosticSessionControl 進入允許工作的 Session
4. ECU 檢查車速、電壓與點火狀態等前置條件
5. 高權限操作視需要完成 SecurityAccess 或其他授權
6. 執行設定、Routine 或程式傳輸
7. ECU 回報結果,工具再次讀取狀態並保存紀錄
8. 診斷結束後回到限制較低的權限與正常運作狀態
這不是任何特定車款的維修程序,也不能取代原廠 Service Manual。
有些 ECU 需要線上授權、憑證或後端服務,有些工作還要配合電源供應、車輛靜止與專用工具。
從資安角度看,這條流程包含多個不同控制點:
| 控制點 | 要確認的問題 |
|---|---|
| 診斷入口 | Client 從 DLC、DoIP 或車內測試節點進入? |
| Routing/Gateway | 哪些來源可以到達哪些 ECU? |
| Session | 目前開放哪些服務與資料?何時 timeout? |
| Security Level | 哪些操作必須先解鎖?失敗如何限制? |
| 車輛條件 | 車速、檔位、電壓與點火狀態是否允許操作? |
| 更新資料 | 軟體或設定是否具備來源驗證與完整性保護? |
| Audit | 誰在何時對哪顆 ECU 做了什麼?是否能追溯? |
Session、SecurityAccess 與 Gateway 都是控制的一部分,但任何單一控制都不應成為唯一防線。
下面是一段只用於教學的已授權測試台紀錄。0x1234 是本文虛構的「校正版本」DID,seed 與 key 也是無真實演算法關係的教學資料:
Client → ECU:10 03
ECU → Client:50 03 ...
Client → ECU:22 12 34
ECU → Client:7F 22 33
Client → ECU:27 01
ECU → Client:67 01 A1 B2 C3 D4
Client → ECU:27 02 5A 6B 7C 8D
ECU → Client:67 02
Client → ECU:22 12 34
ECU → Client:62 12 34 01 07
請先回答:
7F 22 33 拒絕的是哪項服務?NRC 是什麼?27 01 與 27 02 分別代表哪一個步驟?先停在這裡,不要急著往下滑!
請先把 SID、Sub-function、DID、Data Record 與 NRC 分別標出,再往下對照作者的示範答案。
第一組 10 03 是要求進入 Extended Diagnostic Session。
ECU 以 50 03 回覆,表示接受這次 Session 切換,後面再提供 timing parameters。
第一次讀取 0x1234 時,ECU 回覆:
7F 22 33
| Byte | 解讀 |
|---|---|
0x7F |
Negative Response |
0x22 |
被拒絕的 ReadDataByIdentifier |
0x33 |
securityAccessDenied |
接著 Client 用 27 01 要求 seed,再以配對的 27 02 送出 key。
ECU 回覆 67 02,表示這次 SecurityAccess 流程得到 Positive Response。
第二次讀取同一個 DID 時,ECU 回覆:
62 12 34 01 07
| 欄位 | 作者的答案 |
|---|---|
| Positive Response SID | 0x62,對應 Request SID 0x22 |
| DID | 0x1234,本文虛構的校正版本識別碼 |
| Data Record | 01 07,實際語意要由本文假設的診斷規格定義 |
這段紀錄只能顯示 ECU 接受了 seed/key 流程,之後也回傳指定 DID。
它不能單獨證明底層通訊已加密、每筆訊息都有密碼學驗證,也不能證明診斷工具可以存取其他 ECU 或服務。
若要完成資安盤點,還要確認 Client 如何到達 ECU、Gateway 是否限制來源與服務、Security Level 何時失效,以及車速、檔位、電壓與點火狀態等條件。
0x1234、Data Record 與整段紀錄都是教學範例,不代表任何特定車款採用相同 DID、權限或 SecurityAccess 流程。
安全與法律提醒: 診斷服務可能重設 ECU、改變設定、控制輸出或進入程式更新流程。
所有測試只應在模擬環境、隔離測試台或明確取得授權的設備上進行,不要在道路車輛、他人的設備或公共基礎設施上測試,也不要在車輛行駛時操作診斷工具。
0x40
0x7F + Request SID + NRC,必須結合 ECU 狀態與診斷規格解讀0x10 DiagnosticSessionControl 用來切換診斷情境,但 Session 不等於身分驗證或完整授權0x22 ReadDataByIdentifier 以兩個 bytes 的 DID 指定資料,未知 DID 不能只靠數字猜測語意0x27 SecurityAccess 常使用 requestSeed/sendKey 流程開啟 Security Level,但不等於加密通道今天我們把 UDS 當成診斷工具與 ECU 共同理解的服務語言,也看見它可以和下層網路分開思考。
Day 09 將介紹 DoIP,看看 UDS 如何透過 Automotive Ethernet 與 IP 傳送,以及 Vehicle Discovery、Routing Activation 與 TCP/UDP 在診斷流程中各自扮演什麼角色。