无主之地2配置高吗|看真人裸体BBBBB|秋草莓丝瓜黄瓜榴莲色多多|真人強奷112分钟|精品一卡2卡3卡四卡新区|日本成人深夜苍井空|八十年代动画片

網易首頁 > 網易號 > 正文 申請入駐

汽車診斷協議精講:ISO 14229(UDS)與 ISO 15765 的協作機制及代碼示例

0
分享至


1. 引言

現代汽車電子系統由數十個甚至上百個電子控制單元(ECU)構成,它們通過 CAN、LIN、FlexRay 等總線協同工作。當車輛出現故障時,診斷工具(如診斷儀)需要與 ECU 通信,讀取故障碼、實時數據,執行動作測試等。這一套通信規則就是 汽車診斷協議

在基于 CAN 總線的診斷應用中,最核心的兩個標準是:

  • ISO 14229 :定義了 統一診斷服務(UDS,Unified Diagnostic Services) ,是 應用層 協議,規定了診斷請求和響應的格式、服務含義。

  • ISO 15765 :定義了 基于 CAN 總線的診斷傳輸(DoCAN,Diagnostics over CAN) ,是 傳輸層/網絡層 協議,負責將應用層 UDS 消息拆分成適合 CAN 總線傳輸的小幀,并在接收端重組。

很多初學者容易混淆這兩者。一句話總結:UDS 告訴你“問什么問題”,ISO 15765 教你“怎樣把問題裝進 CAN 幀里送過去”。而 ISO 14229 正是 UDS 的標準編號。

本文將從概念到代碼,深入淺出地比較這兩個協議,并給出 C++ 實現示例。

2. 協議棧概覽(OSI 模型視角)

OSI 層

汽車診斷協議棧

標準

作用

應用層

UDS

ISO 14229

診斷服務定義:讀數據、寫數據、例程控制等

傳輸層

DoCAN (ISO 15765-2)

ISO 15765-2

分段、重組、流控制

數據鏈路層

CAN 2.0B

ISO 11898

8 字節 CAN 幀、仲裁、錯誤檢測

物理層

CAN 物理層

ISO 11898

電平、拓撲


  • UDS (ISO 14229)ISO 15765 不是對立關系,而是上下層協作關系。

  • ISO 15765 同時也定義了與 UDS 無關的 時間參數 (如 P2、P2* 等)和 通信控制

3. UDS (ISO 14229) 詳解 —— “說什么”

UDS 是一套面向汽車場景設計的診斷服務集合,每個服務用 服務標識符(SID, Service Identifier) 表示(1 字節)。典型服務包括:

SID (hex)

服務名稱

功能簡述

0x10

Diagnostic Session Control

切換診斷會話(默認、編程、擴展等)

0x11

ECU Reset

重置 ECU

0x22

Read Data By Identifier

通過 DID 讀取數據(如 VIN、軟件版本)

0x2E

Write Data By Identifier

通過 DID 寫入數據

0x19

Read DTC Information

讀取故障碼

0x14

Clear Diagnostic Information

清除故障碼

0x31

Routine Control

啟動/停止例程(如動作測試)


3.1 UDS 請求/響應格式

請求格式(診斷儀 → ECU):

[SID] [子功能(可選)] [參數...]

例如:讀取 DID 0xF190 的數據(假設 DID 占 2 字節)

22 F1 90
  • 0x22 = ReadDataByIdentifier SID

  • 0xF190 = 數據標識符(如 VIN)

肯定響應格式(ECU 成功處理):

[SID+0x40] [子功能(若請求有)] [數據...]

例如對上述請求的肯定響應:

62 F1 90 41 32 ... (實際數據)
  • 0x62 = 0x22+0x40

否定響應格式(ECU 無法處理):

0x7F [SID] [NRC]

例如:請求的 DID 不支持,返回 7F 22 31(0x31 = RequestOutOfRange)

3.2 子功能與抑制肯定響應位

許多服務(如 SessionControl、ECUReset)的第一個字節稱為子功能,其最高位(bit7)為 抑制肯定響應位(SPR, Suppress Pos Resp)

  • SPR = 1:ECU 不發送肯定響應,只發送否定響應(用于減少總線負載)。

  • SPR = 0:ECU 發送肯定響應。

