经验:FatFs文件系统实时写入

实时需求:接收来自CAN总线的数据,20ms一次,一次8个字节
经验总结
0,FAT类文件系统不适合作为实时写入
1,单文件写入次数限制。减少对文件的操作次数,单文件操作次数小于1000次
2,文件打开关闭次数限制。每次写入不要重复的开关文件,最好采用f_write和f_sync组合,无需每次写入完成后关闭文件
3,文件开关时间不确定。单独放到独立实时任务
4,长时间高频写入速度变慢。采用多重大缓冲,缓冲区大小为512的整数倍,如4K
5,采用异步缓冲模式,接收数据和写入数据分开操作
6,采用专供工具SD Card Formatter格式化SD卡
7,RL-FlashFs,完美解决实时存储问题
 
来自网络的原始资料
现在解决了写入失败的问题,是由文件名命名使用了一些特殊字符造成的,另外没有按照8.3格式命名文件名也会造成写失败。每次18Kb,每秒写入10个文件,写了两千多文件全部成功但写到后面超时严重,写一个,丢失两个。每秒写一次的话比较稳定,现在的想法是新建文件后写入十次,再关闭文件,看看是否可以避免文件过多写超时的问题。
采用F405RGT6,SPI DMA接收数据,SDIO DMA写入TF卡,程序中定义5*18*1024的三维数组作为缓冲队列,采用读写分离的方式。
现在60ms接收一次,每秒接收平均16.67次,每次18KB,每1000次数据存在一个文件内。多次测试,能达到接收三万次数据无误不丢失,基本满足了需求。后续还会再进一步测试。
简单分享一下实时写入的一些注意事项:
(1) TF卡品质要好,不同厂家的性能差异很大,建议买闪迪等厂家的高速TF卡。
(2) 根据写入数据需求对TF卡分配单元大小进行格式化,TF卡在FAT32格式化分配单元大小最大为64KB,实时写入建议格式化为64KB,实测不同大小对实时性有很大影响。
(3) 文件系统中创建文件和关闭文件的时间不确定,开关次数过多可能造成某次耗时过长,影响后续数据写入,所以采用每1000次数据写入一个文件的方式,减少
     对文件的开关次数。
(4) 随着写入数据的增多,和文件数目的增多,TF卡的写入速度会越来越慢,同样大小的数据,写入的时间也不确定,所以采用队列进行FIFO缓冲。

基本就是这些,TF卡在数据量较大,写入频率较高时实时写入还是比较有难度的,如果数据量较小频率较低的话还是比较稳定的,做过很多测试。
简单几句话,却是花费了大量时间精力调试测试得到的,记录一下,希望对大家有所帮助。
使用两个月,说一下使用的一些事项,
1. 1000次保存一次数据改为100次保存一次数据,不会降低稳定性。
2. 使用中多次保存超过50000次数据,数据不丢失不错位。
3. 注意SPI连接线的长度以及电源的稳定性,在一台较老的机器进行测试时,经常出现数据丢失和错位的情况,
    怀疑是由于SPI连接线过长且没有屏蔽层,换用了较短的连接线,情况得到了一定改善,但数据依然会出问
    题,对比其他机器发现可能是由于机器电源不稳定造成的问题。建议SPI连接线使用屏蔽线,电源问题暂时
    未解决,
 
总结:稳定的数据写入方法及其速度测试
1.  通过上面的测试可以得出
(1)采用4线DMA方式的话,建议调用f_write函数时,写入的数据不要超过512字节(SD卡扇区大小是512字节),这样比较稳定。
         如果超过512字节的话会调用multiblock传输,容易出错。

#define TEST_FILE_LEN        (2*1024*1024)    /* 用于测试的文件长度 */    
#define BUF_SIZE                 (512)                   /* 每次读写SD卡的最大数据长度 */

每次写4096字节,一次测试连续写入TEST_FILE_LEN / 512= 4096次,共测试了20次,没有出错。
 
https://www.sdcard.org/downloads/formatter/index.html

SD卡联盟强烈强烈建议使用此软件来格式化SD/SDHC/SDXC卡,而不要使用各个操作系统随附的格式化工具。通常,操作系统附带的格式化工具可以格式化包括SD/SDHC/SDXC卡在内的各种存储介质,但是可能无法针对SD/SDHC/SDXC卡进行优化,并且可能导致性能降低。

<ignore_js_op> SDCardFormatterv5_WinEN.zip (6.03 MB, 下载次数: 2029) 

<ignore_js_op> 




FatFS作者ChaN老师也建议大家不要使用操作系统自带的工具来格式化:
<ignore_js_op> 


 

 
DMA的4字节对齐问题
 
 
改成f_open,然后循环调用 f_write, f_sync即可
 

做项目,因为硬件没有设计停止写文件的按钮(或信号),设备断电会导致文件无法在windows显示。后来运用f_sync函数,每写一次SD卡,就用f_sync保存起来。大约每秒使用16次,连续十几个小时采集数据并保存。以为万无一失,然而悲剧发生了。有的设备前几小时数据正常,后面的数据直接出错。有的设备第一次就直接写入错误。

解决办法: 

          (1)每次使用之前都给SD卡格式化。

          (2)减少f_sync函数的使用频率。增加长缓冲区。

          (3)设备增加按钮来停止写文件,并用f_close函数关闭文件,不使用f_sync函数。

 
采用F405RGT6,SPI DMA接收数据,SDIO DMA写入TF卡,程序中定义5*18*1024的三维数组作为缓冲队列,采用读写分离的方式。
现在60ms接收一次,每秒接收平均16.67次,每次18KB,每1000次数据存在一个文件内。多次测试,能达到接收三万次数据无误不丢失,基本满足了需求。后续还会再进一步测试。
简单分享一下实时写入的一些注意事项:
(1) TF卡品质要好,不同厂家的性能差异很大,建议买闪迪等厂家的高速TF卡。
(2) 根据写入数据需求对TF卡分配单元大小进行格式化,TF卡在FAT32格式化分配单元大小最大为64KB,实时写入建议格式化为64KB,实测不同大小对实时性有很大影响。
(3) 文件系统中创建文件和关闭文件的时间不确定,开关次数过多可能造成某次耗时过长,影响后续数据写入,所以采用每1000次数据写入一个文件的方式,减少
     对文件的开关次数。
(4) 随着写入数据的增多,和文件数目的增多,TF卡的写入速度会越来越慢,同样大小的数据,写入的时间也不确定,所以采用队列进行FIFO缓冲。

基本就是这些,TF卡在数据量较大,写入频率较高时实时写入还是比较有难度的,如果数据量较小频率较低的话还是比较稳定的,做过很多测试。
简单几句话,却是花费了大量时间精力调试测试得到的,记录一下,希望对大家有所帮助。

FAT类文件系统不适合作为实时写入,随着你的写入的数据不断加大,写入时间也会加大。

好点的处理方案是创建多个文件进行记录。然后每次写入不要重复的开关文件,最好f_write和f_sync组合即可,无需关闭。
 
 
原文地址:https://www.cnblogs.com/bog-box/p/14592901.html