SD卡驱动中各层中主要的类,结构体和接口函数
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
SD卡驱动中各层中主要的类、
结构体、函数接口分析
1.1 Host Control Driver
主要功能:
●HCD通知总线驱动卡的插入和拔出
●给卡上电,SD定义了可接受的初时电压范围。
●在总线驱动何客户端设置完时钟速度后,打开客户端卡的时钟(80个周期)●初始,把总线宽度设置成1。
如果有需要的话(4-bit mode),把总线宽度
设成4bit
●传输SD命令和数据到/来自卡上。
●负责给槽上电,关电。
●IST在这里存在
●(可选的)唤醒支持(插入,拔出,SDIO中断)
初始化:
1.调用HCD’s XXX_Init函数:DWORD SDP_Init(DWORD dwContext)
2.调用SDHCDAllocateContext()来分配一段HC的上下文,
A)Context是总线驱动和HCD共享的,
B)还需为记录HC具体的内容的结构体分配空间用malloc(),并进行扩展C)细节处理:通过SDGetRegPathFromInitContext()获得注册表路径,供后面读注册表值的操作;设置是否使用DMA模式还是PIO模式。
D)
3.HCD使用SDHCDSetXxx宏来填充总线驱动和HCD共享的上下文结构,
①这个步骤是把HC向总线驱动描述一下;
②包括函数指针,支持的电流,最大时钟,槽数目,SDIO的支持等等。
③包括的函数有:SDHCDSetHCName()、
SDHCDSetControllerInitHandler()、
SDHCDSetControllerDeinitHandler()、
SDHCDSetBusRequestHandler()、
SDHCDSetCancelIOHandler()、
SDHCDSetSlotOptionHandler()。
4.调用SDHCDRegisterHostController()来把自己向总线驱动注册一下(使用静态变量,保
留函数调用后的值)。
5.当总线驱动准备处理SD事件时,它会调用HCD的init函数(pContext->pInitHandler)
(见SDHCDRegisterHostController__X函数)。
6.在初始化里,HCD还应该完成硬件和资源的初始化(IST等)。
①设置SD卡逻辑中断,通过查数据手册可知,实验室所用中断给SD卡分配的中断号
为“2”;
pController->SysIntr = InterruptConnect(Internal,
0,
HWINTR_SD, // #define HWINTR_SD 2
0);
注:对以上主要函数的分析:
①SDHCDSetControllerInitHandler():该函数填充结构体
_SDCARD_HC_CONTEXT,用指向函数的指针的方式。
实际操作的函数是SDIOInitialize(),它将对SD设备作一些初始化工作,主要有:
A)SDIOPlatInit()操作,映射物理地址,设置GPIO_5作为Slot[0]插入时的中断,并对相应的复用引脚进行功能设置;
B)为SD卡中断的配置事件和线程
C)调用SDIOInitializeSlot():初始化SLOT,设置插入中断,并调用SDIOInitializeDMA(),初始化DMA通道,配置DMA中断。
②SDHCDSetBusRequestHandler():也用指向函数的指针的方式。
实际操作
的函数是SDIOBusRequestHandler():通过参数总线驱动和HCD共享的上下文结构体、所在的插槽数、对总线的请求(读或写);最后形成命令,写入插槽命令寄存器(&pSlot->pSD->cmd)中。
做相应的动作—command/read/write, multi-block,等
③SDHCDSetSlotOptionHandler():也用指向函数的指针的方式。
实际操作的
函数是SDIOSlotOptionHandler():应用于插槽的操作。
总线驱动调用HCD的SlotOptionHandler:
⏹SDHCDSetSlotPower–设置电压
⏹SDHCDSetSlotInterface–设置时钟和总线宽度
⏹SDHCDEnableSDIOInterrupts
⏹SDHCDAckSDIOInterrupt
⏹SDHCDDisableSDIOInterrupts
总线要求
●总线驱动把总线要求放入队列然后把它们传入HCD的BusRequestHandler函
数,即函数指针。
●HCD根据要求来做相应的动作—command/read/write, multi-block,等.
●HCD使用某种方式(DMA, PIO, busy-waiting等)来发送命令和数据
●HCD调用SDHCDIndicateBusRequestComplete()来通知总线驱动完成
●总线驱动把完成事件入队列并提交下一个要求给HCD
●总线驱动的调度线程将会通知产生要求的起始源事件完成了。
1.2 SD Bus Driver
bus drivers are responsible for hardware configuration, hardware power control, bus address translation, and loading and unloading of upper-level client drivers. Liao delves into the basics of bus driver operation, how to use them, and how to write them. Details are provided on the PCI bus driver and the "root bus" driver.
主要功能如下:
●枚举板上的卡,并决定他们的类型(MMC, SD Memory or SDIO)
●配置合适的电流给卡。
●根据注册表的值加载clients
●把总线要求入队列
●把来自host controller的异步通知入队列
●总线要求完成,SDIO中断,设备插入\拔出
●出错时重试
参考代码:
D:\WINCE500\PUBLIC\COMMON\OAK\DRIVERS\SDCARD\SDBUSDRIVER
1. As long as I know, After a SD device is inserted, the bus driver
identifies the SD device. and then the bus driver loads the client driver related to the SD device.This operation is initiated by the SD card insertion. And because of the hardware condition, thiis scheme is assumed that the only one device have to be used at
a time.
注:研究SD卡初始化的流程可以参考sd-pecification.pdf中的
Figure 4-2: Card Initialization and Identification Flow (SD mode)
BUS层主要是:枚举板上的卡,并决定他们的类型(MMC, SD Memory or SDIO),配置合适的电流给卡,根据注册表的值加载clients,把总线要求入队列,把来自host controller的异步通知入队列,总线要求完成,SDIO 中断,设备插入\拔出,出错时重试等功能。
(1)其主要的处理流程主要在sdhceventhandlers.cpp中的handleAddDevice()中,在这里面包括了卡的识别,卡的上电,卡的种类的识别,加载Client端的驱动等工作,在调试的时候,可以在这里面添加一些Debug信息,看初始化出要出错出在哪里,并根据相应的回应来驱动为什么出错。
其中
①结构体SDCARD_DEVICE_CONTEXT,记录了SD设备的信息。
,该结构体在类CSDBusDriver中也有定义。
②枚举类型SDCARD_DEVICE_TYPE,记录了SD卡的类型(MMC, SD Memory or SDIO)
③结构体SD_COMMAND_RESPONSE,记录了命令反应的类型和数组。
④结构体SDBUS_HC_SLOT_CONTEXT,记录了SD总线上插槽的信息。
pSlot->hDevice = (SD_DEVICE_HANDLE)pDevice;//保存①中的信息到该结构体中
⑤结构体_SD_CARD_INTERFACE,记录了SD卡传输模式(1位还是4位)
// when powering up the device we settup for 1 bit mode
pDevice->CardInterface.InterfaceMode = SD_INTERFACE_SD_MMC_1BIT;
pDevice->CardInterface.ClockRate = SD_DEFAUL T_CARD_ID_CLOCK_RA TE;
⑥
(2)SD卡初始化流程:
最开始对卡和插槽,主控制器的信息进行设置
①SendSDCommand(),给SD卡发送command。
注:给不同的卡的
类型发送的命令不一样,根据该函数返回的值先做初步判断;
②UpdateCachedRegisterFromResponse(),获得response,并更新寄存器,存储操作信息。
然后根据信息,判断插入卡的类型;
③GetDeviceV oltageRangeFromIO_OCR(),从以上的response中获得支持电压。
④SDGetOperationalV oltageRange(),通过上一步获得的电压信息,设置操作电压。
⑤SetCardPower(),给SD卡所在的槽上电。
············································································
通过以上步骤后,对卡上电的初始化就完成了,接着:
通过GetCardRegisters()函数获得卡上寄存器的信息,继续进行初始化,在这里要做的是:
①CMD2(获得CID的response)→→②CMD3(获得RCA)→→
③CMD9(获得CSD)或CMD4(声明DSR)→→④CMD13(获得卡的状态)→→⑤CMD7(根据RCA选择一个卡进入传输状态) →→进入传输模式状态。
→→ACMD51(获得SCR). ·······································································
之后选择卡的接口以及插槽的接口进行:
①SelectCardInterface()和②SelectSlotInterface()
选择后,在此基础上对接口进行设置:
①SetCardInterface()和②SDSetCardInterfaceForSlot()
总:经过上面的步骤,设备的初始化和配置就完成了。
之后就是下载client driver(s)。
调用CSDBusDriver::SDLoadDevice()
(2)在sdhceventhandlers.cpp中的handleAddDevice()以上(1)、
中完成
Sdmain.cpp中:
SD_API_STA TUS
SDHCDGetHCFunctions(
PSDHOST_API_FUNCTIONS pFunctions
)
帮助填充SDHCD.h中的结构体_SDHOST_API_FUNCTIONS,该结构体中的成员都是指向函数的指针,这些函数都是在sdhcdeum.cpp 中实现。
注:SDHCD.h声明的结构体中包含SD Bus层与Host Control层的函数接口.
1.3 SD Memory Client Driver
(1)流驱动接口SMC_Init(),其中的操作包括有通过初始化的上下文,获得设备注册表的路径,读取里面的值,填充结构体SD_MEMCARD_INFO(记录了设备的信息),分配相应的内存空间等
(2)流驱动接口SMC_IOControl(),定义了SD卡要做的一系列操作,通过IoctlCode命令来调用,其中包括SDMemRead(),SDMemWrite()等等。
附录A: Command注释
详见:sd-pecification.pdf中的4.7.4 Detailed Command Description。
附录B:主要的函数
①SDCardInfoQuery__X():获得SD卡寄存器的信息,如CID;
②GetCustomRegPath():获得客户端注册表路径,用以打开注册表;③。