Linux驱动 您所在的位置:网站首页 mmc指的是什么意思 Linux驱动

Linux驱动

2024-07-14 07:58| 来源: 网络整理| 查看: 265

Linux驱动——mmc概念与框架(一)

备注:   1. Kernel版本:5.4   2. 使用工具:Source Insight 4.0   3. 参考博客: Linux MMC framework(1)_软件架构

1. [mmc subsystem] 概念与框架

文章目录 Linux驱动——mmc概念与框架(一)概念mmc的概念mmc设备mmc协议 软件架构sys下的文件节点说明bus节点host的class节点card对应的sys节点debug节点源码分析

概念 mmc的概念

  mmc有很多种意义,具体如下:

mmc   MultiMedia Card,多媒体存储卡, 但后续泛指一个接口协定(一种卡式),能符合这接口的内存器都可称作mmc储存体。

  

主要特性   工作电压:高电压为2.7~3.6 V,低电压为1.65~1.95 V,可选。

  

mmc总线   mmc总线是和I2C总线、SPI总线类似的一种总线结构。简化系统结构图如下(也可以理解为硬件框架图): 在这里插入图片描述

  

硬件特性

  卡与主控制器间串行传送,工作时钟频率范围为0~200 MHz。   mmc总线上最多可识别64 K个mmc设备,在总线上不超过10个卡时,可运行到最高频率。

mmc设备

  使用mmc接口规范(MCI, Multimedia Card Interface)的设备都可以称之为mmc设备。   可分成三个种类,如下:

mmc type card

(1)标准mmc卡:闪存卡的一种,使用mmc标准。 (2)emmc:Embedded MultiMediaCard,是MMC协会所制定的内嵌式存储器标准规格,带有mmc接口,是具备mmc协议的芯片。

sd type card

(1)sd卡:SD卡为Secure Digital Memory Card, 即安全数码卡。它在MMC的基础上发展而来,增加了两个主要特色:SD卡强调数据的安全,可以设定所储存的使用权限,防止数据被他人复制。兼容mmc接口规范。

sdio type card

(1)sdio设备:SDIO是在SD标准上定义了一种外设接口,它和SD卡规范间的一个重要区别是增加了低速标准。在SDIO卡只需要SPI和1位SD传输模式。低速卡的目标应用是以最小的硬件开销支持低速IO能力。常见的sdio设备有Wi-Fi card、Bluetooth card等等。

  注意,这几种类型的card统称为mmc card。

mmc协议

  类似i2c协议、spi协议,mmc总线上也有一套自己的通讯规范。通信规范后续在说明。

  而上述mmc设备基于上mmc总线通讯规范上由自身硬件特性设置了自己的一套协议。

  jedec的协议规范可以去jedec的官网上下载。

标准mmc卡协议

mmc4.0 mmc4.1《MultiMediaCard (MMC) Electrical Standard, Standard Capacity (MMCA, 4.1)》

mmc4.2《MultiMediaCard (MMC) Electrical Standard, High Capacity (MMCA, 4.2)》

emmc协议(主要区别主要在读写速度上)

emmc4.41《Embedded MultiMediaCard(e•MMC) e•MMC/Card Product Standard, High Capacity, including Reliable Write, Boot, Sleep Modes, Dual Data Rate, Multiple Partitions Supports, Security Enhancement, Background Operation and High Priority Interrupt (MMCA, 4.41)》

emmc4.51《Embedded Multimedia Card (e•MMC), Electrical Standard 4.51》

emmc5.0《Embedded Multi-Media Card (e•MMC) Electrical Standard (5.01)》

emmc5.1《Embedded Multi-Media Card (e•MMC) Electrical Standard (5.1)》

sd协议

sd1.0《SD Host Controller Simplified Specification》

sd2.0《SD Host Controller Simplified Specification》

sd3.0《SD Host Controller Simplified Specification》

sdio4.2《SD Host Controller Simplified Specification》

sdio协议

sdio1.0《SDIO Simplified Specification》

sdio1.1《SDIO Simplified Specification》

sdio2.0《SDIO Simplified Specification》

sdio3.0《SDIO Simplified Specification》

