引言
Windows CE是一個開放的、可升級、可裁減的32位實(shí)時嵌入式操作系統(tǒng),具有可靠性好、實(shí)時性高、內(nèi)核體積小的特點(diǎn),廣泛應(yīng)用于工業(yè)控制、信息家電、移動通信、汽車電子、個人電子消費(fèi)品等領(lǐng)域。最新版本W(wǎng)indows Em-bedded CE 6.0于2006年11月發(fā)布,其特點(diǎn)有:最大進(jìn)程數(shù)量到32K,且每個進(jìn)程有最大2 GB的虛擬內(nèi)存空間;將關(guān)鍵的驅(qū)動程序、文件系統(tǒng)和圖形界面管理器移到了內(nèi)核中,大大減少了CPU在內(nèi)核態(tài)和用戶態(tài)間切換造成的性能損失等。 LPC3250是NXP半導(dǎo)體公司(由Philips公司成立)推出的帶有矢量浮點(diǎn)協(xié)處理器的ARM926EJ-SCPU內(nèi)核的微控制器。它具有豐富的外圍接口,包括7個UART,其中4個是標(biāo)準(zhǔn)UART,另外3個是高速UART,都帶有64字節(jié)的接收和發(fā)送FIFO,最高可支持的速率達(dá)921 600 b/s。為了實(shí)現(xiàn)低功耗,LPC3250采用NXP半導(dǎo)體先進(jìn)的開發(fā)技術(shù)來優(yōu)化內(nèi)在功率,并使用增強(qiáng)型的軟件控制結(jié)構(gòu)使基于功率管理的應(yīng)用得到優(yōu)化。在同時要求高性能和低功耗的嵌入式應(yīng)用中,運(yùn)行Win-dows CE的LPC3250平臺將會有很好的市場前景,對于最常用到的串口的驅(qū)動開發(fā)顯得尤為重要。
1 WindOWS CE的串口驅(qū)動模型
基于Windows CE有兩種驅(qū)動程序模型:本機(jī)設(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)的代碼,它通過實(shí)現(xiàn)一些操作系統(tǒng)預(yù)先定義的接口來實(shí)現(xiàn)某一類設(shè)備的通用功能,通常由微軟提供。操作系統(tǒng)與MDD層之間通過DDI(設(shè)備驅(qū)動接口)進(jìn)行交互。MDD層也實(shí)現(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層的標(biāo)準(zhǔn)流設(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實(shí)現(xiàn),真正與物理底層操作的是CPdd16550的數(shù)據(jù)成員CReg16550中的 Write_XXX、Read_XXX函數(shù));最終通過調(diào)用WRITE_PORT_UCHAR和READ_PORT_UCHAR系統(tǒng)函數(shù)來實(shí)現(xiàn)。
2 WinCE6.0下的LPC3250串口驅(qū)動程序開發(fā)
Windows CE的串口驅(qū)動程序開發(fā)中最重要的是兩點(diǎn):配置串口相關(guān)的寄存器和處理中斷。配置寄存器,包括實(shí)現(xiàn)與物理底層操作的函數(shù),將寄存器地址映射到內(nèi)核進(jìn)程的虛擬地址,在串口操作的不同階段配置好各種寄存器;處理中斷,包括將物理中斷映射為系統(tǒng)中斷,將中斷與事件綁定,中斷發(fā)生時進(jìn)行相應(yīng)的中斷處理。
LPC3250串口與‘550工業(yè)規(guī)范的串口有差異,為了保證程序的通用性和盡量減少代碼量,在實(shí)現(xiàn)LPC3250串口驅(qū)動程序時,需要繼承 CPdd16550和CReg16550類,根據(jù)實(shí)際的硬件特性實(shí)現(xiàn)它們的純虛函數(shù)并擴(kuò)展其虛函數(shù)的功能,配置硬件相關(guān)的寄存器和修改相關(guān)代碼。首先實(shí)現(xiàn) CReg16550的繼承類CRegLPC32xx,主要實(shí)現(xiàn)與物理底層操作的函數(shù)Write_xxx和Read_xxx,對串口寄存器進(jìn)行讀寫操作。這里要注意的是LPC3250串口寄存器地址間隔是32位,而不是標(biāo)準(zhǔn)的8位;CPdd16550的繼承類Clpc32xxPdd16550UART本質(zhì)還是個抽象類,同時為標(biāo)準(zhǔn)串口和高速串口服務(wù),要重新實(shí)現(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)核進(jìn)程的虛擬地址。
在MapHardware中,用GetWindowInfo根據(jù)串口的Active注冊表鍵獲得串口的全部I/O端口和內(nèi)存地址信息,然后用 MmMapIoSpace函數(shù)將串口物理地址和相關(guān)控制寄存器地址轉(zhuǎn)換成內(nèi)核進(jìn)程的虛擬地址,以便后面對寄存器進(jìn)行操作,部分代碼如下:
CreateHardwareAccess函數(shù)根據(jù)MapHardware得到的m_pBaseAddress,構(gòu)造一個CRegLPC32xx類實(shí)例,然后調(diào)用CRegLPC32xx類的Init函數(shù)確保串口控制器硬件進(jìn)入穩(wěn)定的工作狀態(tài)。
根據(jù)LPC3250的數(shù)據(jù)手冊,設(shè)置標(biāo)準(zhǔn)UART的波特率需要設(shè)置小數(shù)波特率預(yù)分頻器和UART波特率發(fā)生器。當(dāng)不用小數(shù)波特率預(yù)分頻器(即X=Y=1) 時,將標(biāo)準(zhǔn)UART的{Baudrate,DLM:DLL}的值定義一個數(shù)組BaudPairs[]。GetDivisorOfRate根據(jù)這個數(shù)組得到分頻系數(shù),然后調(diào)用父類的成員函數(shù)SetBaudRate便可設(shè)置波特率。高速UART的波特率類似,只是波特率計(jì)算公式和分頻系數(shù)與標(biāo)準(zhǔn)UART不同。
用GetWaterMark得到接收器FIFO的觸發(fā)深度,分別為16、32、48和60位,然后在CPdd16550的InitReceive中設(shè)置FIFO控制寄存器,默認(rèn)的FIFO觸發(fā)深度是32位。
Clpc32xxPdd16550UART是個抽象類,實(shí)現(xiàn)通用功能,具體的要分別由繼承的標(biāo)準(zhǔn)串口Clpc32xxPdd16550Stan- dardUART類和高速串口Clpc32xxPdd16550HighUART類實(shí)現(xiàn)。在各自初始化時,主要是配置各種寄存器,實(shí)現(xiàn)具體硬件差異化,包括:配置UART時鐘控制寄存器、時鐘模式寄存器和時鐘選擇寄存器,分別使能UART時鐘、設(shè)置自動時鐘模式、選擇相應(yīng)的時鐘源作為分頻器的輸入時鐘;禁止UART3 Modem和UART6 IrDA功能;禁止UART的回送功能。
特別要強(qiáng)調(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)生時是否進(jìn)入相應(yīng)的處理程序。中斷處理好了,串口驅(qū)動就基本完成了。
上述工作結(jié)束后,就要添加串口的注冊表。以串口3為例,主要是設(shè)置動態(tài)鏈接庫DLL、設(shè)備基地址、中斷號、前綴名、被加載的順序等。根據(jù)注冊表的 DeviceArrayIn-dex、CreateSerialObject就可以構(gòu)造標(biāo)準(zhǔn)串口或高速串口類實(shí)例了, DeleteSerialObject在退出驅(qū)動時刪除實(shí)例。具體代碼如下:
在廣州致遠(yuǎn)電子有限公司的SmartARM3250開發(fā)板上,通過WinCE的串口應(yīng)用程序與上位PC機(jī)進(jìn)行發(fā)送接收實(shí)驗(yàn),本驅(qū)動已經(jīng)實(shí)現(xiàn)標(biāo)準(zhǔn)串口最高460 800 b/s、高速串口最高921 600 b/s的穩(wěn)定傳輸。
結(jié)語
本文介紹了WinCE6.0下的串口驅(qū)動模型,結(jié)合LPC3250的硬件情況,詳細(xì)說明了串口驅(qū)動開發(fā)過程,包括配置串口相關(guān)的寄存器和處理中斷中重要函數(shù)的實(shí)現(xiàn),以及注冊表和Source文件編寫等。本驅(qū)動程序在廣州致遠(yuǎn)電子有限公司的SmartARM3250開發(fā)板上實(shí)驗(yàn)成功。在串口驅(qū)動開發(fā)中所用的思路,對其他類似的驅(qū)動設(shè)計(jì)有較高的參考價值。
責(zé)任編輯:gt
-
WINDOWS
+關(guān)注
關(guān)注
4文章
3612瀏覽量
91355 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
7140瀏覽量
125527 -
應(yīng)用程序
+關(guān)注
關(guān)注
38文章
3333瀏覽量
59003
發(fā)布評論請先 登錄
嵌入式操作系統(tǒng)Windows CE研究
怎么在不同的硬件設(shè)備上實(shí)現(xiàn)Windows CE的驅(qū)動開發(fā)?
Windows CE下的串口驅(qū)動設(shè)計(jì)
Windows CE遠(yuǎn)程應(yīng)用程序接口(Remote API)
嵌入式操作系統(tǒng)Windows CE的研究
Windows CE.Net下基于流驅(qū)動的AD驅(qū)動設(shè)計(jì)與實(shí)現(xiàn)
什么是Windows CE,LynxOS是什么操作系統(tǒng)
Windows CE下事件驅(qū)動的串行通信方式
Windows CE平臺上開發(fā)采集板驅(qū)動程序
Windows CE驅(qū)動程序開發(fā)
Windows CE設(shè)備驅(qū)動程序開發(fā)
Windows CE在指紋傳感器設(shè)備驅(qū)動程序開發(fā)中的應(yīng)用
在Windows CE下實(shí)現(xiàn)串口通信
Windows CE操作系統(tǒng)在工業(yè)控制領(lǐng)域的應(yīng)用
基于Windows CE操作系統(tǒng)實(shí)現(xiàn)OAL層的功能和結(jié)構(gòu)應(yīng)用設(shè)計(jì)

評論