【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个寄存器。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券