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

網(wǎng)易首頁(yè) > 網(wǎng)易號(hào) > 正文 申請(qǐng)入駐

UDS診斷服務(wù)處理詳解:DCM模塊的設(shè)計(jì)與實(shí)現(xiàn)(以0x22服務(wù)為例)

0
分享至


1. 概述

在AUTOSAR架構(gòu)中,DCM(Diagnostic Communication Manager) 是診斷通信的核心模塊,負(fù)責(zé)解析UDS協(xié)議、執(zhí)行診斷服務(wù)并管理ECU的診斷狀態(tài)。它就像ECU的“診斷大腦”,協(xié)調(diào)從底層接收到數(shù)據(jù)、執(zhí)行服務(wù)、生成響應(yīng)并發(fā)送的全流程。

本文以 0x22 ReadDataByIdentifier(按標(biāo)識(shí)符讀取數(shù)據(jù)) 服務(wù)為例,深入講解DCM內(nèi)部的處理機(jī)制,并提供可運(yùn)行的C++示例代碼。

2. UDS診斷棧中的DCM位置

診斷報(bào)文通過物理層(CAN/LIN/ETH)→ 網(wǎng)絡(luò)層(CanTp)逐級(jí)向上遞交。CanTp 負(fù)責(zé)將長(zhǎng)報(bào)文重組為完整的UDS請(qǐng)求數(shù)據(jù)。當(dāng)CanTp完成重組后,會(huì)調(diào)用DCM的入口函數(shù)(例如 Dcm_MainFunctionDcm_ProcessRequest),將完整請(qǐng)求數(shù)據(jù)傳遞給DCM。

DCM承擔(dān)以下職責(zé):

  • 解析服務(wù)ID、子功能、尋址方式

  • 會(huì)話與安全管理

  • 請(qǐng)求格式與參數(shù)有效性檢查

  • 調(diào)用具體服務(wù)處理函數(shù)

  • 構(gòu)造響應(yīng)(正響應(yīng)或否定響應(yīng))并向下傳遞

3. 服務(wù)解析與檢查流程(以0x22為例)

假設(shè)診斷儀發(fā)送了一條物理尋址的 22 11 22 請(qǐng)求,其中:

  • 服務(wù)ID = 0x22 (ReadDataByIdentifier)

  • DID(Data Identifier) = 0x1122

DCM會(huì)按順序執(zhí)行以下檢查:

3.1 提取服務(wù)ID

從請(qǐng)求數(shù)據(jù) [22, 11, 22] 中取出首字節(jié) 0x22,識(shí)別為 ReadDataByIdentifier 服務(wù)。

3.2 尋址方式判定

DCM從底層接收的PDU信息中獲取CAN ID。如果CAN ID屬于診斷物理尋址范圍,則判定為物理尋址,要求ECU必須單獨(dú)響應(yīng);如果是功能尋址,則需要根據(jù)UDS協(xié)議中“抑制正響應(yīng)位”(在子功能中)決定是否響應(yīng)(避免總線沖突)。為簡(jiǎn)化,本例假定為物理尋址,總是需要響應(yīng)。

3.3 會(huì)話與安全檢查

DCM內(nèi)部維護(hù)當(dāng)前診斷會(huì)話類型(默認(rèn)會(huì)話0x01、編程會(huì)話0x02等)以及安全等級(jí)(SecuredUnlocked)。對(duì)于 0x22 服務(wù):

  • 通常允許在默認(rèn)會(huì)話下讀取非敏感DID

  • 但某些安全關(guān)鍵DID(如VIN、序列號(hào)、加密密鑰)要求ECU處于 解鎖狀態(tài)特定會(huì)話

如果當(dāng)前狀態(tài)不滿足要求,DCM立即構(gòu)造否定響應(yīng),例如:

  • 0x7F 22 0x7E —— 子功能不支持或當(dāng)前會(huì)話下不允許

  • 0x7F 22 0x33 —— 安全訪問未通過

3.4 請(qǐng)求格式檢查

