首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

CE下基于Zylonite硬件平台的SD卡驱动开发 04

CE下基于Zylonite硬件平台的SD卡驱动开发 04

由上可得,先要配置SD卡的外部引脚及功能。而SD卡的引脚配置在其下的 \source 文件夹的xllp_mmc_board.c文件XllpMMCConfigure函数内修改。(特别注意:GPIO34要配成检测SD卡插入的中断源。)
      2.2.2、分析修改并改进主控制端驱动重要线程及硬件初始化部分代码
      SD卡主控制端驱动加载及架构解析
      需要声明的是SD卡驱动加载顺序是:
       加载SDBus.dll→加载sdhc_zylonite.dll→加载sdmemory.dll
       我们在这里只详细讨论第2步(sdhc_zylonite.dll的加载),此时SDBus.dll已经加载成功。WINCE系统初始化后,会载入DEVICE.EXE, 对应代码devload.C中的WINMAIN函数会被调用起来,从而启动InitDevice函数,此函数会搜寻(\WINCE500\PLATFORM\Zylonite\Platform\ZYLONITE\SRC\DRIVERS\SDHC下的sdhc_zylonite.reg)注册表根键,准备参数调用WIN32 API接口-----Activedevice,接着利用Dllmaincrtstartup函数找到sdhc_zylonite.dll的入口,执行该文件的入口函数DllMain()然后继续返回到DEVICE.EXE(devload.C),调用launchdevice()函数,再调用sdhc_zylonite.dll的入口main.c文件内的SDH_Init(),自此将开始将开始SD卡主控制端驱动的初始化过程:
       1. 调用SDH_Init()
       2. 调用 SDHCDAllocateContext() 来分配一段主控制器的上下文
       a)Context 是总线驱动和主控制端驱动共享的
       3. 主控制端驱动使用SDHCDSetXxx宏来填充这个上下文结构
       a)这个步骤是把主控制器向总线驱动描述一下
       b)包括函数指针,支持的电流,最大时钟,槽数目,SDIO的支持等等。
       4. 调用 SDHCDRegisterHostController() 来把自己向总线驱动注册一下
       5.  当总线驱动准备处理SD事件时,它会调用主控制端驱动的init 函数(pContext->pInitHandler)
       接着便是sdbus.dll驱动部分的代码和SD卡主控制端驱动部分的交互设置:比如设置电源、时钟和总线宽度等。一般都是sdbus.dll发起请求,再去调用主控制端驱动部分的API,这里最后详细分析插槽状态交互确认,因为这是成功加载sdhc_zylonite.dll的关键。当有SD卡在插槽,sdbus.dll的slotstatuschange()调用并建立一个重要线程SDcardDetectIstThread(),当探测到有卡,即返回给sdbus.dll, 总线驱动即可调用HandleAddDevice()函数,自此初始化结束,sdhc_zylonite.dll加载成功。
       对主控制端驱动重要线程SDcardDetectIstThread()代码的改进
       在前面的叙述中,可以看出线程SDcardDetectIstThread()在sdhc_zylonite.dll最后的加载起决定性作用。然而我们发现在INTEL所给的BSP中,在检测卡的过程里,其采用了轮询的方式----即每隔一定的时间,CPU都会去读一次GPIO34的电平,以确定SD卡是否被插入或拔出,以此来判定是否去加载或卸载SD卡的客户端和主控制端驱动。很显然,这种方式的弊端是占用了过多的CPU资源,效率很低,严重影响了整个系统的实时性。因此,最能解决这个问题的办法无外乎是使用中断检测的方式。以下特别叙述采用2种不同的中断机制的方式实现:
       1中断绑定静态配置:
       1.在Bsp_cfg.h文件内定义一个系统中断号SYSINTR_SDMMC_DETECT
       #define SYSINTR_SDMMC_DETECT (SYSINTR_FIRMWARE+N) N为当前已定义的最大值(以保证此中断未使用过)。
       2.在Xllp_gpio_plat.h文件中找出GPIO34的定义:#define XLLP_GPIO_MMC_CD_0 34
       3.在intr.c文件里将系统中断号和IRQ关联:
       OALIntrStaticTranslate(SYSINTR_SDMMC_DETECT, IRQ_GPIO_SHARE(XLLP_GPIO_MMC_CD_0));
       4.在主控制端驱动的硬件初始化代码Impl.c中的InitializeHardware()加入 EnablesdcardInterrupt()函数。
       5.在Impl.c中完善EnablesdcardInterrupt(),加入GPIO上升沿或下降沿的检测和SET EVENT。   
       6.在Impl.c文件中定义hCardInsertInterruptEvent并在SetupCardDetectIST()内创建hCardInsertInterruptEvent
       7.Impl.c文件中初始化dwSysintrCD= SYSINTR_SDMMC_DETECT,并绑定相应的EVENT:InterruptInitialize     (dwSysintrCD,hCardInsertInterruptEvent,NULL,0)
       8.     改进线程SDcardDetectIstThread()的While部分代码,加入WaitForSingleObject( hCardInsertInterruptEvent, dwTimeout );只有当hCardInsertInterruptEvent被置上,才会往下走,否则一直在此处等待。
       9.同上原理改写CardremoveInterrupt用于动态卸载SD卡主控制端驱动。
       2中断绑定动态配置:
       1.  在Impl.c文件的SetupCardDetectIST()函数内动态配置系统中断号和硬件中断源:KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwSDCDIrq, sizeof(DWORD), &(dwSysintrCD), sizeof(DWORD), NULL))。此处的&dwSDCDIrq可在SD卡主控制端驱动的注册表内更改后,用LoadPlatformRegistrySettings函数加载进来。可在sdhc_zylonite.reg 文件内将"CardDetectIRQ" 的值
返回列表