【Linux驱动学习】SD卡规范学习

摘要:

学习SD卡的相关规范,包括定义,硬件特性,数据传输,命令系统等。不涉及代码。

文章针对Linux驱动开发而写,以助于理解SD卡驱动,不会涉及过多硬件内容。

纲要:

1. SD卡介绍

2. SD卡硬件规范

3. SD卡指令规范

4. SD卡寄存器

1. SD卡介绍

1.1 各类型储存卡/接口

首先了解一下我们在SD卡驱动学习中会碰到的主要几个储存卡名词:

SD:Security Digital Memory Card,新一代多媒体储存卡,高速,安全(但安全机制貌似很少用到)
MMC:Multimedia Card,SD卡的上一代多媒体储存卡,已基本被SD卡代替
eMMC:Embedded Multimedia Card,内嵌式存储器,一般焊在PCB上。内置主控制器,以实现统一MMC接口(在传统MMC接口上拓展,集成了整套理论),Nand Flash就是eMMC
SDIO:Secure Digital Input and Output Card,SD标准上定义了一种外设接口,有很多设备模块采用。如Wifi,GPS,Bluetooth

1.2 SD卡特性

以下是SD卡的部分特性。

  • 正向兼容MMC卡:能插SD卡的接口也可以插MMC卡

  • 最大10个堆叠的卡
  • SD模式和SPI模式
  • 可变时钟(0~25MHz),可变电压(2.0~3.6V)
  • 带电插拔保护
  • 安全系统,双方认证和“新的密码算法”技术

更多的特性请阅读SD卡官方规范。

2. SD卡硬件规范

2.1 SD卡物理接口

下图是SD卡和MMC卡的针脚:

可以看到,SD卡在MMC卡基础上增加了8、9两个针脚,这两个针脚将被用作数据传输,以支持SD传输模式。SD卡支持SD模式(4数据线)和SPI模式(2数据线),MMC卡只支持SPI模式。

SD卡针脚对应的功能:(SD模式)

SD模式:数据并行传输,2地,1电源,1时钟,1命令,4数据线(4出入)(SD模式的命令通过命令线传输)
SPI模式:数据串行传输,2地,1电源,1时钟,1片选,2数据线(1入1出)(SPI模式的命令通过数据线传输)

以下内容,如无分开说明,默认指SD模式。(本文不会涉及SPI模式学习)

2.2 SD卡与主机的连接

SD模式和SPI模式中与主机的连接拓扑图如下:

在SD模式中,数据线和命令线是分开连接到主机各GPIO口中的。在SPI模式中,片选线分别连接到主机各GPIO口,数据线在同一条总线上。

因为SPI模式的数据线在同一总线上,所以需要片选来选择不同的储存卡;SD模式分别连接到主机,不需要片选线。

3. SD卡命令规范

3.1 命令类型

SD卡有数十种指令,但无非都是一些获取信息,数据传输的功能,并不会很难理解。规范书上有详细的状态转换图,下面会有介绍。

下面是4种指令类型:

  • 广播指令,无应答(代号bc):发送完此类命令后,并不会有反馈,但操作已经生效。

  • 广播指令,有应答(代号bcr):发送完此类命令后,SD卡会给予反馈。可能是一些寄存器信息,可能是
  • 寻址(点对点)指令(代号ac):发送完此类命令后,只有指定地址的SD卡会给予反馈(地址通过命令请求SD卡发布,是唯一的)。此时DAT线上无数据传输。
  • 寻址(点对点)数据传输指令(adtc):发送完此类命令后,只有制定地址的SD卡会给予反馈。此时DAT线上有数据传输。

3.2命令表

官方文档将命令分成了好几种功能。下面将所有命令列出,仅作查阅了解用,不需要每个命令都记住:

基础命令:用于重置、切换SD卡状态,获取相关信息

读块命令:读单个、多个块数据,设置块长度

写块命令:写单个、多个块数据,设置块长度

擦除块命令:把对应的块数据擦除

写保护命令:设置、取消对应地址的数据的写保护,可以使其他程序无法写入指定的地址,达到保护目的。用的情况不太多。

锁卡命令:设置、取消锁卡。锁卡后需要密码才能访问SD卡。

