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

Cli*_*ord 15 filesystems embedded sd-card fat

背景

我的电路板在SPI上集成了STM32微控制器和SD/MMC卡,并以48 ksamples/s采样模拟数据.我正在使用Keil Real-time Library RTX内核和ELM FatFs.

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

意见

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

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

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

这个问题

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

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

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

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

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

所以这似乎是卡的一种行为.我将努力尝试一系列卡SD和MMC.

Ama*_*9MF 5

尝试做的第一件事可能很容易:将队列深度增加到640。这将为您提供535 ms的缓冲,并且至少应在此特定文件系统事件中保留下来。

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

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

第三种选择是预分配一个巨大的文件,然后在数据收集期间仅覆盖数据。这将消除大量昂贵的群集分配和FAT操作操作。

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