избежать повреждения SD-карты в ansi C

В настоящее время я работаю над встроенным устройством Linux для регистрации данных. Устройство Linux подключается к CANbus и записывает трафик на SD-карту.

Время от времени SD-карта портится и монтируется только для чтения. Такого поведения необходимо избегать.

Файловая система - FAT (SD-карта должна оставаться доступной для чтения системами Windows).

Встроенное устройство может выйти из строя в любой момент, поэтому мне нужен безопасный способ записи на SD-карту из моей программы на C.

Поскольку я не совсем разбираюсь в C, я полагаюсь на программу под названием «candump», которая в основном печатает сообщения canmessages в стандартный вывод в следующем формате:

<0x006> [8] 77 00 00 00 00 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);

}

Приведенный выше фрагмент кода работает нормально, просто я получаю повреждение SD-карты.

Решение

В итоге я использовал ext3 в качестве файловой системы со стандартными параметрами монтирования. Больше никаких проблем


person user1320852    schedule 17.09.2012    source источник
comment
вы уверены, что коррупция не происходит в другом месте?   -  person J-16 SDiZ    schedule 17.09.2012
comment
это единственная программа, обращающаяся к SD-карте, поэтому я не подумал, что повреждение может произойти где-то еще. и, честно говоря, я не знаю, с чего начать или отследить коррупцию   -  person user1320852    schedule 17.09.2012
comment
/var/log/ — хорошее место, чтобы начать копать, чтобы найти корень проблем с SD-картой (некоторые встроенные системы не ведут журнал по умолчанию/вообще)   -  person drahnr    schedule 17.09.2012
comment
Просто предположение .... попробуйте fsync(fp_log), прежде чем закрыть его и смонтировать SD-карту с помощью -o flush   -  person J-16 SDiZ    schedule 17.09.2012
comment
что произойдет, если встроенное устройство будет выключено до того, как код достигнет fclose(fp_log)?   -  person user1320852    schedule 17.09.2012


Ответы (2)


Повреждение, вероятно, происходит из-за того, что ОС не завершила операции записи в файловой системе FAT. Как правильно указал J-16 SDiZ, вы можете попытаться смягчить проблему, делая sync время от времени чтобы заставить ОС записывать изменения в файловой системе.

Однако у вас возникают проблемы такого рода, потому что вы не используете журналируемую файловую систему (такую ​​как Ext3 или NTFS). Еще одна вещь, которую можно сделать, это fsck файловая система при каждой загрузке, а затем явное принудительное rw перемонтирование, чтобы сохранить точку монтирования чистой и записываемый.

person Avio    schedule 17.09.2012
comment
FAT: ошибка файловой системы (dev mmcblk0p1) кластеры неправильно рассчитаны (56 != 55) FAT: файловая система установлена ​​только для чтения. это сообщение об ошибке, которое я только что заставил (отключение SD-карты во время регистрации), я попробую файловую систему ext3 - person user1320852; 17.09.2012
comment
У меня нет большого опыта работы с ошибками Fat32 под Linux, однако я бы посоветовал перейти на Ext3, чтобы избавиться от этих ошибок. Если вам нужно часто извлекать SD-карту и читать ее под Windows, попробуйте использовать драйверы IFS. . Другим способом удовлетворить это требование может быть установка точки монтирования CIFS, такой как //192.168.1.1/shared /mnt/shared cifs default,noauto,user=guest,pass=guest 0 0 - person Avio; 17.09.2012

Происходит ли повреждение, даже если вы не отключаете питание? Приведенный выше код предназначен только для пользователя и выполняет простые операции FILE *; он не должен повредить устройство.

Если да, то либо сам драйвер устройства глючит, либо что-то еще происходит.

Можете ли вы проверить, есть ли проблемы с питанием, например, которые могут привести к перезагрузке?

person unwind    schedule 17.09.2012
comment
Спасибо за ваш вклад. сбой питания может произойти из-за того, что встроенное устройство питается от ПЛК, который управляет промышленным краном. если зажигание этого крана выключено, ПЛК выходит из строя, и поэтому встроенное устройство происходит довольно часто. - person user1320852; 17.09.2012