I am currently working on an embedded Linux device for data logging. The Linux device is plugged into a CANbus and writes the traffic to an SD card.
From time to time the SD card corrupts and is mounted read-only. This behavior needs to be avoided.
The file system is FAT (the SD card should stay be readable by windows systems).
The embedded device can power fail any time, so I need a safe way to write to the SD card from my C program.
As I am not really into C, I rely on a program called "candump" which basically prints the canmessages to stdout in this format:
<0x006> [8] 77 00 00 00 00 00 00 00
My C program basically opens the candump program, reads from stdout, adds a timestamp and removes unnecessary chars:
1345836055.520 6 7700000000000000
while(running)
{
if (filename != NULL)
{
fp_log = fopen(filename, "a");
if (!fp_log)
{
perror("fopen");
exit (EXIT_FAILURE);
}
}
fgets(line, sizeof(line)-1, fp);
/* reset the row_values so they are always correctly initialized */
row_identifier = 0;
if (strchr(line,'<') != NULL)
{
/* creating a buffer char to store values for casting char to int*/
buffer_ident[0] = line[4];
buffer_ident[1] = line[5];
/* cast buffer e.g. {'1','0','\0'} to int: 10 */
row_identifier = strtol(buffer_ident,NULL,10);
/* heartbeat of the CANBUS PLC */
if(row_identifier == 80)
{
/* return pong on identifier 81 to the PLC */
//system("cansend can0 -i 81 1 > /dev/null");
}
else
{
gettimeofday(&tv,NULL);
fprintf(fp_log,"%d.%03d ", tv.tv_sec, tv.tv_usec/1000);
fprintf(fp_log,"%d ",row_identifier);
/* rowlenght > 11 = data part is not empty */
row_lenght = strlen(line);
if (row_lenght>11)
{
int i=0;
for (i=11;i<row_lenght;i++)
/* remove spaces between the data to save space and copy data into new array */
if (isspace(line[i]) == 0)
fprintf(fp_log,"%c",line[i]);
fprintf(fp_log,"\n");
}
}
}
fclose(fp_log);
}
The code snippet above works fine, its just that I get SD card corruption.
Solution
I ended up using ext3 as the file system with standard mount options. No problems any more
The corruption probably happens because the OS didn't complete its write operations on the FAT filesystem. As correctly pointed out by J-16 SDiZ you can try to mitigate the problem doing sync
from time to time to force the OS to write changes on the filesystem.
However, you are having this kind of problems because you are not using a journaled filesystem (such as Ext3 or NTFS. Another thing to do, could be to fsck
the filesystem every boot and then explicitly forcing a rw
remount to keep the mountpoint clean and writeable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With