《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 設(shè)計應(yīng)用 > 基于WinCE6.0的LPC3250串口驅(qū)動程序開發(fā)
基于WinCE6.0的LPC3250串口驅(qū)動程序開發(fā)
摘要: 本文介紹了WinCE6.0下的串口驅(qū)動模型,,結(jié)合LPC3250的硬件情況,,詳細說明了串口驅(qū)動開發(fā)過程,包括配置串口相關(guān)的寄存器和處理中斷中重要函數(shù)的實現(xiàn),,以及注冊表和Source文件編寫等。本驅(qū)動程序在廣州致遠電子有限公司的SmartARM3250開發(fā)板上實驗成功,。在串口驅(qū)動開發(fā)中所用的思路,,對其他類似的驅(qū)動設(shè)計有較高的參考價值。
Abstract:
Key words :

引 言

Windows CE是一個開放的,、可升級,、可裁減的32位實時嵌入式操作系統(tǒng),具有可靠性好,、實時性高,、內(nèi)核體積小的特點,廣泛應(yīng)用于工業(yè)控制,、信息家電,、移動通信、汽車電子,、個人電子消費品等領(lǐng)域,。最新版本W(wǎng)indows Em-bedded CE 6.0于2006年11月發(fā)布,其特點有:最大進程數(shù)量到32K,,且每個進程有最大2 GB的虛擬內(nèi)存空間,;將關(guān)鍵的驅(qū)動程序、文件系統(tǒng)和圖形界面管理器移到了內(nèi)核中,,大大減少了CPU在內(nèi)核態(tài)和用戶態(tài)間切換造成的性能損失等,。 LPC3250" title="LPC3250">LPC3250是NXP半導(dǎo)體公司(由Philips公司成立)推出的帶有矢量浮點協(xié)處理器的ARM926EJ-SCPU內(nèi)核的微控制器。它具有豐富的外圍接口,,包括7個UART,,其中4個是標準UART,另外3個是高速UART,,都帶有64字節(jié)的接收和發(fā)送FIFO,,最高可支持的速率達921 600 b/s,。為了實現(xiàn)低功耗,LPC3250采用NXP半導(dǎo)體先進的開發(fā)技術(shù)來優(yōu)化內(nèi)在功率,,并使用增強型的軟件控制結(jié)構(gòu)使基于功率管理的應(yīng)用得到優(yōu)化,。在同時要求高性能和低功耗的嵌入式應(yīng)用中,運行Win-dows CE的LPC3250平臺將會有很好的市場前景,,對于最常用到的串口的驅(qū)動開發(fā)顯得尤為重要,。

1 WindOWS CE的串口驅(qū)動" title="串口驅(qū)動">串口驅(qū)動模型

基于Windows CE有兩種驅(qū)動程序模型:本機設(shè)備驅(qū)動程序和流接口驅(qū)動程序。串口驅(qū)動就屬于分層的流接口驅(qū)動程序,。分層驅(qū)動程序?qū)⒃O(shè)備的驅(qū)動程序分為兩層:平臺相關(guān)驅(qū)動 PDD(Platform Dependence Driver)層和模型設(shè)備驅(qū)動MDD(Model Device Driver)層,。PDD層由特定于給定硬件設(shè)備或平臺的代碼組成,很多時候用戶需要根據(jù)具體平臺修改,;MDD層包含平臺無關(guān)的代碼,,它通過實現(xiàn)一些操作系統(tǒng)預(yù)先定義的接口來實現(xiàn)某一類設(shè)備的通用功能,通常由微軟提供,。操作系統(tǒng)與MDD層之間通過DDI(設(shè)備驅(qū)動接口)進行交互,。MDD層也實現(xiàn)了中斷處理線程IST,并定義一些與PDD層的接口函數(shù),,這些接口函數(shù)稱為DDSI(設(shè)備驅(qū)動服務(wù)接口),。

用%_WinCEROOT%來表示W(wǎng)indows CE的安裝根目錄,符合‘550工業(yè)規(guī)范的串口驅(qū)動源碼主要位于\%_WINCEROOT%\PUBLIC\COMMON\OAK\DRIVERS\SERIAL下,,主要看表1所列的一些重要文件。

