文/吳效威 唐懷棟 喬海強 張臻 李茁
通常在CAN 通信程序開發(fā)過程中,開發(fā)人員經(jīng)常需要對程序進(jìn)行仿真及調(diào)試。一般情況下,開發(fā)人員通常會采用硬件USB 轉(zhuǎn)CAN板卡來進(jìn)行CAN 通信程序的仿真或調(diào)試工作。USB 轉(zhuǎn)CAN 板卡一般具備2 個CAN 口供開發(fā)人員使用,若通過在Windows 環(huán)境下編譯的CAN 通信應(yīng)用程序打開USB 轉(zhuǎn)CAN 的0或者1 通道,此時若需通過CANTest 應(yīng)用終端監(jiān)聽CAN 通信設(shè)備之間的報文,則會出現(xiàn)CANTest 應(yīng)用無法正常打開USB 轉(zhuǎn)CAN 設(shè)備的1 或0 通道現(xiàn)象出現(xiàn),該現(xiàn)象即應(yīng)用程序?qū)SB 轉(zhuǎn)CAN 設(shè)備操作的獨占性,仿真或調(diào)試過程中由此現(xiàn)象導(dǎo)致硬件資源出現(xiàn)浪費的現(xiàn)象時有發(fā)生 。
通常情況下,上述問題可通過2 塊USB轉(zhuǎn)CAN 設(shè)備并聯(lián)方案解決,但是對硬件資源產(chǎn)生了巨大的需求及浪費,經(jīng)濟(jì)性較差。理論上若應(yīng)用程序在使用CAN0 的同時使用CAN1充當(dāng)CAN Test 軟件,二者之間進(jìn)行報文交互,即可模擬應(yīng)用程序CAN 通信測試功能,但是在應(yīng)用程序中內(nèi)置CAN Test 軟件的功能,會造成應(yīng)用程序架構(gòu)的冗余,對程序的穩(wěn)定性和可靠性都會產(chǎn)生影響。
針對上述問題,本文提出了一種基于CAN 虛擬設(shè)備的方法,通過對CAN 虛擬設(shè)備制作及多CAN 設(shè)備及其通道自由連接方法的分析及研究,將虛擬CAN 接口函數(shù)和VC 界面相結(jié)合,開發(fā)了一種CAN 虛擬設(shè)備。在無USB 轉(zhuǎn)CAN 條件下,通過CAN 虛擬設(shè)備即可完成即可實現(xiàn)在編寫應(yīng)用程序的過程中對程序CAN 通信功能的測試,有效降低了測試環(huán)境搭建所需硬件資源及所需投入成本。
CAN 虛擬設(shè)備主要由操作界面部分和接口函數(shù)兩部分組成。
為了實現(xiàn)對多個CAN 設(shè)備及其通道進(jìn)行自由連接,需對CAN 虛擬設(shè)備操作界面進(jìn)行詳細(xì)設(shè)計。
如圖1所示,該操作界面共包含8 個CAN 設(shè)備,在操作界面的第一行表示,設(shè)備索引號從左到右依次是0 到7;每個CAN 設(shè)備均有2 個CAN 通道,從左到右的通道號分別是0 和1。其中黑框框起來的CAN 設(shè)備表示該設(shè)備已經(jīng)被其他程序打開,CAN 通道變成黃色表示該通道已經(jīng)完成比特率和濾波等參數(shù)設(shè)置,白色表示未設(shè)置。CAN 通道下面延伸出的黑色、灰色的豎線,表示CAN 通道的狀態(tài)。如圖所示,索引0 的通道0,以及索引1 的通道0,下部均延伸出雙黑線,表示0 通道已經(jīng)正常打開,可以進(jìn)行正常發(fā)送和接收;索引2 的通道0,下面延伸出單黑線,表示該通道設(shè)置為“只聽”模式,可以進(jìn)行接收,但無法進(jìn)行發(fā)送,也無法對收到的報文進(jìn)行回應(yīng);其他通道都是雙灰線,表示無應(yīng)用程序使用。
界面的主體有大量的彩色、黑色的雙橫線,以及處在橫豎線交叉點上的指示塊,指示塊的顏色與所在的雙橫線顏色保持一致。彩色的雙橫線共8 條,若各通道對應(yīng)的指示塊均落在同一根彩線上,表示的上述通道是相連的,并且該條線上所有指示塊之間的連線為了單條粗實線表示;黑色的雙橫線共1 條,各通道對應(yīng)的指示塊若落在黑色雙橫線上時表示通道為鎖死狀態(tài)(既不能自發(fā)自收,也不和其他通道相連)。另外,若出現(xiàn)一條彩線上只有1 個指示塊的時,表示與該指示塊對應(yīng)的通道是孤立的(可以自發(fā)自收,但與其他通道不相連)[3]。
根據(jù)上述界面可知,共提供了8 個CAN虛擬設(shè)備,共計16 個CAN 通道,每個CAN網(wǎng)絡(luò)至少需要2 個CAN 通道,所以我們通過上述8 條雙橫線上各通道對應(yīng)指示塊的組合即可實現(xiàn)這16 個CAN 通道進(jìn)行任意的連接組合,針對需要孤立的通道,可通過將其對應(yīng)的指示塊與黑色雙橫線連接即可。
針對調(diào)試過程中出現(xiàn)主動停止調(diào)試,或者程序崩潰等現(xiàn)象,均可導(dǎo)致設(shè)備被永久占用,界面設(shè)計時提供一個解鎖功能,通過鼠標(biāo)點擊界面的第一行任何一個設(shè)備,即可以解除占用。上述操作界面只允許出現(xiàn)一個,因此檢測到新程序后,舊程序自動退出。完成操作界面之后,生成的程序命名為
“connect_can.exe”。
為了實現(xiàn)報文收發(fā),需要編寫動態(tài)庫,并提供接口庫函數(shù),共計14 個,其中大部分函數(shù)作用均為實現(xiàn)對CAN 設(shè)備的控制,譬如開關(guān)狀態(tài)的轉(zhuǎn)換、比特率設(shè)置和濾波設(shè)置等,僅需對參數(shù)合法性驗證簡單處理即可。VCI_Transmit 為核心庫函數(shù),該函數(shù)發(fā)出的報文可由VCI_GetReceiveNum,VCI_ClearBuffer,VCI_Receive 來處理。每個通道均具有相對應(yīng)的接收緩沖區(qū),從而實現(xiàn)將報文從其中一個CAN 通道傳遞至其他CAN 通道。虛擬CAN的各個函數(shù),不僅需支持進(jìn)程內(nèi)部的多線程操作,而且需要支持跨越多個進(jìn)程之間的操作。為了便于操作,可采用進(jìn)程間共享內(nèi)存的方式,對緩沖區(qū)進(jìn)行操作。發(fā)送函數(shù)需獲得與之相連接的設(shè)備及其設(shè)置參數(shù)方可實現(xiàn)發(fā)送功能。操作界面和動態(tài)庫之間需通過內(nèi)存共享來實現(xiàn)數(shù)據(jù)共享。不論多線程或者單線程,為了確保線程安全,對緩沖區(qū)的操作前需進(jìn)行加鎖設(shè)置,操作完成后解鎖,防止出現(xiàn)多個線程同時對同一個緩沖區(qū)操作導(dǎo)致的非法狀態(tài),可采用標(biāo)準(zhǔn)庫中的標(biāo)準(zhǔn)原子操作實現(xiàn)加鎖操作。
針對發(fā)送函數(shù),主要需作如下處理:
(1)必須對參數(shù)進(jìn)行驗證,任何一個參數(shù)無效均返回0,表示失敗。
(2)確定設(shè)備是否已經(jīng)打開、通道是否已經(jīng)掛在彩色的雙橫線上、通道是否已經(jīng)初始化、通道是否工作于非只聽模式、通道是否已經(jīng)打開,其中任何一個不滿足,均返回0。鑒于函數(shù)均有返回值,在通過上述驗證工作后,通過變量(初始值為0)對成功發(fā)送的報文數(shù)量進(jìn)行計數(shù),對所有CAN 通道進(jìn)行遍歷,并對每個CAN 通道進(jìn)行相應(yīng)處理。對于每一條報文,都要定義一個發(fā)送成功標(biāo)志,這個標(biāo)志初始值為假,然后遍歷各個目標(biāo)通道。遍歷目標(biāo)通道時,首先對發(fā)送方和遍歷目標(biāo)進(jìn)行比較:對于不是“自發(fā)自收”類型的報文,發(fā)送方和遍歷目標(biāo)不同,才能通過;反過來,對于是“自發(fā)自收”類型的報文,只有發(fā)送方和遍歷目標(biāo)一致,才能通過。對遍歷目標(biāo)繼續(xù)判斷:它所在的設(shè)備必須已經(jīng)打開;通道必須已經(jīng)初始化并打開;必須掛在和發(fā)送方相同顏色的雙橫線上;它的比特率必須與發(fā)送方的一致。接下來要討論目標(biāo)的運行模式,是正常模式還是只聽模式。不論是什么模式,都只是影響發(fā)送成功標(biāo)志,而不會影響對方的接收。對正常模式,將發(fā)送成功標(biāo)置為真。然后不論是正常模式還是只聽模式,都可以進(jìn)行后續(xù)處理。
圖1:CAN 虛擬設(shè)備操作界面
圖2:默認(rèn)連接方式
(3)進(jìn)行接收方的驗收濾波處理。驗收通過后數(shù)據(jù)存入目標(biāo)的緩沖區(qū),驗收不通過放棄數(shù)據(jù)。不論驗收是否通過,對之前的發(fā)送成功標(biāo)志均無影響。對緩沖區(qū)的操作前需進(jìn)行加鎖處理,完成后進(jìn)行解鎖。一般情況下,緩沖區(qū)的容量均有限,若在緩沖區(qū)存儲已滿下仍繼續(xù)接受報文,則易產(chǎn)生數(shù)據(jù)丟幀現(xiàn)象??刹捎脠笪淖钚率盏降臄?shù)據(jù),丟棄歷史數(shù)據(jù)的處理方法進(jìn)行處理。當(dāng)全部目標(biāo)遍歷完成后,即可對報文的發(fā)送成功標(biāo)志位進(jìn)行置位:若標(biāo)志位為假,程序直接終止后續(xù)處理,直接返回發(fā)送成功報文數(shù)量;若標(biāo)志位為真,報文發(fā)送成功數(shù)量自加1。
該程序的核心是對報文傳遞的驗證操作,在實現(xiàn)上述14 個接口函數(shù)后,生成動態(tài)庫“virtual_can.dll”。
當(dāng)使用虛擬CAN 時,將動態(tài)庫“virtual_can.dll”重新命名為“controlcan.dll”,并放置在與應(yīng)用程序相同的路徑下,替換掉原來的同名文件。在Debug 模式下使用虛擬CAN,在Release 模式下使用USBCAN,僅需設(shè)置好各自的工作目錄即可,同時將“virtual_can.dll”改名為“controlcan.dll”的動態(tài)庫放置在Debug 模式的工作目錄中,將“usbcan.dll”改名為“controlcan.dll”的動態(tài)庫放置在Release模式的工作目錄中。完成上述操作即可實現(xiàn)“VCI_USBCAN2”在應(yīng)用程序中的設(shè)備類型中的統(tǒng)一使用。
對于CAN Test 工具,則需要對工具下的配置文件進(jìn)行修改處理。如上所述,首先為工具的安裝路徑下的“cfg.ini”文件,該文件會影響界面的菜單。改完之后保存;然后打開安裝路徑下的“kerneldlls”目錄,將制作好的“virtual_can.dll”動態(tài)庫復(fù)制到該目錄下;最后修改這個目錄下的“kerneldll.ini”文件,修改完成后保存。
將“connect_can.exe”文件放置在任意路徑中即可,打開這個文件即可顯示操作界面。為了使用者方便,該界面默認(rèn)狀態(tài)下的連接方式如圖2所示。
打開CAN Test 軟件,點擊“選擇設(shè)備”按鈕,即可看到虛擬CAN 的菜單項了,打開之后即可進(jìn)行正常使用。
另外,根據(jù)圖2所示默認(rèn)連接方式,用戶也可通過直接打開應(yīng)用程序和CAN Test 軟件方式來使用虛擬CAN 設(shè)備。用戶可以隨時打開操作界面,對連接方式進(jìn)行修改,也可以隨時關(guān)閉操作界面,以節(jié)省打開窗口的數(shù)量。與虛擬CAN 有關(guān)的所有進(jìn)程,包括操作界面、使用到虛擬CAN 的應(yīng)用程序、使用到虛擬CAN 的CAN Test 軟件,全部關(guān)閉之后,共享內(nèi)存會由操作系統(tǒng)釋放,因此連接方式的配置會消失,重新打開后會恢復(fù)默認(rèn)連接方式。
打開4 個CAN Test 軟件界面,每個界面下打開2 塊虛擬CAN,每個虛擬CAN 的兩個通道都打開,然后在操作界面 將全部的16 個通道連接在一起,每個通道連續(xù)發(fā)送10 萬條報文,同時發(fā)送不會丟幀,每個通道都收到了150 萬條報文。
本文針對Windows 操作系統(tǒng)環(huán)境下采用USB 轉(zhuǎn)CAN 設(shè)備進(jìn)行應(yīng)用程序CAN 通信測試存在的一些問題,提出了一種CAN 虛擬設(shè)備設(shè)計及測試方法。通過CAN 虛擬設(shè)備,在無需USB 轉(zhuǎn)CAN 輔助硬件設(shè)備條件下即可實現(xiàn)對Windows 操作系統(tǒng)環(huán)境下編譯的應(yīng)用程序CAN 通信功能測試,實驗結(jié)果再次表明了該方法的有效性和可行性。該方法減少了搭建硬件測試環(huán)境工作量,有效降低了測試所需的硬件成本,具備較好的經(jīng)濟(jì)性。