【发布时间】:2014-09-15 21:04:28
【问题描述】:
好的,首先介绍一些背景知识来帮助我弄清楚我的问题:
我正在开发一种设备,该设备从传感器收集某些数据并使用 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] 用于将枚举结果代码转换为字符串。
如果有任何数据丢失,请务必提及。
谢谢
【问题讨论】:
-
您自己实现了 HAL 功能吗? (
disk_read,disk_write?) 我猜你还没在 ebay 上买过 SD 卡? :) -
我将 HAL 函数作为 MSP430 评估板源代码的一部分。但它们确实有效。
-
eBay 问题实际上非常重要。您是否从信誉良好的公司购买了正版卡?仿制卡会死得很快。一张好的 4GB 卡应该可以满足许多 GB 的写入耐久性。