如何使用SD卡以48 ksamples / s记录16位数据?

时间:2010-07-22 09:30:35

标签: filesystems embedded sd-card fat

背景

我的主板包含一个STM32微控制器,SD/MMC card位于SPI,并以48 ksamples / s采样模拟数据。我正在使用Keil Real-time Library RTX内核和ELM FatFs

我有一个高优先级的任务,通过DMA以40个样本(40 x 16位)的块为单位捕获模拟数据;数据通过长度为128的队列(构成大约107毫秒的样本缓冲)传递给第二个低优先级任务,该任务将样本块整理成2560字节缓冲区(这是512字节SD扇区大小和40个样本块大小)。当此缓冲区已满(32个块或大约27 ms)时,数据将写入文件系统。

观察

通过检测代码,我可以看到每32个块,数据被写入并且写入大约需要6 ms。这持续到(在FAT16上)文件大小达到1 MB,当写操作需要440 ms时,此时队列填充并且中止日志记录。如果我将卡格式化为FAT32,则“长写”事件之前的文件大小为4 MB。

发生这种情况的文件大小在FAT16和FAT32之间发生变化这一事实告诉我,它不是卡的限制,而是文件系统在1 MB或4 MB边界处执行需要额外时间的事情

我的任务似乎也在及时安排,并且时间仅在1 MB的ELM FatFs代码中消耗(或FAT32为4)边界。

问题

有解释或解决方案吗?这是一个FAT问题,或者更确切地说是ELM的FatFs代码特有的吗?

我考虑过使用多个文件,但根据我的经验,FAT不能很好地处理单个目录中的大量文件,这也会失败。根本不使用文件系统并且写入原始卡是可能的,但理想情况下我想在带有标准驱动程序且没有特殊软件的PC上读取数据。

我尝试使用编译器优化来缩短写入时间;这似乎有效果,但写入时间似乎变化多了。在-O2我确实得到了一个8 MB的文件,但结果不一致。我现在不确定文件大小和失败点之间是否存在直接关联;我已经看到它在各种文件长度上以这种方式失败,没有特定的边界。也许这是卡片性能问题。

我进一步对代码进行了检测并采用了一种分治方法。这种观察可能会使问题过时,以前所有的观察结果都是错误的或是红色的。

我最后将其缩小为多扇区写入(CMD25)的实例,其中卡的“等待就绪”轮询对于块5中的前三个扇区有时需要174 ms。等待准备超时设置为500毫秒,所以它很乐意忙 - 等待那么久。在一般情况下,迭代地使用CMD24(单扇区写入)很多更慢 - 每个扇区140毫秒 - 而不是偶尔。

毕竟这似乎是卡的行为。我将努力尝试一系列卡片SD和MMC。

2 个答案:

答案 0 :(得分:4)

要尝试的第一件事可能很简单:将队列深度增加到640.这将为您提供535毫秒的缓冲,并且至少应该存在于此特定文件系统事件中。

要看的第二件事是ELM FatFs的配置。默认情况下,许多嵌入式文件系统非常吝啬缓冲区使用。我见过一个用于所有操作的单个512字节块缓冲区,并且它针对某些文件系统事务进行了爬网。我们给了它几千字节,事情变得快了几个数量级。

上述两种情况都取决于您是否有更多的RAM可用。

第三种选择是预先分配一个巨大的文件,然后在数据收集过程中覆盖数据。这将消除许多昂贵的集群分配和FAT操作操作。

由于编译器优化会影响这一点,因此您还必须考虑它是多线程问题的可能性。是否有其他线程在运行,可能会干扰优先级较低的读者线程?您还应尝试将缓冲区更改为除样本大小和闪存块大小的倍数之外的其他内容,以防您遇到某种系统共振。

答案 1 :(得分:0)

您(或阅读此问题的任何其他人)可以尝试此FAT库:https://github.com/fernando-rodriguez/fat32lib

在具有10 Mbit / s SPI总线的40 MIPS Microchip dsPIC33上,它可以在我尝试的任何卡上以230 Ksps(16位)采样。