例如:切換到擴展會話(子功能 0x03),且不需要肯定響應:

10 83   // 0x80 | 0x03 = 0x83
3.3 UDS 示例(無分段)

一個完整診斷請求通過 CAN 發送(假設不超 8 字節):

  • 請求: 10 03 (切換到擴展會話,需要肯定響應)

  • 響應: 50 03 00 32 01 F4 (肯定響應,附帶一些參數)

4. ISO 15765 詳解 —— “怎么送”

CAN 數據鏈路層一幀最多承載 8 字節數據,而一個 UDS 消息可能長達幾十甚至幾百字節(如讀取 VIN 的 17 個字符,加上 DID 等)。ISO 15765-2(常稱為 ISO-TP)定義了分段傳輸協議,將長消息切分成多個 CAN 幀,并管理發送/接收狀態。

4.1 四種幀類型(N_PDU 類型)

幀類型

簡稱

用途

協議控制信息(PCI)字節

單幀

SF

消息總長 ≤ 7 字節(經典 CAN)

第一個字節高 4 位 = 0x0,低 4 位表示數據長度

首幀

FF

長消息的第一幀,告知總長度

第一個字節高 4 位 = 0x1,低 4 位 + 第二字節組成 12 位總長

連續幀

CF

首幀之后的后續數據

第一個字節高 4 位 = 0x2,低 4 位表示序列號(SN,0~15 循環)

流控制幀

FC

接收端控制發送端速率

第一個字節高 4 位 = 0x3,低 4 位表示流控制狀態;后續字節包含塊大小(BS)和最小間隔時間(STmin)


4.2 幀格式詳表(經典 CAN,11 位 ID,單字節 PCI)

單幀 (SF)

| Byte0        | Byte1 ~ Byte7 (最多7字節數據) |
| 0x0 | Len | UDS 數據 (Len 字節) |
  • Len = 4 位,范圍 0~7(實際長度 0~7,若消息總長 >7 必須用多幀)

  • 注意:有些實現使用 首個字節為 PCI,剩余 7 字節 ,Len 不包含 PCI 自身。

首幀 (FF)

| Byte0        | Byte1        | Byte2~Byte7 |
| 0x1 | Len_H | Len_L | 前 6 字節 UDS 數據 |
  • 總長度 = (Len_H << 8) | Len_L,范圍 8~4095 字節

連續幀 (CF)

| Byte0        | Byte1~Byte7 |
| 0x2 | SN | 后續 7 字節 UDS 數據 |
  • SN 從 1 開始,每發一個 CF 加 1,到 15 后回繞到 0。

流控制幀 (FC)

| Byte0        | Byte1        | Byte2        | Byte3~Byte7(保留)|
| 0x3 | FS | BS (塊大小) | STmin (最小間隔) | 0x00... |
  • FS (Flow Status):0=繼續發送(CTS),1=等待(WAIT),2=溢出(OVFLW)

  • BS (Block Size):發送端每發 BS 個 CF 后,需等待下一個 FC 才可繼續(0 表示無限制)

  • STmin:兩個連續幀之間的最小間隔時間(0~127 或 0xF1~0xF9 編碼)

4.3 多幀傳輸流程示例

發送方(如診斷儀)想發送一個 20 字節的 UDS 消息:

  1. 發送 首幀 :PCI=0x10,長度=20,并攜帶前 6 字節數據。

  2. 接收方收到 FF 后,計算所需 CF 數量,準備接收緩沖區,并發送 流控制幀 (BS, STmin)。

  3. 發送方根據 FC 發送 連續幀 ,每幀 7 字節數據,直到全部發完。

5. UDS 與 ISO 15765 的比較

比較維度

UDS (ISO 14229)

ISO 15765-2 (DoCAN)

OSI 層

應用層

傳輸層 / 網絡層

關注點

診斷服務語義:做什么操作、數據含義、錯誤碼

消息分段、流控制、CAN 幀打包與重組

數據單元

UDS 請求/響應(無長度上限)

N_PDU(單幀/首幀/連續幀/流控制幀)

關鍵參數

SID、子功能、DID、DTC、NRC

