Windows CE的SD卡驱动包括总线驱动(bus driver),主控制器驱动(host controller driver)和客户端驱动(client driver).
总线驱动是客户端驱动和主控制器驱动之间的抽象管理层.提供了标准API允许SD卡客户端驱动运行在任何包含Sdbus.dll的Windows CE设备上.总线驱动独立于应用程序和客户端驱动,可以不加修改的移植到不同处理器平台.
主控制器驱动控制主控制器硬件,遵循主控制器驱动接口,能够被客户端驱动使用进行通信和设置参数.主控制器驱动提供了客户端驱动和主控制器实现之间的硬件抽象层.
客户端驱动通过其接口允许与SD卡设备通信.客户端驱动接口被设计抽象了SD总线的物理实现,同时提供了客户端驱动最大的弹性.客户端驱动接口允许客户端驱动实现从简单的,同步访问存储卡驱动到完整线程的异步通信驱动.(翻译自MS帮助,更多内容可参考MS帮助)
下面就结合SMDK2410的SDHC驱动来进行分析.
这个驱动实现了就是主控制器驱动(host controller driver).
主控制器驱动包含了硬件相关的代码,主要包含了controller, slot支持逻辑,包含了实际的硬件实现;实现SD/MMC传送与接收;可以是本地总线上的内存映射设备(如继承控制器),或者是外部总线如PCMCIA,PCI,USB;可以使用IO操作或者DMA.
SMDK2410 BSP下的SDHC是一个流接口驱动.由两部分组成:
SDHCBASE(sdhcmain.cpp,sdiocontrollerbase.cpp,sdiocontrollerbase.h,实现了标准的流接口函数);SDHC(sdiocontroller.cpp,sdiocontroller.h,实际的硬件操作函数)生成最终的dll,同时包含了注册表设置sdhc_sc2410.reg,导出函数定义sdhc_sc2410.def
我们先来看sdhcmain.cpp,里面实现如SDH_Init,,SDH_Deinit,SDH_Open等的流接口函数.
1.DllEntry
DllEntry是最终生成的dll入口函数,在source中定义:DLLENTRY=DllEntry
当加载dll时(DLL_PROCESS_ATTACH)首先调用DisableThreadLibraryCalls来禁止DLL_THREAD_ATTACH和DLL_THREAD_DETACH通知给hLibModule参数定义的dll,在不使用线程级跟踪(thread-level tracking)情况下可以减少工作代码空间.
然后调用SDInitializeCardLib来初始化SD卡库.该函数实现在Sdcardlib.lib(/WINCE500/PUBLIC/COMMON/OAK/DRIVERS/SDCARD/SDCARDLIB).
如果调用SDInitializeCardLib成功,则调用SDHCDInitializeHCLib进一步初始化,如果调用失败则调用SDDeinitializeCardLib(实现在Sdhclib,/WINCE500/PUBLIC/COMMON/OAK/DRIVERS/SDCARD/SDHCLIB)取消初始化SD卡库.设置全局变量g_fRegisteredWithBusDriver表示未使用BusDriver注册.
卸载dll时(DLL_PROCESS_DETACH)调用SDHCDDeinitializeHCLib和SDDeinitializeCardLib来取消SD CardLib和HCLib的初始化.
2.SDH_Init
首先调用SDHCDAllocateContext来分配一段HC的上下文,如果成功就调用CreateSDIOController创建SD Host Controller对象CSDIOController类对象,CSDIOController是(CSDIOControllerBase的继承类).并将其赋值给pHostContext->pHCSpecificContext.接着调用InterpretCapabilities(CSDIOControllerBase成员函数)从注册表获得SD Host Controller信息.该函数的具体实现稍后在看.
最后调用SDHCDRegisterHostController来Host Controller.设置g_fRegisteredWithBusDriver注册标志为TRUE.返回pController.如果上述操作中任何一项失败,则进入Exit调用诸如SDHCDDeregisterHostController和SDHCDDeleteContext来取消注册和删除HC对象(上下文).
3.SDH_PreDeinit
SDH_PreDeinit首先获得HC Context,然后调用CSDIOControllerBase的成员函数PreDeinit,最后调用SDHCDDeregisterHostController解除HC Context的注册.
4.SDH_Deinit
SDH_Deinit首先根据g_fRegisteredWithBusDriver来判断host controller有没被解除注册,没有就再次调用SDHCDDeregisterHostController
然后删除SD Host Controller对象,清除host context.
5..SDH_Open
SDH_Open返回CSDIOControllerBase类对象pController.
6.SDH_IOControl,SDH_Close
SDH_IOControl,SDH_Close未做任何工作,直接返回.
7.SDH_PowerDown,SDH_PowerUp
SDH_PowerDown,SDH_PowerUp分别调用CSDIOControllerBase类的成员函数OnPowerDown和OnPowerUp.
接下来就来看看CSDIOControllerBase和其继承类CSDIOController的实现.