時間:2023-03-02 15:08:39
引言:易發表網憑借豐富的文秘實踐,為您精心挑選了九篇驅動程序設計范例。如需獲取更多原創內容,可隨時聯系我們的客服老師。
關鍵詞:wince 驅動程序;開發;設計
1 引言
WINCE和Windows 98或Windows 2000不同,它可以工作在12種不同的處理器體系結構、180余種CPU上;同時,WINCE是一個實時操作系統(實時系統的意義就是輸入的指令不必進入隊列就可以馬上處理,過去我們使用的DDS就是實時系統),可以滿足應用程序所需要的實時性要求。
Windows CE的模塊化設計使得它能夠在大量的平臺上定制使用,從客戶電子設備到專用的工業控制器。由于它是模塊化的,因而我們可以使用滿足平臺系統需求的最小軟件模塊和組件集合來設計嵌入式系統平臺,從而使內存用量最小,但最大可能地提高操作系統的性能。因此外圍擴展設備就必須要有硬件驅動才能正常工作。
和其它的操作系統一樣,Windows CE也提供設備驅動軟件,這些軟件的目的是驅動內部和外圍的硬件設備,或為它們提供接口。設備驅動程序將操作系統和設備鏈接起來,使得操作系統能夠識別設備或者為應用程序提供設備服務。
Windows CE支持廣泛的基于各種CE平臺的設備驅動程序。也提供一些用于驅動程序開發的模型(model) ,其中包括來自其它操作系統的驅動程序模型(model),因為這些豐富多變的驅動程序模型, Windows CE適應大部分的內部和外圍設備口Microsoft Windows CE設備驅動程序工具包配備了文檔資料,這些文檔資料使得你能夠為Windows CE創建設備驅動程序。目前,Windows CE提供了四種設備模型,其中兩種是專用于Windows CE的模型,另外兩種外部模型來自其它操作系統。
2 驅動程序開發簡介
2.1 開發工具
Windows CE驅動可以使用Platform Builder或者Visual Studio開發,但是開發人員一般都使用Platform Builder開發設備驅動程序,對于部分驅動也會使用Visual Studio開發,應用程序開發人員更多的使用Visual Studio開發驅驅動程序。作為BSP(Board Support Package)的一部分進行整體編譯開發。
2.2 驅動分類
2.2.1 按加載方式和接口類型分類
1) 本機驅動程序(Built-In Drivers)
通常由GWES加載,驅動接口一般都是定制的(Custom Purpose)。
2) 流驅動程序(Stream Drivers)
通常由Device Manager加載,驅動接口是標準的流式接口。
3) 混和型驅動程序
同時有定制式和流驅動兩套驅動接口,但是和系統交互只使用流式驅動接口,比如PC卡槽驅動。
2.2.2 按驅動層次分類
1) 層次型驅動程序(Layered Driver)
> MDD(Model Device Driver),與硬件無關,面向上層應用程序,一般由微軟建立統一框架;
> PDD(Platform Dependent Driver),針對具體硬件平臺的操作代碼,一般由驅動開發商實現MDD和PDD之間通過標準的設備驅動服務供應商接口DDSI連接。
2) 獨立型驅動程序(Monolithic Driver)
> 獨立驅動程序包含了MDD面向上層應用和PDD面向硬件平臺兩方面的代碼;
> 適用于操作不復雜的驅動;
> 減少了MDD和PDD傳遞之間傳遞信息的開銷,實時性更強;
3 流驅動程序的實現
流驅動程序必須實現一套標準接口,流驅動程序適用于IO操作,這也是嵌入式系統中最常見的設備驅動,操作接口和文件系統操作相似,通過CreateFile,ReadFile,WriteFile,IOControl函數等來操作應用程序和流驅動交互,可以把設備當作文件操作。
3.1 文件前綴名確定
根據文件前綴名在系統中必須唯一這一特點,在定義文件前綴名必須是三個字母,若有多個同類設備,由后綴一個阿拉伯數字區分,例如COM1,LPT3等等。文件前綴名將會在驅動的標準接口函數中體現,比如XXX_Init,XXX_Close等。
3.2 通用函數
根據設備的不同,所需函數不同,通用函數如下所示:
1) XXX_Init:通知設備管理器為設備初始化分配資源;
2) XXX_Deinit:通知設備管理器回收設備初始化時分配的資源;
3) XXX_Open:打開設備。應用程序調用CreateFile時,通過文件系統映射為XXX_Open;
4) XXX_Close:關閉設備。應用程序調用CloseFile時,通過文件系統映射為XXX_Close;
5) XXX_PowerUp:設備上電時,操作系統調用該函數完成必要的上電操作;
6) XXX_PowerDown:設備掉電時,操作系統調用該函數完成必要的關機操作
7) XXX_Read:從打開的設備文件中讀取數據,可以通過ReadFile映射;
8) XXX_Write:向打開的設備文件寫數據,可以通過WriteFile映射;
9) XXX_Seek:文件定位,根據設備情況決定是否支持;
10) XXX_IOControl:IO操作擴展,可以根據設備情況來決定支持何種特殊的操作模式。
3.3 DEF文件建立
流驅動一般以DLL形式存在,DEF文件定義了DLL需要導出的接口集,因此DEF文件的名稱與設備驅動名稱相同。
3.4 寫注冊表
在wince中任何設備的識別都是通過注冊表來實現的,因此必須在注冊表中添加具體的設備驅動項,以便系統識別。具體方法如下:
在注冊表中增加驅動程序入口點,找到注冊表項,注冊項位于注冊表的Root Key下,一般為[HKEY_LOCAL_MACHINEDriversBuiltInSampleDrv],建立必要的子鍵和鍵值,“Prefix”和“DLL”是兩個重要,而且是必須的鍵,分別描述了設備前綴名和驅動程序的動態連接庫名,然后根據具體設備的需要建立驅動程序需要的其子他鍵。
4 調試驅動程序
驅動程序編寫完畢后,就應該進行硬件的調試。具體方法如下:
4.1 調試區信息(Debug Zone)
調試區一般和WinCE的控制臺調試工具Cesh.exe配合調試,在不打斷OS運行情況下,進行驅動的實時調試,利用宏開關,可以選擇需要輸出的調試區信息,可以得到進程,線程和調試狀態信息。并且可以利用IDE環境,動態選擇開關調試區信息,但是打印驅動程序輸出調試信。必須借助于至少一種外設顯示調試信息,比如串口或者網卡或者其他通過調用RETAILMSG或者DEBUGMSG完成,不影響OS的運行,保證驅動程序運行的真實性,動態輸出設備的狀態信息,調試相對簡單,也是最廣泛使用的一種調試方法。
4.2 核心調試工具(Kernel Debugger)
核心調試工具將會禁止所有硬件中斷,掛起操作系統,因此可以單步調試OS或者核心代碼,可以訪問堆棧信息,但是必須在Platform的環境下,利用至少一種外設進行通信。
4.3 硬件輔助調試方法
利用硬件調試工具可以觀察物理設備的真實狀態,一般常用的方法可以利用JTAG工具實時查看CPU內部寄存器,利用邏輯分析儀或者示波器實時查看物理外設的輸入輸出狀態。利用指示LED來顯示驅動程序實時狀態信息。
4.4 Visual Studio調試
可以利用VS內置的調試工具進行單步跟蹤,狀態調試等。
5 測試驅動程序
驅動程序經過調試以后就需要對驅動的功能進行測試。其常用的方法如下:
1) 寫一個應用程序來測試驅動程序的正確性
2) 模擬各種可能發生的硬件輸入狀態來測試驅動程序的正確性
3) 利用Windows CE自帶的測試工具CETK來測試驅動程序的性能和完備性
6 驅動程序的集合和
6.1 驅動程序集成
驅動程序經過調試和測試確定其正確性后,就可以對驅動程序進行集成了。具體過程如下:
1) 在BSP的Driver目錄下建立新的驅動文件夾MyDrv
2) 實現MyDrv驅動以及相關的DEF文件
3) 如果需要用到硬件中斷資源,修改原BSP中的相關中斷處理函數OEMInterruptEnable,OEMInterruptDisable,OEMInterruptDone,OEMInterruptHandler
4) 在Platform.reg中,增加驅動程序相關項
5) 在Platform.bib中,增加驅動程序的相關注冊表項MyDrv.Dll$(_FLATRELEASEDIR)MyDrv.dll NK SH
6.2 驅動程序
驅動程序進過集成以后就可以使用了,具體的過程如下所示:
1) 利用CAB Wizard生成.cab驅動包
2) 直接提供驅動程序文件夾以及相關注冊表項和修改說明
7 總結
本為詳細的介紹了,wince下驅動開發的流程,介紹了驅動程序開發到的詳細過程,并詳細說明了各個部分的實現和操作方法,使是初學者對wince下驅動程序的開發流程和一般的開發工具有了初步的了解。
關鍵詞:PCI; vxworks;驅動程序;運動控制卡
中圖分類號:TP311 文獻標識碼:A 文章編號:1009-3044(2012)29-6966-03
VxWorks是目前世界上用戶數量最大的實時嵌入式操作系統, 它具有高度可剪裁的微內核結構、高效的多任務調度、靈活的任務間通信手段、快速靈活的I/O系統、確定的微妙級中斷延遲時間等優點。
本文介紹了基于PCI 接口規范的通用運動控制卡在VxWorks下的驅動程序的設計。對其設計驅動程序需要對實時操作系統、實時軟件設計、硬件設備有深入的了解。因此, 該設計不僅本身具有很高的應用價值, 也為實時驅動程序的設計提供了一個樣例。
1 系統組成
在基于微機的數據采集、處理與控制系統中,計算機接口卡常常是其中的關鍵硬件設備。目前在運動控制領域,各類運動控制卡得到廣泛運用,其中以工控機通過ISA或PCI等系統總線連接運動控制卡的主從式結構最為流行,由工控機發出控制指令和參數,控制卡根據接收到的指令及參數完成具體控制功能。由于PCI總線的高速和即插即用特性,使其取代ISA被廣泛應用于高速數據采集與傳輸等系統中,有效地解決了實時采集、實時傳輸和實時存儲等問題。
2 PCI 配置空間
PCI系統具有三種地址空間:存儲器空間、I/O空間和配置空間。每個PCI設備都有64個配置雙字用于實現配置寄存器,64個配置雙字分為兩部分,⑴PCI協議定義了開頭16個雙字的格式和用途,稱為設備的配置頭區域;⑵其它48個雙字的用途是由設備指定的。目前PCI協議定義了兩種頭區域格式,第1類配置頭區域用于定義PCI-PCI橋,而第0類配置頭區域用于定義其它PCI設備。所有的PCI設備,包括PCI-PCI橋都必須實現下述配置寄存器:廠商標志、設備標志、命令、狀態、分類碼、版本標志和頭區域類型寄存器。如表1所示為PCI配置寄存器。這些寄存器對編程訪問PCI設備至關重要,我們就是利用vendor ID 和device ID來枚舉出對應的設備,再進一步獲得設備的其他信息的。
3 驅動程序的開發
VxWorks 提供在指定目標系統上運行的板級支持包(BSP),本文選用的是針對pentium的板級支持包。VxWorks是支持PCI總線的,提供了一些庫函數專門用來訪問PCI設備。為了調用這些函數以方便開發,需要包含如下頭文件"iosLib.h"、"pciConfigLib.h"、"pciIntLib.h"、"sysLib.h"和"pciLocalBus.h",還需要導入sysOutLong()和sysInByte()等函數。在config.h里面定義INCLUDE_PCI以添加VxWorks對PCI的支持,還可以定義PCI_CFG_TYPE為PCI_CFG_FORCE、PCI_CFG_AUTO 或 PCI_CFG_NONE,我們一般定義為PCI_CFG_NONE,Vxworks只需把配置好的信息讀出來就可以了。
針對PCI 總線結構的數據采集模塊,其驅動程序的主要開發步驟如下:確定設備的PCI 配置信息確定設備的內部存儲器、寄存器基地址及中斷號設備初始化中斷服務程序設備各功能函數。以下按照程序執行的順序分步驟給出源代碼,并加以詳細的說明。
4 結束語
利用上文所述的方法編寫的驅動程序,達到了本項目所要求的性能指標,系統經過實際驗證是高速穩定可靠的,而且由于PCI總線的即插即用特性,不需要用戶去手動跳線,極大得方便了使用。
參考文獻:
[1] microsoft msdn[EB].2001.
引言
近年來電力行業為了快速部署變電站,采用了建造整體變電所的方法:在生產基地將變電站的內部設備安裝、調試完成,只留下與外界的接口,整體運到變電站所在地后進行安裝和簡單調試即可投入運行。其內部設備通過CAN總線進行通信,系統原有的監控軟件基于DOS系統,維護調試比較困難,因此想要尋求更方便、友好的系統支持。經過比較,嵌入式操作系統市場上風頭正勁的Windows CE .NET成為最終選擇。微軟的最新產品Windows CE.NET提供了端對端的開發、調試手段,可以不拆卸設備的情況下通過Telnet登錄到WindowsCE上進行調試和維護,其系統本身為嵌入式市場進行重新設計,包括創建一個基于WindowsCE的定制設備所需的一切。這樣就需要將原來DOS下的程序移植到WindowsCE.NET下,但是各個硬件廠商目前還沒有提供CAN通信卡在Windows CE.NET下的驅動,所以開發Windows CE.NET下的CAN卡驅動成為項目推行中的關鍵一環。
本文主要針對研華的雙口CAN卡PCM3680進行分析,介紹在WindowsCE.ENT系統下進行底層設備驅動開發的方法并提供CAN通信的實例。
1 CAN總線通信協議及CAN通信卡介紹
CAN總線是德國Bosch公司20世紀80年代初為解決現代汽車中眾多的控制與測試儀器之間的數據交換而開的一種串行數據通信協議。它是一種多主總線,廢除了傳統的站地址編碼,而代之以對通信數據塊進行編碼。這種方法使網絡內節點個數在理論上不受限制,擴展格式中的29位的標識碼便可以定義2 29個不同的數據塊。
在本項目中使用的是研華的PCM3680,這是一塊嵌入式PC104的雙口CAN總線通信卡;CAN控制器采用Philips的獨立CAN控制器SJA1000芯片;CAN收發器采用Philips的P82C250,可以同時操作兩個CAN網絡,提供高達1Mb/s的傳輸速度。PCM3680支持很寬的中斷范圍:中斷3、4、5、6、7、9、10、11、12、15,同時1000V的光電隔離提供系統高可靠性。在CAN卡通信中,要用到CAN控制器中的很多寄存器,各個寄存器的含義和作用可以參考控制芯片的說明書。圖1列出驅動程序設計中用到最主要的寄存器結構。
2 CAN卡驅動底層函數設計
本方案設計CAN驅動是放在Windows CE操作系統的內核下層,位于OEM adaptation layer(OAL)層的一個真正的驅動,而不是在主程序中的串口操作。在Windows CE的設備管理器可以看到CAN1和CAN2兩個端口,并且可以查看其工作的正常與否和對其進行配置。如:中斷號和I/O地址。
2.1 CAN卡寄存器讀寫函數
CAN卡的通信是通過操作CAN卡上的CAN控制器進行的。在CAN控制器中有很多寄存器,如控制寄存器、命令寄存器、狀態寄存器、中斷寄存器等,通過讀寫這些寄存器中的命令狀態字可以檢測和控制CAN卡的行為。在Windows CE.NET下,通過調用DOK中的API函數HalTranslateBusAddress,將CAN卡分配的物理地址映射為邏輯地址。這樣各個寄存器對應的就是CAN卡基地址的偏移地址,因此,對寄存器的讀寫就轉化為對內存地址的讀寫。下面是CAN卡寄存器的讀寫函數:
*在偏移量為off的地址讀取一個字節的數據inline BYTE CANR(LPCAN_HW_OPEN_INFO hCan,DWORD off)
{
return hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr[off];
*將一個字節數據寫到偏移量為off的地址中inline VOID CANW(LPCAN_HW_OPEN_INFO hCan,DWORD off,BYTE val)
{
hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr[off]=val;
}
參數LPCAN_HW_OPEN_INFO定義的是CAN卡的數據結構,其中成員lpMappeBaseAddr[0]表示的是映射后基地址,lpMappedBaseAddr[1]就是基地址+1的地址,對應CAN卡的寄存器是命令寄存器。通過上述兩個函數可操作CAN卡上的所有寄存器。
2.2 CAN卡初始化
CAN卡的控制器比較復雜,在通信前必須確認硬件信息正確性、初始化各寄存器。初始化函數的基本流程如圖3所示。
第一步,檢查端口號和硬件信息的正確性,主要是CAN卡中斷號是否有效。
第二卡,設置CAN卡默認參數:
CanCardConfigInfo CAN_DEFAULT_SETTING=
{0X00,0XFF,0X03,0X1C};/*設置默認波特率為125Kbps*/
DWORD dwThreadID =0;
PHYSICAL_ADDRESS phyAddr={hwInfo->dwIOBaseAddr *16,0 };
第三卡,用WinCE API函數LocalAlloc為CAN卡驅動中用到的數據結構分配緩沖區;通過HalTranslateBusAddress和MmMapIoSpace函數映射I/O地址,提供直接訪問設備的虛擬地址:
if(!HalTranslateBusAddress(Isa,0,phyAddr,0,&phyAddr))
goto _ExitInit;
hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr=
(LPBYTE)MmMapIoSpace(phyAddr,CANCARDADDRLEN,FALSE);
if(!hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr)
goto _ExitInit;
如果分配內存或映射邏輯地址失敗,則退出初始化程序,CAN卡初始化失敗。
第四步,初始化讀寫屬性、共享模式、讀超時時間和第二個CAN口的基地址。
第五步,創建CAN卡事件和數據接收事件:hCan->lpCanHWInfo->hCanEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
hCan->lpCanHWInfo->hRecvMsgEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
第六步,初始化中斷,如果CAN卡有復位請求就退出初始化程序。設置好中斷后啟動數據接收線程,設置線程優先級繼續線程處理;最后配置CAN卡參數,進入正常運行狀態。
2.3 CAN卡信息發送
CAN卡的信息發送分為兩個步驟。在對CAN卡基本信息進行檢查后,首先設置發送緩沖的ID號。CAN標準模式的ID號為11位,偏移地址10中存放的是ID號的高8位,偏移地址11的高3位存放的是ID號的低3位,剩下5位分別是RTR位(遠程傳送請求位)和數據長度。通過CANW函數將處理后的數據寫入到相應的偏移地址,設置完相應的地址數據后,通過循環將偏移地址12~19的數據采集回來存到數組中。然后,設置CAN卡的傳輸請求為允許并不斷偵測狀態寄存器的變化,當傳輸緩沖滿標志或傳輸結束標志為1時通出程序,完成一次數據采集。傳輸緩沖區的寄存器如表1所列。
表1
ID號10ID.10ID.9ID.8ID.7ID.6ID.5ID.4ID.3RTR,數據長度碼11ID.2ID.1ID.0RTRDLC.3DLC.2DLC.1DLC.0數據1~812~19數據數據數據數據數據數據數據數據表2
ID號20ID.10ID.9ID.8ID.7ID.6ID.5ID.4ID.3RTR,數據長度碼21ID.2ID.1ID.0RTRDLC.3DLC.2DLC.1DLC.0數據1~822~29數據數據數據數據數據數據數據數據CAN消息發送函數的實現如下:
BOOL CAN_SendMessage(LPCAN_HW_OPEN_INFO hCan,LPCanCardMessageBuflpMsg)
{
BOOL bSuc=FALSE;
ASSERT(hCan && lpMsg && lpMsg->dwMessageLen <=8); /*防錯處理*/
if(0= =(hCan->dwAccessCode & GENERIC_WRITE))
return FALSE;
:: EnterCriticalSection(&hCan->lpCanHWInfo->
TransmitCritSec); /*進入臨界區*/
BYTE byV=static_cast<BYTE>(1pMsg->dwMsgID>>3);
CANW(hCan,10,byV); /*設置ID值高8位*/
byV=static_cast<BYTE>=((lpMsg->dwMsgID & 7)<<5);
if(lpMsg->bRTR) byV|=0x10;
byV+=static_cast<BYTE>(lpMsg->dwMessageLen);
CANW(hCan,11,byV);/*設置ID值低3位、RTR及數據長度*/
for(UINT i=0;<lpMsg->dwMessageLen;++i)
{
CANW(hCan,12+i,lpMsg->byMsg[i]);
} /*采集數據*/
CANW(hCan,1,1);/*重置傳輸請求*/
while(TRUE)
{byV=CANR(hCan,2);
if(byV & 0X40) /*傳輸緩沖區滿,退出*/
{break;}
if(byV & 0X8){ /*傳輸結束,正確返回退出*/
bSuc = TRUE;
break;}
}
::LeaveCriticalSection(&hCan->lpCanHWInfo->TransmitCritSec); /*離開臨界區*/
return bSuc;
}
2.4 CAN卡信息接收
CAN卡的信息接收是發送的逆過程,當接收緩沖區標志為1時,表示緩沖區已滿可以接收數據,將數據接收到數組后釋放接收緩沖區,然后對接收到的數據進行分解并存儲到CAN卡信息緩沖區的結構體。接收緩沖區的寄存器結構如表2所列。
CAN消息接收函數的實現如下:
BOOL CAN_RecvRecvMessage(LPCAN_HW_OPEN_INFO
HCan,OUT LPCanCardMessageBuflpMsg)
{……
if(CANR(hCan,2)&1){ /*判斷接收緩沖區是否已滿*/
for(UINT i=0;i<10;++i)
recvBuf[i]=CANR(hCan,20+i);/*將數據暫存到臨時緩沖區*/
CANW(hCan,1,4); /*釋放接收緩沖區*/
LpMsg->dwMsgID=recvBuf[0]<<3; /*取出ID的高8位*/
BYTE byV =recvBuf[1];
LpMsg->dwMsgID+=byV >>5;/*取出ID低3位,然后和高8位合并*/
LpMsg->bRTR =byV &0x10?TRUE:/*返回RTR狀態*/
LpMsg->dwMessageLen = byV &0XF; /*返回數據長度*/
……
}
else
{++hCan->lpCanHWInfo->dwErrorMsgCount;}/*沒有收到數據,錯誤計數加1*/
::LeaveCriticalSection(&hCan->lpCanHWInfo->
ReceiveCritSec); /*離開臨界區*/
Return bSuc;
}
2.5 CAN卡事件處理
CAN卡事件處理函數是CAN卡驅動程序中很重要的部分。驅動設計要求具有消息通知的功能,當事件發生時及時捕獲事件并進行消息處理。
下面是事件處理函數的實現:
staric DWORD WINAPI CAN_EventHanle(LPVOID lpParam)
{
ASSERT(lpParam);
LPCAN_HW_OPEN_INFO hCan=(LPCAN_HW_OPEN_INFO)lpParam;
CanCardMessageBuf bufMsg;
while(TEUE)
{ /*循環等待CAN卡消息產生,然后進行處理*/
::WaitForSingleObject(hCan->lpCanHWInfo->hCanEvent,0XFFFFFFFF);
if(hCan->lpCanHWInfo->bKillCanThread) break; /*若CAN線程已關閉則中斷*/
if(CAN_RecvMessage(hCan,&hufMsg)){ /*正確接收數據后*/
CAN_RecvBufPush(hCan,&bufMsg);} /*將數據壓入緩沖*/
BYTE byV=CANR(hCan,3); /*將3號寄存器讀出然后立即寫入*/
CANW(hCan,3,byV);/*能夠獲取每次中斷*/
InterruptDone(hCan->lpCanHWInfo->lpCanObj->dwSysIrqt);
} /*本次中斷結束,等待下次中斷*/
return 0;
}
2.6 其它函數
為了提供更多的功能和更方便地使用CAN卡進行通信,在CAN卡驅動程序中還設計了一些函數如CAN_Config用CAN卡信息配置、CAN_RecvBufPop用于處理接收緩沖區、CAN_Reset用于復位CAN卡、CheckHWInfo用于硬件信息檢查等。這些函數提供了對CAN通信卡的設置、檢查等功能,在這里不再詳述了。
3 CAN卡驅動封裝設計
CAN卡底層驅動函數雖然功能完整,但是對于用戶使用比較復雜并且一般用戶不需要了解底層實現的機制。為了便于使用,最后對CAN卡的驅動進行了封裝,提供CanOpenFile、CanSendMsg等五個函數用于CAN總線的通信,以動態連接庫(DLL)的形式提供給用戶調用。封裝函數及功能如下:
*CanOpenFile;初始化并打開CAN卡的一個端口。
*CanCloseFile;關閉由CanOpenFile打開的CAN卡端口。
*CanRecvMsg;接收CAN卡數據,打開CAN卡時必須具有GENERIC_READ權限。
*CanSendMsg;通過CAN卡發送數據。打開CAN卡時必須具有GENERIC_WRITE權限。
*CanIOControl;設置或獲取CAN卡I/O參數支持的I/O控制包括:IOCTL_CAN_CONFIG,IOCTL_CAN_RESET,IOCTL_CAN_TIMEOUT,IOCTL_CAN_SENDREADY,IOCTL_CAN_RECVREADY。
下面是CanSendMsg函數實現的代碼:
BOOL CanSendMSg(
HANDLE hCan,
LPCanCardMessageBuflpMsg)
{
if(!hCan||INVALID_HANDLE_VALUE= =hCan||
!lpMsg||lpMsg->dwMessageLen>8)return FALSE;
return CAN_SendMessage(LPCAN_HW_OPEN_INFO)
hCan,lpMsg);
該函數就是通過封裝CAN卡的底層驅動函數SendMessage來實現的,這樣將功能集中的五個函數更方便了用戶使用。
結語
關鍵詞:嵌入式操作系統;Win CE;SPI;驅動程序
中圖分類號:TP311文獻標識碼:B
文章編號:1004-373X(2009)10-069-04
Design of EP9315-SPI Driver Based on Win CE
ZHANG Dong1,XU Dijian2
(1.Chongqing University of Arts and Sciences,Chongqing,402160,China;2.Chongqing University of Science and Technology,Chongqing,401331,China)
Abstract: It is very important to compile driver connecting operating system with corresponded hardware device.Based on stream interface driver model,the design of SPI driver in embedded operating system Win CE in development environment of platform builder 4.2 and design method are introduced and analysed,realizing virtual address map,key code and the relationship between driver and SPI application program in EVC program environment is discussed.Driver and corresponded application program can be operated on FS_EP9315 development platform of ucdragon rightly.Experience indicates the methord is right and feasible.
Keywords:embedded operating system;Win CE;SPI;driver program
0 引 言
嵌入式是“以應用為中心,以計算機技術為基礎,軟硬件可裁剪,適合應用系統對功能、可靠性、成本、體積、功耗嚴格要求的計算機系統”。Windows 是Microsoft推出的功能強大的緊湊、高效、可伸縮的32位嵌入式操作系統,主要面對各種各樣嵌入式系統的產品[1,2]。
該系統具有多線程、多任務、完全搶占式的特點,是為各種具有嚴格資源限制的硬件系統所設計的。為了將操作系統和硬件設備連接起來,硬件和軟件的驅動聯系就顯得很重要。SPI是一種高速、全雙工、同步的通信總線,在芯片的管腳上只占用4根線,節約了芯片的管腳,同時為PCB的布局節省了空間,提供了方便,正是出于這種簡單易用的特性,現在越來越多的芯片都集成了這種通信協議。SPI的工作模式有兩種:主模式和從模式,SPI總線可以配置成單主單從、單主多從、互為主從。為了充分利用芯片的SPI接口進行相應的驅動程序設計以及應用程序設計,通用方法的研究就顯得十分重要。
1 Win CE提供的驅動模型
Win CE操作系統支持兩種類型的驅動程序,一種為本地驅動程序,是把設備驅動程序作為獨立的任務實現的,直接在頂層任務中實現硬件操作,因此有明確和專一的目的。本地驅動程序適合于那些集成到Win CE平臺的設備,諸如鍵盤、觸摸屏等設備。另一種是具有定制接口的流接口驅動程序,它是一般類型的設備驅動程序,為用戶一級的動態鏈接庫(DLL)文件,用來實現一組固定的函數稱為“流接口函數”,這些流接口函數使得應用程序可以通過文件系統訪問這些驅動程序。這里論述的SPI驅動就屬于流接口驅動。
2 SPI驅動程序的設計
2.1 EP9315芯片及SPI接口簡介
EP9315是一款基于ARM920T,由Cirrus Logic公司生產的工業級芯片[3,4] ,內帶MMU,16 KB的指令Cache,16 KB的數據Cache和數學協處理器,主頻為200 MHz,系統總線為100 MHz。該芯片擁有一組SPI接口,利用它可方便實現與SPI器件進行通信,可大大簡化工程應用的硬件設計軟件。
SPI驅動程序采用Win CE流驅動的標準形式。下面從驅動程序具體設計步驟以及驅動代碼的編寫兩個方面做較為詳細的闡述。
2.2 SPI驅動程序設計步驟
在Platform Builder 4.2下設計Win CE流接口驅動程序可按照以下步驟進行[5-7]:
(1) 在C:\\Win CE420\\PLATFORM\\ep931x\\drivers目錄下新建一個目錄SPI;
(2) 從其他驅動目錄下復制makefile文件到SPI目錄下;
(3) 用文本編輯器建立4個文本文件,文件名分別為SPI.c,SPI.h,SPI.def和sources;
(4) 編輯目錄C:\\Win CE420\\PLATFORM\\ep931x\\driver下的dirs文件。用文本編輯器打開該文件,找到“DIRS=”等式,在該等式最后添加一行, 如下面所示:
DIRS=…
SPI
(5) 在Platform Builder 4.2中打開Platform.bib文件,在該文件最后和FILES之前加入一行,指明在生成Windows CE內核映射時自動將SPI.dll加入到內核映像中,添加內容如下:
SPI.dll MYM(_FLATRELEASEDIR)\ SPI.dll NK SH
(6)具體的流接口驅動程序跟注冊表密不可分,在Platform Builder 4.2中打開platform.reg文件,在該文件最后加入如下所示注冊表信息,以使在生成操作系統映像時,Platform Builder將注冊表信息加入到注冊表中。在Platform.reg中添加內容如下:
[HKEY_LOCAL_MACHINE\\Drivers\\BuiltIn\\SPI]
"Prefix"=" SPI "
"Dll"=" SPI.dll"
"FriendlyName"=" SPI Driver"
"Index"=dword:1
"Order"=dword:0
關鍵詞:MCP2515 嵌入式Linux 驅動 CAN
中圖分類號:TP336 文獻標識碼:A 文章編號:1007-9416(2016)04-0000-00
1系統硬件結構介紹
本系統的硬件平臺主要由OK2440開發板、基于MCP2515的CAN總線通信模塊和以STC89C52為控制器的CAN節點模塊組成。CAN通信模塊用來完成OK2440開發板和STC89C52控制的節點模塊之間的數據傳輸。
1.1 MCP2515功能簡介
MCP2515是一款獨立的CAN總線控制器,完全支持CAN V2.0B 技術規范。MCP2515 擁有六個驗收濾波寄存器和兩個驗收屏蔽寄存器,通過它們可以過濾掉總線上不需要的報文,從而減少MCU關于處理CAN總線上無用數據的開銷。MCP2515與MCU 的連接是通過業界標準串行外設接口來實現的。
1.2 TJA1050功能簡介
TJA1050 是介于CAN控制器和物理總線之間的一種符合ISO 11898標準的高速CAN收發器。其最高速率可達1Mbit/s,而且它的電磁抗干擾EMI性極高,至少可以連接110個節點。在實際電路中,可為物理總線提供差動發送和為CAN控制器提供差動接收。
2 MCP2515相關驅動程序設計
2.1 Linux設備驅動簡介
在Linux系統中,由于對硬件的操作必須處在特權模式下,在用戶工作模式下,程序一般不能直接和硬件進行通信。因此,設備驅動程序則承擔了用戶模式下硬件和用戶應用程序之間的通信工作,同時它還為應用程序和內核中其他的部分訪問這些設備提供了程序接口。大多數設備驅動程序可以在系統工作時,以動態方式進行加載,在不需要的時候又可以將其卸載掉。
2.2 MCP2515驅動程序設計
2.2.1 MCP2515驅動初始化函數
在MCP2515的驅動初始化函數中首先通過s3c2440_spi_ioremap()函數將S3C2440上的SPI寄存器的物理地址映射到內核空間,這樣才可以在驅動程序中訪問和配置S3C2440的SPI寄存器。在正確的配置S3C2410的SPI寄存器后,通過s3c2440_spi_init()來完成對S3C2440相關寄存器的賦值。然后通過s3c2440_irq_init()函數來完成中斷方面相關的設置。MCP2515_init()和MCP2515_dev_init()兩個函數主要是針對于MCP2515控制器進行相關的配置和為MCP2515設備驅動程序申請和初始化內存空間。最后通過MCP2515 _cdev_register(Device0)函數完成MCP2515在內核中的注冊。
2.2.2 MCP2515相關中斷函數的注冊
在CAN總線驅動程序中,CAN通信模塊接收和發送數據必須以中斷的方式與系統內核之間進行數據的交換,所以在MCP2515的驅動程序中必須用到內核中的相關中斷函數。對于MCP2515的中斷注冊函數request_irq(),如果此中斷注冊函數返回值為0則表示中斷注冊成功,返回負數則表示注冊失敗。
2.2.3 MCP2515的文件操作函數
MCP2515_fops中定義了很多與設備有關的操作函數,內核可以通來它來訪問與MCP2515操作有關的函數。在MCP2515的文件操作函數中,read()和write()兩個函數是用來完成讀寫CAN總線上數據的功能的,通過傳遞不同的參數給驅動程序中的read()和write(),我們可以讀取和寫入相應的數據。驅動中的CAN總線讀函數read()是整個驅動程序設計的難點,其中在函數的設計中采用了Linux內核阻塞機制。read()讀取完CAN總線上的數據后,通過驗收濾波寄存器和屏蔽濾波寄存器來決定總線上的數據幀是否存入到總線控制器相應的接收緩沖寄存器里。
2.2.4 MCP2515的卸載函數
當我們不需要繼續使用某個設備時,我們可以將這個設備從內核中卸載掉。在設備的卸載過程中,必須將其內核中所對應的設備號釋放掉。在模塊的卸載函數中,我們通過調用int unregister_chrdev_region(unsigned int major,const char *name)函數來完成設備驅動的卸載。此函數的兩個參數分別對應設備文件的主設備號和設備名。在卸載模塊時,Linux內核會把設備名與內核中已注冊的設備名稱進行對比,如果兩者相等,則完成設備的卸載,反之則卸載失敗。MCP2515的驅動卸載函數主要是完成MCP2515驅動在內核中所占用的中斷的釋放和MCP2515在內核中的注銷。
3 結語
本文重點討論了S3C2440中MCP2515的驅動程序設計方法,并詳細介紹了Linux系統下如何開發MCP2515的驅動程序的方法。實驗結果表明,本文所設計的Linux下MCP2515驅動程序可以在OK2440開發板上正常運行,基本可以完成CAN總線上數據的正常發送與接收,測試結果符合論文的要求。本文提到的基于Linux下MCP2515驅動程序的開發,對其他Linux驅動程序的開發具有一定的啟示作用。
參考文獻
[1]宋寶華.Linux設備驅動開發詳解[M].北京:人民郵電出版社,2008.
[2]楊慶華,張景元.單片機和MCP2515的CAN總線通信模塊設計[J].單片機與嵌入式系統應用,2007.
[3]劉淼.嵌入式系統接口設計與Linux驅動程序開發[M].北京:北京航空航天大學出版社,2006.
關鍵詞:CAN_NODE實驗板;ATmega128;CAN總線驅動程序
中圖分類號:TP305文獻標識碼:B 文章編號:1009-3044(2011)16-3952-03
CAN_NODE Bus Drivers Design Based on Atmega128
LIU Bin, LIU Jun-liang, MA Jin-bo, WANG Jun-qing
(2332 Laboratory, College of Engineering, Ocean University of China, Qingdao 266100, China)
Abstract: CAN_NODE is a powerful 8-bit AVR microcontroller experiment board, it is based on AVR RISC structure 8-bit low-power CMOS microprocessor ATmega128. This paper briefly expounds the profile of the fieldbus technology, hardware structure of CAN_NODE experimental board and characteristic of ATmega128, then the CAN bus drivers based on the experimental board is focused on.
Key words: CAN_NODE experiment board; ATmega128; CAN bus drivers
1 概述
現場總線(Fieldbus)技術是當前自動化技術的熱點之一。現場總線技術集先進的嵌入式系統、現代通信、自控理論、網絡技術于一身,充分體現出先進技術的進步能夠為人類帶來的便利。
CAN:全稱為“Controller Area Network”,即控制器局域網,是國際上應用最廣泛的現場總線之一。最初,CAN被設計作為汽車環境中的微控制器通訊,在車載各電子控制裝置ECU之間交換信息,形成汽車電子控制網絡,比如,發動機管理系統、變速箱控制器、儀表裝備、電子主干系統中,均嵌入CAN控制裝置。
AVR單片機是1997年由ATMEL公司研發出的增強型內置Flash的RISC(Reduced Instruction Set CPU) 精簡指令集高速8位單片機。AVR的單片機可以廣泛應用于計算機外部設備、工業實時控制、儀器儀表、通訊設備、家用電器等各個領域。
2 CAN_NODE實驗板硬件結構
CAN_NODE實驗板上提供了CAN總線通訊所需要的硬件,和一些按鍵,LED,USB接口等常用的功能部件,還提供了為系統擴展而預留的擴展功能接口,也提供了SPI接口和JTAG接口以方便下載和調試。
2.1 CAN_NODE實驗板功能框圖
圖1為系統結構框圖。
2.2 ATmega128的特點
其先進的指令集以及單周期指令執行時間, 使得ATmega128 的數據吞吐率高達1 MIPS/MHz。同時ATmega128具有:128K 節的系統內可編程Flash(具有在寫的過程中還可以讀的能力,即RWW)、4K 字節的EEPROM、4K 字節的SRAM、53 個通用I/O 口線、32個通用工作寄存器、實時時鐘RTC、4 個靈活的具有比較模式和PWM 功能的定時器/ 計數器(T/C)、兩個USART、面向字節的兩線接口TWI、8 通道10 位ADC(具有可選的可編程增益)、具有片內振蕩器的可編程看門狗定時器、SPI 串行端口、與IEEE 1149.1 規范兼容的JTAG 測試接口(此接口同時還可以用于片上調試)。
3CAN總線驅動程序設計
軟件開發采用的是ImageCraft公司開發的ICCAVR,軟件的下載采用雙龍ATMEL_ISP下載軟件。ICCAVR是一種使用符合ANSI 標準的 C 語言來開發ATMEL公司生產的微控制器(MCU)程序的一個工具,它有以下幾個主要特點:
1)ICCAVR 是一個綜合了編輯器和工程管理器的集成工作環境(IDE),其可在Windows9X/NT下工作,源文件可被組織到工程中,文件的編譯和工程的構筑也是在這個環境中完成。
2)編譯錯誤顯示在狀態窗口中,并且當你用鼠標單擊編譯錯誤時,光標會自動跳轉到編輯窗口中引起錯誤的那一行。這個工程管理器還能直接產生您希望得到的可以直接使用的INTELHEX 格式文件,INTEL HEX 格式文件可被大多數的編程器所支持,用于下載程序到芯片中去。
集成開發環境如圖2所示。
CAN總線驅動程序主要包括四個部分:CAN控制器初始化、接收數據、發送數據和總線異常處理。
圖3為主程序流程圖。
主要程序設計如下所示:
3.1 初始化
Can控制器初始化的操作包括:中斷控制,硬件使能,軟件復位,工作模式等。
初始化程序如下
unsigned char can_state;
IOWR(CAN_IP_0_BASE,CAN_IER,0x00);//禁止中斷
IOWR(CAN_IP_0_BASE,CAN_MOD,0x09);//進入復位模式,單驗收濾波器
can_state=(unsigned char)IORD(CAN_IP_0_BASE,CAN_MOD);
while((can_state&0x01)==0x00)//檢測是否進入復位模式
{
IOWR(CAN_IP_0_BASE,CAN_MOD,0x09);//進入復位模式,單驗收濾波器
can_state=(unsigned char)IORD(CAN_IP_0_BASE,CAN_MOD);
}
IOWR(CAN_IP_0_BASE,CAN_CDR,0xC1);//peliCAN,禁止時鐘輸出,禁止TX1,RX1c8
IOWR(CAN_IP_0_BASE,CAN_ACR0,local_code1);//驗收碼1
IOWR(CAN_IP_0_BASE,CAN_ACR1,local_code2);//驗收碼2
IOWR(CAN_IP_0_BASE,CAN_ACR2,local_code3);//驗收碼3
IOWR(CAN_IP_0_BASE,CAN_ACR3,local_code4);//驗收碼4
IOWR(CAN_IP_0_BASE,CAN_AMR0,0xff);//屏蔽碼1
IOWR(CAN_IP_0_BASE,CAN_AMR1,0xff);//屏蔽碼2
IOWR(CAN_IP_0_BASE,CAN_AMR2,0xff);//屏蔽碼3
IOWR(CAN_IP_0_BASE,CAN_AMR3,0xff);//屏蔽碼4
IOWR(CAN_IP_0_BASE,CAN_BTR0,0x01);//同步跳轉3個周期,系統時鐘4倍周期
IOWR(CAN_IP_0_BASE,CAN_BTR1,0x1C);//采樣點3,段一6,段二3
IOWR(CAN_IP_0_BASE,CAN_OCR,0x1A);//控制寄存器
IOWR(CAN_IP_0_BASE,CAN_MOD,0x08);//進入工作模式,單驗收濾波器
can_state=(unsigned char)IORD(CAN_IP_0_BASE,CAN_MOD);
while((can_state&0x01)==0x01)//檢測是否進入復位模式
{
IOWR(CAN_IP_0_BASE,CAN_MOD,0x08);//進入工作模式,單驗收濾波器
can_state=(unsigned char)IORD(CAN_IP_0_BASE,CAN_MOD);
}
IOWR(CAN_IP_0_BASE,CAN_IER,0x01);//開接收中斷
}
CAN是一種基于廣播的通訊機制,廣播通訊依靠報文(Message)的傳送機制來實現,因此CAN并未定義站及站地址,而僅僅定義了報文,這些報文依靠報文確認區(Identifier)來進行識別,一個消息報文確認區在一個網絡中必須是唯一的,它不但描述了某一報文的意義,而且還定義了報文的優先級,當很多站都在訪問總線時,優先級是很重要的,因此,CAN是通過報文的確認區來決定報文的優先級的。
CAN節點之間的數據傳輸采用的協議是報文格式,其29位的幀標識符和報文數據部分的規定如圖4所示。
3.2 數據接收
接收數據可以采用查詢方式或中斷方式。在某一段時間內CAN總線并不是總在活動,為了提高效率,可采用中斷方式。
程序如下:
alt_u8 can_irq_reg;
//can_irq_reg=IORD(CAN_IP_0_BASE,CAN_IR);
//if ((can_irq_reg & 0x01)==1)
{
can_rx_reg[0]=IORD(CAN_IP_0_BASE,CAN_TX_SFF_EFF_H);//發送幀
can_rx_reg[1]=IORD(CAN_IP_0_BASE,CAN_TX_SFF_EFF_C1);//驗收碼1
can_rx_reg[2]=IORD(CAN_IP_0_BASE,CAN_TX_SFF_EFF_C2);//驗收碼2
can_rx_reg[3]=IORD(CAN_IP_0_BASE,CAN_TX_EFF_C3);//驗收碼3
can_rx_reg[4]=IORD(CAN_IP_0_BASE,CAN_TX_EFF_C4);//驗收碼4
can_rx_reg[5]=IORD(CAN_IP_0_BASE,21);
can_rx_reg[6]=IORD(CAN_IP_0_BASE,22);
can_rx_reg[7]=IORD(CAN_IP_0_BASE,23);
can_rx_reg[8]=IORD(CAN_IP_0_BASE,24);
can_rx_reg[9]=IORD(CAN_IP_0_BASE,25);
can_rx_reg[10]=IORD(CAN_IP_0_BASE,26);
can_rx_reg[11]=IORD(CAN_IP_0_BASE,27);
can_rx_reg[12]=IORD(CAN_IP_0_BASE,28);
}
can_rx_flag=1;
IOWR(CAN_IP_0_BASE,CAN_CMR,0X04);//釋放接收緩沖區
can_irq_reg=IORD(CAN_IP_0_BASE,CAN_IR);
while ((can_irq_reg & 0x01 )==0x01)
{
IOWR(CAN_IP_0_BASE,CAN_CMR,0X04);
can_irq_reg=IORD(CAN_IP_0_BASE,CAN_IR);
}
3.3 數據發送
將待發送的數據打包成符合CAN協議的幀格式后,寫入發送緩沖區,然后發送。
程序如下所示:
if(can_rx_flag==1)
{
can_tx_count=0;
can_rx_flag=0;
//IOWR(CAN_IP_0_BASE,21,0x55);
//IOWR(CAN_IP_0_BASE,21,0xaa);
//data_reg=IORD(CAN_IP_0_BASE,21);
IOWR(CAN_IP_0_BASE,CAN_TX_SFF_EFF_H,0x88);//發送幀
IOWR(CAN_IP_0_BASE,CAN_TX_SFF_EFF_C1,local_code1);//驗收碼1
IOWR(CAN_IP_0_BASE,CAN_TX_SFF_EFF_C2,local_code2);//驗收碼2
IOWR(CAN_IP_0_BASE,CAN_TX_EFF_C3,local_code3);//驗收碼3
IOWR(CAN_IP_0_BASE,CAN_TX_EFF_C4,local_code4);//驗收碼4
IOWR(CAN_IP_0_BASE,21,can_rx_reg[5]);//數據
IOWR(CAN_IP_0_BASE,22,can_rx_reg[6]);//數據
IOWR(CAN_IP_0_BASE,23,can_rx_reg[7]);//數據
IOWR(CAN_IP_0_BASE,24,can_rx_reg[8]);//數據
IOWR(CAN_IP_0_BASE,25,can_rx_reg[9]);//數據
IOWR(CAN_IP_0_BASE,26,can_rx_reg[10]);//數據
IOWR(CAN_IP_0_BASE,27,can_rx_reg[11]);//數據
IOWR(CAN_IP_0_BASE,28,can_rx_reg[12]);//數據
IOWR(CAN_IP_0_BASE,CAN_CMR,0x01);//發送
}
3.4 異常情況處理
總線發生故障時,下行的CAN節點可能脫離總線。可通過讀取錯誤計數器對計數器遞減計數的情況進行監測并作相應處理。若前面傳輸到CAN控制器的數據未被讀出,而接收緩沖區又沒有及時釋放,就有可能引起后面信息的丟失。這時必須通過寫命令寄存器來清除CANSR的數據溢出位。這兩種異常可通過異常中斷來處理,只要在中斷子程序中加入處理代碼即可。其他的總線異常處理可根據使用情況決定是否在軟件中處理。
4 結束語
本設計對CAN模塊軟硬件結構及ATmega128的特點進行簡要的描述,主要對基于ATmega128單片機的CAN_NODE總線驅動程序的進行設計。現場總線技術以其獨有的技術優勢和特點,在現代分布式測量與控制技術領域中應用已愈來愈廣泛。各種現場總線的主控制器一般都內嵌有相當完善的、開放式的互聯通信協議,它具有通信速度快、誤碼率低、開發設計簡單及網絡使用維護方便等諸多特點,是實現網絡化現場測量與控制技術的一個發展方向。
參考文獻:
[1] 周立功.iCAN現場總線原理與應用[M].北京:北京航空航天大學,2007.
[2] 范偉成.基于ATmegal28單片機的CAN總線接口設計及應用[M].上海:上海齊耀動力技術有限公司,2008.
[3] 劉濱.基于單片機的CAN_NODE的設計與實現[M].青島:中國海洋大學,2011.
關鍵詞:VxWorks操作系統;串口驅動程序;共享中斷
中圖分類號:TP316文獻標識碼:A文章編號:1009-3044(2009)33-9544-03
The Design of Driver for Multi Serial Sharing IRQ Based on VxWorks System
LIU Wei,TAO Ying
(Department of Information Engineering, Jiangxi Vocational College of Finance and Economics, Jiujiang 332000, China)
Abstract: This paper introduces the structure of serial port driver on the VxWorks system, then the achievement of the driver of serial driver is analyzed. The driver for multi serial sharing IRQ based on VxWorks system is designed, and loading VxWorks system with the module of the driver is achieved.
Key words: VxWorks system; serial port driver; sharing IRQ
VxWorks操作系統是美國Wind River公司開發的一種嵌入式實時操作系統,由于其高可靠性、強實時性以及可裁減性,廣泛應用于航空航天、軍事、民用通信和工業控制等領域。
在某大型控制系統中,我們需要開發一個具有4路串口通訊、1路CAN通訊以及2路以太網通訊的多種通訊方式并存的通訊設備。考慮到通訊能力以及通訊的實時性要求,CPU選用盛博公司PC104+總線的Pentium III處理器,串口選用具有PC104總線接口的4路串口擴展板,采用VxWorks操作系統來實現以上需求。由于每種通訊方式都采用中斷方式觸發,而系統硬件提供的中斷源是有限的,針對這種情況,為了節省系統的中斷資源,本文設計了一個基于VxWorks的多串口共享中斷的驅動程序,并對該驅動程序的功能進行了長時間測試驗證。
1 串行設備驅動的結構
在VxWorks操作系統中,串行設備作為一種特殊的字符型設備,操作系統為其提供一個簡單、統一、獨立于設備的接口,在應用層對于串行設備的任何操作都可以視為對一個文件的操作,而具體的實現是通過串行設備的驅動程序來完成。
在VxWorks中串行設備驅動采用3層抽象的軟件結構,即I/O系統、虛擬設備ttyLib或tyLib以及硬件驅動,其結構示意圖如圖1所示。在VxWorks中,I/O系統并不直接與具體的硬件驅動進行交互,而是將驅動程序中與硬件無關的部分放在虛擬設備ttyLib中實現,再利用虛擬設備ttyLib與I/O系統進行通訊,使得I/O系統獨立于具體的硬件驅動,而驅動程序的開發者只需要實現系統所提供的接口并且將其掛載到虛擬設備ttyLib就能完成具體串行設備驅動的設計,從而保證驅動代碼的可復用性和接口的統一性。
2 串行設備驅動的實現
VxWorks在啟動過程中對串行設備驅動的實現主要包括兩部分:串口的初始化和串行設備的創建。串口的初始化主要包括初始化串口設備,分配串口所需的資源以及完成串口中斷程序的系統掛接;串行設備的創建包括tty驅動的初始化和對tty設備的創建,即建立起I/O系統與硬件驅動層的聯系。
2.1 串口的初始化
sysInit()作為VxWorks操作系統啟動的入口程序會調用第一個C程序函數usrInit(),完成用戶定義系統的初始化工作,而串口的硬件初始化是在usrInit()函數的子函數sysHwInit()中完成。對于VxWorks現有的Intel8250驅動(Tornado目錄/target/src/drv/sio/i8250Sio.c),sysHwInit()還會調用sysSerial.c文件下的sysSerialHwInit(),sysSerialHwInit()函數主要對串行設備的設備描述符進行初始化,在初始化過程中還會調用底層的i8250HrdInit()對串行設備的端口進行初始化。在完成系統硬件和VxWorks內核的初始化以后,系統會啟動一個函數名為usrRoot()的任務,usrRoot()作為VxWorks操作系統的根任務調用sysClkConnect()對系統時鐘中斷進行配置,而具體的工作是由sysClkConnect()的子函數sysHwInit2()完成,其中sysHwInit2()會調用sysSerialHwInit2()來完成串行設備的中斷掛接。
2.2 串行設備的創建
在usrRoot()中通過調用ttyDrv()完成tty驅動的初始化,而ttyDrv()則調用iosDrvInstall()將tty驅動添加到系統的驅動程序列表中,并且完成與I/O系統層的各系統操作函數的連接。tty虛擬設備層與底層硬件驅動的連接則是通過ttyDevCreate()來完成,并實現各個串行設備的創建。
3 多串口共享中斷的驅動程序開發
串口擴展板選用的是盛博的A3-CSD板卡,采用PC104總線接口,集成了4路16C554兼容的光電隔離異步串行口,每個串行口能獨立控制發送與接受,且具有16字節FIFO以減少中斷請求次數,此外該擴展板還具有一個串口中斷狀態指示寄存器,可以指示產生中斷的串口。根據上述硬件配置,可以在現有Intel8250驅動的基礎上進行改進來完成多串口共享中斷的驅動程序設計。
3.1 串口設備的初始化
每個串口設備都需要有一個的描述自身屬性的結構體I8250_CHAN_EX,即設備描述符,且結構體的第一個成員必須為指向SIO_DRV_FUNCS結構的指針,該結構體還包含描述16C554芯片各個端口的信息以及提供給高層協議的回調函數。在系統啟動過程中通過調用sysSerialHwInitEx()完成對該結構體的初始化并且將自定義的全局指針數組pi8250ChanEx[4]中各元素分別指向4個串口的I8250_CHAN_EX結構體,初始化過程中會調用i8250HrdInitEx()將串口驅動程序的設備操作入口函數安裝到SIO_DRV_FUNCS結構中,然后調用sysSerialHwInitEx2()完成串口中斷的系統連接。其中sysSerialHwInitEx2()的實現代碼為:
void sysSerialHwInitEx2 (void)
{
int i;
for (i = 0; i < N_UART_CHANNELS_EX; i++)
if (i8250ChanEx[i].int_vec)
{/*將四個串口設備的中斷服務程序i8250ShareIntEx ()連接到同一中斷*/
(void) intConnect (INUM_TO_IVEC (i8250ChanEx[i].int_vec),
i8250ShareIntEx, (int)&i8250ChanEx[i] );
if (sysBp)
sysIntEnablePIC (devParasEx[i].intLevel);/*中斷使能*/
}}
其中,宏N_UART_CHANNELS_EX表示串口設備的個數,i8250ChanEx結構的成員變量int_vec表示該串口的系統中斷號,這里每個i8250ChanEx結構的int_vec項值都是相同的。
3.2 串口驅動程序的入口點函數編寫
編寫串口設備驅動程序需要完成串口設備的入口點函數,這些函數包括控制命令函數i8250IoctlEx(),啟動發送循環函數i8250StartupEx(),輪詢方式輸入函數i8250PRxCharEx(),輪詢方式輸出函數i8250PTxCharEx(),回調安裝函數i8250CallbackInstallEx(),單串口中斷服務函數i8250IntEx(),多串口共享中斷服務函數i8250ShareIntEx()等函數。這里只列出多串口共享中斷服務函數i8250ShareIntEx(),其余函數可以參考i8250Sio.c文件的各相應函數。
void i8250ShareIntEx (I8250_CHAN_EX*pChan)
{
FASTintoldlevel;
oldlevel = intLock(); /*關閉系統中斷*/
IntStatus = sysInByte(UART_INT_STATUS); /*讀串口中斷狀態指示寄存器* /
while(( IntStatus & 0x0F) != 0x00 )/*判斷是否有串口中斷產生*/
{
if (IntStatus & COM0_ INT _FLAG)
i8250IntEx(pi8250ChanEx[0]);/*串口1產生了中斷*/
……………
if (IntStatus & COM3_ INT _FLAG)
i8250IntEx(pi8250ChanEx[3]);/*串口4產生了中斷*/
}
intUnlock(oldlevel); /*開啟系統中斷*/
}
其中,全局變量pi8250ChanEx為I8250_CHAN_EX結構的指針數組,分別指向4個串口設備所對應的I8250_CHAN_EX結構,宏UART_INT_STATUS表示串口中斷狀態指示寄存器地址。
在進入i8250ShareIntEx()后首先關閉系統中斷,通過查詢串口中斷狀態指示寄存器來判斷產生中斷的串口設備,然后將產生此中斷的串口描述符結構體,即pi8250ChanEx[4]中對應的元素,作為參數傳遞給單串口中斷服務函數i8250IntEx(),最后重新開啟系統中斷。
3.3 以模塊加載串口驅動程序
在config.h中加入#undef INCLUDE_TTY_DEV,執行下面的代碼后生成一個o格式的串口驅動的庫文件8250SioEx.o,然后在應用程序中利用loadModule()將8250SioEx.o動態加載到內存中運行。
sysSerialHwInitEx();/*初始化串口設備*/
sysSerialHwInitEx2(); /*串口中斷的系統掛接*/
if (N_UART_CHANNELS_EX > 0)
{
ttyDrv();
for (int i = 0;i < N_UART_CHANNELS_EX;i++)
{
sprintf (tyName, "%s%d", "/tyCo/", i);
(void) ttyDevCreate (tyName, sysSerialChanExGet (i), 512, 512); /*創建tty設備*/
}
}
其中sysSerialChanExGet()返回一個描述串口設備的I8250_CHAN_EX結構體。
4 結束語
本文詳細分析了串行設備驅動程序的結構以及在VxWorks啟動過程中串行設備驅動程序的加載過程,設計了一個多串口共享中斷的驅動程序,利用該驅動程序對4個串口同時進行了連續10小時的數據收發測試,4個串口都能穩定地發送和接收數據。此外,在測試過程中發現在進入多串口共享中斷服務函數后需要將系統中斷關閉,待執行完中斷處理后再開啟系統中斷,否則會引起串口工作的不穩定。
參考文獻:
[1] 周啟平.VxWorks下設備驅動程序及BSP開發指南[M].北京:中國電力出版社,2004.
[2] 陳智育,溫彥軍,陳琪.VxWorks程序開發實踐[M].北京:人民郵電出版社,2004.
[3] VxWorks programmer’s guide version 2.0[Z].Wind River System Inc,1999.
[4] TL16C550 asynchronous communications element[Z].1998.
關鍵詞:DSP;TMS320C6416;PCI Linux2.6;驅動程序;DMA
中圖分類號:TP368.11 文獻標識碼:A文章編號:1007-9599(2012)04-0000-02
一、引言
數字信號處理器(DSP)在通訊、語音圖像處理、數據加密等各方面得到越來越廣泛的應用。TI C6000系列DSP芯片內嵌PCI接口,支持主/從模式的讀寫,以33MHz的工作頻率和32位地址/數據總線進行數據傳輸,理論上最高可以支持132MByte/s的數據傳輸,在速度上遠遠超過DSP常用的HPI、McBSP總線,完全可以滿足傳輸實時性的要求。
本文在Linux2.6內核下,以TMS320C6416 DSP數據加密卡為平臺,研究了PCI設備驅動程序的開發方法。首先介紹了常規的以IO內存方式對DSP進行讀寫操作的方法,接著結合DSP芯片特點,提出了一種基于DMA傳輸方式的DSP加密卡控制方法,與常規方法比,顯著地提高了傳輸速度,具有較高的應用價值。
二、TMS320C6416的PCI接口
TMS320C6416是一款TI公司生產的DSP芯片,屬于C6000系列。C6000系列DSP片內集成了一個主/從模式的PCI接口,可以通過PCI總線實現主機與DSP的互連。TMS320C6416的PCI接口由EDMA的地址產生硬件與DSP相連,支持PCI接口規范2.2版本[1]。
(一)PCI數據訪問
DSP內嵌PCI主要包含三類寄存器:PCI配置寄存器、PCI I/O寄存器以及存儲器映射寄存器。
PCI主機通過3個基地址空間(Base0-2)能夠訪問DSP全部的存儲器映射空間。如圖1所示,Base0空間定義了一段可預取4Mbytes的DSP存儲器空間。Base1定義了8Mbytes不可預取的存儲器空間。Base2定義了16Byte的I/O空間。當主機上電啟動后,主機操作系統執行配置事務,將DSP的內存和I/O區域映射到主機處理器的地址空間,此段空間的物理地址,可以通過讀取BASE0-2寄存器獲得[2]。
三、Linux驅動程序開發
Linux下對TMS320C6416加密卡進行驅動程序開發,要完成的工作主要包括:對PCI設備的查找、初始化、卸載,對字符設備的數據讀寫和控制,中斷處理等[3]。
(一)PCI設備初始化
在Linux2.6內核中,使用pci_driver結構體來定義PCI驅動。設備查找時通過id_table結構體中的的VENDER_ID、DEVICE_ID來區別不同的設備,對于TMS320C6416芯片,VENDER_ID和DEVICE_ID分別為0x104c、0xa106。
pci_driver結構體中的probe()函數向內核提供了對硬件進行探測并初始化的接口。probe()函數完成的功能有:
1.讀取DSP加密卡Base0-2空間基地址和中斷號,通過pci_read_config_dword()函數實現;
2.將IO內存空間映射到Linux內核虛擬地址空間。通過ioremap()函數實現;
3.申請DSP加密卡中斷服務程序。通過request_irq()函數實現;
4.申請DSP加密卡的主設備號,注冊DSP加密卡字符設備驅動程序。通過cdev_init()、cdev_add()函數實現。
初始化完成后,可以通過設置DSPP寄存器,訪問BASE0空間讀取DSP內存資源,基于I/O內存方式進行PCI數據讀寫關鍵代碼如下:
static ssize_t dsp_read(struct file *fp, char *buf, size_t size, loff_t *f_pos)
{
outl(*f_pos, dsp_dev.iospace+IO_DSPP_OFFSET); //設置DSPP寄存器
copy_to_user(buf,dsp_dev.bar0, size); //拷貝DSP內存至主機
}
在實際使用中, TMS320C6416 PCI接口可以采用DMA方式進行數據操作,通過DMA控制器直接傳輸I/O數據,可大大提高與主機通信的吞吐量。
(二)基于DMA傳輸的加密卡控制
在Linux2.6內核中,file_operations結構體中的ioctl()函數向應用程序提供了對硬件進行命令控制的接口。以DSP加密卡加解密控制命令為例,加密卡加密命令要完成的操作是:通過DMA讀操作將主機數據發送給DSP加密卡,等待DSP加密卡將數據加密完畢后,通過DMA寫操作將加密數據回傳給主機。詳細步驟如下:
1.主機調用內核函數get_free_page()申請DMA空間,調用virt_to_bus()函數將內核空間虛擬地址轉換成PCI總線地址,將此地址寫入到DSP端PCIMA寄存器中;
2.主機訪問Base1空間,調用writel()函數修改DSP端PCIMA、DSPMA寄存器配置DMA傳輸源地址、目的地址,修改DSP端PCIMC寄存器設置DMA傳輸方向并啟動DMA傳輸[4];
3.DMA傳輸完成后,DSP端響應MASTER OK中斷,在中斷中釋放信號量,開始數據加密操作。加密操作完成后,使用DMA方式將產生的密文數據回送給主機,并給主機發送中斷;
4.PC機響應 中斷,將密文數據拷貝至用戶空間。
(三)用戶態設備訪問
Linux系統下可通過使用命令insmod將驅動程序編譯生成的.ko文件插入到內核中,從而實現驅動程序的模塊化動態加載。使用mknod命令創建由主、次設備號確定的加密卡設備文件,然后就可以像操作普通文件一樣來操作DSP加密卡設備。打開設備文件后,就可以實現對設備進行諸如數據讀寫、設備控制等操作。
四、測試結果
在主機上編寫測試程序,設置DSP的EMIF工作在100 MHz/133 MHz時鐘,數據線為32位。PCI總線工作在33MHz時鐘,使用DMA方式進行連續的數據讀寫,傳輸1GB的數據,測得DSP主模式下DMA方式數據寫操作速度為90Mbytes/s,讀操作速度為70MBytes/s,實驗證明,所開發的驅動程序使用良好穩定,傳輸高效,滿足高速數據傳輸和高速數據處理的需要。
參考文獻:
[1]Texas Instruments.TMS320C6000 DSP Peripheral Component Interconnect(PCI)Reference Guide[Z].2007:20221
[2][美]Jonathan C,Alessandro R.LINUX設備驅動程序(第2版)[M].北京:中國電力出版社,2006
[3]宋寶華,華清遠見.LINUX設備驅動開發詳解[M].北京:人民郵電出版社,2010
[4]李靜,趙保軍.基于TMS320C6416內嵌PCI設備驅動程序開發[J].微機發展,2005(10):135-137
計算機專業的學生在初開始接觸專業課時就要學習程序設計,程序設計的學習比較困難,就算對一些理論知識有所理解,但是在實踐階段也很難有效的掌握其技巧與技術。特別是對程序語言設計的學習,很多學生感到不知所措,無從下手。
1.1學生感到程序設計較難理解
計算機程序設計的學習困境主要表現在概念難懂,技術難以掌握,理論與實踐的脫節等方面,尤其是在程序語言學習中面向對象程序設計語言時,絕大多數的學生不理解面向對象程序設計思想,不會使用類的思想進行程序設計。往往感到困難重重而方式深入學習,導致學習成績節節下滑,不利于后來其他計算機專業課的學習。
1.2主動學習能力差
學生長期在傳統應試教育環境影響下,形成了被動學習的習慣,缺乏學習的積極性與主動性,另外還有一些學生養成的不良學習習慣,在課堂學習中情緒比較懶散,精神比較散漫,對教師所講的內容沒有興趣,這樣很難提高學生學習成績,影響教學效果的提高。
1.3實踐能力不高
計算機是一門實踐性比較強的學科,不僅需要學生掌握基本的理論知識,更重要的是理論應用于實際的能力,因為學習計算機的目的就是解決實際中遇到的問題。但是在實際教學中,很多教師設計的教學目標脫離學生的應用宗旨,教學過程中理論課比較多,實踐課程比較少,這樣較難培養學生的實際動手操作能力,很難真正提高教學效果。
1.4教學方法單一
過去教師一般采用傳統的教學方法,從程序設計的概念出發,圍繞理論知識點加以講解,過多注重理論知識的講解,而教材中的實力一般與學生實際生活相差較遠,學生在學習的過程中感到生澀難懂,只會比葫蘆畫瓢,不會舉一反三,缺乏獨立思考問題和解決問題的能力。教師在教學過程中忽略了學生的主體地位,較難提高學生學習興趣,同時也達不到較好的學習效果。
2項目驅動教學模式特點
2.1項目實踐環境突出
項目驅動教學過程中,導師帶領學生在學習專業理論知識的同時進行實際應用項目的開發。學生與老師在學習的過程中始終處于一種相互配合、溝通的環境下,強調學生的自主學習、積極溝通、勇于實踐。學生在項目驅動下,帶著問題進行有效的學習,這樣能夠培養學生思維擴散能力、動手操作能力與團結合作精神。
2.2強調教師的引導作用
項目驅動教學模式注重把理論知識轉化為實際技術,在教學過程中教師僅僅起引導學習的作用,課堂的主體是學生。學生按照項目需求被劃分為若干個小組,導師在課堂中主要監督、指導學生行為,在項目學習過程中導師要隨時解答學生的疑問,為學生補充技能知識,實時啟發學生在項目學習中解決問題的正確思路,開發學生思維創造能力,幫助學生掌握項目技能。
2.3培養學生計算機專業能力
項目驅動模式的實施目的是提高學生軟件開發與應用能力,事件性知識一般比較隱蔽,而項目驅動教學能夠通過教學過程中各種功能的實施,使一些隱藏在軟件開發過程中的核心要素顯現出來,通過這種方式的學習,學生將很快的具備軟件應用開的基本能力,提高學生實踐能力與應用能力。
3項目驅動教學實施過程
3.1項目設計
項目驅動模式教學過程中,首先導師要根據程序設計教學內容,設定教學目標,將教學計劃、目標融入到教學項目中,然后將整個教學項目按照學習小組分成若干個獨立的小項目,再把這些小項目按組分配給學生,最后導師圍繞項目內容設計具體教學內容,項目來源一般源自于教師縱橫向教學項目。
3.2實施形式
利用項目驅動模式進行教學的過程中,學生需要進入專門的工作室進行軟件程序的學習與開發。在工作室中,主要的學習方式是自學,教師在這種模式下主要起引導作用,課程知識除了很少部分較深的理論課由導師專門講授以外,其他的課程都是學生圍繞項目進行自主學習、合作學習,主要學習方式包括:小組研討、導師解疑、技術交流、調查研究等形式;課程的具體的實施要根據教學內容以及學生的實際認知情況進行合理的分配。這種教學模式的目的在于各種信息技術及認知提高計算機教學質量和效率,培養學生自主學習能力、創新能力和勇于探索精神以及實踐能力。其中自主學習是由學生自己積極主動的去學習,在學習過程中導師的角色是解答疑問,并不是直接幫學生解決問題,導師可以向學生傳授解決問題的方法和思路,引導學生向正確的解答思路上靠,提供給學生解決問題的資料,引導學生圍繞疑問積極探索。如果學生在學習過程中遇到難以解決的問題,導師首先要積極引導學生找到解決問題的方法,同時教會學生利用移動通信、互聯網、QQ以及電子郵件等先進技術手段進行搜索或者在線討論與交流,尤其要教會學生怎樣使用互聯網查詢資料,豐富程序設計知識,提高深深學習能力。在個人自主學習的基礎上進行小組討論與交流,在交流中不僅擴展知識與視野,而且能培養團隊協作精神,增進同學之間的感情。導師還要積極引導學生發現規律,找到自己的不足,積極改正,不斷超越自我。
3.3項目驅動教學模式中的成績評定
成績評定是項目驅動模式教學的重要組成部分,成績評定一般具有激勵、引導和反饋的作用,能夠全面反映學生的近況。成績評定比較重視學生在學習過程中能否解決實際問題,旨在培養學生動手操作的能力和創新能力以及計算機素養,樹立科學精神和堅韌不拔的性格以及積極向上的人生觀。如果學生成績提高,教師要給予鼓勵和表揚,激勵學生再接再厲。成績評定的方式采用項目答辯的形式進行,每個小組派出一個代表作主辯手,其他學生補充,導師可以隨時提問,最后結合項目答辯情況給出學生最終考核成績。
4結語