塊大小(BS)、最小間隔(STmin)、序列號(SN)

獨立性

可運行于其他傳輸層(如 DoIP、UART)

專為 CAN 設計,可傳輸任何上層數據(不僅是 UDS,也可以是 OBD、KWP2000)

標準文檔

ISO 14229-1

ISO 15765-2

核心關系:UDS 消息被封裝成 ISO 15765 的 N_PDU 載荷。沒有 ISO 15765,UDS 無法穿越 CAN 總線的 8 字節限制;沒有 UDS,ISO 15765 只是在傳輸無意義的字節流。

6. C++ 代碼舉例:實現 ISO 15765 打包器與 UDS 消息組裝

以下代碼演示:

  • UDSRequest 類:構造一個簡單的 UDS 請求(如 ReadDataByIdentifier)。

  • ISO15765Packer 類:將 UDS 請求字節流轉換為多個 CAN 幀( vector )。

  • ISO15765Unpacker 類:將收到的 CAN 幀還原成 UDS 消息。

為了簡潔,假設 CAN 幀結構為 {id, data[8], dlc},且使用標準 CAN ID(0x7DF 診斷請求,0x7E8 響應)。僅實現發送端打包邏輯。

6.1 基礎數據結構

#include  
          
#include
#include
#include

struct CanFrame {
uint32_t id; // 標準 11 位 ID
uint8_t dlc; // 數據長度 (0~8)
uint8_t data[8];
};

// 輔助打印
void printCanFrame(const CanFrame& frame) {
std::cout << "CAN ID: 0x" << std::hex << frame.id << " DLC:" << std::dec << (int)frame.dlc << " Data:";
for (int i = 0; i < frame.dlc; ++i) {
std::cout << " " << std::hex << (int)frame.data[i];
}
std::cout << std::dec << std::endl;
}
6.2 UDS 請求構造(應用層)

class UDSRequest {
public:
UDSRequest(uint8_t sid, conststd::vector& data = {})
: m_sid(sid), m_data(data) {}

std::vector serialize() const {
std::vector msg;
msg.push_back(m_sid);
msg.insert(msg.end(), m_data.begin(), m_data.end());
return msg;
}

// 示例:構造讀取 DID 的請求 (0x22)
static UDSRequest makeReadDataByIdentifier(uint16_t did) {
return UDSRequest(0x22, {static_cast(did >> 8), static_cast(did & 0xFF)});
}

private:
uint8_t m_sid;
std::vector m_data;
};
6.3 ISO 15765 打包器(將 UDS 消息轉成 CAN 幀序列)

class ISO15765Packer {
public:
// 輸入:UDS 原始字節流(無 PCI)
// 輸出:CAN 幀列表(請求 ID 固定為 0x7DF 示例)
static std::vector pack(const std::vector& udsMsg, uint32_t canId = 0x7DF) {
std::vector frames;
size_t len = udsMsg.size();

if (len <= 7) {
// 單幀模式
CanFrame sf;
sf.id = canId;
sf.dlc = static_cast(1 + len); // PCI + 數據長度
sf.data[0] = static_cast(0x00 | len); // 單幀 PCI
std::copy(udsMsg.begin(), udsMsg.end(), &sf.data[1]);
frames.push_back(sf);
} else {
// 多幀模式:首幀 + 連續幀
// 首幀
CanFrame ff;
ff.id = canId;
ff.dlc = 8; // 首幀總是 8 字節
uint16_t totalLen = static_cast(len);
ff.data[0] = 0x10 | ((totalLen >> 8) & 0x0F); // 高 4 位為 1,低 4 位為長度高 4 位
ff.data[1] = totalLen & 0xFF; // 長度低 8 位
size_t firstPayload = std::min((size_t)6, len); // 首幀攜帶 6 字節數據
std::copy(udsMsg.begin(), udsMsg.begin() + firstPayload, &ff.data[2]);
frames.push_back(ff);

// 后續數據按 7 字節分塊,生成連續幀
size_t offset = firstPayload;
uint8_t sn = 1; // 連續幀序列號從 1 開始
while (offset < len) {
CanFrame cf;
cf.id = canId;
cf.dlc = 8;
cf.data[0] = 0x20 | (sn & 0x0F); // 連續幀 PCI
size_t chunkSize = std::min((size_t)7, len - offset);
std::copy(udsMsg.begin() + offset, udsMsg.begin() + offset + chunkSize, &cf.data[1]);
// 如果不足 7 字節,剩余字節填 0x00(可選,但通常 DLC=8 會包含無用數據)
if (chunkSize < 7) {
std::fill(&cf.data[1 + chunkSize], &cf.data[8], 0x00);
}
frames.push_back(cf);
offset += chunkSize;
sn = (sn + 1) & 0x0F;
}
}
return frames;
}
};
6.4 使用示例

