【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个寄存器。
版权所有,转载请注明出处:
【Linux驱动学习】SD卡规范学习的更多相关文章
- linux驱动开发之块设备学习笔记
我的博客主要用来存放我的学习笔记,如有侵权,请与我练习,我会立刻删除.学习参考:http://www.cnblogs.com/yuanfang/archive/2010/12/24/1916231.h ...
- 如何编写一个简单的Linux驱动(一)
前言 最近在学习Linux驱动,记录下自己学习的历程. 驱动的基本框架 Linux驱动的基本框架包含两部分,“模块入口.出口的注册”和“模块入口.出口函数的实现”,如下方代码. static int ...
- linux 驱动学习笔记01--Linux 内核的编译
由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make confi ...
- Linux驱动学习步骤(转载)
1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ls ...
- 1.5如何学习Linux驱动开发
1.准备一个自己熟悉的Linux操作系统,用于开发和测试Linux驱动,建议使用Ubuntu Linux 10.04及以上版本: 2.准备一块开发板,建议采用基于ARM11的开发板: 3.学习GUN ...
- Linux驱动开发学习的一些必要步骤
1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ...
- 树莓派linux驱动学习之hello world
最近想学习一下linux驱动,看了一些书和教学视频,大概了解了一下,不过要想深入,肯定需要实践.手上有几块linux的板子,最终选择了树莓派作为我的实验平台,资料比较丰富,接口也比较简单. 程序员的入 ...
- Linux驱动学习1.hello world;
最近项目需要使用Linux系统开发,借此机会学习一下Linux驱动开发 hello word代码hello.c #include <linux/module.h> #include < ...
- ARM Linux驱动篇 学习温度传感器ds18b20的驱动编写过程
ARM Linux驱动篇 学习温度传感器ds18b20的驱动编写过程 原文地址:http://www.cnblogs.com/NickQ/p/9026545.html 一.开发板与ds18b20的入门 ...
随机推荐
- 第三十四篇 Python面向对象之 反射(自省)
什么是反射? 反射的概念是由Smith在1982年提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语 ...
- Uniy 组件式泛型单例模式
我们知道,在Unity中,所有对象脚本都必须继承MonoBehavior脚本,才能使用Unity内置的脚本功能; 通常我们可以用静态类来取代单例模式,但是静态类方法的缺点是,它们必须继承最底层的类-- ...
- (vue01)vue环境搭建
腾讯,百度,网易....这么大媒体平台咋老推送这么lower的信息? 你们不缺钱啊....我这么善良的孩子都别你们带坏了 强烈鄙视马化腾 强烈鄙视李彦宏 参考地址: https://segmentfa ...
- Java IO学习--RandomAccessFile
1.什么是 随机访问文件流 RandomAccessFile 这个类在很多资料上翻译成中文都是:随机访问文件,在中文里,随机是具有不确定的含义,指一会访问这里,一会访问那里的意思.如果以这种语义来解释 ...
- css3弹性盒子模型之box-flex
css3弹性盒子模型之box-flex 浏览器支持 目前没有浏览器支持 box-flex 属性. Firefox 支持替代的 -moz-box-flex 属性. Safari.Opera 以及 Chr ...
- C#的internal访问修饰符
文章:C# 访问修饰符internal的访问范围误区释疑 internal访问修饰符限定的类,只能在本程序集中访问.
- 更新协同开发工具SVN的链接的服务器地址
公司内的协同开发工具使用的SVN,因为换了个服务器需要重置SVN地址,一下子有点措手不及. 研究了下SVN的操作菜单,发现有一个功能“重新定位”,应该就是我要找的了,试了一下果真没错,记录下 第一步: ...
- 框架开发中的junit单元测试
首先写一个测试用的公共类,如果要搭建测试环境,只要继承这个公共类就能很容易的实现单元测试,代码如下 import org.junit.runner.RunWith; import org.spring ...
- OJ 列表
维护一个 OJ 列表.(这件事似乎没啥意义?) AtCoder hihoCoder Codeforces DMOJ CodeChef CS Academy HackerRank HackerEarth ...
- BZOJ2460 [BeiJing2011]元素 【线性基】
2460: [BeiJing2011]元素 Time Limit: 20 Sec Memory Limit: 128 MB Submit: 1675 Solved: 869 [Submit][St ...