0x22 服務(wù)的標(biāo)準(zhǔn)請(qǐng)求格式為 [服務(wù)ID, DID高字節(jié), DID低字節(jié)],總長(zhǎng)度應(yīng)為3字節(jié)。若請(qǐng)求長(zhǎng)度不足3字節(jié),則返回否定響應(yīng):

  • 0x7F 22 0x13 —— 報(bào)文長(zhǎng)度錯(cuò)誤

3.5 DID有效性檢查

DCM查詢本地配置的DID列表(例如通過配置表或回調(diào)函數(shù)表)。如果 0x1122 未在ECU中定義,則返回否定響應(yīng):

  • 0x7F 22 0x31 —— 請(qǐng)求超出范圍

若以上檢查全部通過,DCM轉(zhuǎn)入數(shù)據(jù)獲取階段。

4. DCM內(nèi)部層次化調(diào)用結(jié)構(gòu)

AUTOSAR DCM模塊采用分層設(shè)計(jì),將服務(wù)分發(fā)、參數(shù)校驗(yàn)、數(shù)據(jù)獲取解耦。典型的調(diào)用層次如下:

Dcm_ProcessRequest (主入口)
├─ Dcm_MainStateMachine (狀態(tài)機(jī):空閑 -> 請(qǐng)求處理)
├─ Dcm_ServiceTableLookup (根據(jù)服務(wù)ID查找處理函數(shù))
├─ Dcm_Service_ReadDataByIdentifier (服務(wù)級(jí)處理)
│ ├─ 執(zhí)行服務(wù)通用檢查(子功能支持等)
│ ├─ 提取DID
│ ├─ 調(diào)用 DID分發(fā)函數(shù) Dcm_DID_ReadHandler
│ └─ 若失敗則生成否定響應(yīng)
└─ Dcm_DID_ReadHandler_0x1122 (DID級(jí)處理)
├─ 調(diào)用RTE端口讀取應(yīng)用數(shù)據(jù)(如傳感器值)
├─ 或調(diào)用NvM讀取存儲(chǔ)塊(如VIN)
└─ 組裝正響應(yīng)數(shù)據(jù) [0x62, DID高, DID低, 數(shù)據(jù)...]

這種層次化設(shè)計(jì)的優(yōu)點(diǎn):

  • 高擴(kuò)展性 :新增DID只需添加一個(gè)處理回調(diào),無(wú)需修改核心解析邏輯。

  • 職責(zé)分離 :服務(wù)級(jí)處理負(fù)責(zé)通用邏輯,DID級(jí)處理負(fù)責(zé)具體數(shù)據(jù)訪問。

  • 可配置性 :通過配置表即可控制DID的有效性、安全要求等。

5. C++代碼示例(模擬DCM處理0x22服務(wù))

以下代碼模擬了一個(gè)簡(jiǎn)化但完整的DCM模塊,實(shí)現(xiàn)了物理尋址下的 0x22 服務(wù)處理。代碼包含了:請(qǐng)求檢查、否定響應(yīng)生成、服務(wù)分發(fā)、DID回調(diào)、數(shù)據(jù)獲取。

#include  
          
#include
#include
#include
#include

// 模擬診斷請(qǐng)求和響應(yīng)的數(shù)據(jù)結(jié)構(gòu)
struct DiagRequest {
std::vector data; // 收到的UDS請(qǐng)求數(shù)據(jù)(不含CAN ID)
bool isFunctionalAddress; // true=功能尋址, false=物理尋址
};

struct DiagResponse {
std::vector data;
bool isPositive = false; // true=正響應(yīng), false=否定響應(yīng)
};

// ECU當(dāng)前診斷狀態(tài)(簡(jiǎn)化)
class EcuDiagnosticState {
public:
enum SessionType { DEFAULT_SESSION = 0x01, PROGRAMMING_SESSION = 0x02 };
enum SecurityLevel { SECURED, UNLOCKED };

SessionType currentSession = DEFAULT_SESSION;
SecurityLevel currentSecurity = SECURED;

bool isSecurityAccessAllowedForDid(uint16_t did) const {
// 模擬:DID 0x1122 是安全相關(guān)的,需要解鎖
if (did == 0x1122) {
return (currentSecurity == UNLOCKED);
}
// 其他DID默認(rèn)允許
return true;
}
};