int main() {
// 1. 構造 UDS 請求:讀取 DID = 0xF190
auto udsReq = UDSRequest::makeReadDataByIdentifier(0xF190);
std::vector udsMsg = udsReq.serialize(); // 輸出: 0x22 0xF1 0x90 (3 字節)

// 2. 打包成 CAN 幀(單幀)
auto frames = ISO15765Packer::pack(udsMsg, 0x7DF);
for (constauto& frame : frames) {
printCanFrame(frame);
}

// 3. 模擬一個較長的 UDS 消息(例如 20 字節的寫數據請求)
std::vector longMsg(20, 0xAA); // 模擬 20 字節數據
longMsg[0] = 0x2E; // WriteDataByIdentifier SID
longMsg[1] = 0xF1;
longMsg[2] = 0x90;
// 剩余 17 字節為寫入值

auto framesLong = ISO15765Packer::pack(longMsg, 0x7DF);
std::cout << "\nLong message (20 bytes) packed into " << framesLong.size() << " frames:\n";
for (constauto& frame : framesLong) {
printCanFrame(frame);
}

return0;
}

預期輸出

CAN ID: 0x7df DLC:4 Data: 0 22 f1 90
Long message (20 bytes) packed into 4 frames:
CAN ID: 0x7df DLC:8 Data: 10 14 2e f1 90 aa aa aa // 首幀,總長度20
CAN ID: 0x7df DLC:8 Data: 21 aa aa aa aa aa aa aa // CF SN=1
CAN ID: 0x7df DLC:8 Data: 22 aa aa aa aa aa aa aa // CF SN=2
CAN ID: 0x7df DLC:8 Data: 23 aa aa aa aa aa aa aa // CF SN=3 (最后7字節,但剩余6字節,尾部補0)
6.5 ISO 15765 解包器(片段)

實際 ECU 需要接收 CAN 幀并重組。以下展示核心邏輯:

class ISO15765Unpacker {
public:
// 輸入:一個 CAN 幀,輸出:是否完成一個完整的 UDS 消息
bool feed(const CanFrame& frame, std::vector& outUdsMsg) {
if (frame.dlc == 0) returnfalse;
uint8_t pciType = (frame.data[0] >> 4) & 0x0F;
switch (pciType) {
case0x0: { // 單幀
uint8_t len = frame.data[0] & 0x0F;
outUdsMsg.assign(&frame.data[1], &frame.data[1] + len);
returntrue;
}
case0x1: { // 首幀
uint16_t totalLen = ((frame.data[0] & 0x0F) << 8) | frame.data[1];
m_buffer.clear();
m_buffer.reserve(totalLen);
// 首幀攜帶 6 字節數據
size_t payloadLen = std::min((size_t)6, frame.dlc - 2);
m_buffer.insert(m_buffer.end(), &frame.data[2], &frame.data[2] + payloadLen);
m_expectedLen = totalLen;
m_nextSn = 1;
m_waitingForFC = false; // 本示例簡化流控制,實際需要等待 FC
returnfalse;
}
case0x2: { // 連續幀
uint8_t sn = frame.data[0] & 0x0F;
if (sn != m_nextSn) {
// 序列號錯誤,可做錯誤處理
returnfalse;
}
size_t payloadLen = std::min((size_t)7, frame.dlc - 1);
m_buffer.insert(m_buffer.end(), &frame.data[1], &frame.data[1] + payloadLen);
m_nextSn = (m_nextSn + 1) & 0x0F;
if (m_buffer.size() >= m_expectedLen) {
outUdsMsg.swap(m_buffer);
returntrue;
}
returnfalse;
}
case0x3: // 流控制幀(發送端處理,接收端不處理)
default:
returnfalse;
}
}
private:
std::vector m_buffer;
uint16_t m_expectedLen = 0;
uint8_t m_nextSn = 0;
bool m_waitingForFC = false;
};
7. 實際應用中的重要參數與注意事項
  1. CAN ID 分配:診斷通信通常使用 11 位 ID,如物理尋址(特定 ECU)和功能尋址(廣播給所有 ECU)。UDS 不規定 ID,ISO 15765 也不規定,通常由整車廠定義(例如 0x7DF 用于功能請求,0x7E8 為第一個 ECU 的響應)。

  2. 流控制參數

    • **BS (Block Size)**:接收端可以限制連續幀個數,防止發送端淹沒接收端緩沖區。

    • **STmin (Separation Time)**:兩個連續幀之間的最小時間間隔,用于低速 ECU。

  3. 時間參數 P2 / P2*:UDS 應用層定義了 ECU 處理請求的最大響應時間(P2 = 50ms 典型值),ISO 15765 不涉及這個,但診斷儀必須實現超時管理。

  4. 多協議并存:UDS 也可以運行在 DoIP(以太網)、LIN、FlexRay 上,而 ISO 15765 專用于 CAN。因此 ISO 15765 可視為 UDS over CAN 的“運輸層”。

