黃利權(quán),趙治國
(同濟(jì)大學(xué) 汽車學(xué)院,上海 201804)
當(dāng)今汽車因裝配諸多的電控單元(electric control unit, ECU)而帶來的電控系統(tǒng)維修困難,而汽車故障診斷儀則用于檢測汽車上安裝的ECU出現(xiàn)各種軟、硬件故障,故障診斷儀和汽車上各個ECU的診斷模塊進(jìn)行通信,讀取ECU記錄的各種故障數(shù)據(jù)和內(nèi)容信息,控制ECU完成特定的動作測試程序?,F(xiàn)有的開發(fā)平臺通過以下兩種形式來調(diào)試和驗證各種診斷數(shù)據(jù)的正確性:(1)手持式診斷儀和PC機(jī)上的ECU軟件模擬器進(jìn)行通信;(2)手持式診斷儀和實驗室內(nèi)臺架上的ECU軟件模擬器進(jìn)行通信。因為這兩種開發(fā)模式需要操作手持式診斷儀,而當(dāng)診斷內(nèi)容開發(fā)工程師在處理數(shù)量巨大的診斷數(shù)據(jù)時,繁瑣且慢速的儀器操作會導(dǎo)致開發(fā)效率的低下,需要設(shè)計可以在同一臺PC機(jī)上運(yùn)行故障診斷軟件和ECU模擬器的解決方案,通過該ECU模擬器可以對故障診斷儀進(jìn)行診斷數(shù)據(jù)的離線仿真。
另外,根據(jù)ISO15765規(guī)范,PC機(jī)上的應(yīng)用軟件可以利用J2534 API作為訪問Pass-thru(故障診斷儀在PC機(jī)上的工作模塊,在本文中代表了在PC機(jī)上運(yùn)行的診斷軟件)設(shè)備驅(qū)動程序的接口。該協(xié)議包括J2534-1、J2534-2和J2534-3等3個部分。其中J2534-1定義了用于對發(fā)動機(jī)電控單元排放相關(guān)模塊再編程的API接口,這些接口不僅可以用于再編程,也可以用于其他的功能目標(biāo)[1]。通過這些API接口應(yīng)用程序可以控制Pass-thru設(shè)備,也可以控制Pass-thru設(shè)備和車輛之間的通信。Pass-thru設(shè)備不需要解釋所傳輸消息的內(nèi)容,它允許任何的消息策略和消息結(jié)構(gòu)被使用,只要它們能夠被應(yīng)用程序和ECU所理解。J2534相關(guān)的API接口類型如下:通信建立和斷開,消息讀寫,啟動和停止周期性消息,設(shè)置可編程電壓,啟動和關(guān)閉消息過濾器,讀取版本信息和取得Last Error等操作[2]。
為了測試特定車型的診斷數(shù)據(jù),筆者進(jìn)一步開發(fā)了同樣能在PC機(jī)上運(yùn)行的ECU模擬器,只需在配置文件中修改虛擬ECU的診斷數(shù)據(jù),就可以在診斷儀和ECU之間建立通信,實現(xiàn)在一臺電腦上通過J2534診斷協(xié)議來完成故障診斷的數(shù)據(jù)驗證。
ECU模擬器模塊如圖1所示。
圖1 ECU模擬器模塊
ECU模擬器包括MainExcutable、Core和J2534InjectDll 3個模塊。各模塊功能如下:
(1)MainExcutable模塊把操作接口和高級功能提供給了用戶,并在Core模塊提供功能的基礎(chǔ)上升級而成;
(2)Core模塊完成了主要的接口模擬工作,處理來自于MainExcutable和J2534InjectDll的請求;
(3)J2534InjectDll模塊把來自于故障診斷儀的調(diào)用推送給Core,并把來自于Core的響應(yīng)推送給故障診斷儀。
模塊結(jié)構(gòu)圖如圖2所示。
圖2 模塊結(jié)構(gòu)圖
模擬器操作界面模塊UI分別調(diào)用了Log模塊、Vehicle模塊和高級DataView修改模塊,用于顯示和編輯診斷通信數(shù)據(jù)。而J2534模塊則通過Vehicle模塊取得車輛診斷協(xié)議配置信息和ECU相關(guān)的診斷模擬數(shù)據(jù),用于和故障診斷儀的相應(yīng)API接口通信。
J2534Inject.dll模塊經(jīng)過Windows操作系統(tǒng)注冊后就能夠被J2534應(yīng)用程序所識別。J2534應(yīng)用程序首先加載J2534Inject.dll,然后映射到它自己的地址空間,最后調(diào)用J2534Inject.dll中的J2534接口函數(shù)來完成診斷通信。
模擬器接口方案采用的雙進(jìn)程模型如圖3所示。
圖3 雙進(jìn)程模型
其把模擬器從J2534應(yīng)用程序中隔離出來。J2534Inject.dll駐留在以J2534為基礎(chǔ)的診斷軟件中,模擬器有它獨立的進(jìn)程。兩個進(jìn)程通過Windows RPC進(jìn)行信息交換。
模擬器模塊運(yùn)行成一個獨立的進(jìn)程,并構(gòu)建了J2534Inject.dll用于提供J2534接口,因為該DLL在故障診斷儀的上下文中運(yùn)行,需要使用IPC(進(jìn)程間數(shù)據(jù)交換)通信機(jī)制,當(dāng)前IPC沒有選擇共享內(nèi)存機(jī)制,而是使用了基于RPC(遠(yuǎn)程過程調(diào)用,即兩個程序間通過傳輸協(xié)議進(jìn)行通信)的IPC[3]。本研究采用該機(jī)制使得開發(fā)更容易,不需要擔(dān)心進(jìn)程間通信的技術(shù)問題,而是讓操作系統(tǒng)來完成該項工作,開發(fā)人員只需要把它視為本地調(diào)用即可。另外當(dāng)通信發(fā)生在相同的物理機(jī)器上時,RPC可以通過配置來使用LPC(本地過程調(diào)用)方法完成消息推送。
傳統(tǒng)的ECU模擬器方案中手持式診斷儀和PC機(jī)上的ECU軟件模擬器進(jìn)行通信,有如下的缺點:手持式診斷儀在操作時數(shù)據(jù)顯示有一定延遲,且診斷內(nèi)容開發(fā)工程師需要在儀器和PC機(jī)電腦之間反復(fù)切換操作,另外ECU模擬器和手持式診斷儀之間的通信需要有接線盒以及USB轉(zhuǎn)接板等設(shè)備,在調(diào)試時有時會因為通信鏈路存在問題而需要排查原因。而采用了J2534診斷協(xié)議后,則可以完全避免以上問題。同時也可以通過開發(fā)腳本程序把診斷數(shù)據(jù)按照指定格式直接轉(zhuǎn)化為該ECU模擬器的數(shù)據(jù)配置文件,用于診斷通信。
軟件模擬器UML用例圖如圖4所示。
圖4 UML用例圖
診斷應(yīng)用角色代表了診斷儀,而用戶角色則代表了ECU模擬器操作者。診斷儀中的“J2534通信”用例和“車輛協(xié)議模擬”用例通過IPC機(jī)制進(jìn)行通信。同時模擬器的功能用例(整幀匹配、數(shù)據(jù)瀏覽和修改和消息日志)是依賴于“車輛協(xié)議模擬”用例來實現(xiàn)的。而“整幀匹配功能”用例則將匹配結(jié)果反饋給模擬器操作者。最后“配置”用例不同,則“車輛協(xié)議模擬”用例對應(yīng)不同的診斷協(xié)議,即向操作者提供不同的協(xié)議模擬功能。
用例向診斷工具提供了一個含有J2534接口的J2534Inject.dll。診斷工具加載該DLL,并通過它和模擬器進(jìn)行通信。J2534Inject.dll必須遵循J2534標(biāo)準(zhǔn)。
因為該模擬器和J2534Inject.dll并不在同一個進(jìn)程中,必須有一種機(jī)制來完成模擬器和該DLL之間的IPC通信。IPC機(jī)制使得診斷工具可以像調(diào)用自己的內(nèi)部函數(shù)一樣調(diào)用程序。
因為類J2534RpcInvoker包含在J2534InjectDll里,含有該類的文件應(yīng)該被加入J2534InjectDll的工程,而其他類屬于Core工程。
J2534軟件包中的診斷儀接口需要遵循J2534標(biāo)準(zhǔn)。該軟件包包含了用于通信的車輛程序接口和由診斷儀引發(fā)的J2534工作日志。
J2534類圖如圖5所示。
圖5 J2534類圖
其中,通信信道管理器CJChannelMgr中包含了多個信道CJChannel,而每個信道則由若干個消息濾波管理器CJMsgFilterMgr所組成。同時每個信道CJChannel依賴于帶有垃圾回收功能的總線節(jié)點類CBusNode,總線節(jié)點是由相關(guān)診斷協(xié)議棧構(gòu)成,而協(xié)議棧中不同層(物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層和應(yīng)用層)由不同類型的診斷協(xié)議所組合而成[4]。另外CJChannel則負(fù)責(zé)主要的J2534通信,即負(fù)責(zé)收發(fā)消息并調(diào)用消息過濾管理器。它把類似J2534協(xié)議的請求轉(zhuǎn)化為了內(nèi)部的一些協(xié)議和數(shù)據(jù)組織方式。設(shè)備管理器CJDeviceMgr由多個CJDevice所組成,CJDevice目前主要代表了故障診斷儀模型,它記錄了引腳和相關(guān)的電壓信息。
CJMediator繼承自J2534Invoker,實現(xiàn)了J2534協(xié)議中包含的API接口,并且負(fù)責(zé)調(diào)度消息濾波管理器CJMsgFilterMgr,信道CJChannel,設(shè)備管理器CJDeviceMgr和設(shè)備CJDevice。
J2534序列圖如圖6所示。
圖6 J2534序列圖
當(dāng)診斷應(yīng)用發(fā)起一個設(shè)備相關(guān)的調(diào)用時,完成如下工作:
(1)在J2534InjectDll中,J2534接口的調(diào)用工作將被派遣給J2534RpcInvoker,它也有類似于J2534的成員函數(shù);
(2)J2534RpcInvoker封裝了診斷應(yīng)用發(fā)過來的參數(shù),然后再發(fā)送給RPC接口;
(3)在模擬器的處理流程中,當(dāng)接收到一個來自于RPC客戶端的消息時,類RpcServer代表的監(jiān)聽線程將被喚醒用于處理RPC調(diào)用;
(4)RpcServer拆開接收到的參數(shù),然后把它們轉(zhuǎn)發(fā)給含有類似于J2534協(xié)議相關(guān)成員函數(shù)的CJMediator;
(5)CJMediator解釋了J2534協(xié)議相關(guān)的接口并調(diào)用了CJChannel和CJDevice實例提供的方法,如果需要創(chuàng)建一個新的實例,或者需要釋放一個已經(jīng)存在的實例,那么CJMediator將指示CJDeviceMgr和CJChannelMgr分別完成或釋放此類任務(wù);
(6)在處理來自J2534協(xié)議相關(guān)接口的請求后,調(diào)用流程將逆向進(jìn)行,參數(shù)需要被返回,并且函數(shù)的返回值需要被封裝,最后需要由RpcServer和J2534RpcInvoker完成拆解;
(7)負(fù)責(zé)RPC通信機(jī)制的類J2534RpcInvoker包含于J2534InjectDLL,其他則包含在Core模塊里。
Vehicle類屬于Core工程,類中的CVehicle、CBusNode和CDiagProtocol將被本模塊以外的軟件包所引用。
Vehicle類圖如圖7所示。
圖7 Vehicle類圖
主要內(nèi)容解釋如下:
(1)核心的處理類是CVehicle,并通過它給出了CBus和CECU。一個CBus(即某個車型的總線)是由多個CBusNode實例組成,同時一個CECU是由于多個CDiagProtocol實例組成;
(2)CBusNode是J2534模塊和Vehicle模塊通信的橋梁;
(3)CDiagProtocol帶有面向UI接口。
當(dāng)J2534通道從RPC接收到消息時,它將把消息推送到關(guān)聯(lián)在它身上的CBusNode上。
Vehicle消息處理時序過程如圖8所示。
圖8 Vehicle消息序列圖
對于所有消息都按照如下過程處理:
(1)CJChannel把消息放置到掛在它上面的CBusNode上(通過調(diào)用J2534Node);
(2)J2534Node把消息從診斷協(xié)議棧上層傳到底層(上層和底層根據(jù)ISO協(xié)議分層定義),每一個存在層均按照協(xié)議規(guī)范封裝消息(通常添加了報文頭和校驗碼),最后底層把消息傳到總線上(CBus的實例);
(3)CBus把它緩沖里的消息推送到其他CBusNode實例(這里為EcuSysNode);
(4)當(dāng)EcuSysNode的診斷協(xié)議棧底層接收到消息時,它把消息從底層往上層傳遞,每個協(xié)議棧中存在的協(xié)議層均按照協(xié)議解析消息(通常是遠(yuǎn)程報文頭和校驗碼);
(5)如果一條消息能夠在EcuSysNode的某一協(xié)議層中被處理,那么停止繼續(xù)向上層傳遞消息,當(dāng)前協(xié)議層將直接處理它并發(fā)送響應(yīng);如果消息不被診斷層以下的協(xié)議層處理,CDiagProtocol將接收下,并有機(jī)會去處理它。在處理后它會發(fā)送報文響應(yīng),響應(yīng)消息的處理路徑按從EcuSysNode到CBus,再到J2534Node,最后到CJChannel的流程運(yùn)轉(zhuǎn)。
協(xié)議棧每一層的命令處理流程如圖9所示。
圖9 每層中命令處理的活動圖
整幀的匹配操作有著最高優(yōu)先級,如果它在每個工作的層中被包含,那么對于接收到的每個消息,整幀將被首先進(jìn)行匹配。如果該消息沒有匹配已存在的任何命令,則該層將進(jìn)行下面的協(xié)議處理,如果發(fā)現(xiàn)相應(yīng)的響應(yīng)報文,則發(fā)送響應(yīng)報文。
CProtocolLayer類是消息的協(xié)議處理的基本定義,CProtocolLayer是一個抽象類,它沒有任何實例,一些方法被定義成純虛函數(shù)。
這些診斷協(xié)議類繼承自CDiagProtocol,主要診斷協(xié)議子類型如表1所示。
表1 繼承自CDiagProtocol類的診斷協(xié)議類
CHDC_CAN類—代表了ISO15765協(xié)議;CH9X類—代表了Honda系列協(xié)議;CKwp2000Diag類—代表了Keyword2000協(xié)議
本類繼承自CProtocolLayer,主要成員函數(shù)如表2所示。
表2 CNodeLayer類的主要成員函數(shù)
(1)CNodeLayer的實例是在協(xié)議棧的各層中,它有一個可選的上、下層,根據(jù)ISO下層提供服務(wù)給上層,所以每個CNodeLayer實例都有一個處理它下層的句柄,SetLayerDown()方法是被用來設(shè)置此類句柄;
(2)CNodeLayerBottom和CNodeLayerTop繼承自該類,它們組成了CBusNode中的協(xié)議棧里的各個診斷協(xié)議層,例如ISO/WD 15765協(xié)議則是基于CAN總線的Keyword2000協(xié)議,即該協(xié)議棧的數(shù)據(jù)鏈路層是ISO 11898-1 CAN協(xié)議,上層是由Keyword2000或UDS的應(yīng)用層移植而成[5];
(3)UpdateSend()和UpdateRecv()在主循環(huán)中被用于消息處理;
(4)PutIntoTXBuf()和GetFromRXBuf()是用于推動消息傳遞;
(5)Configure()采用一個具體的配置類來完成參數(shù)配置、定義和檢查配置參數(shù)的有效性。
CIso15765_2Layer和CKwp2000DLLayer兩個類繼承自CNodeLayer。
CIso15765_2Layer是ISO15765協(xié)議的網(wǎng)絡(luò)層。ISO/DIS 15765:1999年出臺ISO/DIS 15765(Diagnostics on CAN-based on KWP2000),該診斷標(biāo)準(zhǔn)是基于ISO 14230在CAN線上的擴(kuò)充,源于K線的診斷標(biāo)準(zhǔn)。其基本原理是把KWP2000的應(yīng)用層診斷服務(wù)移植到CAN總線,它的數(shù)據(jù)鏈路層采用ISO 11898-1[6]。
CKwp2000DLLayer是KWP2000的數(shù)據(jù)鏈路層。ISO 14230:ISO 14230于1999年出臺,該診斷標(biāo)準(zhǔn)基于K線,波特率為10.4 kb/s,用單線(K線)通信,也可用雙線(K線和L線)通信。ISO14230的頭格式不是固定的,有3或4個字節(jié),報文傳輸不用分包,最大可傳255個字節(jié)數(shù)據(jù),K線本質(zhì)上是一種半雙工串行通信總線[7]。
協(xié)議數(shù)據(jù)類型相關(guān)類是包含在命名空間ProtoDataType中,并且繼承自CBaseMgr。它們被用來作為CDiagProtocol實例的擴(kuò)展屬性。包含CBaseMgr在內(nèi),都是派生自CGarbagable類。
繼承自CBaseMgr類的協(xié)議數(shù)據(jù)類型如表3所示。
表3 繼承自CBaseMgr類的協(xié)議數(shù)據(jù)類型
CUintData—用于無符號整形數(shù)值屬性;CmdAndRes—用于整幀匹配;CDataList—用于診斷協(xié)議的數(shù)據(jù)模型
CMemBlock用于診斷協(xié)議的內(nèi)存模型。
數(shù)據(jù)驗證所使用的模擬器配置文件中A/C ECU的DID數(shù)值設(shè)置相關(guān)的版本信息部分如表4所示。
表4 模擬器配置文件中A/C ECU的DID數(shù)值設(shè)置——(讀取版本信息)
數(shù)據(jù)驗證所使用的模擬器配置文件中A/C ECU的DID數(shù)值設(shè)置相關(guān)的數(shù)據(jù)流部分如表5所示。
表5 模擬器配置文件中A/C ECU的DID數(shù)值設(shè)置——(讀數(shù)據(jù)流)
模擬器端數(shù)據(jù)驗證工作原理如下:ECU模擬器根據(jù)表4中的ECU版本信息構(gòu)造相關(guān)的DID(數(shù)據(jù)標(biāo)識符)版本數(shù)據(jù),根據(jù)表5中的數(shù)據(jù)換算公式構(gòu)造相關(guān)的DID數(shù)據(jù),并把構(gòu)造的測試數(shù)據(jù)寫入它的診斷數(shù)據(jù)配置文件DVP(自定義的文件格式)中。在ECU模擬器和DiagAnalyzer進(jìn)行診斷通信會話時,它將加載DVP文件中的診斷數(shù)據(jù),通過故障診斷儀軟件完成對ECU模擬器的測試。
診斷儀顯示的A/C ECU的DID數(shù)值設(shè)置相關(guān)的版本信息部分如表6所示。
表6 診斷儀顯示的A/C ECU的DID數(shù)值設(shè)置——(讀取版本信息)
診斷儀顯示的A/C ECU的DID數(shù)值設(shè)置相關(guān)的數(shù)據(jù)流部分如表7所示。
表7 診斷儀顯示的A/C ECU的DID數(shù)值設(shè)置——(讀數(shù)據(jù)流)
該ECU模擬器可以對所有采用了Keyword 2000和UDS診斷協(xié)議[8]的ECU進(jìn)行診斷數(shù)據(jù)的仿真,同時為了充分驗證程序的正確性,筆者采用了在北美地區(qū)銷售的斯巴魯某車型中的ECU集合進(jìn)行了驗證。測試DataManager所涉及的ECU集合如表8所示。
表8 測試DataManager所涉及的ECU集合
每個ECU所測試的內(nèi)容包括:DID數(shù)值設(shè)置(ECU版本號,軟硬件版本號等),顯示數(shù)據(jù)流,讀取和清除DTC故障碼等項目。經(jīng)過測試診斷結(jié)果顯示內(nèi)容與ECU模擬器中配置的故障碼的故障描述及故障信息在個數(shù)和內(nèi)容上完全一致,且診斷結(jié)果顯示內(nèi)容中的數(shù)據(jù)值不斷刷新顯示,即在執(zhí)行中連續(xù)讀取數(shù)據(jù),診斷結(jié)果相對ECU配置的數(shù)據(jù)值具有較高的精確度,因此讀取故障碼診斷功能實現(xiàn),且其診斷結(jié)果相對ECU模擬器的故障碼和數(shù)據(jù)流更準(zhǔn)確、可靠。
本研究開發(fā)了ECU模擬器及其與診斷儀通信接口,具有如下優(yōu)點:通過該模擬器,開發(fā)工程師只要在軟件的數(shù)據(jù)配置文件中根據(jù)故障診斷協(xié)議寫入各種診斷數(shù)據(jù),即可完成對特定車型診斷數(shù)據(jù)的開發(fā)和調(diào)試,只需要一臺PC機(jī)就可以完成汽車上各個ECU的診斷數(shù)據(jù)開發(fā);同時該ECU模擬器支持目前市場主流的故障診斷協(xié)議。另外,由于該ECU模擬器遵循J2534接口協(xié)議,可以和其他遵循該協(xié)議的故障診斷軟件進(jìn)行匹配和通信。
具體結(jié)論如下:
(1)該ECU模擬器支持UDS和Keyword2000等診斷協(xié)議,用戶只需要按照指定格式修改DVP配置文件即可實現(xiàn)新ECU診斷數(shù)據(jù)的加載;
(2)通過使用J2534Inject.dll,可以在電腦平臺上完成DiagAnalyzer故障診斷儀和ECU模擬器之間的診斷數(shù)據(jù)通信,省略了硬件轉(zhuǎn)換模塊;
(3)在模擬器的GUI操作界面上開發(fā)了多種數(shù)據(jù)展示和修改方式,可以提高工作效率;
(4)在一個被模擬的ECU上可以設(shè)置多個信號,并且給特定信號指定最大值、最小值、回包中所處的位置等。