// 數(shù)據(jù)標(biāo)識(shí)符回調(diào)函數(shù)類型:輸入DID,輸出數(shù)據(jù)字節(jié)流
using DidReadCallback = std::function(uint16_t did)>;

// DCM模塊
class Dcm {
public:
Dcm() {
// 注冊(cè)DID及對(duì)應(yīng)的讀取回調(diào)
registerDid(0x1122, [this](uint16_t did) -> std::vector {
// 模擬通過RTE讀取應(yīng)用數(shù)據(jù)(例如發(fā)動(dòng)機(jī)轉(zhuǎn)速,占2字節(jié))
uint16_t dummyEngineSpeed = 3500; // 單位RPM
return { static_cast((dummyEngineSpeed >> 8) & 0xFF),
static_cast(dummyEngineSpeed & 0xFF) };
});
registerDid(0xF190, [this](uint16_t did) -> std::vector {
// 模擬從NvM讀取VIN(17字節(jié)ASCII)
std::string vin = "WDD12345678901234";
return std::vector(vin.begin(), vin.end());
});
}

// 外部調(diào)用接口:CanTp遞交流程
DiagResponse processRequest(const DiagRequest& request) {
// 1. 主狀態(tài)機(jī):空閑 -> 請(qǐng)求處理
std::cout << "[DCM] 進(jìn)入請(qǐng)求處理狀態(tài)" << std::endl;

// 2. 服務(wù)分發(fā):根據(jù)服務(wù)ID查找處理函數(shù)
if (request.data.empty()) {
return createNegativeResponse(0x00, 0x13); // 報(bào)文長(zhǎng)度錯(cuò)誤
}
uint8_t serviceId = request.data[0];
auto it = serviceHandlers.find(serviceId);
if (it == serviceHandlers.end()) {
return createNegativeResponse(serviceId, 0x11); // 服務(wù)不支持
}

// 3. 調(diào)用對(duì)應(yīng)服務(wù)的處理函數(shù)
return it->second(request);
}

private:
// 服務(wù)處理函數(shù)表
std::map> serviceHandlers;

// DID回調(diào)表
std :: map < uint16_t , DidReadCallback> didCallbacks;

// ECU狀態(tài)
EcuDiagnosticState diagState;

// 注冊(cè)DID讀取回調(diào)
void registerDid(uint16_t did, DidReadCallback callback) {
didCallbacks[did] = callback;
}

// 創(chuàng)建否定響應(yīng)
DiagResponse createNegativeResponse(uint8_t serviceId, uint8_t nrc) {
DiagResponse resp;
resp.isPositive = false ;
resp.data = { 0x7F , serviceId, nrc };
return resp;
}

// 創(chuàng)建正響應(yīng)(0x62服務(wù)負(fù)責(zé)拼接)
DiagResponse createPositiveResponseForReadByIdentifier(uint16_t did, const std::vector& data) {
DiagResponse resp;
resp.isPositive = true ;
resp.data.push_back( 0x62 ); // 正響應(yīng)服務(wù)ID = 0x62
resp.data.push_back( static_cast < uint8_t >((did >> 8 ) & 0xFF ));
resp.data.push_back( static_cast < uint8_t >(did & 0xFF ));
resp.data.insert(resp.data.end(), data.begin(), data.end());
return resp;
}

// 服務(wù)級(jí)處理:0x22 ReadDataByIdentifier
DiagResponse handleReadDataByIdentifier(const DiagRequest& request) {
// 1. 請(qǐng)求格式檢查(最小長(zhǎng)度3字節(jié))
if (request.data.size() < 3 ) {
std :: cout << "[DCM] 錯(cuò)誤: 0x22請(qǐng)求長(zhǎng)度不足" << std :: endl ;
return createNegativeResponse( 0x22 , 0x13 ); // 報(bào)文長(zhǎng)度錯(cuò)誤
}

// 2. 提取DID
uint16_t did = ( static_cast < uint16_t >(request.data[ 1 ]) << 8 ) | request.data[ 2 ];

// 3. 會(huì)話與安全檢查
// (尋址方式簡(jiǎn)化:假設(shè)物理尋址總是需要響應(yīng),且無(wú)抑制位)
if (!diagState.isSecurityAccessAllowedForDid(did)) {
std :: cout << "[DCM] 錯(cuò)誤: DID 0x" << std ::hex << did << " 需要解鎖" << std :: endl ;
return createNegativeResponse( 0x22 , 0x33 ); // 安全訪問未通過
}

// 可選:檢查當(dāng)前會(huì)話是否允許此服務(wù)(默認(rèn)會(huì)話允許0x22,編程會(huì)話也允許,此例略)

// 4. DID有效性檢查(是否已注冊(cè)回調(diào))
auto it = didCallbacks.find(did);
if (it == didCallbacks.end()) {
std :: cout << "[DCM] 錯(cuò)誤: DID 0x" << std ::hex << did << " 未配置" << std :: endl ;
return createNegativeResponse( 0x22 , 0x31 ); // 請(qǐng)求超出范圍
}

// 5. 調(diào)用DID級(jí)處理回調(diào)獲取數(shù)據(jù)
std :: vector < uint8_t > data;
try {
data = it->second(did);
} catch (...) {
std :: cout << "[DCM] 錯(cuò)誤: DID 0x" << std ::hex << did << " 讀取失敗" << std :: endl ;
return createNegativeResponse( 0x22 , 0x22 ); // 條件不滿足(數(shù)據(jù)暫時(shí)不可用)
}

// 6. 構(gòu)造正響應(yīng)
std :: cout << "[DCM] 成功讀取DID 0x" << std ::hex << did << ",數(shù)據(jù)長(zhǎng)度=" << std ::dec << data.size() << std :: endl ;
return createPositiveResponseForReadByIdentifier(did, data);
}

// 構(gòu)造函數(shù)中注冊(cè)服務(wù)處理函數(shù)
void initServiceHandlers() {
serviceHandlers[ 0x22 ] = [ this ]( const DiagRequest& req) {
return handleReadDataByIdentifier(req);
};
}

public :
Dcm() {
initServiceHandlers();
}
};
5.1 使用示例

