LINUX MMC子系统分析之二 MMC子系统驱动模型分析(包括总线、设备、驱动)

      本模块主要介绍MMC子系统与设备-总线-驱动模型的关联,并介绍该MMC子系统是如何借助LINUX内核的设备-总线-驱动模型实现自己的驱动模型的。针对MMC子系统而言,主要使用了系统中的两个模型:设备-总线-驱动模型、块设备驱动模型。

 

设备-总线-驱动模型

    在分析MMC子系统的设备-总线-驱动模型时,我们可以借助之前已经分析的i2c驱动模型、spi驱动模型的实现,来学习mmc子系统的驱动模型,通过与i2c驱动模型、spi驱动模型的对比,也可以加深我们对mmc子系统驱动模型的理解(从已知去学习未知,可提供我们的学习效率)。我们知道针对复杂的设备,则需要借助控制器进行通信,而针对i2c、spi、mmc而言,均需要对应的控制器实现与该类设备的通信。而针对这三类控制器,其模块都进行了抽象,其中i2c控制器抽象为i2c adapter、spi控制器抽象为spi master,而针对mmc控制器,则抽象为mmc host;而针对这三种类型设备的抽象,i2c设备抽象为i2c client、spi设备抽象为spi device、mmc device抽象为mmc card。

下面分析下这三类驱动模型的异同:

  1. 均为控制器创建了对应的class,用于将对应的控制器设备链接至对应的class上;
  2. 针对i2c adapter、spi master这两类而言,其驱动模型中均创建了对应的链表,将所有注册的控制器设备链接在一起,而mmc子系统并没有为mmc host创建类似的链表;
  3. I2c/spi设备不属于热插拔设备,因此在具体系统的板级文件或者设备树中,需要针对系统中存在的i2c/spi设备定义注册信息,从而在LINUX系统初始化时完成i2c/spi设备的注册;而针对mmc子系统其属于热插拔的,因此在系统初始化时不需要单独进行设备的注册;
  4. 针对mmc子系统而言,针对mmc card的注册,mmc子系统提供了rescan接口,而该接口作为延迟工作队列的回调函数。针对mmc card而发起扫描的时机如下:
    1. 在mmc host添加的时候,执行一次mmc card的扫描操作;
    2. 若mmc host支持卡在位检测引脚(即cd引脚),在cd引脚对应的中断发生后,在该中断的处理函数中,会进行延迟队列的调度,从而完成一次mmc card的扫描操作;
    3. 若mmc host不支持卡在位检测,则可以将卡在位检测设置为轮询机制,则针对该mmc host,以1s为周期进行mmc card的扫描;
  5. 针对i2c/spi驱动模型而言,针对不同类型的外设,需要对应类型的设备驱动程序,而针对mmc子系统而言,因mmc、emmc等协议规范中已经规定了所有mmc/sd/tf/emmc设备的操作方法、寄存器定义等,因此针对mmc总线而言,mmc子系统提供了一个统一的mmc driver,所有的mmc/sd/tf/emmc设备均与该驱动绑定(当然了,针对sdio总线而言,因其外设的功能不一,因此针对具体的设备也需要对应的设备驱动)。针对mmc子系统的mmc设备而言,不需要驱动开发者实行mmc 设备驱动,仅对sdio外设需要实现对应的mmc设备驱动;
  6. 因mmc driver仅有一个,因此针对mmc bus而言其match函数直接返回1,而不需要像spi/i2c总线的match接口那样对设备和驱动进行匹配检测;
  7. 因一个mmc控制器仅与一个mmc card关联,且mmc子系统提供了mmc rescan接口,可以实现对mmc host下的mmc card进行扫描并进行mmc card的创建、与mmc host的绑定以及注册至mmc总线上;因此不需要像上述2中所述的i2c/spi那样,将所有已注册的控制器设备链接在一起方便查找从而实现i2c/spi设备的注册与绑定;
  8. 针对spi master、i2c adapter,均提供与外设通信的方法(spi_master->transfer、i2c_adapter->master_xfer/smbus_xfer),而针对mmc host而言,也需要提供相应的访问接口(记为mmc_host->request);
  9. 因mmc/emmc协议规范已经规定了访问mmc card的命令格式以及相应的寄存器定义,所有mmc/sd/tf/emmc设备均需要遵守,因此mmc子系统针对访问mmc card的命令抽象出统一的接口,包括设备状态设置、卡使能去使能、sleep/awake、poweroff notify、cid/rca/dsr/csd寄存器读写、通过mmc switch命令实现与extend csd寄存器的读写等接口

 

    以上即是i2c/spi/mmc各模块的异同点,针对上面的几点分析,也大大加深了我们的印象,也基本上了解了mmc子系统的设备-总 线-驱动、设备-类模型。下面我们从mmc子系统设备-驱动-总线模型间数据结构体之间的关联,来进一步分析mmc子体系的驱动模型。

