基于MCU的SD卡fat文件系统读写移植
背景
https://blog.csdn.net/huang20083200056/article/details/78508490
SD卡(Secure Digital Memory Card)具有体积小、容量大、数据传输快、可插拔、安全性好等优点,被广泛应用于便携式设备上。例如作为数码相机的存储卡,作为手机、平板多媒体扩展卡用的TF卡(micro sd)等等。
SD卡概述
SD卡技术是在MMC卡的基础上发展起来的,其尺寸与MMC卡一样,只是比MMC卡厚了0.7mm,因此SD主机可以识别并存取MMC卡。SD卡接口除了保留MMC卡的7针外,还在两边加了2针,作为数据线,目的是通过把传输方式由串行变成并行,以提高传输速率。此时的规范为SD1.0版本,最高容量只能到4GB。
为了跟进产品的更新换代,SD联合协会在06年发布了容量更大、存储更快的下一代SD卡规范SD2.0。该规范重新定义了SD卡的速度等级,分为三档:Class 2、4、6,分别对应写入速度2MB/S、4MB/S、6MB/S。根据卡容量又分为标准卡(小于2GB)和高容量卡(2GB~32GB),目前市面上应用的SD卡绝大部分都是SD2.0版本的卡。
为了让储存卡更加迷你,通过SD卡规范标准,又衍生了MiniSD卡和Micro SD卡,这些卡均比标准SD卡尺寸小,通过SD转接套可以当作一般的SD卡使用。尤其是Micro SD卡,可以算是最小的存储卡了,超小的体积可以极大的节省消费电子产品内部设计的空间,基本目前的Android手机均是选用Micro SD卡作为多媒体扩展储存卡。随着科技的进步,SD2.0规范SD卡也渐渐无法满足应用的需求,在10年SD联合协会又发布了新的SD3.0规范,该规范定义了sdxc和uhs,并增加了Class10,容量范围为32GB~2TB。
MMC,SD,SDIO等之间的关系,如下图所示。
MMC卡(MultiMediaCard): 是一种快闪存储器卡标准。技术基于东芝的NAND闪存技术。比早期基于Inter NOR快闪技术的记忆卡(如CF卡)体积更小。
eMMC(Embedded MultiMediaCard):将NAND flash+主控IC封装在一起的IC芯片,一般是BGA封装。主要针对手机等产品的内嵌式存储器标准规格。
SD卡(Secure Digital Memory Card):数据传送和物理规范等在MMC的基础上发展而来,强调安全,速度比2.11版的MMC卡更快。SDSC卡容量<=2GB,SDHC的为2GB32GB、**SDXC**的为32GB2TB。miniSD卡体积比SD卡小,而microSD卡则更小。
SDIO:SD卡接口的基础上发展起来的外设接口,不止科技SD卡,还可以接蓝牙、wifi、电视卡等。
TF卡(Trans-flash Card):2004年正式更名为Micro SD卡。
在sdxc卡仍需进一步坐等其价格下降的情况下,SD4.0规范已经开始在紧张的制订中,这已超出本文的讨论范围内了。
SD卡驱动方式
SD卡共支持三种传输模式:SPI模式、1位SD模式、4位SD模式。所有的SD卡都必须支持较老的SPI/MMC模式,这个模式支持慢速的四线SPI接口,使很多微控制器都可以通过SPI或模拟SPI接口来读写SD卡。万利的LPC5411x开发板通过SPI接口扩展了一个TF卡槽,可以用SPI接口读写TF卡。
SD2.0标准定义了物理层相关规范以及主机控制器规范,SD卡驱动的编写必须参考这两个规范,遵循标准的SD卡均可以采用统一的软件驱动实现数据访问。NXP对于其全系列的芯片提供了sdmmc库中间件用于支持SD/MMC卡的读写,可以在官网下载相应的BSP,里面包含sdmmc库,fsl_sdspi.h/fsl_sdspi.c
即为SPI模式访问SD卡的标准驱动,可以直接应用到LPC5411x开发环境中。SD卡驱动最主要实现三个接口,分别是SD卡的识别初始化、SD卡的块读、SD卡的块写,具体实现可以参考fsl_sdspi.h/fsl_sdspi.c
驱动文件。
3. Fatfs
数据往往以文件的形式保存在储存设备中,对于SD卡,一般采用的是Fat32文件系统,Fatfs由于其开源免费,支持Fat32,受到了广泛的应用。
Fatfs是由日本工程师ChaN所编写的Fat文件系统模块,从06年发布第一个Fatfs版本开始,作者就从未停止维护和更新。Fatfs的编写遵循ANSI C,并且完全与磁盘I/O层分开。它不依赖于硬件架构,代码和工作区占用空间小,使之可以嵌入到各个低成本的微控制器中,如AVR、8051、PIC、ARM、Z80、68K等。由于SD卡一般使用Fat32文件系统,在使用到SD卡的系统中移植Fatfs,将很好地实现对SD卡文件的管理。
Fatfs模块完全独立于磁盘I/O层,因此底层磁盘I/O访问并不属于Fatfs的模块部分,用户必须自己实现这部分用来访问存储设备。通常在diskio.c中实现这几个函数disk_initialize()
、disk_status()
、disk_read()
、disk_wirte()
、disk_ioctl()
即可,如果使能了OS相关的特性,则还需额外实现进程/内存函数。其中disk_initialize()
对应SD卡驱动中的卡识别初始化接口,disk_read()
对应SD卡的块读接口,disk_wirte()
对应SD卡的块写接口。NXP对于其全系列的芯片提供了Fatfs中间件的支持,Fatfs对应SD卡驱动接口的具体实现可以参考BSP中已移植好的Fatfs中间件。
4. 读写测试
移植好SD卡驱动以及Fatfs底层对应接口后,就可以用Fatfs应用编程接口读写SD卡里面的文件。应用以2KB大小为读写单位,测试读写10MB大小文件的平均读写速度。
uint8_t TestBuffer[2048];
int main() {
uint32_t i;
FATFS fs;
FIL file;
FRESULT Res;
uint32_t TimeCount;
uint32_t ByteWrite, ByteRead;
/* Board pin, clock, debug console init */
/*attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
/* enable clock for GPIO*/
CLOCK_EnableClock(kCLOCK_Gpio0);
CLOCK_EnableClock(kCLOCK_Gpio1);
BOARD_InitPins();
BOARD_BootClockFROHF96M();
BOARD_InitDebugConsole();
Gpio_Init();
f_mount(&fs, "4:" , 0);
/*
Res = f_mkfs("", 0, 4096);
if (Res != RES_OK) {
PRINTF("f_mkfs error %d\r\n",Res);
while(1);
}
*/
PRINTF("Writing test.bin, file sise10MB\r\n");
Res= f_open(&file, "4:test.bin", FA_WRITE | FA_CREATE_ALWAYS);
if (Res != RES_OK) {
PRINTF("Createfile failed\r\n");
while(1){
GPIO_TogglePinsOutput(GPIO,0, 1u << 15);
Delay_ms(300);
}
}
for (i=0; i<sizeof(TestBuffer); i++) {
TestBuffer[i]= i;
}
TimeCount =timer_get_current_milliseconds();
for (i=0;i<10*1024*1024/sizeof(TestBuffer); i++) {
Res= f_write(&file, &TestBuffer, sizeof(TestBuffer), &ByteWrite);
if(Res != RES_OK) {
f_close(&file);
PRINTF("Writefile error\r\n");
while(1){
GPIO_TogglePinsOutput(GPIO,0, 1u << 15);
Delay_ms(300);
}
}
}
f_close(&file);
PRINTF("Sd write speed %dKB/s\r\n", 10*1024*1024/(timer_get_current_milliseconds()-TimeCount));
PRINTF("Reading test.bin, file sise10MB\r\n");
Res = f_open(&file, "4:test.bin", FA_READ | FA_OPEN_EXISTING);
if (Res != RES_OK) {
PRINTF("Openfile failed\r\n");
while(1){
GPIO_TogglePinsOutput(GPIO,0, 1u << 15);
Delay_ms(300);
}
}
TimeCount = timer_get_current_milliseconds();
for (i=0;i<10*1024*1024/sizeof(TestBuffer); i++) {
Res= f_read(&file, (unsigned char *)&TestBuffer, sizeof(TestBuffer),&ByteRead);
if(Res != RES_OK) {
f_close(&file);
PRINTF("Readfile error\r\n");
while(1){
GPIO_TogglePinsOutput(GPIO,0, 1u << 15);
Delay_ms(300);
}
}
}
f_close(&file);
PRINTF("Sd read speed %dKB/s\r\n", 10*1024*1024/(timer_get_current_milliseconds()-TimeCount));
while(1) {
GPIO_TogglePinsOutput(GPIO,0, 1u << 15);
Delay_ms(1000);
}
}
读写速度测试结果如下:
Writing test.bin, file size 10MB
Sd write speed 872 KB/S
Reading test.bin, file size 10MB
Sd read speed 1169 KB/S
SD卡写速度为872 KB/S,读速度为1169 KB/S,SD卡通过SPI接口读写,SPI时钟采用FRO 12M时钟,因此这个读写速度是合适的。SD卡读写速度跟卡速度等级、数据传输速率有关,读写多块要比一块一块分多次读写快,此处测试一次性读取8块(512字节/块),2048字节,读写速度主要受限于SPI的传输速率,LPC5411x的SPI接口最高支持48M的时钟,SPI可以通过采用PLL时钟、内部高速时钟,进一步提高SPI的传输速率,从而进一步提高SD卡的读写速度。
附录:例程
MDK工程,包含SPI模式的SD驱动,Fatfs文件系统模块,SD卡读写速度测试应用例程。
附录:参考文档
- sd物理层协议规范,Part1_Physical_Layer_Simplified_Specification_Ver6.00.PDF,https://www.sdcard.org/downloads/pls/index.html
- sd host控制器协议规范, PartA2_SD Host_Controller_Simplified_Specification_Ver4.20.PDF,https://www.sdcard.org/downloads/pls/index.html
基于MCU的SD卡fat文件系统读写移植的更多相关文章
- SD卡fat文件系统移植
经过充分的研究,发现fatfs文件系统移植的比较简单!因为代码都已经被别人做好了!我们只需把io层稍稍做个处理就ok了: 至于sd卡的驱动请看我这篇博客:http://blog.csdn.net/ie ...
- SD卡FAT32文件系统格式
一.声明 1.本文来源和主旨 2.本文测试环境 二.SD卡FAT文件系统 1.SD卡FAT32文件系统的整体布局 2.FAT文件系统简介 ① 文件分配表 ② 目录项 三.DBR(DOS BOOT RE ...
- 玩转X-CTR100 l STM32F4 l SD卡FatFs文件系统
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] X-CTR100控制器具有SD卡接口,本教程使用免费 ...
- SPI模式下MCU对SD卡的控制及操作命令
一.前言 SD 卡有两个可选的通讯协议:SD 模式和 SPI模式 SD 模式是SD 卡标准的读写方式,但是在选用SD 模式时,往往需要选择带有SD 卡控制器接口的 MCU,或者必须加入额外的SD卡控制 ...
- SPI模式下MCU对SD卡的控制及操作命令(转)
源:SPI模式下MCU对SD卡的控制及操作命令 一.前言 SD 卡有两个可选的通讯协议:SD 模式和 SPI模式 SD 模式是SD 卡标准的读写方式,但是在选用SD 模式时,往往需要选择带有SD 卡控 ...
- 单元测试+内存、SD卡、SP读写+XmlPullParser
测试: 测试的相关概念 1.根据是否知道源代码分类: 黑盒测试: a - b - c 边值测试 测试逻辑业务 白盒测试: 根据源代码写测试方法 或者 测试用例; 2.根据测试的粒度分类: 方法测试:写 ...
- FileUtils【获取SD卡根目录、读写文件、移动、复制、删除文件、获取文件名、后缀名操作类】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 封装了获取SD卡根目录路径.以及对文件读写.获取文件名等相关操作. 因为需要用到android.permission.READ_EX ...
- 在XC2440的uboot中挂载U盘,利用FAT文件系统读写U盘文件
转:http://blog.chinaunix.net/uid-22030783-id-3347608.html 在XC2440的uboot_V1.3版本中已经支持USB HOST驱动和FAT文件系统 ...
- Keil MDK STM32系列(九) 基于HAL和FatFs的FAT格式SD卡TF卡读写
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- 第37章 基于SD卡的FatFs文件系统—零死角玩转STM32-F429系列
第37章 基于SD卡的FatFs文件系统 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...
随机推荐
- Git实战技巧:恢复被强制push -f失踪的代码
前言 Git是一个易学难精的分布式版本控制系统,被我们码农常用于代码的管理.如果你还不了解Git,建议先通过廖雪峰的Git教程进行了解,再来看本文,因为本文以使用技巧为主,不会在基础名词上做过多解释. ...
- 51k+ Star!动画图解、一键运行的数据结构与算法教程!
大家好,我是 Java陈序员. 我们都知道,<数据结构与算法> -- 是程序员的必修课. 无论是使用什么编程语音,亦或者是前后端开发,都需要修好<数据结构与算法>这门课! 在各 ...
- Python使用HTMLTestRunner运行所有用例并产生报告
#coding:utf-8import unittestimport osimport sysimport HTMLTestRunnercase_path = os.path.join(os.path ...
- VUE+element页面按钮调用dialog
VUE+element通过按钮调用普通弹框(弹框页面独立出一个dialog页面,非在同一个页面文件里) 代码如下 <el-dialog> <el-button type=" ...
- Mybatis学习五($和#区别以及其他tips)
1.$和#区别 1 #是将传入的值当做字符串的形式,eg:select id,name,age from student where id =#{id},当前端把id值1,传入到后台的时候,就相当于 ...
- Competition Set - AtCoder I
这里记录的是这个账号的比赛情况. ARC172 2024-2-18 Solved:4/6 D(Hard-,2936) 给定所有数对 \((i,j),1\le i\lt j\le n\) 的一个排列 \ ...
- LLaMA 3 源码解读-大语言模型5
本来不是很想写这一篇,因为网上的文章真的烂大街了,我写的真的很有可能没别人写得好.但是想了想,创建这个博客就是想通过对外输出知识的方式来提高自身水平,而不是说我每篇都能写得有多好多好然后吸引别人来看. ...
- 联想G470安装黑苹果
macos10136 黑苹果usb无线网卡 1.系统下载: 下面是我自制的带clover 4596版本的u盘镜像: 链接: https://pan.baidu.com/s/1wRdVddwkei7bf ...
- 在线自动加字幕!超快完成Pr的字幕制作!
在线自动加字幕!超快完成Pr的字幕制作! https://www.bilibili.com/video/BV1T441167eX/?spm_id_from=333.788.videocard.3 ht ...
- 26ObjectStream
ObjectStream ObjectOutputStream 用于将属性和内容保存到文件中,保存数据类型和值,即序列化,该流为处理流 static和transient修饰的属性无法序列化,切被序列化 ...