sd卡的了解(二)

时间:2022-07-11 18:22:51

  在上一篇blog中已经简单介绍了一下sd卡,接下来我们结合代码来看一下,设备是如何使sd卡工作的,这个神奇的小卡片都经历了什么呢。

  首先看一下代码目录,driver/mmc/下面有三个关键的文件夹,分别是card、core、host。

sd卡的了解(二)

图1目录结构

  那么这三个文件有什么关系呢?

  sd卡的了解(二)

图2三者关系图

  现在简单介绍一下三者各自的功能:

   (1)host部分是针对不同主机的驱动程序,主要完成硬件的注册和初始话

      (2)core部分是核心部分,主要完成了不同协议和规范的实现,为host层的驱动提供了函数接口

   (3)card部分主要是将sd卡实现为块设备

  

  1)路径:drivers/mmc/host/sdhci-msm.c

sd卡的了解(二)  

图3host中主要操作

  sdhci_msm_ops: 主控制器参数设置

  sdhci_pltfm_init: 初始化host

  mmc_of_parse: 解析设备树相关信息

  sdhci_add_host:转换sdhci_host结构提到mmc_host内核标准结构体,并挂接上相关标准函数,加入mmc子系统。

  2) 

sd卡的了解(二)

图4参数设置的主要过程

  sdhci_msm_execute_tuning: 调整时钟频率

  sdhci_reset: 重置设备

  sdhci_set_clock: 设置时钟

  sdhci_set_bus_width: 设置bus宽度

  sdhci_set_uhs_signaling: 设置传输速度


  static struct sdhci_ops sdhci_msm_ops = {
        .platform_execute_tuning = sdhci_msm_execute_tuning,
        .reset = dhci_reset,
        .set_clock = sdhci_set_clock,
        .set_bus_width = sdhci_set_bus_width,
        .set_uhs_signaling = sdhci_set_uhs_signaling,
    };


    3)

sd卡的了解(二)

图5host初始化过程

  

  platform_get_resource:获取设备资源

  sdhci_alloc_host:启动延时,然后去执行 mmc_rescan 函数

  platform_get_irq:获取中断资源

  mmc_rescan()是通过mmc_rescan_try_freq()这个函数来实现扫描卡的类型,该函数首先发送复位命令(CMD52,该命令只有SDIO类型的卡才能够识别),然后发送CMD0,让设备进入IDLE模式,随后发送CMD8,获取该卡所支持的电压值,最后从所调用的各个函数名字可以看出,它是在对卡的类型进行判断,这里依次判断外设是SDIO卡、SD卡还是MMC卡中的哪一种。

  

  4)

sd卡的了解(二)

图6添加mmc子系统流程

  mmc_add_host:添加mmc子系统

  这个函数首先通过device_add()添加一个mmc_host的devices,这个devices会与block.c中注册的mmc_driver相匹配,可以在sys/bus/platform/devices目录下找到相应的设备节点,然后调用mmc_start_host()去调用mmc_set_ios()设置电源、时钟等的寄存器。

  requset_threaded_irq:申请线程中断

  该函数会调用sdhci_irq()这个终端服务程序,该终端服务程序一般在插卡、拔卡或者从设备反馈给host信息时会被调用。

  tasklet_init:初始化一个tasklet

  程序会读取normal interrupt status寄存器的值,该寄存器有两个bit分别表示卡的插入和拔出。一旦检测到有卡插入就会调用中断下文函数sdhci_tasklet_card。这个函数用来处理mmc插槽上的状态变化,并调用mmc_detect_change()来调度host的工作队列,而他delay后调用的就是mmc_rescan()函数。


  到此,sd卡的冰山一角暂时了解了这些。下次blog我们再继续。