先说项目上遇到的SD卡问题及解决方案。再说我目前了解到的SD卡的基础知识。本文使用的是SDIO接口的TF卡。
最近没少因为SD卡的原因找bug。主要有这么两个:
1、是接手了项目后换了个其他厂家的SD卡发现这张卡无法正常初始化。原来是有个转1.8V工作电压的命令,但是本电路上没设计1.8V电路,因此把这个转1.8V命令关闭,再试就可以正常使用了。
那么这个1.8V的命令是干啥的呢?这得先说一下SD卡的分类了。
按通信接口可以分为两种:一种是 SPI 接口,另外一种就是 SDIO 接口。SDIO 接口的设备类型如下:
图片摘自SDIO—SD 卡读写测试_sd卡测试_萧 十 三的博客-CSDN博客
不同型号的SD卡支持不同的协议版本、具有不同的容量、工作电压、数据传输速率。SD卡默认数据传输时钟为25MHz,对于支持高速传输的SD卡则可通过转1.8V的命令工作在50MHz的高速模式,既满足高速传输又可以低功耗。系统复位后SD卡先处在卡识别模式,主机通过下图中的各种命令识别 SD卡类型、确认SD卡的工作电压范围。识别完成后,SD卡由“卡识别模式”进入“数据传输模式”。
识别卡的命令图:
图片摘自SDIO—SD 卡读写测试_sd卡测试_萧 十 三的博客-CSDN博客
本案例中就是因为SD卡是支持1.8V的,所以在初始化卡识别过程中转成了1.8V工作,而实际电路不支持1.8V导致初始化失败,SD卡无法使用。
2、是在读取SD卡中的文件时发现有些文件读取时间很长。即使删除了文件夹里的其他文件,这些耗时长的文件的读取时间依旧不变。在单次操作文件时并不会觉察出耗时的差异,问题出在当循环多次打开文件、读取内容、关闭文件、再打开文件、读取下一条内容、再关闭文件,这样循环造成的时间累积,在大容量文件时会出现等待数秒的情况,严重影响使用。
如何解决?首先文件数量过多时,单次打开文件耗时长,这个是无法修改的(如果有大佬做到了请不吝赐教)。但是循环读取可以进行优化,在进入循环体前先f_open文件,在循环体内读取文件内容,循环结束后f_close文件。即可解决由多次重复开关文件造成的时间累积。
那为什么删除多余文件后,剩余的几个原耗时久的文件依旧耗时久呢?这需要先了解SD卡内文件存储的逻辑。
SD卡的空间分3部分:保留区(引导扇区)+FAT表+数据区,具体如下图:
图片摘自SD卡中FAT32文件格式快速入门(图文详细介绍)_fat32格式_TomiTwo的博客-CSDN博客
对于FAT32系统,一般情况下FAT32的根目录位于数据区内的第2簇,每创建一个新文件夹或文件时,在根目录里会生成对应的目录项(包括文件名、文件大小、文件起始地址)。当要操作某文件A时,先f_open该文件,此函数内会逐个检索根目录中的目录项中的文件名,与所要操作的文件信息比对。那么当文件数量很多时,而且文件A的目录项地址很大,就会造成检索次数增多,耗时增加(主要时间花在了f_open ---> follow_path ---> dir_find)。而删除其他文件,并不会改变文件A在根目录里的目录项地址,检索次数和耗时依旧不变。