Windows ce 的SD卡驱动协议栈包含总线驱动,主控制端驱动,客户端驱动。
总线驱动作为提取和管理层处于主控制驱动和客户端驱动之间。它包括在SDbus.dll文件。为客户端驱动提供了标准的API,允许运行在任何的基于windows ce设备。总线驱动将是独立于应用程序和主控制端驱动,在不同的处理器之间移植,并不需要改动。
主控制端驱动控制包含主控制器硬件,遵循主控制端驱动接口,它被用于总线驱动通信和设置操作参数。主控制器驱动接口提供一个硬件提取层,在总线和主控制端执行之间。
客户端驱动和SD客户端驱动通信接口允许客户端驱动去和SD设备通信。客户端驱动接口是有计划地抽象SD总线物理设备的执行,提供了客户端驱动最大的弹性。客户端驱动接口允许客户端驱动去衡量一个单一的,同步的访问存储卡驱动使用一个线程,异步通信设备驱动。
SD卡主控制端驱动
SD卡主控制驱动是软件构成,控制主控制器硬件和遵循主控制器软件接口(和主线驱动通信并且设置操作参数)。主控制驱动使用API设置输出口,被总线驱动去注册和取消注册。
注册包括提供信息关于host and slot的性能,包含最大时钟速率,可接受的电压范围,SD卡的总线宽度,上电延迟。注册提供回调函数,插槽选择操作、电源操作、和总线请求操作。
SD卡使用动态结构,随时允许主控制器去注册或取消注册。
主控制驱动接口提供硬件抽象层在总线驱动和主控制器执行之间。主控制驱动包含平台和芯片集相关代码,只有通过这些接口和总线驱动通信。这些将保持总线驱动独立于主控制器和平台设置。这些主控制驱动接口是只为主控制端驱动需要,和其它客户驱动API无关。
主控制驱动:
包含控制器,插槽,逻辑支持,并且包含实际的硬件执行。
执行SD和MMC发送和接收。
能够被内存映射设备在逻辑总线上,作为一个完整的控制,或在一个外围总线上作为PCMCIA,PIC,和USB。
能够使用I/O编程或DMA。
SD卡驱动体系结构考虑到每一个系统主控制器的没限制。多个插槽的必须使用独立的电源、时钟、总线宽度控制。这些将承认系统在不同的SD接口条件下去识别卡。
SD卡主控制端可以选择1位或4位模式,时钟频率可以设定在0至25M,主控制端驱动负责注册插槽性能为总线驱动。
一个主控制器可以基于任何的从总线结构,例如,一个PCI-based主控制可以作为流驱动被加载。
SD卡和MMC的兼容性
SD卡的物理接口和协议都兼容于MMC规格,包括外观(这里讲的是普通SD卡,现在有miniSD和microSD,插槽并不兼容,可以通过转换插槽,也可以在硬件设计的时候把插槽设计成microSD兼容的样式,以适应现在主流的SD卡设备)。早期的7线SD插槽在是个MMC插槽同样风格,这允许在同样的硬件结构下通用。一个通用的插槽连接器可以支持两种卡类型。
在同一协议级别上,某些SD卡命令并不支持MMC设备,一个SD memory-aware host可以确定控制的是SD卡或MMC。
WINCE SDIO控制器可支持MMC的功能性。
SD卡总线驱动
SD卡总线驱动抽象了主控制端的物理执行,去提供给客服驱动一个单一的发送命令方法,和总线拓扑无关。如果是处于性能因素,客户端驱动必须知道卡物理连接的详细情况,它可以通过询问总线驱动来得到。
总线驱动公开了一组服务为客户端驱动和一组服务为主控制端驱动。两种服务都是为了去减少驱动的复杂操作。例如客户端驱动的加载和卸载。SD卡询问和鉴别,客户端驱动总线请求,和IO取消。这些操作都是通过总线驱动来实现的。
当一个卡被插入到总线驱动,它便有一组动作去确定卡的类型和加载适合的客户端驱动。SD总线驱动加载客户端驱动是使用ActivateDeviceEx函数。
由于SD卡协议栈的分层结构,总线驱动抽象了SD卡协议,提供给客户端驱动。这个抽象隐藏了所有的主控制端的底层硬件操作。因为这些抽象是单纯基于软件的,所以客户端驱动可以操作再任何硬件平台下。
总线驱动提供了在安全线程下多客户端驱动的同步访问。如果客户端驱动在运行时,卡拔出插槽或多功能卡去除某部分功能时,总线驱动提供了适当的持续和同步事件。
SD卡的客户端驱动
在SD卡的识别过程中,总线驱动执行了总线的处理去确定SD设备的种类和类型。在卡的种类或类型上,总线驱动加载了客户驱动使用适当的协议和设备关联。总线驱动加载客户驱动基于热插拔从SD卡读的信息。
安装一个客户端驱动在一个released设备,ISV(独立软件开发商)将提供一个应用程序去安装客户端驱动在设备上,并且设置适当的注册表键值和卡的驱动匹配。
客户端驱动可以同步或异步发送命令到卡。如果客户端驱动不需要电源或性能随异步操作而增长,SD卡协议栈提供了一个单一的同步接口,为了从客户端驱动中去除大量的复杂性。
客户端驱动反汇编BSQUARE SD协议栈适当的功能,当使用CE SD协议栈。然而,一个客户端驱动反汇编CE SD协议栈将没有BSQUARE SD协议栈的功能,使用的LEGACY_COMPATIBILITY_MODE的值必须定义在Sdcardapistubs.cpp文件里面。
客户端驱动的入口
SD卡客户端驱动是一个标准的流接口驱动,执行标准的流接口入口点。这些入口点只有XXX_Init (Device Manager) and XXX_Deinit (Device Manager)是必须的。这些功能总是被调用在设备加载或卸载的时候。一个或更多的进入点执行是必要的,为了去提供一个应用程序接口给设备。XXX_Open (Device Manager), XXX_Close (Device Manager), XXX_Write (Device Manager), XXX_Read (Device Manager), XXX_Seek (Device Manager), or XXX_IOControl (Device Manager)
SD卡客户端驱动不使用XXX_PowerUp (Device Manager) and XXX_PowerDown (Device Manager)函数。电源管理通过使用它的IOCTLs。然而,客户端驱动可以执行这些进入点去上电和去电的通知信息。上电和去电的只被使用于通知设备事件。自从这些函数被调用在非独占的中断环境,很少可以做除了设置设备标志外?
一个DLL入口点被CE模块调用,一旦一个DLL被加载或卸载。客户端驱动初始化或卸载初始化SD卡库。下面的例子是一个DLL的进入点:
BOOL SDMemoryDllEntry (HINSTANCE hInstance,
ULONG Reason,
LPVOID pReserved)
{
if(Reason == DLL_PROCESS_ATTACH ) {
if(!SDInitializeCardLib()) {
fRet = FALSE;
}
}
else if(Reason == DLL_PROCESS_DETACH ) {
SDDeinitializeCardLib();
}
return fRet;
}
客户端驱动的进入点必须同样包含在相关的sources文件里面。下面代码例子给出了在sources文件内客户端驱动的进入点。
DLLENTRY = SDMenoryDllEntry
客户端驱动的注册
SD卡客户端驱动没有和输出函数直接连接。相反的,这些函数调用去访问客户端驱动得通过客户端的注册过程。
在这个过程期间,客户驱动通过他自己的信息给总线驱动,并且接收信息需要去调用给外部函数。在注册之后,提供宏使能客户端驱动去访问那些API。这些宏只被客户端驱动使用。
去完成注册的过程,客户端驱动必须使用SDRegisterClient为SD设备发送它的本地设备信息,和一个友名给总线驱动。
卡信息结构
一个SDIO卡包含一个或多个卡信息结构(CIS)。一个SD客户端驱动将需要从这些结构中读出信息,以获得卡的性能和功能。
一个CIS被组成一个块的数据链,包含标准和特殊的应用信息。一个SDIO卡有一个所有卡的公共CIS区域,和每一个卡都有一个独自的CIS区域。客户端驱动可以从CIS区域读出它自己的功能,或从公共CIS区域,通过使用CommonCIS参数标志。
SDGetTuple函数允许客户端去访问一个指定的tuple。由于tuples经常不知道结构的大小,如果pBuffer为空的话,SDGetTuple函数通过pBufferSize返回一个tuple的长度。
一个tuple长度为0,tuple是不存在的。当tuple长度被确定,客户端驱动可以分配足够的存储和调用API再与一个非空的pBuffer值去读tuple 数据。
(注:
tuple
元组,数组
In a relational data base, a part of a relation that identifiers an entity and its attributes.
关系数据库中,标识一个实体及其属性的关系的一部分。 参阅relation。)
插槽事件回调
SD卡客户端驱动可以选择插槽事件回调。这个回调提供异步信息关于插槽状态的改变。下面的代码例子就是一类插槽事件回调。
VOID SlotEventCallBack(SD_DEVICE_HANDLE hDevice,
PVOID pContext,
SD_SLOT_EVENT_TYPE SlotEventType,
PVOID pData,
DWORD DataLength)
{
PSD_MY_DEVICE_INSTANCE pDevice = (PSD_MEMCARD_INFO)pContext;
switch (SlotEventType) {
case SDCardEjected :
// mark that the card is being ejected
pDevice->CardEjected = TRUE;
break;
}
}
客户端驱动使用注册信息结构去提供一个指向客户端函数的指针,下面例子是一类注册信息结构。
memset(&ClientInfo, 0, sizeof(ClientInfo));
// set client options and register as a client device
_tcscpy(ClientInfo.ClientName, TEXT("MyDriver"));
// set the callback, we want slot events
ClientInfo.pSlotEventCallBack = SlotEventCallBack;
// register the client
Status = SDRegisterClient(hClientHandle,
pDevice,
&ClientInfo);
插槽事件类型通过作为参数传给回调函数。回调函数可以被调用再任何线程空间。插槽事件类型可以限制,当回调函数被调用的时候要不要被触发。
当卡从插槽移开时SDCardEjected被调用。当事件类型显示出来,客户端驱动将不会在回调函数里面承交任何总线请求。
回调函数被调用,先前调用XXX_Deinit (Device Manager)的进入点为客户端驱动,这些会给客户端驱动一个机会去设置内部设备状态。例如,回调函数可以设置一个标志允许客户驱动去拒绝用户的应用程序IO请求。
客户端驱动的总线请求
SD客户端驱动使用总线请求发送命令和相应到SD卡,同时也是通过总线接收命令和相应。总线请求包含SD卡协议栈信息被使用在:
控制命令发送给SD卡
控制发送或响应任何的命令相关数据
SDBusRequest函数使客户端驱动可以异步发送总线请求给卡。这些参数在同步和异步功能的使用上是类似的。CommandCode参数是命令,在SD规格上定义。CommandArgument是32位任意的参数,在SD规格上定义。
所有的SD命令,除了CMD0,都需要卡反馈一个响应。一些命令可以使卡发送数据。一些命令使卡准备去接收数据。
SDBusRequest函数里面的TransferClass参数是存放当前类别的种类。下面表是现实当前的总类:
SD_COMMAND说明是一个命令或相应
SD_READ说明是一个命令、相应或数据读
SD_WRITE说明是一个命令、相应或数据写
ResponseType参数说明了希望从命令中得到SD响应类型。
数据可以通过块传输给SD卡。pBlockBuffer参数是指向一个缓冲区的指针,这缓冲区需要足够大去存储指定块的数量。
一些命令类型需要在总线上专用的操作。客户端驱动可以使用总线请求标志来实现。
同步和异步总线请求功能包含可选的Flags参数。这些Flags参数允许SD客户端在总线上提出一些特殊操作的请求,特殊的命令类型。如果总线驱动没有请求特殊操作,这个参数将被设置为0。
同步总线请求
从一些SD命令,比如SET_BLOCKLEN,这里没有强制执行异步传输。一般来说,提供同步总线请求。客户端驱动直到总线请求程序段完成。SDSynchronousBusRequest函数被使用在这些请求上面。
pResponse参数用来从SD卡获得相应。这相应将包含一些命令数据的错误状态。
异步总线请求。
通过使用异步总线请求,客户端驱动可以发出多总线请求,不需要等待先前的请求执行完成。总线请求队列在总线驱动内部,等待SD总线可用。
可以使用同步请求,客户端驱动可以最大使用可用的SD总线宽度。当SDIO网络适配器忙着传输包时,客户端驱动可以格式化下一个将要被发送的包。
当每一个请求完成,总线驱动调用回调程序给客户端驱动。回调程序可以通知主客户端驱动线程请求已经完成。
SDBusRequest
一个异步总线请求通过调用SDBusRequest函数。pCallback参数是一个指向回调函数的指针,当总线请求完成,它将被总线驱动的线程调用。RequestParam参数是可选的,它通过回调程序为总线请求。
ppRequest参数被使用去获得一个指向新创建的总线请求结构。通常,客户端驱动将保存这个指针去使能请求的取消和删除。这不是强制性的,指针是通过回调函数在请求完成之上。
SDFreeBusRequest
客户驱动为了去释放存储分配为新的总线请求。当请求完成的时候,它可以去调用SDFreeBusRequest函数。在请求成功,错误或取消的时候。
SDCancelBusRequest
客户端驱动可以去取消任何的总线请求,调用SDCancelBusRequest函数。如果总线请求还没被发送,它将从队列中移开。回调函数必须释放总线请求,SD_API_STATUS_CANCELED状态表示请求被取消。通常情况厦,客户端驱动将等待知道所有请求都完成。
单功能卡,多功能卡,和结合卡
SD卡可以分城下面3种类型:
单功能卡,在总线驱动内只有一种设备操作,只加载一种客户端驱动。
多功能卡,执行超过一种IO功能。
结合卡,执行一种或多种IO功能,包含SD存储功能。
单功能卡
单功能卡可以可以作为SD存储客户端驱动或单功能的SDIO设备。客户端驱动去加载要通过注册表查询。一个单功能的SDIO设备在总线驱动内只有一种设备操作,只加载一种客户端驱动。
SD存储客户端驱动
下面的注册表需要去加载一个SD存储客户端驱动的入口
[HKEY_LOCAL_MACHINE\Drivers\SDCARD\ClientDrivers\Class\SDMemory_Class]
下面注册表可以使用为加载一个自定义的客户端驱动的默认设置
[HKEY_LOCAL_MACHINE\Drivers\SDCARD\ClientDrivers\Custom\CID-M-AA-PPPPP]
M的值是厂商的ID,AA值是OEM使用的ID为两个字节。PPPPP值是产品名为5个字符。
SDIO Device
下面注册表是加载SDIO设备的入口
[HKEY_LOCAL_MACHINE\Drivers\SDCARD\ClientDrivers\Class\SDIO_Class\<class interface code>]
下面是加载自定义的SDIO设备的入口
[HKEY_LOCAL_MACHINE\Drivers\SDCARD\ClientDrivers\Custom\MANF-<manufacturer ID>-CARDID-<card ID>-FUNC-<function number>]
厂商ID和卡ID值将被存储在十六进制中。function可以被一个从1-7的值。
多功能卡
多功能卡属于SDIO卡,行使超过一个IO功能。每个功能都在分开的SDIO寄存器上操作,可以被独立的控制。
一个多功能卡有一个单独共享的SDIO卡控制器。卡控制器执行一个公共的配置区域,总线驱动可以使用去查询卡的性能和启动公共的特征。
总线驱动创建设备实例操作,每一个功能,都加载一个客户端驱动。总线驱动加载客户端驱动基于注册表键值,定义的接口类,或没定义类型检查自定义的ID键。
每一个客户端驱动都存在未知功能,可以被操作执行。如果其中一个功能在多设备不被支持,总线驱动将还是会允许其它可用的功能正常工作。
下面的图说明了多功能卡的结构:
文章评论(0条评论)
登录后参与讨论