黃利權,趙治國
(同濟大學 汽車學院,上海 201804)
當今汽車因裝配諸多的電控單元(electric control unit, ECU)而帶來的電控系統維修困難,而汽車故障診斷儀則用于檢測汽車上安裝的ECU出現各種軟、硬件故障,故障診斷儀和汽車上各個ECU的診斷模塊進行通信,讀取ECU記錄的各種故障數據和內容信息,控制ECU完成特定的動作測試程序。現有的開發平臺通過以下兩種形式來調試和驗證各種診斷數據的正確性:(1)手持式診斷儀和PC機上的ECU軟件模擬器進行通信;(2)手持式診斷儀和實驗室內臺架上的ECU軟件模擬器進行通信。因為這兩種開發模式需要操作手持式診斷儀,而當診斷內容開發工程師在處理數量巨大的診斷數據時,繁瑣且慢速的儀器操作會導致開發效率的低下,需要設計可以在同一臺PC機上運行故障診斷軟件和ECU模擬器的解決方案,通過該ECU模擬器可以對故障診斷儀進行診斷數據的離線仿真。
另外,根據ISO15765規范,PC機上的應用軟件可以利用J2534 API作為訪問Pass-thru(故障診斷儀在PC機上的工作模塊,在本文中代表了在PC機上運行的診斷軟件)設備驅動程序的接口。該協議包括J2534-1、J2534-2和J2534-3等3個部分。其中J2534-1定義了用于對發動機電控單元排放相關模塊再編程的API接口,這些接口不僅可以用于再編程,也可以用于其他的功能目標[1]。通過這些API接口應用程序可以控制Pass-thru設備,也可以控制Pass-thru設備和車輛之間的通信。Pass-thru設備不需要解釋所傳輸消息的內容,它允許任何的消息策略和消息結構被使用,只要它們能夠被應用程序和ECU所理解。J2534相關的API接口類型如下:通信建立和斷開,消息讀寫,啟動和停止周期性消息,設置可編程電壓,啟動和關閉消息過濾器,讀取版本信息和取得Last Error等操作[2]。
為了測試特定車型的診斷數據,筆者進一步開發了同樣能在PC機上運行的ECU模擬器,只需在配置文件中修改虛擬ECU的診斷數據,就可以在診斷儀和ECU之間建立通信,實現在一臺電腦上通過J2534診斷協議來完成故障診斷的數據驗證。
ECU模擬器模塊如圖1所示。

圖1 ECU模擬器模塊
ECU模擬器包括MainExcutable、Core和J2534InjectDll 3個模塊。各模塊功能如下:
(1)MainExcutable模塊把操作接口和高級功能提供給了用戶,并在Core模塊提供功能的基礎上升級而成;
(2)Core模塊完成了主要的接口模擬工作,處理來自于MainExcutable和J2534InjectDll的請求;
(3)J2534InjectDll模塊把來自于故障診斷儀的調用推送給Core,并把來自于Core的響應推送給故障診斷儀。
模塊結構圖如圖2所示。

圖2 模塊結構圖
模擬器操作界面模塊UI分別調用了Log模塊、Vehicle模塊和高級DataView修改模塊,用于顯示和編輯診斷通信數據。而J2534模塊則通過Vehicle模塊取得車輛診斷協議配置信息和ECU相關的診斷模擬數據,用于和故障診斷儀的相應API接口通信。
J2534Inject.dll模塊經過Windows操作系統注冊后就能夠被J2534應用程序所識別。J2534應用程序首先加載J2534Inject.dll,然后映射到它自己的地址空間,最后調用J2534Inject.dll中的J2534接口函數來完成診斷通信。
模擬器接口方案采用的雙進程模型如圖3所示。

