關(guān)鍵詞:Zylonite Platform Builder BSP SD卡驅(qū)動(dòng)
0、引言
隨著通信領(lǐng)域新業(yè)務(wù)需求的不斷增長(zhǎng)及計(jì)算機(jī)技術(shù),半導(dǎo)體技術(shù)和電子技術(shù)的術(shù)的迅速發(fā)展,嵌入式系統(tǒng)異軍突起,已經(jīng)滲透到社會(huì)生活的方方面面了。它是集軟件,硬件于一體的高可靠性系統(tǒng)。其特點(diǎn)即為可以通過(guò)裁減裝卸系統(tǒng)模塊來(lái)配置整個(gè)平臺(tái)所要求的功能。
Windows CE是由微軟公司所開(kāi)發(fā)的一個(gè)嵌入式操作系統(tǒng),它與Windows平臺(tái)的編程接口有很強(qiáng)的兼容性。其平臺(tái)開(kāi)發(fā)工具Platform Builder是一個(gè)完全集成的開(kāi)發(fā)環(huán)境(IDE)。本項(xiàng)目所涉及的硬件開(kāi)發(fā)套件Intel Zylonite Development System裝配有Intel的Xscale芯片處理器Monahans L(PXA300),并配有相關(guān)外設(shè)電路接口(USB2.0,SD/MMC,音頻,以太網(wǎng)口等)及外設(shè)(觸摸屏,KEYPAD,揚(yáng)聲器,聽(tīng)筒,話筒等)。其獨(dú)特的結(jié)構(gòu)優(yōu)化能力保證了操作環(huán)境和通用應(yīng)用設(shè)備可以在高頻率和的情況下快速處理任務(wù)。
1、 WINCE 下的SD卡驅(qū)動(dòng)架構(gòu)
Wince 下SD卡驅(qū)動(dòng)協(xié)議棧組成 :
u HOST硬件底層部分 (主控制端驅(qū)動(dòng)) SDHC_XXX.DLL
u BUS 中間邏輯命令層 (總線驅(qū)動(dòng)) SDBUS.DLL
u CLIENT上層(客戶端驅(qū)動(dòng)) SDMEMORY.DLL
1.1、主控制端驅(qū)動(dòng)
主控制端驅(qū)動(dòng)控制包含主控制器硬件,遵循主控制端驅(qū)動(dòng)接口,它被用于總線驅(qū)動(dòng)通信和設(shè)置操作參數(shù)。主控制器驅(qū)動(dòng)接口提供一個(gè)硬件提取層,在總線和主控制端執(zhí)行之間。即:SDHC_XXX.DLL是層,因?yàn)檫@層是硬件關(guān)聯(lián)層,因此取名XXX便是為了對(duì)應(yīng)的具體的硬件BSP包(如本項(xiàng)目的硬件平臺(tái)是ZYLONITE,其硬件供應(yīng)商給的BSP包名即為ZYLONITE,在實(shí)際項(xiàng)目中我們便將SDHC_XXX.DLL取代為SDHC_ZYLONITE.DLL),它負(fù)責(zé)具體的發(fā)命令,大多數(shù)情況下都需要修改。
1.2、總線驅(qū)動(dòng)
總線驅(qū)動(dòng)作為提取和管理層處于主控制驅(qū)動(dòng)和客戶端驅(qū)動(dòng)之間。它包括在SDbus.dll文件。為客戶端驅(qū)動(dòng)提供了標(biāo)準(zhǔn)的API,允許運(yùn)行在任何的基于windows ce設(shè)備。總線驅(qū)動(dòng)將是獨(dú)立于應(yīng)用程序和主控制端驅(qū)動(dòng),在不同的處理器之間移植,并不需要改動(dòng)。SDBus.dll是中間層,負(fù)責(zé)整合命令和管理。
1.3、客戶端驅(qū)動(dòng)
客戶端驅(qū)動(dòng)和SD客戶端驅(qū)動(dòng)通信接口允許客戶端驅(qū)動(dòng)去和SD設(shè)備通信。客戶端驅(qū)動(dòng)接口是有計(jì)劃地抽象SD總線物理設(shè)備的執(zhí)行,提供了客戶端驅(qū)動(dòng)的彈性。客戶端驅(qū)動(dòng)接口允許客戶端驅(qū)動(dòng)去衡量一個(gè)單一的,同步的訪問(wèn)存儲(chǔ)卡驅(qū)動(dòng)使用一個(gè)線程,異步通信設(shè)備驅(qū)動(dòng)。SDMemory.dll是層,類(lèi)似于應(yīng)用層。
2.立足微軟SD卡協(xié)議棧開(kāi)發(fā)Zylonite 的BSP包的SD卡驅(qū)動(dòng)
當(dāng)我們開(kāi)發(fā)SD卡驅(qū)動(dòng)時(shí),并詳細(xì)分析比較了Microsoft的SD驅(qū)動(dòng)架構(gòu)和Intel所提供的BSP內(nèi)的參考SD卡驅(qū)動(dòng)以后,可以得出如下結(jié)論:
l 針對(duì)主控制端驅(qū)動(dòng)(SDHC_XXX.DLL):因?yàn)檫@一層是直接操作硬件的一層,所以大多數(shù)情況下都需要修改。修改的內(nèi)容基本為收發(fā)命令部分以及數(shù)據(jù)傳輸和硬件初始化部分.
l 針對(duì)總線驅(qū)動(dòng)(SDBUS.DLL):因?yàn)檫@一層處于主控制驅(qū)動(dòng)和客戶端驅(qū)動(dòng)之間,用于他們之間的通信,SD卡總線請(qǐng)求都放在它里面,微軟提供了非常完備的樣例代碼,所以我們一般都不需要改動(dòng),直接調(diào)用它的接口就可以了。
l 針對(duì)客戶端驅(qū)動(dòng)( SDMEMORY.DLL):因?yàn)镾DMemory就是所謂的Client層,類(lèi)似于應(yīng)用層,它還可用來(lái)識(shí)別卡的,不同種類(lèi)的卡,比如sd memory card等,鑒于我們只需開(kāi)發(fā)SD卡部分的驅(qū)動(dòng),所以也不需要怎么修改了(如果我要開(kāi)發(fā)SD接口的SDIO設(shè)備,那么就得在這層做比較大的改動(dòng)了)。
Intel所提供的BSP內(nèi)的參考SD卡驅(qū)動(dòng)自己實(shí)現(xiàn)了主控制端驅(qū)動(dòng)(SDHC_ZYLONITE.DLL),而調(diào)用并保留了總線驅(qū)動(dòng)(SDBUS.DLL)和客戶端驅(qū)動(dòng)( SDMEMORY.DLL)。因此結(jié)合具體的硬件設(shè)計(jì)(SD卡的CONNECTOR等),我們的主要任務(wù)便是利用BSP內(nèi)的SD卡主控制端驅(qū)動(dòng)代碼,開(kāi)發(fā)(配置并改進(jìn))我們實(shí)際項(xiàng)目?jī)?nèi)的SD卡驅(qū)動(dòng)。
2.1、Zylonite BSP內(nèi)的SD卡主控制端驅(qū)動(dòng)概述
SD卡的驅(qū)動(dòng)程序是以流的形式提供的,而該SD卡主控制端驅(qū)動(dòng)以sdhc_zylonite.dll 的形式提供,入口在: \WINCE500\PLATFORM\Zylonite\public\csp\monahans\sdhc
有如下兩個(gè)文件:
l sdcontrol.c:內(nèi)含一個(gè)非常重要的線程---SDControllerISTHandler,主要負(fù)責(zé)卡與控制器的交互,處理控制器接收的消息等,具體的控制和處理函數(shù)均在此文件中。
l main.c: SDH(主控制端驅(qū)動(dòng))的導(dǎo)出流接口在該文件中實(shí)現(xiàn),并包含有主控制端驅(qū)動(dòng)的(sdhc_zylonite.dll)的入口點(diǎn)。
SD卡硬件初始化及其主控制端驅(qū)動(dòng)的注冊(cè)表信息設(shè)置路徑為:
\WINCE500\PLATFORM\Zylonite\Platform\ZYLONITE\SRC\DRIVERS\SDHC
主要文件為:
l impl.c: 主要是在加載SD卡主控制端驅(qū)動(dòng)時(shí)初始化硬件。內(nèi)含一個(gè)非常重要的線程---- SDCardDetectIstThread,專門(mén)處理SD卡的插拔操作。但是具體的插拔操作也是在Sdcontrol.c文件實(shí)現(xiàn)的。
2.2、結(jié)合實(shí)際項(xiàng)目的開(kāi)發(fā)流程
2.2.1 SD卡的外部引腳及功能配置
在實(shí)際項(xiàng)目(一款以WINCE為操作系統(tǒng)內(nèi)核的GSM/PHS雙模智能手機(jī))中,SD卡的外部引腳與Monahans_L的GPIO連接圖及連接控制器的電路圖如下所示:
由上可得,先要配置SD卡的外部引腳及功能。而SD卡的引腳配置在其下的 \source 文件夾的xllp_mmc_board.c文件XllpMMCConfigure函數(shù)內(nèi)修改。(特別注意:GPIO34要配成檢測(cè)SD卡插入的中斷源。)
2.2.2、分析修改并改進(jìn)主控制端驅(qū)動(dòng)重要線程及硬件初始化部分代碼
l SD卡主控制端驅(qū)動(dòng)加載及架構(gòu)解析
需要聲明的是SD卡驅(qū)動(dòng)加載順序是:
加載SDBus.dll→加載sdhc_zylonite.dll→加載sdmemory.dll
我們?cè)谶@里只詳細(xì)討論第2步(sdhc_zylonite.dll的加載),此時(shí)SDBus.dll已經(jīng)加載成功。WINCE系統(tǒng)初始化后,會(huì)載入DEVICE.EXE, 對(duì)應(yīng)代碼devload.C中的WINMAIN函數(shù)會(huì)被調(diào)用起來(lái),從而啟動(dòng)InitDevice函數(shù),此函數(shù)會(huì)搜尋(\WINCE500\PLATFORM\Zylonite\Platform\ZYLONITE\SRC\DRIVERS\SDHC下的sdhc_zylonite.reg)注冊(cè)表根鍵,準(zhǔn)備參數(shù)調(diào)用WIN32 API接口-----Activedevice,接著利用Dllmaincrtstartup函數(shù)找到sdhc_zylonite.dll的入口,執(zhí)行該文件的入口函數(shù)DllMain()然后繼續(xù)返回到DEVICE.EXE(devload.C),調(diào)用launchdevice()函數(shù),再調(diào)用sdhc_zylonite.dll的入口main.c文件內(nèi)的SDH_Init(),自此將開(kāi)始將開(kāi)始SD卡主控制端驅(qū)動(dòng)的初始化過(guò)程:
1. 調(diào)用SDH_Init()
2. 調(diào)用 SDHCDAllocateContext() 來(lái)分配一段主控制器的上下文
a)Context 是總線驅(qū)動(dòng)和主控制端驅(qū)動(dòng)共享的
3. 主控制端驅(qū)動(dòng)使用SDHCDSetXxx宏來(lái)填充這個(gè)上下文結(jié)構(gòu)
a)這個(gè)步驟是把主控制器向總線驅(qū)動(dòng)描述一下
b)包括函數(shù)指針,支持的電流,時(shí)鐘,槽數(shù)目,SDIO的支持等等。
4. 調(diào)用 SDHCDRegisterHostController() 來(lái)把自己向總線驅(qū)動(dòng)注冊(cè)一下
5. 當(dāng)總線驅(qū)動(dòng)準(zhǔn)備處理SD事件時(shí),它會(huì)調(diào)用主控制端驅(qū)動(dòng)的init 函數(shù)(pContext->pInitHandler)
接著便是sdbus.dll驅(qū)動(dòng)部分的代碼和SD卡主控制端驅(qū)動(dòng)部分的交互設(shè)置:比如設(shè)置電源、時(shí)鐘和總線寬度等。一般都是sdbus.dll發(fā)起請(qǐng)求,再去調(diào)用主控制端驅(qū)動(dòng)部分的API,這里詳細(xì)分析插槽狀態(tài)交互確認(rèn),因?yàn)檫@是成功加載sdhc_zylonite.dll的關(guān)鍵。當(dāng)有SD卡在插槽,sdbus.dll的slotstatuschange()調(diào)用并建立一個(gè)重要線程SDcardDetectIstThread(),當(dāng)探測(cè)到有卡,即返回給sdbus.dll, 總線驅(qū)動(dòng)即可調(diào)用HandleAddDevice()函數(shù),自此初始化結(jié)束,sdhc_zylonite.dll加載成功。
l 對(duì)主控制端驅(qū)動(dòng)重要線程SDcardDetectIstThread()代碼的改進(jìn)
在前面的敘述中,可以看出線程SDcardDetectIstThread()在sdhc_zylonite.dll的加載起決定性作用。然而我們發(fā)現(xiàn)在INTEL所給的BSP中,在檢測(cè)卡的過(guò)程里,其采用了輪詢的方式----即每隔一定的時(shí)間,CPU都會(huì)去讀一次GPIO34的電平,以確定SD卡是否被插入或拔出,以此來(lái)判定是否去加載或卸載SD卡的客戶端和主控制端驅(qū)動(dòng)。很顯然,這種方式的弊端是占用了過(guò)多的CPU資源,效率很低,嚴(yán)重影響了整個(gè)系統(tǒng)的實(shí)時(shí)性。因此,能解決這個(gè)問(wèn)題的辦法無(wú)外乎是使用中斷檢測(cè)的方式。以下特別敘述采用2種不同的中斷機(jī)制的方式實(shí)現(xiàn):
1中斷綁定靜態(tài)配置:
1.在Bsp_cfg.h文件內(nèi)定義一個(gè)系統(tǒng)中斷號(hào)SYSINTR_SDMMC_DETECT
#define SYSINTR_SDMMC_DETECT (SYSINTR_FIRMWARE+N) N為當(dāng)前已定義的值(以保證此中斷未使用過(guò))。
2.在Xllp_gpio_plat.h文件中找出GPIO34的定義:#define XLLP_GPIO_MMC_CD_0 34
3.在intr.c文件里將系統(tǒng)中斷號(hào)和IRQ關(guān)聯(lián):
OALIntrStaticTranslate(SYSINTR_SDMMC_DETECT, IRQ_GPIO_SHARE(XLLP_GPIO_MMC_CD_0));
4.在主控制端驅(qū)動(dòng)的硬件初始化代碼Impl.c中的InitializeHardware()加入 EnablesdcardInterrupt()函數(shù)。
5.在Impl.c中完善EnablesdcardInterrupt(),加入GPIO上升沿或下降沿的檢測(cè)和SET EVENT。
6.在Impl.c文件中定義hCardInsertInterruptEvent并在SetupCardDetectIST()內(nèi)創(chuàng)建hCardInsertInterruptEvent
7.Impl.c文件中初始化dwSysintrCD= SYSINTR_SDMMC_DETECT,并綁定相應(yīng)的EVENT:InterruptInitialize (dwSysintrCD,hCardInsertInterruptEvent,NULL,0)
8. 改進(jìn)線程SDcardDetectIstThread()的While部分代碼,加入WaitForSingleObject( hCardInsertInterruptEvent, dwTimeout );只有當(dāng)hCardInsertInterruptEvent被置上,才會(huì)往下走,否則一直在此處等待。
9.同上原理改寫(xiě)CardremoveInterrupt用于動(dòng)態(tài)卸載SD卡主控制端驅(qū)動(dòng)。
2中斷綁定動(dòng)態(tài)配置:
1. 在Impl.c文件的SetupCardDetectIST()函數(shù)內(nèi)動(dòng)態(tài)配置系統(tǒng)中斷號(hào)和硬件中斷源:KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwSDCDIrq, sizeof(DWORD), &(dwSysintrCD), sizeof(DWORD), NULL))。此處的&dwSDCDIrq可在SD卡主控制端驅(qū)動(dòng)的注冊(cè)表內(nèi)更改后,用LoadPlatformRegistrySettings函數(shù)加載進(jìn)來(lái)。可在sdhc_zylonite.reg 文件內(nèi)將"CardDetectIRQ" 的值改為“IRQ_GPIO_SHARE_BASE+x-2” 在本平臺(tái)內(nèi),IRQ_GPIO_SHARE_BASE=52,X=34。
2. 接上5-6-7-8-9。
3、總結(jié)
本論文以Intel Xscale架構(gòu)為目標(biāo)平臺(tái),Windows CE為軟件的開(kāi)發(fā)環(huán)境,詳細(xì)解析了Windows CE 5.0下SD卡驅(qū)動(dòng)的整體架構(gòu)及具體的加載過(guò)程,此外,詳述了實(shí)際項(xiàng)目中SD卡驅(qū)動(dòng)開(kāi)發(fā)的流程。
本文作者創(chuàng)新點(diǎn):在實(shí)現(xiàn)SD卡主控制端驅(qū)動(dòng)的加載方式上,分析了原有系統(tǒng)的SD卡的輪詢機(jī)制的弊端,提出了兩種不同方式的中斷加載機(jī)制,從而替換了原來(lái)CPU占用率高的機(jī)制,有效地改善了整個(gè)系統(tǒng)的實(shí)時(shí)性。
參考文獻(xiàn)
[1]Mike Thomson. Windows CE. NET Real-Time. 2003
[2]Jay Loney Windows CE. NET Device Driver Architecture. 2003
[3] SD Specification Part A2 SD Host Controller Standard Simplified Specification Version 1.00
[4]Platform Builder for Microsoft Windows CE 5.0 Help
[5]杜春雷.ARM體系結(jié)構(gòu)與編程.北京.清華大學(xué)出版社.2003:11-18
[6]高軼萌、王澄非.Windows CE.NET 平臺(tái)流接口USB驅(qū)動(dòng)的設(shè)計(jì). 微計(jì)算機(jī)信息 2007年第2-2期
[7] SD卡標(biāo)準(zhǔn)化組織:http://www.sdcard.org/