如圖1所示,,串口應(yīng)用程序通過設(shè)備管理器調(diào)用mdd.c中MDD層的標準流設(shè)備驅(qū)動接口COM_XXX,,在COM_XXX中通過結(jié)構(gòu)體 HW_INDEP_INFO中HWOBJ結(jié)構(gòu)體調(diào)用串口硬件操作函數(shù)HWxxx;然后在cserpdd.cpp中GetSeri-alObject函數(shù)通過HW_VTBL類型數(shù)組IoVTb1將HWxxx映射為Serxxx系列函數(shù),,Serxxx系列函數(shù)則調(diào)用CSerialPDD類中的成員函數(shù)(其中的純虛函數(shù)由CserialP-DD的繼承類CP-dd16550實現(xiàn),,真正與物理底層操作的是CPdd16550的數(shù)據(jù)成員CReg16550中的 Write_XXX、Read_XXX函數(shù)),;最終通過調(diào)用WRITE_PORT_UCHAR和READ_PORT_UCHAR系統(tǒng)函數(shù)來實現(xiàn),。


2 WinCE6.0" title="WinCE6.0">WinCE6.0下的LPC3250串口驅(qū)動程序開發(fā)

Windows CE的串口驅(qū)動程序開發(fā)中最重要的是兩點:配置串口相關(guān)的寄存器和處理中斷。配置寄存器,,包括實現(xiàn)與物理底層操作的函數(shù),,將寄存器地址映射到內(nèi)核進程的虛擬地址,在串口操作的不同階段配置好各種寄存器,;處理中斷,,包括將物理中斷映射為系統(tǒng)中斷,將中斷與事件綁定,,中斷發(fā)生時進行相應(yīng)的中斷處理,。