8. 結論
  • UDS (ISO 14229) 是汽車診斷的“語言”,定義了豐富而統一的服務,讓診斷工具與不同 ECU 能夠互通。

  • ISO 15765 是這套語言在 CAN 總線上的“信使”,解決了 CAN 幀過小的限制,提供了可靠的分段、重組與流控制機制。

  • 二者相輔相成:沒有 UDS,ISO 15765 傳輸的只是無意義的字節;沒有 ISO 15765,UDS 將無法穿越 CAN 總線的長度壁壘。

理解這兩者的分工是開發任何基于 CAN 的診斷工具或 ECU 固件的基礎。通過本文的 C++ 代碼示例,讀者可以親手打包一個 UDS 請求,觀察它如何被拆分成 CAN 幀,從而更直觀地掌握汽車診斷協議棧的層次協作。在實際工程中,建議使用成熟的 ISO-TP 庫(如 isotp-c)和 UDS 庫,但掌握原理始終是調試復雜問題的關鍵。

特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關推薦
熱點推薦
100萬公里,成了汽車行業不敢提的詞?

100萬公里,成了汽車行業不敢提的詞?

虎嗅APP
2026-05-14 18:07:07
44歲卡里克確認轉正!簽約3年 救火4個月率曼聯重返歐冠+15戰10勝

44歲卡里克確認轉正!簽約3年 救火4個月率曼聯重返歐冠+15戰10勝

我愛英超
2026-05-15 22:10:38
特朗普離京前,對臺灣問題已作明確表態,解讀如下:

特朗普離京前,對臺灣問題已作明確表態,解讀如下:

大中國
2026-05-15 21:04:02
新婚15天就爆不倫!日諧星床戰照外泄 人妻私訊「穿最色內褲」求歡

新婚15天就爆不倫!日諧星床戰照外泄 人妻私訊「穿最色內褲」求歡

ETtoday星光云
2026-05-14 15:58:05
中央氣象臺連發大霧暴雨強對流預警!廣東南部沿海有大暴雨

中央氣象臺連發大霧暴雨強對流預警!廣東南部沿海有大暴雨

南方都市報
2026-05-15 10:50:26
中美這場舉世矚目的會晤,釋放了哪些重要信號?

中美這場舉世矚目的會晤,釋放了哪些重要信號?

補壹刀
2026-05-15 14:03:13
新能源概念通脹退潮后,誰在裸泳?

新能源概念通脹退潮后,誰在裸泳?

虎嗅APP
2026-04-23 22:36:41
江西舉報恩人沈女士已社死,正臉照曝光,大叔崗位被調,景區回應

江西舉報恩人沈女士已社死,正臉照曝光,大叔崗位被調,景區回應

