轉載自:http://www.cnblogs.com/nesta/archive/2008/05/30/967860.html
這個部落格上的東東值得學習
WinCE 5.0下面SD卡驅動的開發。這是我做的第一個項目,當時做這個項目花費了相當的時間和精力,搞的我精疲力盡。幾乎可以說當時對WinCE一點都不懂。也不知道從何處下手,就東看西看。東改西改,改的是一塌糊塗。幸好老闆和老大都比較寬容,給了我充裕的時間和支援,將自己有關SD卡在WinCE 5。0下面的驅動理解的點滴給記錄下來,希望能夠對別人有所協助。
目前WinCE下面的驅動主要有兩種架構,一種就是WinCE內建的三層架構(Host,BUS,Client)。另外就是直接將驅動寫成Block驅動的形式,分真正的驅動和一個專門用來Loader的程式。本人用的微軟內建的三層架構,下面將較為詳細的介紹一下這種架構,以及如何在這種架構下來實現SD卡驅動。(建議大家做SD卡驅動前先將SD card的Spec看一下(下載SDSPEC),知道其的一些特性,主要包括初始化流程,那些命令是幹什麼的。還有就是有那些內部寄存器。這些寄存器又是又通過那些命令獲得的,瞭解了這些才能再以後能有個好的調試。) 有關SD卡的一些規格(網上一大堆到處都又)本文將不做介紹,主要介紹其在WinCE下面的實現。
WinCE下面SD卡的架構如所示:
:最下面的是你的H/W部分,其中SD Host Controller是你的SD硬體控制器部分,你寫驅動需要這部分的SPEC。接著上面的SD Host Controller Driver就是你需要實現的部分了,直接和你的控制器打交道。 而BUS層則是位於Host和Client之間的一層,主要用來進行兩層之間的通訊,並根據不同的裝置來載入不同的Client驅動,如果是SD Memory卡就載入SD Memory。如果是具有WIFI功能的SDIO卡就會載入這個SDIO WIF驅動。
驅動BUS Driver和Client Driver均由微軟提供,但是不是微軟自己寫的。貌似是一個叫什麼BSQUARE公司開發的。其中BUS層的代碼位於C:/WINCE500/PUBLIC/COMMON/OAK/DRIVERS/SDCARD/SDBUSDRIVER下面。(C:/WINCE500是你安裝WinCE的目錄)。而Client端的代碼位於C:/WINCE500/PUBLIC/COMMON/OAK/DRIVERS/SDCARD/SDCLIENTDRIVERS下面,其下面微軟帶了一個兩個Client 驅動(BLUETOOTH 和 SDMEMORY)。下面介紹各層的主要功能,BUS層主要是:枚舉板上的卡,並決定他們的類型(MMC, SD Memory or SDIO),配置合適的電流給卡,根據註冊表的值載入clients,把匯流排要求入隊列,把來自host controller的非同步通知入隊列,匯流排要求完成,SDIO 中斷,裝置插入/拔出,出錯時重試等功能。
其主要的處理流程主要在sdhceventhandlers.cpp中的handleAddDevice()中,在這裡麵包括了卡的識別,卡的上電,卡的種類的識別,載入Client端的驅動等工作,在調試的時候,可以在這裡面添加一些Debug資訊,看初始化出要出錯出在哪裡,並根據相應的回應來驅動為什麼出錯。其中
while (NULL != pCurrentDevice)
{
// try to load devices
CSDBusDriver::SDLoadDevice(pCurrentDevice);
pCurrentDevice = pCurrentDevice->pNext;
}
這段主要就是用來根據上面得到的資訊來Load Client端驅動的。其中如果僅僅是儲存卡的話,就會load SDMemory.dll。而如果是SDIO WIFI卡的話,就會load相應的WIFI Client端驅動。其中初始化的流程主要就在這個函數裡面實現:
主要的命令有:CMD5----CMD55/CMD41---CMD2--CMD3等等,具體的CMD參考SD的SPEC。這些命令均有BUS層下給HOST Controller層的。
其中Host Controller層主要實現將命令下給H/W,並且得到相應的Response,把這些response按照相應的格式放到某個Buffer中,傳給bus層,由bus層來處理。bus層就是根據這些response來確定卡的類型,卡的大小,卡的傳輸速度,卡的一些屬性的。
卡的讀寫: 檔案系統的讀寫會先到SDMemory層,SDMemory先將CardIO轉化為DISKIO然後通過BUS層傳遞給Host Controller,其中讀寫主要由CMD17和CMD18,以及CMD24和CMD25。在完成每一次BUS層的處理之後,都要想BUS層發送一個BUSRequest Handle Complete事件,通知BUS層讀寫操作已經完成。讀寫操作需要用到DMA操作,這裡需要COPY動作,因為DMA需要物理地址,而層傳下來的BUF是虛擬位址。
以上部分,大概是WinCE下面SD卡驅動的大概,有很多地方都沒有講解清楚。拖了這麼久才寫完。唉,好多東西還不是很明白,有什麼問題,希望大家交流,
USB 功能切換器【提供下載】 :http://gopise.blog.ccidnet.com/blog-htm-do-showone-uid-50640-type-blog-itemid-247151.html