int main() {
Dcm dcm;

// 模擬物理尋址請(qǐng)求: 0x22 0x11 0x22
DiagRequest req;
req.data = {0x22, 0x11, 0x22};
req.isFunctionalAddress = false; // 物理尋址

DiagResponse resp = dcm.processRequest(req);
std::cout << "響應(yīng): ";
for (auto b : resp.data) {
std::cout << std::hex << (int)b << " ";
}
std::cout << std::endl;
// 預(yù)期輸出正響應(yīng): 62 11 22 xx xx (xx xx為發(fā)動(dòng)機(jī)轉(zhuǎn)速數(shù)據(jù))
return 0;
}

輸出示例:

[DCM] 進(jìn)入請(qǐng)求處理狀態(tài)
[DCM] 錯(cuò)誤: DID 0x1122 需要解鎖
響應(yīng): 7f 22 33

若先執(zhí)行安全解鎖(代碼中未展現(xiàn),可通過31服務(wù)等實(shí)現(xiàn)),再次請(qǐng)求則可獲得正響應(yīng)。

6. 否定響應(yīng)碼(NRC)一覽

NRC

含義

觸發(fā)場(chǎng)景

0x11

ServiceNotSupported

服務(wù)ID未在服務(wù)表中注冊(cè)

0x13

IncorrectMessageLength

請(qǐng)求報(bào)文長(zhǎng)度不符合UDS規(guī)范

0x22

ConditionsNotCorrect

DID數(shù)據(jù)暫時(shí)不可讀(如未就緒)

0x31

RequestOutOfRange

DID未配置或超出范圍

0x33

SecurityAccessDenied

DID要求解鎖而未解鎖

0x7E

SubFunctionNotSupported

服務(wù)不支持當(dāng)前會(huì)話


7. 總結(jié)與擴(kuò)展