LPC3250串口與‘550工業(yè)規(guī)范的串口有差異,為了保證程序的通用性和盡量減少代碼量,在實現(xiàn)LPC3250串口驅(qū)動程序時,,需要繼承 CPdd16550和CReg16550類,,根據(jù)實際的硬件特性實現(xiàn)它們的純虛函數(shù)并擴展其虛函數(shù)的功能,配置硬件相關(guān)的寄存器和修改相關(guān)代碼,。首先實現(xiàn) CReg16550的繼承類CRegLPC32xx,,主要實現(xiàn)與物理底層操作的函數(shù)Write_xxx和Read_xxx,對串口寄存器進行讀寫操作,。這里要注意的是LPC3250串口寄存器地址間隔是32位,,而不是標準的8位;CPdd16550的繼承類Clpc32xxPdd16550UART本質(zhì)還是個抽象類,,同時為標準串口和高速串口服務(wù),,要重新實現(xiàn)Init、GetDivisorO-{Rate,、GetWaterMark,、 MapHardware、CreateHardwareAc-cess,、CreateSerialObject,、DeleteSerialObject等函數(shù),其他的函數(shù)可以直接調(diào)用CPdd16550的成員函數(shù),,只需要修改相關(guān)串口寄存器的宏定義,。


在Clpc32xxPdd16550UART的Init函數(shù)中,GetIsrInfo以串口的Active注冊表鍵為依據(jù)查出物理中斷號,,并保存在 DDKISRINFO結(jié)構(gòu)體的dwlrq成員中,。KernelloCon-trol函數(shù)將物理中斷號轉(zhuǎn)換為邏輯中斷號,符合條件就將邏輯中斷號回寫到注冊表中,。相關(guān)代碼如下:

接著調(diào)用父類CPdd16550的Init函數(shù),,創(chuàng)建中斷服務(wù)線程(IST)事件,并通過InterruptInitialize函數(shù)將事件與邏輯中斷號關(guān)聯(lián)起來,,最后調(diào)用CreateHardwareAccess和MapHardware函數(shù)將串口基地址及相關(guān)寄存器片內(nèi)地址映射到內(nèi)核進程的虛擬地址,。
在MapHardware中,用GetWindowInfo根據(jù)串口的Active注冊表鍵獲得串口的全部I/O端口和內(nèi)存地址信息,,然后用 MmMapIoSpace函數(shù)將串口物理地址和相關(guān)控制寄存器地址轉(zhuǎn)換成內(nèi)核進程的虛擬地址,,以便后面對寄存器進行操作,部分代碼如下:

CreateHardwareAccess函數(shù)根據(jù)MapHardware得到的m_pBaseAddress,,構(gòu)造一個CRegLPC32xx類實例,,然后調(diào)用CRegLPC32xx類的Init函數(shù)確保串口控制器硬件進入穩(wěn)定的工作狀態(tài)。

根據(jù)LPC3250的數(shù)據(jù)手冊,,設(shè)置標準UART的波特率需要設(shè)置小數(shù)波特率預(yù)分頻器和UART波特率發(fā)生器,。當不用小數(shù)波特率預(yù)分頻器(即X=Y=1) 時,,將標準UART的{Baudrate,DLM:DLL}的值定義一個數(shù)組BaudPairs[],。GetDivisorOfRate根據(jù)這個數(shù)組得到分頻系數(shù),,然后調(diào)用父類的成員函數(shù)SetBaudRate便可設(shè)置波特率。高速UART的波特率類似,,只是波特率計算公式和分頻系數(shù)與標準UART不同,。

用GetWaterMark得到接收器FIFO的觸發(fā)深度,分別為16,、32,、48和60位,然后在CPdd16550的InitReceive中設(shè)置FIFO控制寄存器,,默認的FIFO觸發(fā)深度是32位,。

Clpc32xxPdd16550UART是個抽象類,實現(xiàn)通用功能,,具體的要分別由繼承的標準串口Clpc32xxPdd16550Stan- dardUART類和高速串口Clpc32xxPdd16550HighUART類實現(xiàn),。在各自初始化時,主要是配置各種寄存器,,實現(xiàn)具體硬件差異化,,包括:配置UART時鐘控制寄存器、時鐘模式寄存器和時鐘選擇寄存器,,分別使能UART時鐘,、設(shè)置自動時鐘模式、選擇相應(yīng)的時鐘源作為分頻器的輸入時鐘,;禁止UART3 Modem和UART6 IrDA功能,;禁止UART的回送功能。

特別要強調(diào)的是關(guān)于中斷的處理,,串口驅(qū)動中斷可以用動態(tài)映射,也可以用靜態(tài)映射,。在OEMInter-ruptHandler,、 Clpc32xxPdd16550UART::Init、CPdd16550::Init,、CPdd16550::ThreadRun等處加入調(diào)試打印信息,,可以較快地找到問題所在,確定硬件中斷是否映射為系統(tǒng)中斷,、系統(tǒng)中斷與中斷事件是否綁定,、中斷產(chǎn)生時是否進入相應(yīng)的處理程序。中斷處理好了,,串口驅(qū)動就基本完成了,。

上述工作結(jié)束后,,就要添加串口的注冊表。以串口3為例,,主要是設(shè)置動態(tài)鏈接庫DLL,、設(shè)備基地址、中斷號,、前綴名,、被加載的順序等。根據(jù)注冊表的 DeviceArrayIn-dex,、CreateSerialObject就可以構(gòu)造標準串口或高速串口類實例了,, DeleteSerialObject在退出驅(qū)動時刪除實例。具體代碼如下:





在廣州致遠電子有限公司的SmartARM3250開發(fā)板上,,通過WinCE的串口應(yīng)用程序與上位PC機進行發(fā)送接收實驗,,本驅(qū)動已經(jīng)實現(xiàn)標準串口最高460 800 b/s、高速串口最高921 600 b/s的穩(wěn)定傳輸,。

結(jié) 語

本文介紹了WinCE6.0下的串口驅(qū)動模型,,結(jié)合LPC3250的硬件情況,詳細說明了串口驅(qū)動開發(fā)過程,,包括配置串口相關(guān)的寄存器和處理中斷中重要函數(shù)的實現(xiàn),,以及注冊表和Source文件編寫等。本驅(qū)動程序在廣州致遠電子有限公司的SmartARM3250開發(fā)板上實驗成功,。在串口驅(qū)動開發(fā)中所用的思路,,對其他類似的驅(qū)動設(shè)計有較高的參考價值。 

此內(nèi)容為AET網(wǎng)站原創(chuàng),,未經(jīng)授權(quán)禁止轉(zhuǎn)載,。