圖3 雙進程模型
其把模擬器從J2534應用程序中隔離出來。J2534Inject.dll駐留在以J2534為基礎的診斷軟件中,模擬器有它獨立的進程。兩個進程通過Windows RPC進行信息交換。
模擬器模塊運行成一個獨立的進程,并構建了J2534Inject.dll用于提供J2534接口,因為該DLL在故障診斷儀的上下文中運行,需要使用IPC(進程間數據交換)通信機制,當前IPC沒有選擇共享內存機制,而是使用了基于RPC(遠程過程調用,即兩個程序間通過傳輸協議進行通信)的IPC[3]。本研究采用該機制使得開發更容易,不需要擔心進程間通信的技術問題,而是讓操作系統來完成該項工作,開發人員只需要把它視為本地調用即可。另外當通信發生在相同的物理機器上時,RPC可以通過配置來使用LPC(本地過程調用)方法完成消息推送。
傳統的ECU模擬器方案中手持式診斷儀和PC機上的ECU軟件模擬器進行通信,有如下的缺點:手持式診斷儀在操作時數據顯示有一定延遲,且診斷內容開發工程師需要在儀器和PC機電腦之間反復切換操作,另外ECU模擬器和手持式診斷儀之間的通信需要有接線盒以及USB轉接板等設備,在調試時有時會因為通信鏈路存在問題而需要排查原因。而采用了J2534診斷協議后,則可以完全避免以上問題。同時也可以通過開發腳本程序把診斷數據按照指定格式直接轉化為該ECU模擬器的數據配置文件,用于診斷通信。
軟件模擬器UML用例圖如圖4所示。

圖4 UML用例圖
診斷應用角色代表了診斷儀,而用戶角色則代表了ECU模擬器操作者。診斷儀中的“J2534通信”用例和“車輛協議模擬”用例通過IPC機制進行通信。同時模擬器的功能用例(整幀匹配、數據瀏覽和修改和消息日志)是依賴于“車輛協議模擬”用例來實現的。而“整幀匹配功能”用例則將匹配結果反饋給模擬器操作者。最后“配置”用例不同,則“車輛協議模擬”用例對應不同的診斷協議,即向操作者提供不同的協議模擬功能。
用例向診斷工具提供了一個含有J2534接口的J2534Inject.dll。診斷工具加載該DLL,并通過它和模擬器進行通信。J2534Inject.dll必須遵循J2534標準。
因為該模擬器和J2534Inject.dll并不在同一個進程中,必須有一種機制來完成模擬器和該DLL之間的IPC通信。IPC機制使得診斷工具可以像調用自己的內部函數一樣調用程序。
因為類J2534RpcInvoker包含在J2534InjectDll里,含有該類的文件應該被加入J2534InjectDll的工程,而其他類屬于Core工程。
J2534軟件包中的診斷儀接口需要遵循J2534標準。該軟件包包含了用于通信的車輛程序接口和由診斷儀引發的J2534工作日志。
J2534類圖如圖5所示。

圖5 J2534類圖
其中,通信信道管理器CJChannelMgr中包含了多個信道CJChannel,而每個信道則由若干個消息濾波管理器CJMsgFilterMgr所組成。同時每個信道CJChannel依賴于帶有垃圾回收功能的總線節點類CBusNode,總線節點是由相關診斷協議棧構成,而協議棧中不同層(物理層、數據鏈路層、網絡層和應用層)由不同類型的診斷協議所組合而成[4]。另外CJChannel則負責主要的J2534通信,即負責收發消息并調用消息過濾管理器。它把類似J2534協議的請求轉化為了內部的一些協議和數據組織方式。設備管理器CJDeviceMgr由多個CJDevice所組成,CJDevice目前主要代表了故障診斷儀模型,它記錄了引腳和相關的電壓信息。
CJMediator繼承自J2534Invoker,實現了J2534協議中包含的API接口,并且負責調度消息濾波管理器CJMsgFilterMgr,信道CJChannel,設備管理器CJDeviceMgr和設備CJDevice。
J2534序列圖如圖6所示。

圖6 J2534序列圖
當診斷應用發起一個設備相關的調用時,完成如下工作:
(1)在J2534InjectDll中,J2534接口的調用工作將被派遣給J2534RpcInvoker,它也有類似于J2534的成員函數;
(2)J2534RpcInvoker封裝了診斷應用發過來的參數,然后再發送給RPC接口;
(3)在模擬器的處理流程中,當接收到一個來自于RPC客戶端的消息時,類RpcServer代表的監聽線程將被喚醒用于處理RPC調用;
(4)RpcServer拆開接收到的參數,然后把它們轉發給含有類似于J2534協議相關成員函數的CJMediator;
(5)CJMediator解釋了J2534協議相關的接口并調用了CJChannel和CJDevice實例提供的方法,如果需要創建一個新的實例,或者需要釋放一個已經存在的實例,那么CJMediator將指示CJDeviceMgr和CJChannelMgr分別完成或釋放此類任務;
(6)在處理來自J2534協議相關接口的請求后,調用流程將逆向進行,參數需要被返回,并且函數的返回值需要被封裝,最后需要由RpcServer和J2534RpcInvoker完成拆解;
(7)負責RPC通信機制的類J2534RpcInvoker包含于J2534InjectDLL,其他則包含在Core模塊里。
Vehicle類屬于Core工程,類中的CVehicle、CBusNode和CDiagProtocol將被本模塊以外的軟件包所引用。
Vehicle類圖如圖7所示。