本文通過一個(gè)簡(jiǎn)化的C++ DCM實(shí)現(xiàn),展示了UDS 0x22 服務(wù)的檢查流程與層次化調(diào)用結(jié)構(gòu)。真實(shí)AUTOSAR DCM遠(yuǎn)比此復(fù)雜,還包括:

  • 功能尋址抑制位處理suppressPosRspMsgIndicationBit

  • 多DID連續(xù)讀取0x22 允許一次請(qǐng)求多個(gè)DID)

  • 子功能支持 (如 0x19 ReadDTCInformation 包含復(fù)雜子功能)

  • 定時(shí)器與響應(yīng)超時(shí)管理

  • 安全訪問算法的具體實(shí)現(xiàn)(seed&key)

  • 并發(fā)請(qǐng)求的隊(duì)列處理

但核心思想是一致的:嚴(yán)格的請(qǐng)求檢查 + 服務(wù)分發(fā) + 分層處理。掌握該設(shè)計(jì)模式,很容易擴(kuò)展實(shí)現(xiàn) 0x2E WriteDataByIdentifier0x31 RoutineControl 等其他UDS服務(wù)。

希望本文對(duì)您理解UDS診斷軟件的實(shí)現(xiàn)有所幫助。

特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。

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.

相關(guān)推薦
熱點(diǎn)推薦
啥都和愛國(guó)扯到一起,就是一種病

啥都和愛國(guó)扯到一起,就是一種病

老唐有話說
2026-05-14 16:18:17
A股:剛剛,國(guó)務(wù)院國(guó)資委發(fā)布,不出意外的話,下周將迎來新變化

A股:剛剛,國(guó)務(wù)院國(guó)資委發(fā)布,不出意外的話,下周將迎來新變化

云鵬敘事
2026-05-16 00:00:09
國(guó)家發(fā)改委主任鄭柵潔會(huì)見波音公司總裁奧特伯格

國(guó)家發(fā)改委主任鄭柵潔會(huì)見波音公司總裁奧特伯格

新京報(bào)
2026-05-15 20:29:22
上海87-82戰(zhàn)勝北京!賽后數(shù)據(jù)一清二楚,不是王哲林 最大功臣是他

上海87-82戰(zhàn)勝北京!賽后數(shù)據(jù)一清二楚,不是王哲林 最大功臣是他

小火箭愛體育
2026-05-15 21:32:09
難怪黃仁勛那么積極跟著特朗普訪華,一到北京就拿下了大額訂單。

難怪黃仁勛那么積極跟著特朗普訪華,一到北京就拿下了大額訂單。

魔都姐姐雜談
2026-05-14 22:09:10
人活多久,看喝酒就知道?壽命短的人,喝酒一般有這6個(gè)特征

人活多久,看喝酒就知道?壽命短的人,喝酒一般有這6個(gè)特征

芹姐說生活
2026-05-14 23:38:55
上海奪G1但3人需總結(jié)!盧偉應(yīng)變差點(diǎn),白邊優(yōu)勢(shì)被打沒,弗格太鐵

上海奪G1但3人需總結(jié)!盧偉應(yīng)變差點(diǎn),白邊優(yōu)勢(shì)被打沒,弗格太鐵

籃球資訊達(dá)人
2026-05-16 01:09:21
38.98萬(wàn),夸張啊...

38.98萬(wàn),夸張啊...

放毒
2026-05-15 19:14:23
中紀(jì)委再次重拳出擊!這4個(gè)領(lǐng)域?qū)⒈粐?yán)查,這4種行為將被嚴(yán)肅處理

中紀(jì)委再次重拳出擊!這4個(gè)領(lǐng)域?qū)⒈粐?yán)查,這4種行為將被嚴(yán)肅處理

細(xì)說職場(chǎng)
2026-05-15 14:01:05
鄺兆鐳U17亞洲杯首秀!送助攻后或舊傷復(fù)發(fā),只踢半場(chǎng)仍獲贊

鄺兆鐳U17亞洲杯首秀!送助攻后或舊傷復(fù)發(fā),只踢半場(chǎng)仍獲贊

奧拜爾
2026-05-16 02:13:48
悲催!上海一母親將700萬(wàn)遺產(chǎn)給兒子,6年后才發(fā)現(xiàn)被女兒徹底拉黑

