代码之家  ›  专栏  ›  技术社区  ›  Clifford

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

  •  14
  • Clifford  · 技术社区  · 14 年前

    背景

    我的董事会包括 STM32 微控制器 SD/MMC card SPI 并以48 ksamples/s采样模拟数据。我使用的是Keil实时库RTX内核,以及 ELM FatFs .

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

    观察

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

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

    似乎我的任务安排得很及时,时间也被榆树占用了。 FatFs 代码 只有 在1 mb(或对于FAT32为4)边界处。

    问题

    有什么解释或解决办法吗?这是一个重要的问题,或者可能是榆树的FATF代码的特定问题?

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

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

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

    最后,我把范围缩小到一个多扇区写入(CMD25)的实例,在这个实例中,有时对卡的“等待就绪”轮询会在5个块的前三个扇区中花费174毫秒。等待就绪的超时设置为500毫秒,因此很高兴它会忙着等待那么长时间。反复使用CMD24(单扇区写入)是 许多的 一般情况下,速度较慢——每个扇区140 ms——而不是偶尔。

    所以这似乎是一种卡的行为。我将努力尝试一系列的卡sd和mmc。

    2 回复  |  直到 7 年前
        1
  •  4
  •   Peter Mortensen John Conde    11 年前

    第一件要尝试的事情可能非常简单:将队列深度增加到640。这将给您535毫秒的缓冲时间,并且应该至少在这个特定的文件系统事件中存活下来。

    第二件事要看的是榆树脂肪的配置。许多嵌入式文件系统在默认情况下对缓冲区的使用非常吝啬。我见过一个在所有操作中都使用一个512字节的块缓冲区,并对某些文件系统事务进行了爬行。我们给了它几个千字节,它就更快地变成了数量级。

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

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

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

        2
  •  0
  •   Peter Mortensen John Conde    7 年前

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

    在一个40微芯片上 dsPIC33 使用10_mbit/s SPI总线,它可以在我尝试过的任何卡上以230 ksps(16位)的速度采样。