首页 > 其他分享 >SPI方式读写SD卡速度有多快?

SPI方式读写SD卡速度有多快?

时间:2023-05-12 14:25:56浏览次数:52  
标签:DMA 读写 SPI 测试 速度 SD

SD卡是一个嵌入式中非常常用的外设,可以用于存储一些大容量的数据。但是,用单片机读写SD卡速度一般都有限(对于高速SD卡,主要是受限于单片机本身的接口速度),在高速、实时数据存储时可能会有影响。那么,具体速度可以达到多少呢?让我们来实际测试一下。

SD卡一般有两种常用的接口SPI和SDIO,SDIO又有1线和4线之分。很多单片机没有SDIO接口,但SPI接口就比较常用,今天主要来测试一下SPI接口读写SD卡的速度,主要是写入速度。

测试条件:

  • 单片机:STM32L433CCT6

  • 编译环境:MDK 5.30+HAL库

  • SD卡:32Gbit  SDNAND(型号:米客方德MKDV32GCL-STH)

  • 文件系统:FatFS R0.12c

1、单纯SPI接口测试(非DMA)

我们知道,像SD卡之类的Flash存储器,一般都是按扇区擦除整块数据。因此每次写入字节数是扇区整数倍时,效率会比较高。同时,每次写入数据时,都需要先发送一些SD卡的指令,所以单次写入数据量越大,平均速度也就越快。了解了这些,我们就知道如何进行测试了。

首先,SD卡底层驱动使用的是HAL库函数,单字节读写,没有任何改动和优化:

uint8_t SPI_ReadWriteByte(uint8_t TxData)
{
  uint8_t RxData = 0;
  
HAL_SPI_TransmitReceive(&hspi3,&TxData,&RxData,1,100);
  return RxData;
}

接下来,我们先确定SPI和时钟频率多少合适,经过测试,发现20MHz的时钟频率比较合适,10MHz时读写速度会降低,再高的时钟频率对速度的提升也很小。因此我们这里用20MHz的时钟。

然后,我们分别测试单次写入4KB、8KB、16KB时的速度为多少,测试结果如下:

 

可以看到,单次写入数据量越大,平均速度就越快。当单次写入数据达到32KB时,速度提升不明显。而且一般单片机内部RAM缓存也有限,单次写入16KB是一个比较合适的选择。

看到这个不到100KB/S速度,我还是有的不敢相信的,毕竟20MHz的时钟,理论上速度可以达到2MB/S左右,考虑到一些文件系统等协议的消耗,能到1/3差不多,那也得600多KB,现在的速度差距有点大。

当然,这个与使用的HAL库函数有关,HAL_SPI_TransmitReceive函数效率比较低,内部做了大量的判断等操作,而且单字节传输也严重影响效率。如果自己优化一下,相信效率会有很大的提升。有兴趣的小伙伴可以试试。我们这次其实主要是测试SPI+DMA的速度,所以就不在这里纠结了。

2、SPI+DMA接口测试

DMA可以在外设和内存之间搬运数据,而不需要CPU的参与。其优势在于大量数据传输时,比如SD卡读写、SPI接口的液晶屏刷屏等。如果只是读写几个字节的数据,比如一些SPI接口的AD、DA等,DMA的优势就不明显。

因为SPI接口的设备一般都不是纯数据传输,都要配合一些指令等。所以即使使用DMA,也是要等待DMA传输完成再进行其它操作。当然这期间CPU可以通过中断方式去处理一些其它事情。

SPI+DMA写数据函数如下,使用的也是HAL库,没有进行优化。         

int8_t SD_WriteBuffer_DMA(const uint8_t *TxData, uint16_t Size){  uint32_t i = 0;          // 循环变量
SPI3_DMA_Flag = 0; SPI_TransmitReceive_DMA(&HSPI_TF, (uint8_t*)TxData, txrxdata, Size);
/* 等待DMA传输完成 */ while (1) { if(SPI3_DMA_Flag == 1) break; i++; if (i > 0xFFFFFF) { return 1; /* 超时退出 */ } } return 0;}

以向SD卡写数据为例,需要改为DMA的地方有2处:写命令和写扇区数据,因为这两处发送的字节数比较多。一些SD卡的起始、结束、应答等单字节的数据传输使用的还是非DMA方式传输。下面是部分程序:

 

 我们进行了两种测试:只使能DMA写扇区数据,以及使能DMA写扇区数据和发送指令。都是按照单次写入16KB进行测试,测试结果如下:

 

 可以看到,速度提升非常明显。数据和指令都用DMA传输时,速度最快。如果再进行一些底层函数的优化,速度还会有提升。最后我们对读取速度也进行了测试,使用DMA方式,使能DMA读扇区数据和发送指令,测试结果如下,读取速度可以达到1.1MB~1.2MB/S。

 

 

