STM32F469I discovery驱动SD卡
-----东方青
SD卡,一种廉价的存储介质,深深的融入在我们的生活中。平常我们看到的SD卡,是可以通过读卡器插在PC上,然后将文本文件、音频文件或者视频文件等等Copy到其中去存储,这是多么的简单和方便。但是作为程序猿,我们更应该去了解SD卡隐藏在背后的秘密,而不是简简单单的通过文件系统来Copy文件。
1.SD卡的简介和技术难度
SD卡(Secure Digital Memory Card)是一种基于半导体闪存工艺的存储卡。它支持SDIO协议接口和SPI接口。它是一种很复杂的存储设备,其配备了SD卡协议,关于SD卡协议可在相应官网上找到。
因为它有自己的协议,并且协议也相当复杂,所以想要直接操作SD卡还是有一点的困难的,不过好在官方同样也提供了相应的SD卡驱动代码的源码进行移植,并且相应的SD卡协议上也定义了SD卡的命令表,从而只需了解SD卡的基本存储结构和SDIO协议接口或者SPI接口,就可以操作了。
在这里不进行SD卡具体存储结构的讲解,只是简单介绍,如需了解,请找度娘。SD卡的存储使用是以扇区/块为单位的(解释一下:其实我也不知道为什么,有些人以扇区来命名,有些人以块来命名,在Flash上,扇区和块是不等同的单位;但是往往大家在操作SD卡时,以块来命名一个基础的操作单位,但是其实操作的也就是512字节,而一个扇区实实在在的是512字节,而在文件系统中,块(BLOCK)的单位是4K字节,所以显得有些混乱,基于此,本文后面的命名全部以扇区为基础单位)。也就是说,每一次进行SD卡的读或写,都必须以操作512Byte为基本单位。其他的关于字节存储等等就和Flash等一样了。SD卡的难点就是理解它的存储结构和存储方式,不过具体的可以在操作中体现出来。
2.SD卡的另一种使用方法
在SD卡的使用中,常常是以文件系统的存在访问,所以我们能通过设备(PC或者移动设备)能看到其存储是文件,但是我们并不知道它们是如何存储的。眼见为实,这面向普通用户群体是非常实在的。
但是还有一种用法是用户看不见的,但却实实在在存在的方式。使用隐藏区,什么意思呢?在这里举一个例子。对于一些设备或者产品,使用到了SD卡作为存储大量数据或者文件的存储介质,但是还有一部分系统数据是需要存储的,但是这部分数据不能让用户操作,否则会导致系统崩溃。那么怎么办呢?解决方案通常是两种:
(1)在SD卡文件系统中设置一个系统配置目录,在目录中设置相应的配置文件来存储系统配置参数;然后对此目录做写保护。
(2)直接对SD卡进行分区,分为隐藏区和FAT区,将系统配置参数存放于隐藏区中,而FAT去中的文件数据可由用户随便操作,包括格式化SD卡,用户永远也看不到隐藏区的数据。
这两种方法各有优缺点,第一种方法所存放的数据应该是公开的,就算用户看见了也没事,只要不修改东西就好(实际上普通用户是修改不了的),但是经过试验,尽管有写保护,但是还是有被干掉的可能的;第二中方法不适用用经常读写的情况,只适用于少量读写或者只读不写的情况,因为一张SD卡的寿命平均也就是10W次左右。经常读写的话只能用Flash或者EEPROM了。对于用户而言,隐藏区是不存在的,所以它无从修改。下面我贴图证明,首先说明这里我使用的是一张4GByte大小的SD卡,如下图:
呵看见了木有?显示的可用空间(也就是FAT区)只有1.94G。那么除去厂商计算和计算机或者程序猿的计算差异(厂商计算1K等于1000,而计算机和程序员的1K等于1024,所以跟程序猿借钱你要小心了,哈哈玩笑),还有大概1.8G的空间去哪里了呢?为了证明我并没有欺骗广大人民群众,的使用分区助手看看,如下图:
如上图,整一张卡的可用空间为3.69G,没错,的确是4G卡;此卡被分成三个分区,其中FAT区的大小为1.94G,是前面在计算机页面看到的。而另外两个分区被隐藏起来了。为了证明这些隐藏区得到了使用,就需要使用WinHex工具打开,SD卡,找到使用位置。如下图:
如上图为SD卡10扇区位置,我使用来存储了地址索引,对应的相应地址通过自定义公式计算,去查找相应的内容,就是这样,如此简单。这部分内容对应用户而言,是不存在的,对于开发人员而言,是非常重要的。
3.板子硬件资源
关于硬件资源,上图表明一切了,具体对应的SDIO端口,请自行查看Datasheet和参考手册了。
4.移植SD卡驱动
ST同样为用户提供了完善的SD卡驱动,前面也介绍了SD卡的使用,所以这里直接移植使用,请初学者自行跟读代码。与SD卡相关的文件为stm32469i_discovery_sd.c和stm32469i_discovery_sd.h,将其添加到工程代码中即可(前提是CMSIS没问题)。
5.测试使用SD卡
首先,要确定使用思路,再确定测试思路。
使用思路:以扇区为单位对SD卡进行读操作、写操作和擦除操作。在使用前,可以通过命令进行检测是否插SD卡。
测试思路:基于使用思路,ST在初始化代码中当初始化SDIO完毕后,对SD卡进行检测,是否有SD卡存在。当SD卡存在时,尝试对其的5扇区进行擦除、写数据和读数据操作,最后对比读取到的数据和写入是数据进行比对,从而判断测试是否成功。当不成功是,亮红灯报警。
首先来确定一下,SD卡的操作概念和基本定义:
如上图,读写Buffer的大小为512Byte,操作的扇区是5扇区,起始地址为0XA00(即5<<9位),每个扇区的大小为512Byte。注意,在这里我是一扇区为单位的,但是在ST的例程中,是以块为单位的,请自行注意异同点。
关于SD卡的调用就如上图了,整一个实验思路流程很清晰。
6.测试效果
又到了测试代码的时候了,在运行代码之前,我想干一件事,如下图:
通过WinHex在5扇区写上一段话(MY Name is DFQ),看看程序运行之后,还能否找到此段话。在板卡上插入SD卡,运行程序,有如下图:
OK!从运行结果可以看出,SD卡的测试实验已经成功,但是,还是有必要看看所操作扇区的数据为何:
如上图,可以看到,前面写入的字符串”MY Name is DFQ”已经不存在了,而存在的这些值,即为在TxBuffer中填充的值。
总结:本文尽管没有详细的代码分析,但是却分析了整一个SD卡的使用思路和不同的使用方案。并且如果单纯从使用的角度去理解SD卡协议,整一个工程代码还是很简单的。