2012-09-17 8 views
5

Ich arbeite derzeit an einem Embedded-Linux-Gerät für die Datenprotokollierung. Das Linux-Gerät wird in einen CAN-Bus gesteckt und schreibt den Datenverkehr auf eine SD-Karte.vermeiden SD-Karte Korruption in ansi C

Von Zeit zu Zeit beschädigt die SD-Karte und ist schreibgeschützt montiert. Dieses Verhalten muss vermieden werden.

Das Dateisystem ist FAT (die SD-Karte sollte von Windows-Systemen lesbar bleiben).

Das Embedded-Gerät kann jederzeit Stromausfall, also brauche ich eine sichere Möglichkeit, auf die SD-Karte von meinem C-Programm zu schreiben.

Wie ich bin nicht wirklich in C, verlasse ich mich auf ein Programm namens „candump“, die im Grunde die canmessages druckt in diesem Format an stdout:

<0x006> [8] 77 00 00 00 00 00 00 00 

Mein C-Programm eröffnet grundsätzlich die candump Programm liest aus stdout, fügt einen Zeitstempel und entfernt überflüssige Zeichen:

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

} 

Das Code-snippet oben funktioniert gut, es ist nur, dass ich SD-Karte Korruption zu bekommen.

Lösung

landete ich mit Standard-Mount-Optionen mit ext3 als Dateisystem auf. Keine Probleme mehr

+0

Sind Sie sicher, dass die Korruption nicht woanders geschieht? –

+0

Dies ist das einzige Programm, das auf die SD-Karte zugreifen, so habe ich nicht in Betracht gezogen, dass die Korruption anderswo passieren könnte und um ehrlich zu sein, weiß ich nicht wo um die Korruption zu starten oder aufzuspüren – user1320852

+0

/var/log/ist ein guter Ort, um zu graben beginnen, um die Wurzel der SD-Karte Probleme zu finden (einige eingebettete Systeme protokollieren keine Sachen standardmäßig/überhaupt) – drahnr

Antwort

1

Die Beschädigung tritt wahrscheinlich auf, weil das Betriebssystem seine Schreiboperationen auf dem FAT-Dateisystem nicht abgeschlossen hat. Wie richtig von J-16 SDiZ gezeigt, können Sie versuchen, das Problem von sync von Zeit zu Zeit zu mildern, um das Betriebssystem zu zwingen, Änderungen auf dem Dateisystem zu schreiben.

Allerdings haben Sie diese Art von Problemen, weil Sie nicht auf ein Journaled-Dateisystem (wie Ext3 oder NTFS verwenden. Eine andere Sache zu tun, jeder Schuh zu fsck das Dateisystem sein könnte, und dann zwingen explizit eine rw Remount zu halten der Mountpoint sauber und beschreibbar

+1

FAT: Dateisystemfehler (dev mmcblk0p1) Cluster schlecht berechnet (56! = 55) FAT: Dateisystem wurde schreibgeschützt gesetzt. Dies ist die Fehlermeldung, die ich gerade erzwinge (SD-Karte während der Protokollierung entfernen) Ich werde versuchen ext3 Dateisystem – user1320852

+0

Ich habe nicht viel Erfahrung mit Fat32-Fehlern unter Linux, aber ich würde vorschlagen, zu Ext3 zu verschieben, um diese Fehler zu schneiden. Wenn Sie die SD-Karte häufig entfernen und unter Windows lesen müssen, können Sie versuchen, [IFS-Treiber] (http://www.fs-driver.org/) zu verwenden. Eine andere Möglichkeit, diese Anforderung zu erfüllen, könnte darin bestehen, einen CIFS-Mountpoint wie '//192.168.1.1/shared \t/mnt/shared \t cifs \t default, noauto, user = gast, pass = guest 0' einzurichten – Avio

0

Tritt die Beschädigung auch dann auf, wenn Sie nicht entfernen? Der obige Code ist nur auf Benutzerebene und macht einfache Operationen FILE *; Es sollte das Gerät nicht beschädigen können.

Wenn dies der Fall ist, ist entweder der Gerätetreiber selbst fehlerhaft oder es ist etwas anderes passiert.

Können Sie überprüfen, ob es Stromversorgungsprobleme gibt, die z. B. Rücksetzungen verursachen könnten?

+0

danke für Ihre Eingabe. Stromausfälle können auftreten, weil das Embedded-Gerät von einer SPS betrieben wird, die einen Industriekran steuert. Wenn die Zündung dieses Krans ausgeschaltet wird, geht die SPS runter und so das eingebettete Gerät und es passiert ziemlich oft. – user1320852