圖7 Vehicle類圖
主要內容解釋如下:
(1)核心的處理類是CVehicle,并通過它給出了CBus和CECU。一個CBus(即某個車型的總線)是由多個CBusNode實例組成,同時一個CECU是由于多個CDiagProtocol實例組成;
(2)CBusNode是J2534模塊和Vehicle模塊通信的橋梁;
(3)CDiagProtocol帶有面向UI接口。
當J2534通道從RPC接收到消息時,它將把消息推送到關聯在它身上的CBusNode上。
Vehicle消息處理時序過程如圖8所示。

圖8 Vehicle消息序列圖
對于所有消息都按照如下過程處理:
(1)CJChannel把消息放置到掛在它上面的CBusNode上(通過調用J2534Node);
(2)J2534Node把消息從診斷協議棧上層傳到底層(上層和底層根據ISO協議分層定義),每一個存在層均按照協議規范封裝消息(通常添加了報文頭和校驗碼),最后底層把消息傳到總線上(CBus的實例);
(3)CBus把它緩沖里的消息推送到其他CBusNode實例(這里為EcuSysNode);
(4)當EcuSysNode的診斷協議棧底層接收到消息時,它把消息從底層往上層傳遞,每個協議棧中存在的協議層均按照協議解析消息(通常是遠程報文頭和校驗碼);
(5)如果一條消息能夠在EcuSysNode的某一協議層中被處理,那么停止繼續向上層傳遞消息,當前協議層將直接處理它并發送響應;如果消息不被診斷層以下的協議層處理,CDiagProtocol將接收下,并有機會去處理它。在處理后它會發送報文響應,響應消息的處理路徑按從EcuSysNode到CBus,再到J2534Node,最后到CJChannel的流程運轉。
協議棧每一層的命令處理流程如圖9所示。

圖9 每層中命令處理的活動圖
整幀的匹配操作有著最高優先級,如果它在每個工作的層中被包含,那么對于接收到的每個消息,整幀將被首先進行匹配。如果該消息沒有匹配已存在的任何命令,則該層將進行下面的協議處理,如果發現相應的響應報文,則發送響應報文。
CProtocolLayer類是消息的協議處理的基本定義,CProtocolLayer是一個抽象類,它沒有任何實例,一些方法被定義成純虛函數。
這些診斷協議類繼承自CDiagProtocol,主要診斷協議子類型如表1所示。

表1 繼承自CDiagProtocol類的診斷協議類
CHDC_CAN類—代表了ISO15765協議;CH9X類—代表了Honda系列協議;CKwp2000Diag類—代表了Keyword2000協議
本類繼承自CProtocolLayer,主要成員函數如表2所示。

表2 CNodeLayer類的主要成員函數
(1)CNodeLayer的實例是在協議棧的各層中,它有一個可選的上、下層,根據ISO下層提供服務給上層,所以每個CNodeLayer實例都有一個處理它下層的句柄,SetLayerDown()方法是被用來設置此類句柄;
(2)CNodeLayerBottom和CNodeLayerTop繼承自該類,它們組成了CBusNode中的協議棧里的各個診斷協議層,例如ISO/WD 15765協議則是基于CAN總線的Keyword2000協議,即該協議棧的數據鏈路層是ISO 11898-1 CAN協議,上層是由Keyword2000或UDS的應用層移植而成[5];
(3)UpdateSend()和UpdateRecv()在主循環中被用于消息處理;
(4)PutIntoTXBuf()和GetFromRXBuf()是用于推動消息傳遞;
(5)Configure()采用一個具體的配置類來完成參數配置、定義和檢查配置參數的有效性。
CIso15765_2Layer和CKwp2000DLLayer兩個類繼承自CNodeLayer。
CIso15765_2Layer是ISO15765協議的網絡層。ISO/DIS 15765:1999年出臺ISO/DIS 15765(Diagnostics on CAN-based on KWP2000),該診斷標準是基于ISO 14230在CAN線上的擴充,源于K線的診斷標準。其基本原理是把KWP2000的應用層診斷服務移植到CAN總線,它的數據鏈路層采用ISO 11898-1[6]。
CKwp2000DLLayer是KWP2000的數據鏈路層。ISO 14230:ISO 14230于1999年出臺,該診斷標準基于K線,波特率為10.4 kb/s,用單線(K線)通信,也可用雙線(K線和L線)通信。ISO14230的頭格式不是固定的,有3或4個字節,報文傳輸不用分包,最大可傳255個字節數據,K線本質上是一種半雙工串行通信總線[7]。
協議數據類型相關類是包含在命名空間ProtoDataType中,并且繼承自CBaseMgr。它們被用來作為CDiagProtocol實例的擴展屬性。包含CBaseMgr在內,都是派生自CGarbagable類。
繼承自CBaseMgr類的協議數據類型如表3所示。

