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

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

UDS協議之DTC狀態機剖析:從狀態位跳變到14服務清除的完整實現

0
分享至


1. 前言

在UDS(ISO 14229-1)診斷協議中,故障碼(DTC,Diagnostic Trouble Code)不僅僅是“有故障”或“無故障”的簡單標記。每個DTC都附帶一個1字節的狀態位(Status Byte),用于精確描述該故障在當前操作循環及歷史記錄中的生命周期。同時,14服務用于重置這些狀態。

理解狀態位的跳變邏輯,是開發高質量診斷軟件(如ECU固件)或診斷工具(如Tester)的基礎。

2. 故障碼狀態位詳解 2.1 狀態位定義(Bit 0 - Bit 7)

根據ISO 14229-1定義,DTC狀態字節的8個位含義如下:

Bit

名稱

描述

核心邏輯

0

TestFailed

當前操作循環中,最近一次測試結果為失敗。

瞬時故障標志

1

TestFailedThisOperationCycle

當前操作循環中,曾經檢測到故障。

本循環歷史

2

PendingDTC

當前循環失敗,但尚未達到確認閾值(防抖中)。

待確認故障

3

ConfirmedDTC

故障已確認(達到閾值),存儲在NVM中。

固化故障

4

TestNotCompletedSinceLastClear

自上次清除后,該DTC從未被測試過。

測試未運行

5

TestFailedSinceLastClear

自上次清除后,至少一次測試結果為失敗。

永久歷史標志

6

TestNotCompletedThisOperationCycle

當前操作循環中,該DTC測試未完成。

本循環未測

7

WarningIndicatorRequested

請求點亮警告燈(如MIL燈)。

報警標志


2.2 常用狀態位組合(十六進制值)

在實際診斷中,工具通常通過讀取狀態字節來判斷故障類型:

狀態位組合 (Bit)

Hex

含義解釋

bit0=1

0x01

當前正好有故障(瞬態)

bit3=1

0x08

歷史確認故障(存儲在內存中)

bit3=1, bit0=1

0x09

當前存在且已確認的硬故障

bit2=1

0x04

待處理故障(防抖中,未確認)

bit5=1

0x20

上次清除后發生過故障(用于二手車檢測)


3. 狀態位跳變邏輯(核心難點)

狀態位并不是隨機變化的,而是遵循“測試-防抖-確認-老化”的嚴格狀態機。

3.1 跳變流程圖解

下圖中,橫坐標為操作循環(點火循環)。假設該DTC的確認閾值(Confirmed Threshold)為 2個操作循環

                操作循環 1                    操作循環 2
|-----------------------| |-----------------------|
測試結果: 無 合格(Pass) 失敗(Fail) 失敗 無 失敗
| | | | | | | |
bit0(當前):0-->0-->1-->0-->1------------>0?-->1----------->? (車企自定義)
bit1(本循環):0-->0-->1-->1-->1------------>0-->1----------->1
bit3(確認):0-->0-->0-->0-->0------------>0-->0-->1(計數2)->1
bit6(未測):1-->0-->0-->0-->0------------>1-->0----------->0
3.2 關鍵跳變邏輯詳解
  1. 初始化 :ECU上電或執行14服務后, bit4=1bit6=1 (表示尚未測試)。

  2. **測試通過 (Passed)**:當監控器執行檢測且結果為“合格”。

    • bit0 置 0, bit4 置 0, bit6 置 0。

  3. 測試失敗 (Failed) - 防抖階段

    • 一旦檢測到失敗,** bit0 立即置 1**。

    • bit1 置 1(本循環發生過失敗)。

    • bit2 (Pending) 置 1。

    • 注意 :此時 bit3 (Confirmed) 不一定為1,需要計數器累加。

  4. 從 Pending 到 Confirmed

    • 內部計數器 DTCFailureCounter 累加。

    • FailureCounter >= ConfirmationThreshold (如 2)時,** bit3 置 1**,故障寫入NVM。

  5. **跨操作循環 (Power Cycle)**:

    • 下電再上電(操作循環2開始): bit6 被初始化為 1(本循環還未測)。

    • 如果故障消失, bit0 變為 0,但 bit3 維持 1(歷史故障)。

    • bit1 重置為 0(新的循環開始)。

4. 14服務:清除診斷信息

0x14 服務用于清除ECU中一個或多個DTC的相關信息(狀態位、快照、擴展數據、計數器)。

4.1 報文格式

請求 (Request):14 [GroupOfDTC]

  • 14 : SID (Service Identifier)

  • GroupOfDTC (3字節): 指定清除范圍。最常用的是 FF FF FF ,代表清除所有DTC。