3、总结

SPI+DMA的方式读写SD卡速度优势明显,推荐使用。当然,这跟非DMA方式的底层函数效率低下有很大的关系。

但DMA的另一个更重要的优势在于,读写数据时可以大部分释放CPU资源。比如我之前的一个应用,需要以1KHz的频率在外部中断中去读取一些数据,每次大约需要几十uS。如果使用非DMA方式,频繁的中断,且几十uS时间也不短,会导致SD卡写入出错。而使用DMA方式则不会有这个问题。

最后,附上底层驱动程序链接:

https://pan.baidu.com/s/1RnMCw5EAm_xMjT-UkUKoMA?pwd=98sb

提取码:98sb

标签:DMA,读写,SPI,测试,速度,SD
From: https://www.cnblogs.com/rongjiangwei/p/17393976.html

相关文章

  • percona-server-rocksdb-8.0.32 安装
    MyRocks是关系型数据库Mysql基于RocksDB的存储引擎,一个可嵌入的、持久的键值存储。PerconaMyRocks是集于PerconaServerforMySQL的.RocksDB存储基于日志结构的合并树(LSMtree)。它针对快速存储进行了优化,有出色的空间和写入效率以及可接受的读取性能。因此,如果您的工作负......
  • 工程监测NLM5无线中继采集发送仪使用$SETPTool 工具读写参数
    工程监测NLM5无线中继采集发送仪使用$SETPTool工具读写参数 $SETPTool是通用的设备测试、参数读写工具,适用于稳控科技绝大部分设备机器。如果要编写自己的测试工具,可参考“2.通讯协议”章节说明。$SETPToolForNLM5xx的主界面如下图所示。 按照主界面左下角操作提示......
  • flutter Android SDK not configed
    https://stackoverflow.com/questions/64359564/error-java-home-is-not-set-and-no-java-command-could-be-found-in-your-flutterflutterconfig--android-studio-dir="C:\ProgramFiles\Android\AndroidStudio"......
  • 有感步进电机 SSD2505 方案
    有感步进电机SSD2505方案ID:695188666828466329......
  • 2020-05-21:es底层读写原理?倒排索引原理?
    es不熟悉,答案仅供参考:es写数据过程1、客户端选择一个node发送请求过去,这个node就是coordinatingnode(协调节点)2、coordinatingnode对document进行路由,将请求转发给对应的node(有primaryshard)3、实际的node上的primaryshard处理请求,然后将数据同步到replicanode。4、coord......
  • Qt编写视频监控系统72-通过onvif增删改查OSD
    一、前言之前监控系统中原创的onvif协议解析机制,已经能够满足绝大部分用户的需要,比如搜索设备、获取视频流地址并播放、云台控制、预置位管理、图片亮度色彩饱和度等参数设置等,近期又多了一个需求,那就是通过onvif国际标准协议来对摄像头的OSD进行增删改查,可以通过协议添加OSD、删......
  • SpringBoot3.x中spring.factories SPI 服务发现机制的改变
    目录一、基础背景二、服务发现接口spring.factories三、服务发现机制调用1.启动SpringApplication2.加载SpringApplication.run1.SpringApplication.createApplicationContext2.SpringApplication.prepareContext3.SpringApplication.refreshContext4.AutoConfigurationImportSele......
  • HDFS文件读写初窥- Java API
    安装HDFS1)hadoop下载:https://hadoop.apache.org/releases.html2)本地安装:https://hadoop.apache.org/docs/r3.3.5/hadoop-project-dist/hadoop-common/SingleCluster.html3)修改配置:etc目录下存放了hadoop相关配置文件,这里要在本地部署伪分布式模式,需要修改以下两个文件:e......
  • 洛谷 P3321 [SDOI2015] 序列统计
    洛谷传送门感觉挺综合的一道题。考虑朴素dp,\(\forallx\inS,f_{i+1,jx\bmodm}\getsf_{i,j}\)。复杂度\(O(nm^2)\)。显然可以矩乘优化至\(O(m^3\logn)\),但是不能通过。如果转移式中是加法而不是乘法,那很容易卷积优化。接下来是一个很重要的套路:化乘为加。实数......
  • Frequently CRSD Appear Unresponsive/Intermediate/Offline Status (Doc ID 2352557.
    事件背景描述:环境:Linux/Oracle12.2.0.1.0/RAC问题:数据库监听无法连接,集群异常问题处理过程:1.登录数据库查看相关状态,如下,发现crsd进程状态为cleaning2.发现crsd进程异常后,判断可能是网络层面问题,通过查杀gipc进程集群并未恢复正常3.联系主机工程师上线排查网络问题,网络工程师排......