软件架构

请添加图片描述

  MMC framework分别有“从左到右”和“从下到上”两种层次结构。

1) 从左到右   MMC协议是一个总线协议,因此包括Host controller、Bus、Card三类实体(从左到右)。相应的,MMC framework抽象出了host、bus、card三个软件实体,以便和硬件一一对应:

  host,负责驱动Host controller,提供诸如访问card的寄存器、检测card的插拔、读写card等操作方法。从设备模型的角度看,host会检测卡的插入,并向bus注册MMC card设备;

  bus,是MMC bus的虚拟抽象,以标准设备模型的方式,收纳MMC card(device)以及对应的MMC driver(driver);

  card,抽象具体的MMC卡,由对应的MMC driver驱动(从这个角度看,可以忽略MMC的技术细节,只需关心一个个具有特定功能的卡设备,如存储卡、WIFI卡、GPS卡等等)。

2)从下到上

  MMC framework从下到上也有3个层次(老生常谈了):

  MMC core位于中间,是MMC framework的核心实现,负责抽象host、bus、card等软件实体,负责向底层提供统一、便利的编写Host controller driver的API;   MMC host controller driver位于底层,基于MMC core提供的框架,驱动具体的硬件(MMC controller);   MMC card driver位于最上面,负责驱动MMC core抽象出来的虚拟的card设备,并对接内核其它的framework(例如块设备、TTY、wireless等),实现具体的功能。   这里补充说明,sdhci并不是实际的host驱动,而是上述说明的sdhc标准的host的驱动部分,如:sdhci-msm和sdhci-s3c都使用了SDHC标准。

3)文件目录结构      Linux kernel把mmc,sd以及sdio三者的驱动代码整合在一起,俗称mmc子系统。源码位于drivers/mmc下。其下有两个子目录,分别是: 请添加图片描述

core(核心层) 主要子文件:bus.h/.c、core.h/.c、host.h/.c、mmc.c、sdio.c、sd.c、block.c、queue.h、queue.c等。   作用一:主要是按照 LINUX 块设备驱动程序的框架实现一个卡的块设备驱动;   作用二:核心层封装了 MMC/SD 卡的命令,例如存储卡的识别,设置,读写;

文件说明:   block.c: 在 该文件当中我们可以看到写一个块设备驱动程序时需要的 block_device_operations 结构体变量的定义,其中有 open/release/ioctl 函数的实现;

  queue.c :则是对内核提供的请求队列的封装,我们暂时不用深入理解它,只需要知道一个块设备需要一个请求队列就可以了。

  bus:总线相关操作,连接驱动和设备的桥梁;

  core:提供存储卡的相关操作,core.c由 sd.c、mmc.c 两个文件支撑的, core.c 把 MMC 卡、 SD 卡的共性抽象出来,它们的差别由 sd.c 和 sd_ops.c 、 mmc.c 和 mmc_ops.c 来完成。

host(主机控制层)   主机控制器则是依赖于不同的平台的,例如 s3c2410 的卡控制器和 atmel 的卡控制器必定是不一样的,所以要针对不同的控制器来实现。   以 s3cmci.c 为例,它首先要进行一些设置,例如中断函数注册,全能控制器等等。然后它会向 core 层注册一个主机( host ),用结构 mmc_host_ops 描述,这样核心层就可以拿着这个 host 来操作 s3c24xx 的卡控制器了,而具体是 s3c24xx 的卡控制器还是 atmel 的卡控制器, core 层是不用知道的。

sys下的文件节点说明 bus节点

mmc bus节点的对应路径为/sys/bus/mmc。在mmc_register_bus中生成。