mmc子系统设备-总线-驱动模型

       如下即为mmc_bus_type、mmc_card、mmc_host、mmc_driver、kset、kobject的关联如下图(针对设备驱动模型、sysfs文件系统这两个部分,之前已经分析过,个人认为把这两部分内容熟悉了之后,针对大多数的设备驱动模型理解,均会比较轻松,因此强烈建议大家先熟悉这两个模块)。其中i2cbus、mmc bus、spi总线均通过其对应的kobject完成关联。而mmc host与mmc card通过其指针成员完成了绑定,而mmc card、mmc driver、mmc bus则借助设备-总线-驱动模型的数据结构完成了关联操作。

 

mmc子系统mmc host与mmc class的关联

 

mmc子系统的mmc host借助其device类型的程序class_dev以及device-class模型的数据结构完成了绑定操作,如下为mmc host与mmc class的关联,同时mmc host借助kref、mmc_class->dev_release接口,可完成mmc host变量的动态释放(当mmc_host的引用计数为0后,则会调用device_release接口进行释放操作,最终调用mmc_host_classdev_release接口,完成mmc_host的内存释放)。

mmc子系统的逻辑架构

针对mmc子系统内部,其与上层应用以及底层设备的关联如下图所示(该逻辑图并不是很准确,但大体正确):

Mmc block部分:

  1. MMC子系统的block部分负责与上层VFS之间的关联,用于与VFS的sys_open等接口关联;
  2. Mmc block层通过调用core层接口函数,通过调用具体host->ops->request接口,实现向mmc/sd card读写数据;

core接口层:

host相关接口:

  1. 提供mmc host注册、注销的接口;
  2. 提供mmc host class的创建,并使用device-class模型,实现mmc_host与mmc_host_class的关联;

Mmc/sd ops接口:

针对mmc/sd,mmc/emmc spec协议中规定了所有寄存器定义、命令,针对所有的mmc/sd/sdio设备均需要遵守,因此mmc子系统针对mmc/sd/sdio设备的命令访问操作进行实现,提供统一的接口,供mmc子系统各部分调用,提供的接口包括设备状态设置、卡使能去使能、sleep/awake、poweroff notify、cid/rca/dsr/csd寄存器读写、通过mmc switch命令实现与extend csd寄存器的读写等接口。而这些接口最终会调用mmccore提供的封装接口(间接调用mmc_host->ops->request接口),借助mmc controller实现与mmc/sd/sdio设备的通信

Mmc bus ops接口(mmc.c):

主要是提供了mmc card初始化及注册至mmc总线(即与)、csd、cid、extent csd寄存器各值的设置、mmc host与mmc card的绑定、mmc card的sleep/awake/suspend/alive等接口。这些接口主要供mmc core相关的接口调用,实现mmc card的创建及与设备-驱动-总线模型以及mmc host的绑定等内容。该部分也会调用mmc core提供的接口,主要用于设置mmc总线的电压、总线宽度、总线模式、块长度、块计数、mmc data timeout参数等。

Mmc/sdio bus接口:

mmc子系统提供了mmc/sdio bus的定义,通过使用设备-总线-驱动模型提供的接口,实现mmc子系统的总线-设备-驱动模型

 

Mmc core接口:

该部分的提供的接口包括mmc bus的注册与注销、mmc 通信接口(提供同步的与mmc 设备通信的接口)、mmc host与mmc_bus ops接口的绑定及解绑接口、mmc device的rescan接口(并提供poll机制的rescan功能,若在硬件设计时,未提供卡检测相关的cd引脚,则可以借助mmc 子系统提供的poll机制,实现对mmc device的rescan)、提供设置mmc总线的电压、总线宽度、总线模式、块长度、块计数、mmc data timeout参数等、powerup、poweroff notify、reset、mmc 总线io相关的配置等等。

 

 

该逻辑图可能不严谨,但大致脉络清晰,也有助于我们理解mmc子系统的实现。

 

小结

本文从两个部分说明了mmc字体的驱动模型,首先通过设备-总线-驱动模型入手,讲述数据结

构间的关联(其实linux内核的各模块,通过其数据结构间的关联,即可大致理解其模块代码的实现,因此在我们进行应用程序的开发时,可以借助linux内核的这种思想,注重数据结构体的构建);然后从mmc子系统的逻辑架构进行入手,理清mmc子系统大致的逻辑架构。以上内容希望能对大家有所帮助。

发布了140 篇原创文章 · 获赞 30 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/lickylin/article/details/104717819
今日推荐