一、开发环境
|
|
- 主 机:VMWare--Fedora 9
- 开发板:Mini2440--64MB Nand, Kernel:2.6.30.4
- 编译器:arm-linux-gcc-4.3.2
二、MMC/SD介绍及SDI主机控制器
- MMC:(Multi Media Card)由西门子公司和首推CF的SanDisk于1997年推出的多媒体记忆卡标准。
- SD:(Secure Digital Memory Card)由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制的新一代记忆卡标准,已完全兼容MMC标准。
- SDIO:(Secure Digital Input and Output Card)安全数字输入输出卡。 SDIO是在SD标 准上定义了一种外设接口,通过 SD 的I/O接脚 来连接外围设备,并且通过SD 上的 I/O 数据接位与这些外围设备进行数据传输。是目前较热门的技术,如下图中的一些设备:GPS、相机、Wi-Fi、调频广播、条形码读卡器、蓝牙等。
- 工作模式:工作模式是针对主机控制器来说的。也就是说,S3C2440中的SDI 控制器可以在符合MMC的标准下工作,或者可以在符合SD的标准下工作,或者可以在符合SDIO的标准下工作。故就分别简称为:MMC模式、SD模式和 SDIO模式。
- 传输模式:传输模式也是针对主机控制器来说的,指控制器与卡之间数据的传输模式, 或者说是总线类型。S3C2440中的SDI控制器可支持SPI、1位和4位的三种传输模式(总线类型)。那么什么又是SPI呢?请参考这里: SPI协议简介 ;至于1位和4位又是什么意思呢?他们是指传输数据总线的线宽,具体参考数据手册。
下面使用表格列出了MMC、SD、SDIO的电气特性及性能和不同工作模式下支持的传输模式情况:
那么,我们现在怎样让主机控制器在我们所要求的工作模式和传输模式上工作呢?很简单,就是对主机控制器的各个寄存器进行相应的配置 即可。下面来简单介绍一下SDI主机控制器的结构和各寄存器的用途。
S3C2440内的SDI主机控制器结构图如下:
如上图所示,SDI主机控制器是使用1个串行时钟线与5条数据线同步进行信息移位和采样。传输频率通过设定SDIPRE寄存器的相应位的设定来 控制,可以修改频率来调节波特率数据寄存器的值。
各主要寄存器介绍,对于具体的寄存器位的设置就参考数据手册:
- SDICON:控制寄存器,完成SD卡基础配置,包括大小端,中断允许,模式选择,时钟使能 等。
- SDIPRE:波特率预定标器寄存器,对SDCLK的配置。
- SDICmdArg:指令参数寄存器,指令的参数存放在这里。
- SDICCON:控制指令形式的寄存器,配置SPI还是SDI指令,指令的反馈长 度,是否等待反馈,是否运行指令,指令的索引等。
- SDICmdSta:指令状态寄存器,指令是否超时,传送,结束,CRC是否正确 等。
- SDIRSP0-3:反映SD的状态。
- SDIDTimer:设置超时时间。
- SDIBSize:模块大小寄存器。
- SDIDatCon:数据控制寄存器,配置是几线传输,数据发送方向,数据传送方 式等。
- SDIDatSta:数据状态寄存器,数据是否发送完,CRC效验,超时等。
- SDIFSTA:FIFO状态寄存器,DMA传输是否判断FIFO。
- SDIIntMsk:中断屏蔽寄存器。
- SDIDAT:SDI数据寄存器。
SDI主机控制器在SD/MMC工作模式下的设置步骤:(注意:因为SD模式兼容MMC模式,所以我们只需了解SD模式的即可,而SDIO的工作模 式则是针对SDIO设备的,所以这里就不讨论了)
- 设置SDICON寄存器来配置适当的时钟及中断使能;
- 设置SDIPRE寄存器适当的值;
- 等待74个SDCLK时钟以初始化卡;
- 命令操作步骤:
a. 写命令参数32位到SDICmdArg寄存器;
b. 设置命令类型并通过设置SDICCON寄存器开始命令传输;
c. 当SDICSTA寄存器的特殊标志被置位,确认命令操作完成;
d. 如果命令类型相应,标志是RspFin,否则标志是CmdSend;
e. 通过对相应位写1,清除SDICmdSta的标志。 - 数据操作步骤:
a. 写数据超时时间到SDIDTimer寄存器;
b. 写模块大小到SDIBSize寄存器(通常是0x80字节);
c. 确定模块模式、总线线宽、DMA等且通过设置SDIDatCon寄存器开始数据传输;
d. 发送数据->写数据到SDIDAT寄存器,当发送FIFO有效(TFDET置位),或一半(TFHalf置位),或空(TFEmpty置位);
e. 接收数据->从数据寄存器SDIDAT读数据,当接收FIFO有效(RFDET置位),或满(RFFull置位),或一半(RFHalf置位),或 准备最后数据(RFLast置位);
f. 当SDIDatSta寄存器的DatFin标志置位,确认数据操作完成;
g. 通过对相应位写1,清除SDIDatSta的标志。
三、MMC/SD协议
这 里我并不是要讨论MMC/SD的整个通信协议(详细的协议请看MMC/SD规范),而是遵循MMC/SD协议了解一下MMC/SD在被驱动的 过程中卡所处的各种阶段和状态。根据协议,MMC/SD卡的驱动被分为:卡识别阶段和数据传输阶段。在卡识别阶段通过命令使MMC/SD处于:空闲 (idle)、准备(ready)、识别(ident)、等待(stby)、不活动(ina)几种不同的状态;而在数据传输阶段通过命令使MMC/SD处 于:发送(data)、传输(tran)、接收(rcv)、程序(prg)、断开连接(dis)几种不同的状态。所以可以总结MMC/SD在工作的整个过 程中分为两个阶段和十种状态。下面使用图形来描述一下在两个阶段中这十种状态之间的转换关系。
卡识别阶段,如下图:
数据传输阶段,如下图:
四、MMC/SD设备驱动在Linux中的结构层次
我 们翻开MMC/SD设备驱动代码在Linux源码中的位置 /linux-2.6.30.4/drivers/mmc/,乍一看,分别有card、core和host三个文件夹,那哪一个文件才是我们要找的驱动代 码文件啊?答案是他们都是。不是吧,听起来有些可怕,三个文件夹下有多少代码啊。呵呵,还是先放下对庞大而又神秘代码的恐惧感吧,因为在实际驱动开发中, 其实只需要在host文件夹下实现你具体的MMC/SD设备驱动部分代码,现在你的心情是不是要好点了。具体的MMC/SD设备是什么意思呢?他包括 RAM芯片中的SDI控制器(支持对MMC/SD卡的控制,俗称MMC/SD主机控制器)和SDI控制器与MMC/SD卡的硬件接口电路。
本文详细介绍了嵌入式Linux环境下SD卡驱动的原理与实现过程,涵盖了开发环境搭建、SDI主机控制器配置、MMC/SD协议解析以及Linux内核中驱动的层次结构等内容。
955

被折叠的 条评论
为什么被折叠?