在devices目录下有如下节点 /sys/bus/mmc/devices/mmc0:5048 其中mmc0:5048就是mmc core抽象出来的card设备,对应于我们板子上的sd。 对应代码参考mmc_alloc_card & mmc_add_card。 在drivers目录下有如下节点 /sys/bus/mmc/drivers/mmcblk 其中mmcblk就是block.c中实现的card driver。 对应代码参考mmc_register_driver。 在devices目录下有如下节点 /sys/bus/sdio/devices/mmc1:0001:1 其中mmc1:0001:1就是mmc core抽象出来的card设备,对应于我们板子上的sdio wifi。 对应代码参考mmc_alloc_card & mmc_add_card。 在drivers目录下有如下节点 /sys/bus/sdio/drivers/rtl8189fs host的class节点

  mmc core实现了一个class用于维护和管理mmc host。其对应路径为/sys/class/mmc_host。mmc core会为每个注册到mmc core中的mmc host在该class目录下添加一个对应的节点。在mmc_add_host中生成。 示例如下:

创建class的代码参考mmc_register_host_class 在/sys/class/mmc_host下有如下目录: /sys/class/mmc_host/mmc0 /sys/class/mmc_host/mmc1 mmc0就是对应alias序号为0的host,而mmc1就是对应alias序号为1的host。 具体代码参考mmc_alloc_host。 /sys/class/mmc_host/mmc0下有如下属性: device mmc0:5048 power subsystem uevent /sys/class/mmc_host/mmc1下有如下属性: device mmc1:0001 power subsystem uevent card对应的sys节点

mmc core把mmc设备抽象为card设备。 从两个地方可以找到其对应的sys节点。 简单示例如下:

以mmc0:5048设备为例,mmc0表示这个card挂载mmc0这个host上,0001表示card设备地址为5048(也就是RCA,协议的东西,后续会说明) (1)/sys/bus/mmc/devices/mmc0:5048(因为是挂在mmc bus上) (2)/sys/class/mmc_host/mmc0/mmc0:5048(因为card的parent device为mmc host的class device) 具体代码参考mmc_alloc_card & mmc_add_card。 其有如下属性: block hwrev scr cid manfid serial csd name ssr date ocr subsystem driver oemid type dsr power uevent erase_size preferred_erase_size fwrev rca debug节点

  mmc core为每个注册到core中的host创建了对应的debug节点。   以mmc0这个host为例,其对应节点路径为/sys/kernel/debug/mmc0。

/sys/kernel/debug/mmc0有如下属性: caps caps2 clock ios mmc0:5048 具体代码参考mmc_add_host——》mmc_add_host_debugfs mmc0:5048下有如下debug属性: state status 源码分析

源码路径:drivers/mmc/core/core.c

static int __init mmc_init(void) { int ret; ret = mmc_register_bus();//注册mmc bus if (ret) return ret; ret = mmc_register_host_class(); //注册mmc_host class if (ret) goto unregister_bus; ret = sdio_register_bus(); //注册sdio bus if (ret) goto unregister_host_class; return 0; unregister_host_class: mmc_unregister_host_class(); unregister_bus: mmc_unregister_bus(); return ret; } static void __exit mmc_exit(void) { sdio_unregister_bus(); mmc_unregister_host_class(); mmc_unregister_bus(); } subsys_initcall(mmc_init); module_exit(mmc_exit); MODULE_LICENSE("GPL");

mmc bus注册: 源码路径:drivers/mmc/core/bus.c

static struct bus_type mmc_bus_type = { .name = "mmc", .dev_groups = mmc_dev_groups, .match = mmc_bus_match, .uevent = mmc_bus_uevent, .probe = mmc_bus_probe, .remove = mmc_bus_remove, .shutdown = mmc_bus_shutdown, .pm = &mmc_bus_pm_ops, }; int mmc_register_bus(void) { return bus_register(&mmc_bus_type); }

sdio bus注册: 源码路径:drivers/mmc/core/sdio_bus.c

static struct bus_type sdio_bus_type = { .name = "sdio", .dev_groups = sdio_dev_groups, .match = sdio_bus_match, .uevent = sdio_bus_uevent, .probe = sdio_bus_probe, .remove = sdio_bus_remove, .pm = &sdio_bus_pm_ops, }; int sdio_register_bus(void) { return bus_register(&sdio_bus_type); }

mmc_host class注册: 源码路径:drivers/mmc/core/host.c

static struct class mmc_host_class = { .name = "mmc_host", .dev_release = mmc_host_classdev_release, }; int mmc_register_host_class(void) { return class_register(&mmc_host_class); }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有