悲催!上海一母親將700萬(wàn)遺產(chǎn)給兒子,6年后才發(fā)現(xiàn)被女兒徹底拉黑

火山詩(shī)話
2026-05-15 06:49:15
特朗普還沒回國(guó),就開始放狠話了

特朗普還沒回國(guó),就開始放狠話了

利刃號(hào)
2026-05-15 17:16:39
第一次感受到“荔枝核的威力”,泡水里20天,長(zhǎng)成“粉盆栽”

第一次感受到“荔枝核的威力”,泡水里20天,長(zhǎng)成“粉盆栽”

美家指南
2026-05-15 15:27:43
國(guó)宴名場(chǎng)面刷屏:穿紅衣的服務(wù)員火了,這才是大國(guó)該有的體面

國(guó)宴名場(chǎng)面刷屏:穿紅衣的服務(wù)員火了,這才是大國(guó)該有的體面

娛樂洞察點(diǎn)點(diǎn)
2026-05-15 12:40:18
“錢車兩空”!男子以租代購(gòu)跑網(wǎng)約車,三年還清13.5萬(wàn),過戶前一夜車被拖走

“錢車兩空”!男子以租代購(gòu)跑網(wǎng)約車,三年還清13.5萬(wàn),過戶前一夜車被拖走

網(wǎng)約車觀察室
2026-05-14 10:00:49
張雪宣布停產(chǎn)!博主:雷軍出問題你建議退款 自己出問題只補(bǔ)償

張雪宣布停產(chǎn)!博主:雷軍出問題你建議退款 自己出問題只補(bǔ)償

念洲
2026-05-14 14:29:33
不是洛夫頓!不是古德溫!許利民贊上海隊(duì)1人,威廉姆斯傷情出爐

不是洛夫頓!不是古德溫!許利民贊上海隊(duì)1人,威廉姆斯傷情出爐

老吳說體育
2026-05-15 23:31:25
這跟不穿有啥區(qū)別?趙露思演唱會(huì)內(nèi)衣外穿:被眾嘲一套比一套辣眼

這跟不穿有啥區(qū)別?趙露思演唱會(huì)內(nèi)衣外穿:被眾嘲一套比一套辣眼

胡一舸南游y
2026-05-13 15:23:56
看好誰(shuí)當(dāng)選臺(tái)北市長(zhǎng)?1.4萬(wàn)人網(wǎng)絡(luò)投票結(jié)果一面倒

看好誰(shuí)當(dāng)選臺(tái)北市長(zhǎng)?1.4萬(wàn)人網(wǎng)絡(luò)投票結(jié)果一面倒

新時(shí)光點(diǎn)滴
2026-05-16 00:10:48
沙拉維深情告別羅馬:我即將離開,但我的一部分靈魂將永駐于此

沙拉維深情告別羅馬:我即將離開,但我的一部分靈魂將永駐于此

懂球帝
2026-05-16 02:43:35
2026-05-16 02:59:00
新能源自動(dòng)駕駛 incentive-icons
新能源自動(dòng)駕駛
專注于半導(dǎo)體行業(yè)資訊
977文章數(shù) 347關(guān)注度
往期回顧 全部

科技要聞

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

頭條要聞

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

頭條要聞

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

體育要聞

德約科維奇買的球隊(duì),從第6級(jí)聯(lián)賽升入法甲

娛樂要聞

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

財(cái)經(jīng)要聞

騰訊掉隊(duì),馬化騰戳破真相

汽車要聞

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

態(tài)度原創(chuàng)

藝術(shù)
手機(jī)
時(shí)尚
家居
公開課

藝術(shù)要聞

1008米!沙特“世界第一高樓”項(xiàng)目,為何極有可能建成?

手機(jī)要聞

iPhone 17系列全系跳水,最高立減2500!

頂級(jí)團(tuán)隊(duì)拍出來的作品不如素人,問題出在哪兒了?

家居要聞

110㎡淡而有致的生活表達(dá)

公開課

李玫瑾:為什么性格比能力更重要?

無(wú)障礙瀏覽 進(jìn)入關(guān)懷版