好的,首先介绍一些背景知识以帮助阐明我的问题:
我正在开发一种从传感器收集特定数据并使用 GSM 调制解调器将它们发布到服务器的设备。由于 GSM 连接并非 100% 可靠,因此它将包含一种记录机制,可将未发送的数据写入 SD 卡。
我们正在使用 Chan's FatFs为我们提供文件系统的模块,因为我们希望日志在 PC 上可读。
现在我一直在测试 FAT 系统的边界条件,即尝试完全填满卡片。
在第一次运行中,我打开文件并将代码设置为继续写入字符串,直到驱动器已满。该程序将在每次写入后同步。
我让代码整夜运行。
第二天,我检查了 SD 卡。我发现该文件的大小只有 150 MB。大约有 120 万行写入其中。该卡仍然可以读取,但不能写入或格式化。
下次我尝试相同类型的测试,但这次我使用f_lseek()
函数将文件预分配到1GB。然后它将写入该文件,直到达到该限制。这次数据将在 50 次写入后同步。然后它会关闭该文件并打开另一个文件以执行相同的操作。
您可以猜到另一张勇敢的小卡片那天失去了理智。
所以这些是我想要帮助的:
- 写入大量数据时如何防止损坏卡?
- 长时间打开文件是否有任何负面影响?
由于完整代码可能太长,这里主要写的是代码
for(file_count=3;file_count>=0;--file_count){
ax_log_msg(E_LOG_INFO,"===================================");
ax_log_msg(E_LOG_INFO,file_names[file_count]);
f_open(&file_ptr,file_names[file_count],FA_WRITE|FA_OPEN_ALWAYS);
if(result!=FR_OK){
ax_log_msg(E_LOG_INFO,"\n\rf_open Failed\n\rResult code");
ax_log_msg(E_LOG_INFO,FRESULT_S[result]);
continue;
}
ax_log_msg(E_LOG_INFO,"\n\rf_open Sucessfull");
result=f_lseek(&file_ptr,FILE_SIZE_LIMIT_1GB);
if(result!=FR_OK){
ax_log_msg(E_LOG_INFO,"\n\rf_lseek Failed for preallocation\n\rResult code");
ax_log_msg(E_LOG_INFO,FRESULT_S[result]);
f_close(&file_ptr);
continue;
}
ax_log_msg(E_LOG_INFO,"\n\rf_lseek Sucessfull for preallocation");
f_lseek(&file_ptr,0);
bytes_to_write=sizeof(messages[file_count]);
write_count=0;
while( (f_tell(&file_ptr) < FILE_SIZE_LIMIT_1GB )){
result=f_write(&file_ptr,messages[file_count],bytes_to_write,&bytes_written);
if(result==FR_OK){
++write_count;
if(write_count%50==0){
f_sync(&file_ptr);
}
}else{
ax_log_msg(E_LOG_INFO,"\n\rWrite failed\n\rFRESULT=");
ax_log_msg(E_LOG_INFO,FRESULT_S[result]);
break;
}
}
f_close(&file_ptr);
}
注意:
- ax_log_msg() 是要在控制台上打印的设备固件的一部分。
- FRESULT_S[result] 用于将枚举结果代码转换为字符串。
如果有任何数据缺失,请务必指出。
谢谢
最佳答案
您可能需要缓冲整个数据 block ,可能是 4 KB,以避免每次刷新时都刷新整个数据 block 。但是,只要您不显式调用 fflush
,文件系统或驱动程序就会为您做这件事,这才是真正的教训。
为什么需要如此频繁地同步?也许计时器会比按记录数设置间隔更好?
关于c - 如何避免大量写入损坏SD卡?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24931502/