朱 旭
(中國航發西安動力控制科技有限公司,陜西 西安 710077)
CAN(Controller Area Network,控制器局域網絡)總線是20 世紀80 年代提出的一種串行數據通訊總線,已在包括航空工業在內的眾多領域中得到廣泛應用[1]。在航空發動機測試、使用過程中,通常需要針對CAN 設備進行二次開發,用于與各設備間的數據傳輸。二次開發的應用軟件將人機交互程序分為應用層與驅動層,見圖1。驅動程序負責操控設備的相關信息,應用程序負責功能實現。
目前在市場上存在多品牌、多種類的CAN 通訊設備,盡管不同品牌的CAN 通訊設備功能一樣,但每個設備的原理、使用方法卻不盡完全相同,導致使用者(二次開發者)在使用過程中,針對各類設備的二次開發,需配合不同應用程序,這樣會影響生產效率,甚至容易導致出錯。本文提出一種利用C#工具開發驅動程序方法,在應用程序中添加后,只提供同一接口給應用層調用。因此當使用不同設備后,只需在驅動層中添加或更改相應模塊,不會影響應用層功能,在降低程序開發復雜度的同時提高了二次開發程序的通用性。
本文在VS2010 工具下完成C#程序開發工作[2]。采用面向對象技術,將所有CAN 通訊設備歸結為一個類,作為基類。每個CAN 設備看成一個基類的派生類,這樣,派生類擁有基類的特性。再將特定的方法和屬性組合,封裝為一個特定功能集合(稱為接口),每個實例的具體內容在其接口中進行定義實現[3-4]。
基類完成共同功能的設計,將基類設定為抽象類,每個設備作為一實例,派生于基類。這樣每個實例就擁有了基類的屬性和方法,各實例的不同功能在實例的接口中分別具體實現,針對不同情況,做出適應性更改。這樣既滿足了相同功能的一致性,又達到不同設備靈活使用的現實需求。
上位機程序設計分為驅動層和應用層兩個部分。驅動層主要用于配置設備參數,使其能夠正常通訊。針對使用設備進行類的實例化,繼承基類的共有屬性和方法,完成共同狀態的配置。對于具體功能方法,需要引用不同接口,在接口中進行定制化和個性化的詳細功能實現。在驅動層通過基類和接口完成不同設備的驅動,同時為應用層提供了相同的入口參數。應用層接受驅動層傳遞的數據,進過分析、識別判斷,完成最終程序的功能,如數據物理量的轉換、顯示。在此只考慮與驅動接口的數據類型和格式是否一致,不需關心驅動層的設備類型。
按照上述設計思路,UML表示法如下頁圖2 所示。

圖2 軟件架構UML 圖
本文通過CAN 通訊卡實現上位機和嵌入式控制器之間的數據交互,從而對控制器中相應內容進行管理、更改、維護。如下頁圖3 所示,上位機的人機界面發送指令到控制器,控制器接受到指令,先判斷格式是否正確,然后按照通訊協議,分析出指令的具體內容,執行相應動作,完成后反饋信號或發送數據到上位機,以通知其執行結果。上位機接收到數據,同樣要進行數據的甄別、判斷,若正確則將結果顯示于界面,提示用戶執行結果。

圖3 系統框圖
假設整個系統中使用了2 種不同品牌的CAN 通訊卡,對于用戶而言,接入任意設備,其使用方法應完全一致。
在進入程序時,如圖4 所示,首先在人機界面選擇設備類型。后續進入主程序時根據之前的選擇自動完成設備初始化工作,并在主界面提示設備狀態。初始化完成后根據指令,進行數據傳輸和發送等功能,并將數據解析的結果顯示在程序主界面。如圖5 所示。

圖4 初始化界面

圖5 程序主界面
設備1、2 分別提供不同的動態鏈接文件,完成各自的驅動和功能實現。
每種設備的提供的動態鏈接文件格式和使用方法都不一樣,因此,在驅動設計時,將2 個設備分別定義為DevCan1、DevCan2 類,根據使用情況進行選擇,然后實例化對象,在實例化時將抽象類的虛方法進行重寫。
首先,定義一個抽象基類DevClass。類定義包含ID、波特率、數據格式等字段,用以配置使用環境。基類方法包括InitialCan()和CloseCan()方法,這兩個方法用于設備初始化和關閉。在函數內分別各自調用原廠家提供的動態鏈接庫實現。再次,定義2 個接口,分別為發送數據ISendMessage、接收數據IRec-Data 函數。每個接口實現函數的返回值一致(例如,0表示失敗,1 表示成功)。因此,同樣結果對應用層處理邏輯就是一致的。
若使用設備1,則實例化對象設備1,并繼承于基類,支持發送、接收2 個接口。在發送和接收過程中,將待發送和接收的數據存放于數組中,供應用層調配。
同理,若使用設備2,則實例化設備2,并完成相應配置。
下面以初始化為例,具體實現代碼如下:

應用層與驅動層的數據交互采用共享數組的方式。驅動層完成設備驅動后,將事件和所需數據整理后,傳遞到應用層。應用層負責接收、響應事件,并解析、處理數據。在主程序中定義委托,將方法封裝在委托對象內,實現傳遞回調函數的作用,多個委托可以完成多種事件的訂閱,事件訂閱對于使用的設備可不必關心。程序中將接收和發送數據事件分別定義,具體代碼(以設備1 為例)如下:

在應用層建立2 個線程,分別用于接收數據、發送指令,各線程獨立工作,互不影響,從而提高程序的執行效率。線程中處理委托中的訂閱事件,執行相應操作,實現數據交換和通訊功能。程序架構如圖6所示。

圖6 程序架構
本文設計了針對不同CAN 通信設備的通用上位機應用程序,在同一應用程序中,利用接口和類完成不同設備的驅動,為應用層提供數據和事件。應用層只負責事件和數據處理,與驅動的設備無關,應用層針對不同設備的事件處理邏輯一致。在實際使用中,新增設備只需進行驅動部分的設計,完成對應接口的功能,就能直接使用,這樣能夠快速開發完成程序,提高通用性,縮短了開發周期。經過試驗驗證,此方法能夠有效、正確實現多設備同時驅動的目標。