肯定響應 (Positive Response):54 [GroupOfDTC]

  • 54 : 肯定響應SID( 14 + 0x40

否定響應 (Negative Response):7F 14 [NRC]

  • 常見NRC:

    • 13 : 報文長度錯誤。

    • 22 : 當前條件不滿足(例如車輛速度不為0時禁止清除)。

    • 31 : 請求的DTC組不支持。

4.2 執行邏輯

ECU收到14服務后,執行流程如下:

1. 驗證長度 (len == 4?) -> 否則返回 NRC 13
2. 驗證 GroupOfDTC 支持性 -> 不支持返回 NRC 31
3. 檢查安全條件 (例如: 是否已解鎖SecurityAccess) -> 否返回 NRC 22
4. 遍歷DTC列表:
- 清除狀態字節 (置為特定值,通常是 0x00 或 0x40/0x80)
- 清除快照數據 (Snapshot)
- 清除擴展數據 (Extended Data)
- 重置 Confirmation Counter 和 Aging Counter
5. 返回肯定響應 0x54
5. C++代碼實現示例

以下是一個在ECU端模擬DTC狀態管理及14服務的C++類實現。

#include  
          
#include
#include
#include
#include

// 模擬DTC結構體
struct DtcInfo {
uint32_t id; // DTC編號 (如 0x123456)
uint8_t status; // 狀態位
uint8_t failureCounter; // 確認計數器 (用于防抖)
bool existsInNvm; // 是否已存儲在NVM中

DtcInfo(uint32_t dtcId) : id(dtcId), status(0x40), failureCounter(0), existsInNvm(false) {
// 初始狀態: TestNotCompletedSinceLastClear (bit4=1)
}
};

class UdsDiagnosticManager {
private:
std::map dtcDatabase; // 存儲所有DTC
uint8_t sessionMode; // 當前會話 (默認1-默認會話, 2-編程會話等)

// 模擬NVM讀寫 (生產環境需調用Flash驅動)
void WriteToNvm(uint32_t dtcId, uint8_t status) {
std::cout << "[NVM] 寫入DTC: 0x" << std::hex << dtcId << " 狀態: 0x" << (int)status << std::endl;
}

void EraseNvmForDtc(uint32_t dtcId) {
std::cout << "[NVM] 擦除DTC記錄: 0x" << std::hex << dtcId << std::endl;
}

// 核心邏輯: 更新DTC狀態 (當監控器上報測試結果時調用)
void UpdateDtcStatus(DtcInfo& dtc, bool testResultPassed) {
uint8_t oldStatus = dtc.status;
// 1. 清除 "測試未完成" 標志 (bit4和bit6)
dtc.status &= ~0x50; // 清除 bit4(0x40) 和 bit6(0x10)? 注意掩碼: bit4=16 (0x10), bit6=64 (0x40) -> 糾正: bit6=64, bit4=16
// 糾正掩碼: bit4=0x10, bit6=0x40, 兩者清除: ~0x50
dtc.status &= ~0x50;

if (testResultPassed) {
// 測試合格: 清除當前故障標志
dtc.status &= ~0x01; // bit0 = 0
// 如果當前是 "待確認" 狀態,且計數器遞減? (實際邏輯更復雜,這里簡化)
if (dtc.failureCounter > 0) {
// 防抖遞減邏輯: 如果連續合格,計數器減1,但不低于0
// 此處簡化為: 如果計數器小于閾值,暫時不清除Confirmed標志
}
std::cout << "診斷結果: 通過 (Pass) -> DTC 0x" << std::hex << dtc.id << std::endl;
}
else {
// 測試失敗: 置位當前故障標志
dtc.status |= 0x01; // bit0 = 1 (TestFailed)
dtc.status |= 0x02; // bit1 = 1 (TestFailedThisOpCycle)
dtc.status |= 0x04; // bit2 = 1 (PendingDTC)
dtc.status |= 0x20; // bit5 = 1 (TestFailedSinceLastClear)
// 防抖計數: 增加FailureCounter
dtc.failureCounter++;
std::cout << "診斷結果: 失敗 (Fail), 當前計數器=" << (int)dtc.failureCounter << std::endl;
// 檢查確認閾值 (假設閾值為2)
if (dtc.failureCounter >= 2) {
if (!(dtc.status & 0x08)) { // bit3 = 0 尚未確認
dtc.status |= 0x08; // bit3 = 1 (ConfirmedDTC)
std::cout << "故障已確認 (Confirmed)! 寫入NVM." << std::endl;
// 存儲到NVM
WriteToNvm(dtc.id, dtc.status);
dtc.existsInNvm = true;
}
}
}
std::cout << "狀態更新: 0x" << std::hex << (int)oldStatus << " -> 0x" << (int)dtc.status << std::endl;
}

public:
UdsDiagnosticManager() : sessionMode(1) {}

// 模擬診斷監控器調用 (周期性執行)
void ReportTestResult(uint32_t dtcId, bool passed) {
auto it = dtcDatabase.find(dtcId);
if (it == dtcDatabase.end()) {
// 動態創建DTC (如果不存在)
dtcDatabase.emplace(dtcId, DtcInfo(dtcId));
it = dtcDatabase.find(dtcId);
}
UpdateDtcStatus(it->second, passed);
}

// 實現14服務 (清除診斷信息)
std::vector HandleService_14(const std::vector& request) {
std::vector response;
// 1. 長度檢查: 14服務請求必須為 4字節 (SID + 3字節 GroupOfDTC)
if (request.size() != 4) {
response = {0x7F, 0x14, 0x13}; // NRC 13: incorrectMessageLength
return response;
}
// 提取 GroupOfDTC (例如 0xFFFFFF 表示清除所有)
uint32_t group = (request[1] << 16) | (request[2] << 8) | request[3];
// 2. 會話檢查 (某些組需要編程會話)
if (group == 0xFFFF00 && sessionMode != 2) { // 假設清除所有DTC需要編程會話
response = {0x7F, 0x14, 0x22}; // NRC 22: conditionsNotCorrect
return response;
}
// 3. 執行清除操作
std::cout << "\n[14服務] 收到清除請求, Group: 0x" << std::hex << group << std::endl;
if (group == 0xFFFFFF) { // 清除所有DTC
for (auto& pair : dtcDatabase) {
DtcInfo& dtc = pair.second;
// 清除狀態位: 重置為 0x40 (TestNotCompletedSinceLastClear)
dtc.status = 0x40;
dtc.failureCounter = 0;
EraseNvmForDtc(dtc.id);
dtc.existsInNvm = false;
std::cout << "清除DTC: 0x" << std::hex << dtc.id << std::endl;
}
// 如果允許CDD抑制,還需清除全局快照數據
}
else if (group == 0x000001) { // 清除特定組: 排放相關
// 遍歷過濾邏輯...
}
// 4. 返回肯定響應
response = {0x54, request[1], request[2], request[3]};
return response;
}

// 打印所有DTC當前狀態 (用于調試)
void PrintAllDtcStatus() {
std::cout << "\n========== 當前DTC列表 ==========" << std::endl;
for (const auto& pair : dtcDatabase) {
std::cout << "DTC: 0x" << std::hex << pair.first
<< " | Status: 0x" << (int)pair.second.status
<< " | FailCnt: " << std::dec << (int)pair.second.failureCounter
<< std::endl;
}
std::cout << "================================\n" << std::endl;
}
};

// 主函數示例
int main() {
UdsDiagnosticManager diag;
// 場景模擬: 模擬一個電壓故障 (DTC 0x123456)
uint32_t voltDtc = 0x123456;
std::cout << "=== 操作循環 1 開始 ===" << std::endl;
diag.ReportTestResult(voltDtc, false); // 第一次失敗 -> Pending
diag.PrintAllDtcStatus();
diag.ReportTestResult(voltDtc, false); // 第二次連續失敗 -> Confirmed (bit3=1)
diag.PrintAllDtcStatus();
std::cout << "\n=== 操作循環 2 開始 (模擬下電上電) ===" << std::endl;
// 注意: 在實際ECU中,跨循環時會重置 bit1=0, bit6=1,此處省略模擬重置函數,僅演示清除邏輯
std::cout << "\n=== 執行 14 服務清除故障 ===" << std::endl;
std::vector clearReq = {0x14, 0xFF, 0xFF, 0xFF};
auto resp = diag.HandleService_14(clearReq);
// 打印響應
if (resp[0] == 0x54) {
std::cout << "14服務肯定響應成功!" << std::endl;
} else if (resp[0] == 0x7F) {
std::cout << "14服務拒絕, NRC: 0x" << std::hex << (int)resp[2] << std::endl;
}
diag.PrintAllDtcStatus(); // 觀察狀態位被重置為 0x40
return 0;
}
代碼輸出預期

=== 操作循環 1 開始 ===
診斷結果: 失敗 (Fail), 當前計數器=1
狀態更新: 0x40 -> 0x27 (二進制: 0010 0111 -> bit0,1,2,5 = 1)

========== 當前DTC列表 ==========
DTC: 0x123456 | Status: 0x27 | FailCnt: 1

診斷結果: 失敗 (Fail), 當前計數器=2
故障已確認 (Confirmed)! 寫入NVM.
狀態更新: 0x27 -> 0x2F (bit3 變 1)

========== 當前DTC列表 ==========
DTC: 0x123456 | Status: 0x2F | FailCnt: 2

=== 執行 14 服務清除故障 ===
[14服務] 收到清除請求, Group: 0xffffff
[NVM] 擦除DTC記錄: 0x123456
清除DTC: 0x123456
14服務肯定響應成功!

========== 當前DTC列表 ==========
DTC: 0x123456 | Status: 0x40 | FailCnt: 0
6. 總結
  1. 狀態位是動態的bit0 代表此時此刻, bit3 代表歷史包袱, bit5 代表自上次清零后的“案底”。

  2. 跳變依賴防抖機制 :從 Pending (bit2)Confirmed (bit3) 需要達到預設的失敗計數閾值,防止偶發干擾導致誤報。

  3. 14服務是重置動作 :它不僅清除狀態位,還會銷毀快照和計數器。執行14服務前通常需要 SecurityAccess (27服務) 解鎖,且不同DTC組可能對應不同權限。

  4. 開發建議 :在ECU代碼中,務必使用狀態機管理DTC,并嚴格區分 RAM 中的當前狀態和 NVM 中的固化狀態。診斷工具側讀取到 0x08 (Confirmed DTC) 時,即可認為車輛確實存在歷史故障記錄。

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

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.

相關推薦
熱點推薦
啥都和愛國扯到一起,就是一種病

啥都和愛國扯到一起,就是一種病

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

A股:剛剛,國務院國資委發布,不出意外的話,下周將迎來新變化

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

國家發改委主任鄭柵潔會見波音公司總裁奧特伯格

新京報
2026-05-15 20:29:22
上海87-82戰勝北京!賽后數據一清二楚,不是王哲林 最大功臣是他

上海87-82戰勝北京!賽后數據一清二楚,不是王哲林 最大功臣是他

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

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

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

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

芹姐說生活
2026-05-14 23:38:55
上海奪G1但3人需總結!盧偉應變差點,白邊優勢被打沒,弗格太鐵

上海奪G1但3人需總結!盧偉應變差點,白邊優勢被打沒,弗格太鐵

籃球資訊達人
2026-05-16 01:09:21
38.98萬,夸張啊...

38.98萬,夸張啊...

放毒
2026-05-15 19:14:23
中紀委再次重拳出擊!這4個領域將被嚴查,這4種行為將被嚴肅處理

中紀委再次重拳出擊!這4個領域將被嚴查,這4種行為將被嚴肅處理

細說職場
2026-05-15 14:01:05
鄺兆鐳U17亞洲杯首秀!送助攻后或舊傷復發,只踢半場仍獲贊

鄺兆鐳U17亞洲杯首秀!送助攻后或舊傷復發,只踢半場仍獲贊

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

悲催!上海一母親將700萬遺產給兒子,6年后才發現被女兒徹底拉黑

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

特朗普還沒回國,就開始放狠話了

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

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

美家指南
2026-05-15 15:27:43
國宴名場面刷屏:穿紅衣的服務員火了,這才是大國該有的體面

國宴名場面刷屏:穿紅衣的服務員火了,這才是大國該有的體面

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

“錢車兩空”!男子以租代購跑網約車,三年還清13.5萬,過戶前一夜車被拖走

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

張雪宣布停產!博主:雷軍出問題你建議退款 自己出問題只補償

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

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

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

這跟不穿有啥區別?趙露思演唱會內衣外穿:被眾嘲一套比一套辣眼

胡一舸南游y
2026-05-13 15:23:56
看好誰當選臺北市長?1.4萬人網絡投票結果一面倒

看好誰當選臺北市長?1.4萬人網絡投票結果一面倒

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

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

懂球帝
2026-05-16 02:43:35
2026-05-16 02:59:00
新能源自動駕駛 incentive-icons
新能源自動駕駛
專注于半導體行業資訊
977文章數 347關注度
往期回顧 全部

科技要聞

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

頭條要聞

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

頭條要聞

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

體育要聞

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

娛樂要聞

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

財經要聞

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

汽車要聞

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

態度原創

游戲
房產
旅游
健康
公開課

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

房產要聞

老黃埔熱銷之下,珠江春,為何去化僅3成?

旅游要聞

藏在沈陽鬧市的金色秘境!2 萬㎡油菜花全開,地鐵直達還免費

專家揭秘干細胞回輸的安全風險

公開課

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

無障礙瀏覽 進入關懷版