应用特殊命令:CMD55,使用ACMD前必须先发送的命令;CMD56是标准的读、写命令,会读、写一个block的数据。

SDIO命令:预留给SDIO设备使用(CMD5也是预留给SDIO设备),在SD卡官方文档中没有说明具体用途

SD卡专用命令:MMC卡无法使用这些命令,里面包括如设置数据总线位宽,获取SD卡信息(寄存器)。

3.2 命令/数据传输方式

命令的传输协议大致如下:

  • 0开头,1结尾

  • 大端传输:先MSB,最后LSB
  • CRC校验

下面这幅图是无响应和无数据两种命令的传输情况:

非常清晰易懂,就不赘述了。

下面这幅图是多块数据读的数据传输情况:

主机发送多块读命令时,首先sd卡会做出回应,同时准备数据。数据准备完成后开始发送,并在每个block传输完成后加入crc校验码。传输完一个block和crc后紧跟着下一个block的数据传输,直到传输完成,或主机发送了新的命令。

SD模式有4根数据线,一次可以传输半个字节,两次一个字节。他们的传输方式如下图:

同样是先传MSB,再传LSB,一次传半个字节,这样做可以方便主机做位移组合成一个字节。如果每条线单独传一个字节,则需要移位8次才可以获得一个完整的byte。

3.3 状态转换

下图为SD卡状态转换图。重新上电时为Idle状态:

看起来这个状态图很复杂,其实我们要走的流程并不复杂。Linux驱动对SD卡做初始化会经过如下步骤:

CMD0上电重置到idle状态(防止一些机型关机不掉电,如某些FPGA平台)->ACMD41获取SD卡支持的电压信息(还需要通过主机控制器设置电压)->CMD2获取卡商信息->CMD3请求SD卡发布相对地址->CMD9获取CSD寄存器,即卡的电气特性数据(需要使用SD卡相对地址)->CMD7通过相对地址选择对应的SD卡,该卡进入数据传输Transfer State状态->各种CMD进行block读写

3.4 流程差异

不同种类的卡初始化过程是不一样的,通过流程差异我们可以判断不同类型的卡。

SDIO:CMD0之后执行CMD5,CMD5只有SDIO类型才会有响应。

MMC:ACMD 41换为CMD1,ACMD类命令只有SD或SDIO卡才有响应。所以要先检测是否是SDIO,再检测是否是SD,最后检测是否是MMC(core层代码中也是这个顺序),否则会出现误判。

4. SD卡寄存器

SD卡一共有6个寄存器,我们用的对多的是CID(卡商信息),RCA(相对地址)和OCR(电压信息):

CID:卡信息:生产商,OEM,产品名,版本,出产日期,CRC校验(所有寄存器都有,下同),常用
RCA:卡地址:在初始化时发布,用于与host通信,0x0000表示与所有卡通信,常用
DSR:驱动相关,总线电流大小,上升沿时间,最大开启时间,最小开启时间
CSD:数据传输要求:包括读写时间,读写电压最大最低值,写保护,块读写错误
SCR:特性支持,如CMD支持,总线数量支持
OCR:支持的电压,常用
SSR:特有特性,卡类型(OTP,SD等),一次擦除块数量
CSR:R1返回指令的卡状态,此寄存器用与传输卡状态给host

命令系统中有对应的指令获取这6个寄存器。

版权所有,转载请注明出处:

http://www.cnblogs.com/sickworm/p/4015932.html

时间: 2024-08-03 01:21:03

【Linux驱动学习】SD卡规范学习的相关文章

linux驱动开发之块设备学习笔记

学习参考:http://www.cnblogs.com/yuanfang/archive/2010/12/24/1916231.html 1.块设备 块设备将数据按照固定块大小的块中,每个块的大小通常在512字节到32768字节之间,磁盘.SD卡都是常见的块设备. 2.字符设备和块设备的区别: 字符设备 块设备 ---------------------------------------------- 按字节访问 按块进行访问 只能按照数据流访问 随机访问 直接访问设备 挂在文件系统的方式访问

linux驱动开发学习路线

