结构体mmc_host定义于/include/linux/mmc/host.c,可以认为是linux为SD卡控制器专门准备的一个类,该类里面的成员是所有SD卡控制器都需要的,是描述主机控制器的共有结构,具体的控制器结构体包含结构体mmc_host,如:

//该结构体有自己编写,根据实际项目来编写自己的host结构体
struct pxamci_host {
 struct mmc_host  *mmc;
 
 struct mmc_request *mrq;
 struct mmc_command *cmd;
 struct mmc_data  *data;
 
 ... ...
};
struct mmc_host {
 const struct mmc_host_ops *ops;     // SD卡主控制器的操作函数,即该控制器所具备的驱动能力
 
 const struct mmc_bus_ops *bus_ops; // SD总线驱动的操作函数,即SD总线所具备的驱动能力
 
 struct mmc_ios  ios;  // 配置时钟、总线、电源、片选、时序等
 
 struct mmc_card  *card;  // 连接到此主控制器的SD卡设备
    ... ...
};
struct mmc_host_ops {
 void (*request)(struct mmc_host *host, struct mmc_request *req);  // 核心函数,完成主控制器与SD卡设备之间的数据通信
 void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);  // 配置时钟、总线、电源、片选、时序等
 int (*get_ro)(struct mmc_host *host); //获取gpio管脚,判断是否是写保护
 void (*enable_sdio_irq)(struct mmc_host *host, int enable); //卡插入与拔出中断
};
struct mmc_bus_ops {
 void (*remove)(struct mmc_host *);    // 拔出SD卡的回调函数
 void (*detect)(struct mmc_host *);      // 探测SD卡是否还在SD总线上的回调函数
 void (*suspend)(struct mmc_host *);
 void (*resume)(struct mmc_host *);
};
struct mmc_card {
 struct mmc_host  *host;  /* the host this device belongs to */
 struct device  dev;  /* the device */
 unsigned int rca;  /* relative card address of device */
 unsigned int  type;  /* card type */
 unsigned int  state;  /* (our) card state */
 unsigned int  quirks;  /* card quirks */
 u32   raw_cid[4]; /* raw card CID */
 u32   raw_csd[4]; /* raw card CSD */
 u32   raw_scr[2]; /* raw card SCR */
 struct mmc_cid cid;  /* card identification */
 struct mmc_csd csd;  /* card specific */
 struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */
 struct sd_scr scr;  /* extra SD information */
 struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ unsigned int  sdio_funcs; /* number of SDIO functions */
 struct sdio_cccr cccr;  /* common card info */
 struct sdio_cis  cis;  /* common tuple info */
   ... ...
};

mmc_card结构体内的数据结构主要存放SD卡的信息,其中RCA, CID, CSD, SCR为SD卡内部的32位寄存器

eMMC获取剩余容量 emmc数据提取_eMMC获取剩余容量


2.1.2 struct mmc_request

结构体mmc_request定义于/include/linux/mmc/core.h,它主要存放两大数据结构的指针,分别是cmd和data,顾名思意,一个为指令,一个为数据,也就是说,mmc_request结构体存放了进行主控制器与sd卡间通信所需要的指令和数据,struct mmc_request, struct mmc_command *cmd, struct mmc_data *data三者之间的关系如下所示,
struct mmc_request {
 struct mmc_command *cmd;
  struct mmc_data  *data;
  struct mmc_command *stop;
 
 void   *done_data; /* completion data */
  void   (*done)(struct mmc_request *);/* completion function */
 };
  1. 物理结构
SD卡有9个pin脚(micro-SD为8个,少一个接地pin脚),如图所示,

eMMC获取剩余容量 emmc数据提取_#define_02

eMMC获取剩余容量 emmc数据提取_ci_03

SD的数据传输方式有两种,普通SD模式和SPI模式,以SD模式为例,9个pin脚分别是VDD,VSS,CLK,以及我们需要关注的一根指令线CMD,4根数据线DAT0~DAT3。

  1. 传输模式

首先由主机向SD卡发送命令command,等待SD卡的回复response,如果成功收到回复,则进行数据传输。其中,指令线和数据线上传输的指令和数据都要遵循相应的协议格式。

eMMC获取剩余容量 emmc数据提取_ios_04

  1. 指令格式

eMMC获取剩余容量 emmc数据提取_ios_05

一条指令command共48位,其中command index指代这条具体的指令名称,argument为该指令的参数。

一条回复response根据不同的指令有几种不同类型。

struct mmc_command {
  u32   opcode;            // 对应command index
  u32   arg;                  // 对应argument
  u32   resp[4];           // 对应response
  unsigned int  flags;  /* expected response type */
 
 ... ...
 
 unsigned int  retries; /* max number of retries */
  unsigned int  error;  /* command error */
 
 struct mmc_data  *data;  /* data segment associated with cmd */
  struct mmc_request *mrq;  /* associated request */
 };
  1. 数据格式
    数据传输按数据线可分为一线传输和四线传输,按数据大小可分为字节传输和块传输(512字节)。
struct mmc_data {
  unsigned int  timeout_ns; /* data timeout (in ns, max 80ms) */
  unsigned int  timeout_clks; /* data timeout (in clocks) */
  unsigned int  blksz;  /* data block size */
  unsigned int  blocks;  /* number of blocks */
  unsigned int  error;  /* data error */
  unsigned int  flags;
 
#define MMC_DATA_WRITE (1 << 8)
 #define MMC_DATA_READ (1 << 9)
 #define MMC_DATA_STREAM (1 << 10)
 
 unsigned int  bytes_xfered;
 
 struct mmc_command *stop;  /* stop command */
  struct mmc_request *mrq;  /* associated request */
 
 unsigned int  sg_len;  /* size of scatter list */
  struct scatterlist *sg;  /* I/O scatter list */
 };