表3 繼承自CBaseMgr類的協議數據類型
CUintData—用于無符號整形數值屬性;CmdAndRes—用于整幀匹配;CDataList—用于診斷協議的數據模型
CMemBlock用于診斷協議的內存模型。
數據驗證所使用的模擬器配置文件中A/C ECU的DID數值設置相關的版本信息部分如表4所示。

表4 模擬器配置文件中A/C ECU的DID數值設置——(讀取版本信息)
數據驗證所使用的模擬器配置文件中A/C ECU的DID數值設置相關的數據流部分如表5所示。

表5 模擬器配置文件中A/C ECU的DID數值設置——(讀數據流)
模擬器端數據驗證工作原理如下:ECU模擬器根據表4中的ECU版本信息構造相關的DID(數據標識符)版本數據,根據表5中的數據換算公式構造相關的DID數據,并把構造的測試數據寫入它的診斷數據配置文件DVP(自定義的文件格式)中。在ECU模擬器和DiagAnalyzer進行診斷通信會話時,它將加載DVP文件中的診斷數據,通過故障診斷儀軟件完成對ECU模擬器的測試。
診斷儀顯示的A/C ECU的DID數值設置相關的版本信息部分如表6所示。

表6 診斷儀顯示的A/C ECU的DID數值設置——(讀取版本信息)
診斷儀顯示的A/C ECU的DID數值設置相關的數據流部分如表7所示。

表7 診斷儀顯示的A/C ECU的DID數值設置——(讀數據流)
該ECU模擬器可以對所有采用了Keyword 2000和UDS診斷協議[8]的ECU進行診斷數據的仿真,同時為了充分驗證程序的正確性,筆者采用了在北美地區銷售的斯巴魯某車型中的ECU集合進行了驗證。測試DataManager所涉及的ECU集合如表8所示。

表8 測試DataManager所涉及的ECU集合
每個ECU所測試的內容包括:DID數值設置(ECU版本號,軟硬件版本號等),顯示數據流,讀取和清除DTC故障碼等項目。經過測試診斷結果顯示內容與ECU模擬器中配置的故障碼的故障描述及故障信息在個數和內容上完全一致,且診斷結果顯示內容中的數據值不斷刷新顯示,即在執行中連續讀取數據,診斷結果相對ECU配置的數據值具有較高的精確度,因此讀取故障碼診斷功能實現,且其診斷結果相對ECU模擬器的故障碼和數據流更準確、可靠。
本研究開發了ECU模擬器及其與診斷儀通信接口,具有如下優點:通過該模擬器,開發工程師只要在軟件的數據配置文件中根據故障診斷協議寫入各種診斷數據,即可完成對特定車型診斷數據的開發和調試,只需要一臺PC機就可以完成汽車上各個ECU的診斷數據開發;同時該ECU模擬器支持目前市場主流的故障診斷協議。另外,由于該ECU模擬器遵循J2534接口協議,可以和其他遵循該協議的故障診斷軟件進行匹配和通信。
具體結論如下:
(1)該ECU模擬器支持UDS和Keyword2000等診斷協議,用戶只需要按照指定格式修改DVP配置文件即可實現新ECU診斷數據的加載;
(2)通過使用J2534Inject.dll,可以在電腦平臺上完成DiagAnalyzer故障診斷儀和ECU模擬器之間的診斷數據通信,省略了硬件轉換模塊;
(3)在模擬器的GUI操作界面上開發了多種數據展示和修改方式,可以提高工作效率;
(4)在一個被模擬的ECU上可以設置多個信號,并且給特定信號指定最大值、最小值、回包中所處的位置等。