碼NRC)
在汽車電子開(kāi)發(fā)和測(cè)試領(lǐng)域CANoe 是進(jìn)行總線仿真、分析和測(cè)試的核心工具。工程師在日常工作中經(jīng)常需要處理大量的總線日志文件例如 .blf 格式的報(bào)文記錄。一個(gè)典型的需求是從海量的歷史報(bào)文數(shù)據(jù)中快速、準(zhǔn)確地篩選出包含特定診斷否定響應(yīng)碼NRC的報(bào)文序列用于分析診斷失敗的原因、驗(yàn)證診斷服務(wù)邏輯或進(jìn)行故障復(fù)現(xiàn)。手動(dòng)在 CANoe Trace 窗口中逐條查看不僅效率低下而且容易遺漏。因此掌握如何通過(guò)腳本或工具批量掃描 .blf 文件并提取包含特定 NRC 的報(bào)文是一項(xiàng)非常實(shí)用的工程技能。本文將以一個(gè)具體的工程任務(wù)為例詳細(xì)介紹如何使用 CANoe 的 CAPL 腳本和 .NET 接口實(shí)現(xiàn)對(duì) .blf 文件的批量自動(dòng)化掃描。我們將從理解 .blf 文件結(jié)構(gòu)和 NRC 在報(bào)文中的位置開(kāi)始逐步構(gòu)建一個(gè)完整的解決方案包括環(huán)境準(zhǔn)備、腳本編寫(xiě)、關(guān)鍵代碼解析、運(yùn)行驗(yàn)證以及常見(jiàn)問(wèn)題的排查。無(wú)論你是剛接觸 CANoe 自動(dòng)化測(cè)試的新手還是希望優(yōu)化現(xiàn)有工作流的老手都能通過(guò)本文獲得一套可直接復(fù)用的方法。1. 理解任務(wù)核心BLF 文件與 NRC 報(bào)文在開(kāi)始編寫(xiě)代碼之前必須清晰地理解我們要處理的對(duì)象和目標(biāo)。1.1 BLF 文件是什么BLFBinary Logging Format是 Vector 公司定義的一種二進(jìn)制日志格式專門(mén)用于高效記錄 CAN、LIN、FlexRay、Ethernet 等總線上的報(bào)文、事件和系統(tǒng)變量。與文本格式的 .asc 文件相比.blf 文件體積更小讀寫(xiě)速度更快并且能記錄更精確的時(shí)間戳和更多類型的信號(hào)。在 CANoe 中你可以通過(guò) Measurement - Logging 功能錄制總線活動(dòng)生成 .blf 文件。后續(xù)的分析、回放或自動(dòng)化腳本處理都基于這個(gè)文件。1.2 NRC 在報(bào)文中的位置NRCNegative Response Code是 UDSUnified Diagnostic Services協(xié)議中ECU 對(duì)診斷請(qǐng)求發(fā)出否定響應(yīng)的原因碼。它出現(xiàn)在診斷響應(yīng)報(bào)文中。一個(gè)典型的 UDS 報(bào)文在 CAN 總線上遵循一定的格式。例如使用 CAN 標(biāo)準(zhǔn)幀11位 ID功能尋址請(qǐng)求 ID 為 0x7DF物理尋址響應(yīng) ID 可能為 0x7E8。報(bào)文數(shù)據(jù)場(chǎng)遵循 ISO 15765-2ISO-TP協(xié)議進(jìn)行傳輸。對(duì)于一個(gè)否定響應(yīng)其報(bào)文數(shù)據(jù)場(chǎng)通常如下結(jié)構(gòu)字節(jié)偏移含義值示例0否定響應(yīng)服務(wù)標(biāo)識(shí)0x7F1請(qǐng)求的服務(wù)標(biāo)識(shí)SID例如 0x22ReadDataByIdentifier2否定響應(yīng)碼NRC例如 0x31requestOutOfRange因此我們的掃描任務(wù)本質(zhì)上是解析 .blf 文件中的每一幀 CAN 報(bào)文檢查其 ID 和數(shù)據(jù)場(chǎng)判斷是否為包含特定 NRC如 0x31的診斷否定響應(yīng)報(bào)文。2. 環(huán)境準(zhǔn)備與方案選型要實(shí)現(xiàn)批量掃描我們需要一個(gè)能夠編程式讀取 .blf 文件并解析其中報(bào)文的執(zhí)行環(huán)境。主要有兩種主流方案2.1 方案對(duì)比方案使用場(chǎng)景優(yōu)點(diǎn)缺點(diǎn)CAPL 腳本在 CANoe 環(huán)境內(nèi)需要對(duì)報(bào)文進(jìn)行復(fù)雜邏輯判斷、與仿真系統(tǒng)交互、或邊掃描邊回放。與 CANoe 深度集成可直接使用 CANoe 的數(shù)據(jù)庫(kù)DBC解析信號(hào)訪問(wèn)系統(tǒng)變量方便集成到現(xiàn)有測(cè)試序列中。執(zhí)行效率相對(duì)較慢不適合超大規(guī)模文件批量處理依賴 CANoe 運(yùn)行時(shí)環(huán)境。.NET / Python 使用 Vector API需要離線、高速處理大量 .blf 文件或集成到 CI/CD 流水線中。執(zhí)行速度快不依賴 CANoe GUI資源占用低易于集成。需要額外安裝 Vector 提供的庫(kù)如 vxlapi.dll, BLF .NET API初始配置稍復(fù)雜。考慮到“批量掃描”通常意味著對(duì)大量文件進(jìn)行離線、快速處理本文重點(diǎn)介紹第二種方案即使用 .NETC#配合 Vector 提供的Vector.Blf庫(kù)來(lái)實(shí)現(xiàn)。同時(shí)我們也會(huì)簡(jiǎn)要說(shuō)明如何在 CAPL 中實(shí)現(xiàn)類似功能以滿足不同場(chǎng)景的需求。2.2 開(kāi)發(fā)環(huán)境準(zhǔn)備安裝 CANoe確保 CANoe建議版本 11.0 或更高已正確安裝。安裝過(guò)程中會(huì)包含必要的運(yùn)行時(shí)庫(kù)。安裝開(kāi)發(fā)環(huán)境.NET 方案安裝 Visual Studio 2019 或更高版本并確保已安裝 .NET Framework 4.7.2 或 .NET Core 3.1 / .NET 5 開(kāi)發(fā)包。Python 方案安裝 Python 3.8并使用 pip 安裝vector-blf庫(kù)如果可用需注意官方對(duì) Python 接口的支持程度。定位依賴庫(kù)Vector 的 BLF .NET API 通常位于 CANoe 安裝目錄下例如C:\Program Files\Vector CANoe\Exec32\Vector.Can.Common.dll和C:\Program Files\Vector CANoe\Exec32\Vector.Blf.dll。在項(xiàng)目中需要引用這些 DLL。3. 使用 .NET (C#) 批量掃描 BLF 文件我們將創(chuàng)建一個(gè) C# 控制臺(tái)應(yīng)用程序其核心邏輯是遍歷指定文件夾下的所有 .blf 文件逐個(gè)打開(kāi)讀取每一條 CAN 報(bào)文對(duì)象并檢查其數(shù)據(jù)是否符合目標(biāo) NRC 模式。3.1 創(chuàng)建項(xiàng)目與引用打開(kāi) Visual Studio新建一個(gè)“控制臺(tái)應(yīng)用 (.NET Framework 或 .NET Core)”項(xiàng)目命名為BlfNrcScanner。在解決方案資源管理器中右鍵點(diǎn)擊項(xiàng)目“引用” - “添加引用”。點(diǎn)擊“瀏覽”導(dǎo)航到 CANoe 安裝目錄下的Exec32文件夾選擇并添加以下 DLL具體名稱可能因版本略有差異Vector.Blf.dllVector.Can.Common.dllVector.Collections.dllVector.Diagnostics.dllVector.Utilities.dll在代碼文件頂部添加必要的命名空間引用。using System; using System.Collections.Generic; using System.IO; using System.Linq; using Vector.Blf; using Vector.Can.Common; using Vector.Can.Common.Entities;3.2 核心掃描邏輯實(shí)現(xiàn)下面是一個(gè)完整的Program.cs示例它實(shí)現(xiàn)了掃描單個(gè) .blf 文件查找包含特定 NRC 的 CAN 報(bào)文的功能。namespace BlfNrcScanner { class Program { // 定義要查找的 NRC 值例如 0x31 (requestOutOfRange) static readonly byte TargetNrc 0x31; // 定義診斷否定響應(yīng)的基礎(chǔ)模式0x7F 請(qǐng)求的 SID NRC // 這里我們假設(shè)請(qǐng)求的 SID 是 0x22 (ReadDataByIdentifier)你可以根據(jù)需要修改或擴(kuò)展 static readonly byte[] NegativeResponsePattern new byte[] { 0x7F, 0x22, TargetNrc }; static void Main(string[] args) { string blfFolderPath C:\YourLogDirectory; string searchPattern *.blf; if (!Directory.Exists(blfFolderPath)) { Console.WriteLine($目錄不存在: {blfFolderPath}); return; } var blfFiles Directory.GetFiles(blfFolderPath, searchPattern, SearchOption.AllDirectories); Console.WriteLine($找到 {blfFiles.Length} 個(gè) BLF 文件。); foreach (var blfFilePath in blfFiles) { Console.WriteLine($\n處理文件: {Path.GetFileName(blfFilePath)}); ScanBlfForNrc(blfFilePath); } Console.WriteLine(\n掃描完成。); Console.ReadKey(); } static void ScanBlfForNrc(string filePath) { int matchCount 0; try { // 使用 BlfReader 打開(kāi) BLF 文件 using (var blfReader new BlfReader(filePath)) { IBlfContainer container; // 循環(huán)讀取文件中的每一個(gè)容器通常包含一條報(bào)文或事件 while ((container blfReader.ReadNextContainer()) ! null) { // 我們只關(guān)心 CAN 報(bào)文容器 if (container is CanMessage canMessageContainer) { var canMessage canMessageContainer.Object; // 檢查是否為 CAN 數(shù)據(jù)幀非遠(yuǎn)程幀、錯(cuò)誤幀 if (canMessage.FrameType FrameType.Data) { // 這里假設(shè)我們關(guān)注的是標(biāo)準(zhǔn)診斷響應(yīng) ID例如 0x7E8 // 實(shí)際項(xiàng)目中你需要根據(jù) DBC 或項(xiàng)目規(guī)范確定目標(biāo) ID if (canMessage.Identifier 0x7E8) { var data canMessage.Data; // 檢查數(shù)據(jù)長(zhǎng)度至少為 3 字節(jié)并且匹配否定響應(yīng)模式 if (data.Length 3) { // 比較數(shù)據(jù)場(chǎng)的前三個(gè)字節(jié)是否與我們的模式匹配 if (data[0] NegativeResponsePattern[0] data[1] NegativeResponsePattern[1] data[2] NegativeResponsePattern[2]) { matchCount; // 輸出匹配到的報(bào)文詳細(xì)信息 Console.WriteLine($ 匹配到 NRC 0x{TargetNrc:X2} 的報(bào)文:); Console.WriteLine($ 時(shí)間戳: {canMessageContainer.TimeStamp.ToLocalTime():HH:mm:ss.ffffff}); Console.WriteLine($ CAN ID: 0x{canMessage.Identifier:X3}); Console.Write($ 數(shù)據(jù): ); foreach (byte b in data.Take(8)) // 通常顯示前8字節(jié) { Console.Write(${b:X2} ); } Console.WriteLine(); } } } } } } } Console.WriteLine($ 文件 {Path.GetFileName(filePath)} 中共找到 {matchCount} 條匹配報(bào)文。); } catch (Exception ex) { Console.WriteLine($ 處理文件 {filePath} 時(shí)出錯(cuò): {ex.Message}); } } } }3.3 關(guān)鍵代碼解析與配置依賴與命名空間Vector.Blf和Vector.Can.Common是處理 BLF 和 CAN 報(bào)文的核心命名空間。必須正確引用對(duì)應(yīng)的 DLL。BlfReader類這是讀取 BLF 文件的入口。它通過(guò)ReadNextContainer()方法迭代讀取文件中的所有記錄。每條記錄都被包裝在一個(gè)實(shí)現(xiàn)了IBlfContainer接口的對(duì)象中。報(bào)文類型判斷if (container is CanMessage canMessageContainer)用于篩選出 CAN 報(bào)文記錄。BLF 中還可能包含日志注釋、系統(tǒng)變量變化等其他類型的容器。CAN 報(bào)文過(guò)濾canMessage.FrameType FrameType.Data確保是數(shù)據(jù)幀。canMessage.Identifier 0x7E8這是一個(gè)關(guān)鍵配置點(diǎn)。0x7E8 是示例中的物理尋址診斷響應(yīng) ID。在實(shí)際項(xiàng)目中你必須將其替換為你的項(xiàng)目中 ECU 實(shí)際使用的響應(yīng) ID。這個(gè) ID 通??梢栽陧?xiàng)目的 DBC 文件或通信矩陣中找到。你可能需要處理多個(gè)響應(yīng) ID。NRC 模式匹配NegativeResponsePattern數(shù)組定義了我們要查找的報(bào)文數(shù)據(jù)模式。{ 0x7F, 0x22, 0x31 }表示查找“對(duì) SID 0x22 請(qǐng)求的否定響應(yīng)且 NRC 為 0x31”。重要這里的0x22ReadDataByIdentifier是一個(gè)示例。你需要根據(jù)你關(guān)心的診斷服務(wù)來(lái)修改這個(gè)值。例如如果查找對(duì)0x10DiagnosticSessionControl的否定響應(yīng)則應(yīng)改為{ 0x7F, 0x10, TargetNrc }。代碼中使用了簡(jiǎn)單的逐字節(jié)比較。對(duì)于更復(fù)雜的匹配如忽略 SID只關(guān)心 NRC可以修改匹配邏輯。時(shí)間戳canMessageContainer.TimeStamp提供了報(bào)文的精確時(shí)間對(duì)于問(wèn)題定位非常有價(jià)值。錯(cuò)誤處理使用try-catch包裹文件讀取邏輯確保單個(gè)文件損壞不會(huì)導(dǎo)致整個(gè)程序崩潰。4. 運(yùn)行驗(yàn)證與結(jié)果分析4.1 編譯與運(yùn)行在 Visual Studio 中將blfFolderPath變量的值修改為你存放 .blf 文件的真實(shí)路徑。按 F5 編譯并運(yùn)行程序??刂婆_(tái)會(huì)輸出掃描進(jìn)度和結(jié)果。4.2 預(yù)期輸出示例找到 5 個(gè) BLF 文件。 處理文件: test_log_20231001.blf 匹配到 NRC 0x31 的報(bào)文: 時(shí)間戳: 14:23:45.123456 CAN ID: 0x7E8 數(shù)據(jù): 7F 22 31 00 00 00 00 00 匹配到 NRC 0x31 的報(bào)文: 時(shí)間戳: 14:24:01.987654 CAN ID: 0x7E8 數(shù)據(jù): 7F 22 31 AA BB CC DD EE 文件 test_log_20231001.blf 中共找到 2 條匹配報(bào)文。 處理文件: test_log_20231002.blf 文件 test_log_20231002.blf 中共找到 0 條匹配報(bào)文。 ... 掃描完成。4.3 結(jié)果驗(yàn)證為了確保腳本工作正常建議進(jìn)行交叉驗(yàn)證使用 CANoe 手動(dòng)驗(yàn)證用 CANoe 打開(kāi)被掃描的 .blf 文件在 Trace 窗口中過(guò)濾出 ID 為 0x7E8 的報(bào)文手動(dòng)檢查數(shù)據(jù)場(chǎng)確認(rèn)是否確實(shí)存在7F 22 31 ...格式的報(bào)文。構(gòu)造測(cè)試文件使用 CANoe 錄制一段包含明確 NRC 0x31 響應(yīng)的診斷會(huì)話生成一個(gè)小的 .blf 文件用此文件來(lái)驗(yàn)證掃描腳本是否能正確識(shí)別。5. 方案擴(kuò)展與高級(jí)處理基礎(chǔ)的掃描功能實(shí)現(xiàn)后可以根據(jù)實(shí)際需求進(jìn)行增強(qiáng)。5.1 擴(kuò)展匹配規(guī)則當(dāng)前的代碼匹配固定的 SID 和 NRC。你可以很容易地?cái)U(kuò)展它匹配多個(gè) NRC將TargetNrc改為一個(gè)列表Listbyte然后在匹配時(shí)檢查data[2]是否在列表中。匹配多個(gè)響應(yīng) ID將canMessage.Identifier 0x7E8改為檢查 ID 是否在一個(gè)哈希集合HashSetuint中。模糊匹配例如只關(guān)心是否為否定響應(yīng)第一個(gè)字節(jié)為 0x7F以及 NRC不關(guān)心是對(duì)哪個(gè) SID 的響應(yīng)??梢詫⑵ヅ溥壿嫺臑閕f (data[0] 0x7F data[2] TargetNrc) { // 匹配成功 }5.2 輸出結(jié)果到文件將結(jié)果輸出到控制臺(tái)適合快速查看但處理大量文件時(shí)輸出到文件更便于歸檔和分析。修改ScanBlfForNrc方法接受一個(gè)StreamWriter參數(shù)或?qū)⒔Y(jié)果收集到Liststring中最后統(tǒng)一寫(xiě)入 CSV 或文本文件。static void ScanBlfForNrc(string filePath, StreamWriter resultWriter) { // ... 掃描邏輯 ... if (matchFound) { string line ${Path.GetFileName(filePath)},{canMessageContainer.TimeStamp},{canMessage.Identifier:X},{BitConverter.ToString(data)}; resultWriter.WriteLine(line); } // ... }5.3 性能優(yōu)化對(duì)于非常大的 .blf 文件數(shù)GB可以考慮以下優(yōu)化并行處理文件使用Parallel.ForEach來(lái)同時(shí)處理多個(gè) .blf 文件。注意Vector.Blf庫(kù)本身是否是線程安全的通常每個(gè)文件在一個(gè)獨(dú)立線程中處理是安全的。Parallel.ForEach(blfFiles, blfFilePath { ScanBlfForNrc(blfFilePath); });減少輸出在循環(huán)內(nèi)減少Console.WriteLine的調(diào)用尤其是在找到大量匹配報(bào)文時(shí)可以先緩存結(jié)果最后一次性輸出。6. 在 CANoe CAPL 環(huán)境中實(shí)現(xiàn)掃描如果你需要在 CANoe 測(cè)試模塊內(nèi)部集成掃描功能例如在 Test Module 或 Test Unit 中可以使用 CAPL 腳本。CAPL 提供了blf文件訪問(wèn)函數(shù)。以下是一個(gè) CAPL 函數(shù)示例演示了類似邏輯// CAPL 腳本示例 - 需在 CANoe 的 CAPL Browser 中編寫(xiě) variables { dword gBlfHandle; long gMatchCount; } // 函數(shù)掃描單個(gè) BLF 文件 void ScanBlfFile(char fileName[]) { CanMessage msg; byte data[64]; dword dlc; int i; gBlfHandle blfOpen(fileName, 0); // 0 表示只讀 if(gBlfHandle 0) { write(錯(cuò)誤無(wú)法打開(kāi)文件 %s, fileName); return; } gMatchCount 0; while(blfRead(gBlfHandle, msg) 1) // 成功讀取一條報(bào)文 { // 檢查 CAN ID例如 0x7E8 if(msg.id 0x7E8) { dlc msg.dlc; for(i 0; i dlc; i) { data[i] msg.byte(i); } // 檢查是否為否定響應(yīng) (0x7F) 且 NRC 為 0x31 // 這里假設(shè)是對(duì) SID 0x22 的響應(yīng) if(dlc 3 data[0] 0x7F data[1] 0x22 data[2] 0x31) { gMatchCount; write(在文件 %s 中發(fā)現(xiàn)匹配報(bào)文時(shí)間: %f, ID: 0x%X, 數(shù)據(jù): %02X %02X %02X ..., fileName, msg.time, msg.id, data[0], data[1], data[2]); } } } blfClose(gBlfHandle); write(文件 %s 掃描完成共找到 %d 條匹配報(bào)文。, fileName, gMatchCount); } // 在某個(gè)事件如測(cè)試開(kāi)始中調(diào)用 on start { char filePath[256]; // 這里需要構(gòu)建或獲取文件路徑實(shí)際項(xiàng)目中可能通過(guò)面板輸入 snprintf(filePath, elcount(filePath), C:\\logs\\diagnostic_errors.blf); ScanBlfFile(filePath); }CAPL 方案注意事項(xiàng)CAPL 的blfRead函數(shù)一次讀取一條報(bào)文記錄循環(huán)處理大文件可能較慢。CAPL 腳本運(yùn)行在 CANoe 測(cè)量環(huán)境中適合與仿真、測(cè)試步驟結(jié)合。文件路徑處理在 CAPL 中不如 .NET 靈活批量遍歷文件夾需要更多代碼。7. 常見(jiàn)問(wèn)題排查在實(shí)際運(yùn)行掃描腳本時(shí)你可能會(huì)遇到以下問(wèn)題問(wèn)題現(xiàn)象可能原因檢查與解決方式程序拋出FileNotFoundException或DllNotFoundException未能正確找到或引用 Vector 的 DLL。1. 確認(rèn)引用的 DLL 路徑正確且與當(dāng)前 CANoe 版本匹配。2. 對(duì)于 .NET Core/5 項(xiàng)目確保將 DLL 復(fù)制到輸出目錄設(shè)置“復(fù)制本地”為 True。3. 嘗試將 Vector DLL 放到程序運(yùn)行目錄下。程序運(yùn)行但找不到任何報(bào)文1. 文件路徑錯(cuò)誤程序未讀取到文件。2. CAN ID 過(guò)濾條件錯(cuò)誤。3. NRC 匹配模式錯(cuò)誤。4. 文件本身不包含目標(biāo)報(bào)文。1. 檢查blfFolderPath確認(rèn)文件存在。2.使用 CANoe 打開(kāi)目標(biāo) .blf 文件在 Trace 中查看報(bào)文的實(shí)際 ID 和數(shù)據(jù)。這是最直接的驗(yàn)證方法。3. 調(diào)整代碼中的Identifier和NegativeResponsePattern為實(shí)際值。4. 在代碼中臨時(shí)取消 ID 過(guò)濾打印所有 CAN 報(bào)文的 ID 和數(shù)據(jù)觀察文件內(nèi)容。程序崩潰或讀取文件出錯(cuò)1. BLF 文件損壞或不兼容。2. 使用的 Vector API 版本與 CANoe 版本不匹配。1. 嘗試用 CANoe 能否正常打開(kāi)該文件。2. 確保開(kāi)發(fā)環(huán)境引用的 DLL 版本與生成該 .blf 文件的 CANoe 主版本兼容。掃描速度非常慢1. 單個(gè)文件極大。2. 控制臺(tái)輸出過(guò)于頻繁。3. 未使用并行處理。1. 考慮優(yōu)化匹配邏輯減少不必要的操作。2. 將結(jié)果先存入內(nèi)存列表掃描結(jié)束后再統(tǒng)一輸出。3. 對(duì)于多文件使用Parallel.ForEach注意線程安全。匹配到不相關(guān)的報(bào)文匹配邏輯過(guò)于寬泛。例如數(shù)據(jù)場(chǎng){0x7F, 0x22, 0x31}可能偶然出現(xiàn)在非診斷報(bào)文的其他位置。增加過(guò)濾條件例如結(jié)合 CAN ID 范圍、報(bào)文長(zhǎng)度DLC進(jìn)行更精確的匹配。診斷否定響應(yīng)幀的 DLC 通常為固定長(zhǎng)度如 3 或 8。8. 最佳實(shí)踐與生產(chǎn)環(huán)境建議將腳本用于實(shí)際項(xiàng)目或自動(dòng)化流水線時(shí)應(yīng)考慮以下幾點(diǎn)配置外置化不要將 CAN ID、NRC 值、文件路徑等硬編碼在代碼中。應(yīng)該將它們放在配置文件如appsettings.json或通過(guò)命令行參數(shù)傳入。這提高了腳本的復(fù)用性。日志記錄除了輸出匹配結(jié)果還應(yīng)記錄程序運(yùn)行日志如開(kāi)始時(shí)間、處理的文件列表、遇到的錯(cuò)誤等便于后期審計(jì)和問(wèn)題排查??梢允褂肗Log或Serilog等日志框架。結(jié)果結(jié)構(gòu)化輸出將掃描結(jié)果輸出為結(jié)構(gòu)化的格式如 CSV 或 JSON。這樣便于導(dǎo)入到 Excel、數(shù)據(jù)庫(kù)或其他分析工具中進(jìn)行進(jìn)一步處理。FileName,Timestamp,CanId,DataHex,NrcValue,MatchedService test.blf,2023-10-01 14:23:45.123,0x7E8,7F22310000000000,0x31,0x22集成到 CI/CD在持續(xù)集成環(huán)境中可以將此掃描腳本作為一個(gè)檢查步驟。例如在每日構(gòu)建后自動(dòng)掃描測(cè)試產(chǎn)生的日志統(tǒng)計(jì)特定 NRC 的出現(xiàn)頻率如果超過(guò)閾值則標(biāo)記構(gòu)建為不穩(wěn)定。錯(cuò)誤處理與重試對(duì)于網(wǎng)絡(luò)驅(qū)動(dòng)器上的文件或正在被其他進(jìn)程占用的文件代碼應(yīng)有良好的錯(cuò)誤處理和重試機(jī)制。版本管理腳本本身應(yīng)納入版本控制系統(tǒng)如 Git。對(duì) CAN ID、NRC 等關(guān)鍵參數(shù)的修改應(yīng)有記錄。代碼可測(cè)試性將核心的掃描邏輯如ScanBlfForNrc函數(shù)與文件 IO 操作分離便于編寫(xiě)單元測(cè)試使用模擬的報(bào)文數(shù)據(jù)進(jìn)行邏輯驗(yàn)證。通過(guò)遵循以上步驟和最佳實(shí)踐你可以構(gòu)建一個(gè)健壯、高效且可維護(hù)的 .blf 文件批量掃描工具顯著提升處理診斷日志和分析 NRC 相關(guān)問(wèn)題的效率。這個(gè)方案的核心思路——解析二進(jìn)制日志、匹配特定報(bào)文模式——同樣可以應(yīng)用于其他總線類型如 LIN、Ethernet或其他特定報(bào)文模式的搜索場(chǎng)景。