奇思妙想草葉君
2026-05-15 07:33:51
U17國足極速扳平!萬項戲耍沙特防線,3場造4球,鄺兆鐳助攻

U17國足極速扳平!萬項戲耍沙特防線,3場造4球,鄺兆鐳助攻

奧拜爾
2026-05-16 01:35:34
悲催!網傳四川一貿易公司半夜倒閉,工資馬上發,員工哭訴失業了

悲催!網傳四川一貿易公司半夜倒閉,工資馬上發,員工哭訴失業了

火山詩話
2026-05-15 14:45:12
國企為什么不上桌?

國企為什么不上桌?

家傳編輯部
2026-05-15 15:17:35
馬特·達蒙新片大賣,全員發獎金

馬特·達蒙新片大賣,全員發獎金

娛圈觀察員
2026-05-15 01:31:22
持續引領百萬級豪華市場,攬勝與路虎衛士的不可替代性從何而來?

持續引領百萬級豪華市場,攬勝與路虎衛士的不可替代性從何而來?

球叔教你買車
2026-04-29 09:24:34
影壇大咖去世,66歲鐘楚紅淚灑靈堂,周星馳周潤發送花,眾星現身

影壇大咖去世,66歲鐘楚紅淚灑靈堂,周星馳周潤發送花,眾星現身

開開森森
2026-05-15 08:51:25
戛納紅毯第二彈!章澤天好美,袁姍姍嚇我一跳,周也沒扛住生圖

戛納紅毯第二彈!章澤天好美,袁姍姍嚇我一跳,周也沒扛住生圖

八卦南風
2026-05-15 15:58:56
特朗普結束訪華,大贊中南海景致:若待得慣都不想走

特朗普結束訪華,大贊中南海景致:若待得慣都不想走

澎湃新聞
2026-05-15 18:28:12
英超官方承認曼城獲利,VAR漏判恐讓阿森納痛失冠軍

英超官方承認曼城獲利,VAR漏判恐讓阿森納痛失冠軍

樂道足球C
2026-05-15 20:34:33
保時捷中國高管喊話被抄襲無奈,羅永浩怒懟:論流氓誰能跟保時捷比,新能源抄了保時捷的,不是只有那個誰和那個誰嗎

保時捷中國高管喊話被抄襲無奈,羅永浩怒懟:論流氓誰能跟保時捷比,新能源抄了保時捷的,不是只有那個誰和那個誰嗎

大風新聞
2026-05-15 12:21:07
成交價1.1億!國際足聯低頭,央視拿下世界杯版權,卻遭全網吐槽

成交價1.1億!國際足聯低頭,央視拿下世界杯版權,卻遭全網吐槽

譚談社會
2026-05-15 16:49:00
張雪機車再拿第一!WSBK捷克站自由賽:53號車手德比斯奪全場第一

張雪機車再拿第一!WSBK捷克站自由賽:53號車手德比斯奪全場第一

快科技
2026-05-15 18:00:34
2026-05-16 03:00:49
新能源自動駕駛 incentive-icons
新能源自動駕駛
專注于半導體行業資訊
977文章數 347關注度
往期回顧 全部

汽車要聞

高爾夫GTI刷新紐北紀錄 ID. Polo GTI迎全球首秀

頭條要聞

黃仁勛在北京喝豆汁痛苦皺眉 問“這是什么東西”

頭條要聞

黃仁勛在北京喝豆汁痛苦皺眉 問“這是什么東西”

體育要聞

德約科維奇買的球隊,從第6級聯賽升入法甲

娛樂要聞

方媛為何要來《桃花塢6》沒苦硬吃?

財經要聞

騰訊掉隊,馬化騰戳破真相

科技要聞

直降千元起步!蘋果華為率先開啟618讓利

態度原創

時尚
親子
游戲
本地
軍事航空

頂級團隊拍出來的作品不如素人,問題出在哪兒了?

親子要聞

孕婦補鈣怕刺激怎么選?液體鈣無添加配方實測,藍帽認證更靠譜

《街霸6》春麗新品來了!招牌肉腿完美還原

本地新聞

用蘇繡的方式,打開江西婺源

軍事要聞

烏克蘭首都基輔遭空襲 死亡人數增至12人

無障礙瀏覽 進入關懷版