这篇文章是和大四学弟交流的文章,贴出来,和大家学习讨论 需要掌握的基本技能: C/C++/ python shell makefile linux基本操作 以android手机为例,我通俗的介绍下市场上产品的软件结构. 手机---> 硬件:cpu(arm架构单片机)+各种传感器(显示屏.距离传感器.温度传感器.gms模块 gprs模块等等).本质上手机就是一个单片机加上一堆传感器,单片机控制各个传感器与人进行负责的交互.(驱动工程师就是在linux底层让传感器可以工作,然后提供控制硬件的接口交给

Linux驱动学习步骤(转载)

1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, lsmod, rmmod. 在驱动的init函数里打印hello world, insmod后应该能够通过dmesg看到输出. 5. 写一完整驱动, 加上read, write, ioctl, polling等各种函数的驱动实现. 在ioctl里完成从用户空间向内核空间传递结构体的实现. 6. 写一bl

Linux驱动学习之Linux-2.6.20.4内核移植

最近一段时间一直在学习向TQ2440开发板移植内核.移植驱动.真心觉得这方面的知识有很大的难度.但是从另一角度去看,难度越大,能力提升的空间就越大!! 1.解压源码 从网上下载一个Linux 内核,我是用的是Linux-2.6.20.4.然后用命令解压.建议解压到"/home/用户名"目录下.我的内核源码存放在: 2.添加对ARM的支持 因为所用的是TQ2440开发板,属于ARM9.因此要在系统中添加对ARM的支持. 方法:进入内核源码目录, 修改"Makefile"

linux驱动学习之tasklet分析

tasklet是中断处理下半部分最常用的一种方法,驱动程序一般先申请中断,在中断处理函数内完成中断上半部分的工作后调用tasklet.tasklet有如下特点: 1.tasklet只可以在一个CPU上同步地执行,不同的tasklet可以在不同地CPU上同步地执行. 2.tasklet的实现是建立在两个软件中断的基础之上的,即HI_SOFTIRQ和TASKLET_SOFTIRQ,本质上没有什么区别,只不过HI_SOFTIRQ的优先级更高一些 3.由于tasklet是在软中断上实现的,所以像软中断一

Linux驱动学习之TQ2440 DM9000E网卡驱动移植(Linux-2.6.30.4)

引言 在之前的文章中,我们介绍了如何使用Scala IDE也就是eclipse中集成的Scala开发插件来进行Scala语言程序的开发,在使用了一段时间之后,发现eclipse对Scala的支持并不是很好.用户体验比较差,比如联想速度比较慢等.由于在公司一直使用的Scala开发工具是Intellij IDEA(好吧,其实我使用Scala IDE的目的就是想试一下这两个各有什么优缺点),各方面感觉还不错,所以在此介绍一下这个开发环境. Intellij IDEA是jetbrain开发的一个IDE,

linux 驱动学习笔记01--Linux 内核的编译

由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make config(基于文本的最为传统的配置界面,不推荐使用)#make menuconfig(基于文本菜单的配置界面)#make xconfig(要求 QT 被安装)#make gconfig(要求 GTK+被安装)在配置 Linux 2.6 内核所使用的 make config. make menuconfig. mak

Linux驱动开发学习的一些必要步骤

1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, lsmod, rmmod. 在驱动的init函数里打印hello world, insmod后应该能够通过dmesg看到输出. 5. 写一完整驱动, 加上read, write, ioctl, polling等各种函数的驱动实现. 在ioctl里完成从用户空间向内核空间传递结构体的实现. 6. 写一bl

Linux内核(17) - 高效学习Linux驱动开发

这本<Linux内核修炼之道>已经开卖(网上的链接为: 卓越.当当.china-pub ),虽然是严肃文学,但为了保证流畅性,大部分文字我还都是斟词灼句,反复的念几遍才写上去的,尽量考虑到写上去的每段话能够让读者产生什么疑惑,然后也都会紧接着尽量的去进行解释清楚,中间的很多概念也有反复纠结过怎么解释能够更容易的理解,力求即使对于初学者也可以有很少阻碍的一气读完.同时我也把书中一部分自己的感悟抽出来整理了精华版,share出来.当然水平有限,错漏之处有发现而修订时遗漏的,也有尚没有发现的.这本书