避免ansi C中的SD卡损坏

避免ansi C中的SD卡损坏,c,file-io,sd-card,embedded-linux,can-bus,C,File Io,Sd Card,Embedded Linux,Can Bus,我目前正在开发一款嵌入式Linux设备,用于数据记录。Linux设备插入CAN总线并将通信量写入SD卡 SD卡有时会损坏并以只读方式安装。这种行为需要避免 文件系统是FAT(SD卡应保持windows系统可读) 嵌入式设备随时可能断电,因此我需要一种安全的方法从我的C程序写入SD卡 由于我不是真正的C语言爱好者,我依赖一个名为“candump”的程序,它基本上以以下格式将CAN消息打印到stdout: <0x006> [8] 77 00 00 00 00 00 00 00 [8]7

我目前正在开发一款嵌入式Linux设备,用于数据记录。Linux设备插入CAN总线并将通信量写入SD卡

SD卡有时会损坏并以只读方式安装。这种行为需要避免

文件系统是FAT(SD卡应保持windows系统可读)

嵌入式设备随时可能断电,因此我需要一种安全的方法从我的C程序写入SD卡

由于我不是真正的C语言爱好者,我依赖一个名为“candump”的程序,它基本上以以下格式将CAN消息打印到stdout:

<0x006> [8] 77 00 00 00 00 00 00 00
[8]77 00 00 00
我的C程序基本上打开candump程序,从stdout读取,添加时间戳并删除不必要的字符:

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);

}
1345836055.5206770000000000000
(跑步时)
{
如果(文件名!=NULL)
{
fp_log=fopen(文件名,“a”);
如果(!fp_log)
{
佩罗尔(“福彭”);
退出(退出失败);
}  
}  
fgets(生产线,尺寸(生产线)-1,fp);
/*重置行_值,使其始终正确初始化*/
行_标识符=0;

如果(strchr)(第,行),即使不断电,是否也会发生损坏?以上代码仅为用户级代码,执行简单的
文件*
操作;它应该不会损坏设备

如果是,那么要么是设备驱动程序本身有问题,要么是发生了其他事情


您是否可以检查是否存在可能导致重置的电源问题?

发生损坏的原因可能是操作系统没有在FAT文件系统上完成写入操作。正如您正确指出的,您可以不时尝试通过执行
同步
来缓解问题,以强制操作系统在FAT文件系统上写入更改文件系统


但是,您会遇到这种问题,因为您没有使用日志文件系统(例如Ext3或NTFS。另一件事是,每次引导时对文件系统执行
fsck
操作,然后显式强制执行
rw
重新装载,以保持装载点干净和可写。

您确定损坏不会发生在其他地方吗?这是唯一一个访问sd卡的程序,因此我没有考虑到损坏会导致sd卡损坏。)uld可能发生在其他地方。老实说,我不知道从哪里开始或追踪腐败/var/log/是一个开始挖掘SD卡问题根源的好地方(一些嵌入式系统默认情况下根本不记录东西/根本不记录东西)只是一个猜测……试试
fsync(fp_log)
在关闭sd卡并使用
-o flush安装sd卡之前
如果在代码到达fclose(fp\U日志)之前关闭嵌入式设备会发生什么情况?感谢您的输入。电源故障可能会发生,因为嵌入式设备由PLC供电,PLC控制工业起重机。如果该起重机的点火开关关闭,PLC将关闭,因此嵌入式设备和它经常发生。FAT:文件系统错误(dev mmcblk0p1)群集计算错误(56!=55)FAT:文件系统已设置为只读。这是我刚才强制执行的错误消息(在日志记录时拔下sd卡)我将尝试使用ext3文件系统我对Linux下的Fat32错误没有太多经验,但是我建议使用ext3来消除这些错误。如果您需要经常移除SD卡并在Windows下读取,可以尝试使用。满足此要求的另一种方法是设置CIFS装入点,如
//192.168.1.1/sha红色/mnt/共享cifs默认值,noauto,用户=来宾,通行证=来宾0