CE下基于Zylonite硬件平台的SD卡驱动开发
摘要:本文結(jié)合實(shí)際項(xiàng)目(一款以WINCE為操作系統(tǒng)內(nèi)核的GSM/PHS雙模智能手機(jī))對嵌入式系統(tǒng)Windows?CE5.0的底層驅(qū)動(dòng)(SD卡)的架構(gòu)進(jìn)行了分析和研究,以MARVELL公司提供的基于INTEL?Zylonite硬件平臺(tái)的BSP為基礎(chǔ),利用Windows?CE5.0的Platform?Builder集成開發(fā)環(huán)境(IDE)開發(fā)適合實(shí)際項(xiàng)目的SD卡驅(qū)動(dòng)代碼,分別以輪詢和中斷方式實(shí)現(xiàn)該驅(qū)動(dòng)的動(dòng)態(tài)加載,并深入分析SD卡驅(qū)動(dòng)(流驅(qū)動(dòng))的詳細(xì)的加載過程。?
關(guān)鍵詞:Zylonite??Platform?Builder???BSP??SD卡驅(qū)動(dòng)?
0、引言
隨著通信領(lǐng)域新業(yè)務(wù)需求的不斷增長及計(jì)算機(jī)技術(shù),半導(dǎo)體技術(shù)和電子技術(shù)的術(shù)的迅速發(fā)展,嵌入式系統(tǒng)異軍突起,已經(jīng)滲透到社會(huì)生活的方方面面了。它是集軟件,硬件于一體的高可靠性系統(tǒng)。其最大特點(diǎn)即為可以通過裁減裝卸系統(tǒng)模塊來配置整個(gè)平臺(tái)所要求的功能。
???????? Windows CE是由微軟公司所開發(fā)的一個(gè)嵌入式操作系統(tǒng),它與Windows平臺(tái)的編程接口有很強(qiáng)的兼容性。其平臺(tái)開發(fā)工具Platform Builder是一個(gè)完全集成的開發(fā)環(huán)境(IDE)。本項(xiàng)目所涉及的硬件開發(fā)套件Intel Zylonite Development System裝配有Intel的Xscale芯片處理器Monahans L(PXA300),并配有相關(guān)外設(shè)電路接口(USB2.0,SD/MMC,音頻,以太網(wǎng)口等)及外設(shè)(觸摸屏,KEYPAD,揚(yá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便是為了對應(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è)單一的,同步的訪問存儲(chǔ)卡驅(qū)動(dòng)使用一個(gè)線程,異步通信設(shè)備驅(qū)動(dòng)。SDMemory.dll是最高層,類似于應(yīng)用層。
?
2.立足微軟SD卡協(xié)議棧開發(fā)Zylonite?的BSP包的SD卡驅(qū)動(dòng)
當(dāng)我們開發(fā)SD卡驅(qū)動(dòng)時(shí),并詳細(xì)分析比較了Microsoft的SD驅(qū)動(dòng)架構(gòu)和Intel所提供的BSP內(nèi)的參考SD卡驅(qū)動(dòng)以后,可以得出如下結(jié)論:
l?????????針對主控制端驅(qū)動(dòng)(SDHC_XXX.DLL):因?yàn)檫@一層是直接操作硬件的一層,所以大多數(shù)情況下都需要修改。修改的內(nèi)容基本為收發(fā)命令部分以及數(shù)據(jù)傳輸和硬件初始化部分.
l?????????針對總線驅(qū)動(dòng)(SDBUS.DLL):因?yàn)檫@一層處于主控制驅(qū)動(dòng)和客戶端驅(qū)動(dòng)之間,用于他們之間的通信,SD卡總線請求都放在它里面,微軟提供了非常完備的樣例代碼,所以我們一般都不需要改動(dòng),直接調(diào)用它的接口就可以了。
l?????????針對客戶端驅(qū)動(dòng)(?SDMEMORY.DLL):因?yàn)镾DMemory就是所謂的Client層,類似于應(yīng)用層,它還可用來識(shí)別卡的,不同種類的卡,比如sd memory card等,鑒于我們只需開發(fā)SD卡部分的驅(qū)動(dòng),所以也不需要怎么修改了(如果我要開發(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)代碼,開發(fā)(配置并改進(jìn))我們實(shí)際項(xiàng)目內(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)的注冊表信息設(shè)置路徑為:
?\WINCE500\PLATFORM\Zylonite\Platform\ZYLONITE\SRC\DRIVERS\SDHC
主要文件為:
l?????????impl.c:?主要是在加載SD卡主控制端驅(qū)動(dòng)時(shí)初始化硬件。內(nèi)含一個(gè)非
?常重要的線程---- SDCardDetectIstThread,專門處理SD卡的插拔操作。但是具體的插拔操作也是在Sdcontrol.c文件實(shí)現(xiàn)的。
2.2、結(jié)合實(shí)際項(xiàng)目的開發(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要配成檢測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
我們在這里只詳細(xì)討論第2步(sdhc_zylonite.dll的加載),此時(shí)SDBus.dll已經(jīng)加載成功。WINCE系統(tǒng)初始化后,會(huì)載入DEVICE.EXE,?對應(yīng)代碼devload.C中的WINMAIN函數(shù)會(huì)被調(diào)用起來,從而啟動(dòng)InitDevice函數(shù),此函數(shù)會(huì)搜尋(\WINCE500\PLATFORM\Zylonite\Platform\ZYLONITE\SRC\DRIVERS\SDHC下的sdhc_zylonite.reg)注冊表根鍵,準(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(),自此將開始將開始SD卡主控制端驅(qū)動(dòng)的初始化過程:
1.?調(diào)用SDH_Init()
2.?調(diào)用?SDHCDAllocateContext()?來分配一段主控制器的上下文
a)Context?是總線驅(qū)動(dòng)和主控制端驅(qū)動(dòng)共享的
3.?主控制端驅(qū)動(dòng)使用SDHCDSetXxx宏來填充這個(gè)上下文結(jié)構(gòu)
a)這個(gè)步驟是把主控制器向總線驅(qū)動(dòng)描述一下
b)包括函數(shù)指針,支持的電流,最大時(shí)鐘,槽數(shù)目,SDIO的支持等等。
4.?調(diào)用?SDHCDRegisterHostController()?來把自己向總線驅(qū)動(dòng)注冊一下
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ā)起請求,再去調(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)探測到有卡,即返回給sdbus.dll,?總線驅(qū)動(dòng)即可調(diào)用HandleAddDevice()函數(shù),自此初始化結(jié)束,sdhc_zylonite.dll加載成功。
l?????????對主控制端驅(qū)動(dòng)重要線程SDcardDetectIstThread()代碼的改進(jìn)
在前面的敘述中,可以看出線程SDcardDetectIstThread()在sdhc_zylonite.dll最后的加載起決定性作用。然而我們發(fā)現(xiàn)在INTEL所給的BSP中,在檢測卡的過程里,其采用了輪詢的方式----即每隔一定的時(shí)間,CPU都會(huì)去讀一次GPIO34的電平,以確定SD卡是否被插入或拔出,以此來判定是否去加載或卸載SD卡的客戶端和主控制端驅(qū)動(dòng)。很顯然,這種方式的弊端是占用了過多的CPU資源,效率很低,嚴(yán)重影響了整個(gè)系統(tǒng)的實(shí)時(shí)性。因此,最能解決這個(gè)問題的辦法無外乎是使用中斷檢測的方式。以下特別敘述采用2種不同的中斷機(jī)制的方式實(shí)現(xiàn):
1中斷綁定靜態(tài)配置:
1.在Bsp_cfg.h文件內(nèi)定義一個(gè)系統(tǒng)中斷號SYSINTR_SDMMC_DETECT
#define SYSINTR_SDMMC_DETECT (SYSINTR_FIRMWARE+N) N為當(dāng)前已定義的最大值(以保證此中斷未使用過)。
2.在Xllp_gpio_plat.h文件中找出GPIO34的定義:#define XLLP_GPIO_MMC_CD_0 34
3.在intr.c文件里將系統(tǒng)中斷號和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上升沿或下降沿的檢測和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.同上原理改寫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)中斷號和硬件中斷源:KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwSDCDIrq, sizeof(DWORD), &(dwSysintrCD), sizeof(DWORD), NULL))。此處的&dwSDCDIrq可在SD卡主控制端驅(qū)動(dòng)的注冊表內(nèi)更改后,用LoadPlatformRegistrySettings函數(shù)加載進(jìn)來。可在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。
總結(jié)
以上是生活随笔為你收集整理的CE下基于Zylonite硬件平台的SD卡驱动开发的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为畅享50系列今天发:麒麟芯、鸿蒙OS
- 下一篇: Hive-Based Registry使