去年毕业到9月份才找到工作,还好做的东西和学校里的还算有连续性,也是做嵌入式系统方面的工作。不过在学校的时候什么都不知道,学的东西都是乱七八糟的,什么东西都想学什么都没搞清楚。工作以后主要搞WinCE,主要是在做SD部分的驱动。搞了一年其实也感觉没什么长足的进步,感觉还有好多东西的不懂,看来还有的要学啊。有些东西写下来自己也可以再看看,以免时间久了忘光了。
第一篇还是先写点关于SD的驱动方面的内容吧。搞了这么久还是没搞太明白。对于SD的驱动来说,目前我们使用的是微软的架构,主要分为三个部分:
1.Host Driver
2.Bus Driver
3.Client Driver
这三个部分按照CE下对于驱动的划分来说,Bus Driver和Client Driver可以算作MDD Driver,而Host Driver则对应着PDD Driver。
Bus Driver和Client Driver作为MDD的部分,几乎不用做修改就可以使用。对于SD驱动来说主要的部分还是在Host Driver部分。
由于项目中基本是Memory Card,所以Client Driver对于我来说只是涉及到Memory,对于SDIO来说不考虑。所以目前我所接触到的SD Driver就是SD Memory,SD BUS和SD Host的内容。
先看看SD Driver:系统启动的时候由BusEnum.dll加载注册表下BuiltIn下的所有驱动,在启动过程中对于SD来说需要加载SDBUS和SD Host两个部分,首先要加载SD BUS部分,在注册表中需要设置Order值比SD Host先加载。SD Bus作为一个中间层驱动起着承上启下的作用,在SD Bus中实际上提供了两组函数接口,分别提供Client层和Host层来使用。所以对于Host和Client层来说,只需要设计好这两组接口就可以。
SD Bus的Source Code在Public/common/oak/driver/sdcard/sdbus。在SD Bus加载的时候,首先会运行DllEntry,接下来会运行在Sdclient.cpp的SDC_Init()在这个函数里创建了一个HostContainer并调用成员Init来初始化。
接下来加载Host Driver,这部分代码各个平台下应该都会不同,和具体的SD Host Controller有密切联系,不过对于符合SD Spec2.0的Controller来说,SDA提供了一组标准寄存器,应该来说差异也就不会很大。
在SD Host Driver中也是首先会执行DllEntry,在Host 的DllEntry中,会初始化SDHCDInitializeHCLib(),这部分其实就是之前提到的一组Bus层的接口。如果初始化不成功那么DllEntry会返回FALSE。
之后运行SDH_Init ()在SDH的Init中会调用Bus层提供的一个接口:SDHCDAllocateContext(m_cSlots, &m_pHCDContext),其中的参数m_pHCDContext是很关键的一个参数。Host通过调用SDHCDAllocateContext让Bus层去完成一些工作,由SDHCDAllocateContext知道Host如果有什么需要Bus层去完成的只要调用Bus层提供的接口就可以了,那么Bus层如果需要Host去完成一些操作怎么去告知Host Driver呢?这就是参数m_pHCDContext所提供的,该结构中提供了一组Handler,Bus层通过这一组Handler来操作Host层,在SDH_Init中初始化这一组Handler,接下来Host Driver调用SDHCDRegisterHostController向Bus注册,在ReisterHostController中会调用一个Handler:InitHandler。这个Handler会继续进行Host Driver的初始化:创建一个Event用于SD卡的中断,同时创建一个Thread去监测这个Event。卡插入和拔出触发中断会监测到并执行中断IST。如果监测到卡插入的中断,执行卡插入部分的代码,完成时钟的设置,之后调用接口SDHCDIndicateSlotStateChange(m_pHCDContext,(UCHAR) m_dwSlot, sdEvent);其中的sdEvent是SD_SLOT_EVENT结构中的成员,主要有DeviceEjected,DeviceInserted,BusRequestComplete等。之后卡的识别过程都会由Bus层的代码来判断同时会建立一系列的结构并调用ActiveDeviceEx来加载Client Driver。
在Bus层调用ActiveDeviceEx之后,系统发送一个消息给StorageManager一个Block设备需要加载,对于Block设备Wince会有一个固定的GUID来代表。这个时候就由StorageManager来为刚才的Block设备加载对应的文件系统,Block驱动就是Client层的驱动,我所接触到的就是Memory层的驱动。这样在设备上就可以看到SD卡的图标了。