Forum: Mikrocontroller und Digitale Elektronik Auf SD-Karte schreiben Lesen geht !


von U. B. (ub007)


Lesenswert?

Hallo !

Ich hab eine Testanwendung für SD-Karte und mein ehem. Kollege hat die 
Libs von Ulrich Radig verwendet.
Was die Lese-Routine einliest sollte erstmal unwesentl. sein.
Das Lesen geht und sieht wie folgt aus:
1
void get_konfig(int CG, char *Dat, int Zeile)
2
{
3
   unsigned char KBuffer[CG];
4
   unsigned int Clustervar = 0;
5
   unsigned char Dir_Attrib = 0;
6
   unsigned long Size = 0;
7
   
8
   if (fat_search_file((unsigned char *)Dat,&Clustervar,&Size,&Dir_Attrib,KBuffer) == 1)
9
   {   
10
      usart_write_TM("\r\nKonfig.txt gefunden!!\r\n");
11
      int c = 0;
12
      int einmal = 0;
13
14
      fat_read_file (Clustervar,KBuffer,0);
15
      for (int a = 0;a<240;)
16
      {            
17
         if (KBuffer[a] == '$')
18
         {
19
            if (einmal == 0)
20
            {
21
               Zeile++;
22
               c=0;
23
               einmal++;
24
            }
25
            else
26
                     nop();
27
         }
28
         else
29
         {
30
            if(KBuffer[a] != 0x0D && KBuffer[a] != 0x0A)
31
            {
32
               usart_write("%c",KBuffer[a]);
33
               Konfig[Zeile][c]=KBuffer[a];
34
               c++;
35
            }
36
         }
37
         a++;
38
      }
39
   }
40
   else
41
   {
42
      usart_write_TM("\nKonf not found!!\r\n");   
43
      Blink_Err_nTimes(3);      // Optische Anzeige 
44
45
      while(1)   
46
      {   
47
      }
48
   }
49
   Clustervar = 0;
50
   Dir_Attrib = 0;
51
   Size = 0;
52
}

Jetzt hat sich herausgestellt, dass es sinnvoll wäre wenn man für den 
Fehlerfall ein LOG-File rauschreibt.
Entsprechend hab ich die obige Routine wie folgt abgeändert:
1
void write_error(int CG, unsigned char Error_String[CG])
2
{
3
   unsigned int Clustervar = 0;
4
   unsigned char Dir_Attrib = 0;
5
   unsigned long Size = 0;
6
   
7
   if (fat_search_file((unsigned char *)"xerror.log",&Clustervar,&Size,&Dir_Attrib,Error_String) == 1)
8
   {   
9
      usart_write_TM("\r\nxerror.log gefunden!!\r\n");   
10
11
      usart_write(" Error-Meldung: %s ", Error_String);    
12
      fat_write_file (Clustervar,Error_String,0);    
13
   }
14
   else
15
   {
16
      usart_write_TM("\r\nxerror-File not found!!\r\n");   
17
      Blink_Err_nTimes(7);      // Optische Anzeige
18
19
      while(1)   
20
      {
21
      } // while(1) End
22
   } // else End
23
24
25
   Clustervar = 0;
26
   Dir_Attrib = 0;
27
   Size = 0;
28
}
Nur das ganze funktioniert nicht mehr. Selbst wenn ich die Zeile mit dem 
eigentl. Befehl (fat_write_file...) rauslasse, will das Programm nicht 
mehr richtig einlesen. Es wäre wichtig dass ich die Error-Strings im 
File appenden kann !
Kann mir jemand sagen was hier nicht O.K. ist ?

Gruß U

von U. B. (ub007)


Lesenswert?

Hallo !

Ich hab einen kleinen Fehler mit der usart gehabt. Ich hab jetzt die 
usart-Ausgabe bei write_error rausgemacht und jetzt tut es halbwegs.
bei dem Befehl
1
fat_write_file (Clustervar,Error_String,0);

schreibt er mir nur die ersten drei Zeichen des Error_Strings.
Ich kann machen was ich will, es bleibt bei drei.
Wenn im Error String folgendes steht:    Erste Zeile ...
dann erscheint    Ers   sonst nichts.
Kann mir jemand weiterhelfen warum er nicht den ganzen String 
rausschreibt ?

Gruß U

von Krapao (Gast)


Lesenswert?

> Selbst wenn ich die Zeile mit dem
> eigentl. Befehl (fat_write_file...) rauslasse, will das Programm nicht
> mehr richtig einlesen.

Der Unterschied ist dann

>      usart_write(" Error-Meldung: %s ", Error_String);

Bist du sicher, dass du diese Funktion richtig verwendest? Ist der 
String in Error_String Nullterminiert oder nicht? Die explizite Angabe 
von CG lässt andere Schlüsse zu.

> Ich hab einen kleinen Fehler mit der usart gehabt. Ich hab jetzt die
> usart-Ausgabe bei write_error rausgemacht und jetzt tut es halbwegs.
> bei dem Befehl
>
> fat_write_file (Clustervar,Error_String,0);

Wurde der Fehler behoben (s.o.) oder nur nicht mehr aufgerufen?

http://www.mikrocontroller.net/attachment/36575/fat.c
1
//Schreiben eines 512Bytes Blocks von einem File
2
void fat_write_file (
3
  unsigned int cluster,     //Angabe des Startclusters vom File
4
  unsigned char *buffer,    //Workingbuffer
5
  unsigned long blockCount) //Angabe welcher Bock vom File gespeichert 
6
                            //werden soll a 512 Bytes

d.h. du musst unsigned char Error_String[] mindestens mit 512 
Feldelementen definiert haben. Hast du das?

von U. B. (ub007)


Lesenswert?

Hallo Krapao !

Erstmal danke für deine Antwort !
Um es kurz zu sagen es funktioniert jetzt aber etwas seltsames ist 
passiert !
Also die usart funktion spukt ja den String "Erste Zeile ...\r\n" aus. 
Das wollte ich ja, um zu sehen ob der Error-String gefüllt ist.
-- Er ist --
Und jetzt kommt das seltsame. (Vielleicht habe ich auch etwas 
überlesen):
Es standen ja wie ich sagte im Error.log-File immer die ersten drei 
Buchstaben vom String - also     Ers
Es hätte ja sein können, dass es noch vom letzten mal drin steht und er 
gar nichts rausschreibt.
Also habe ich die Buchstaben  Ers   durch   1234567890   ersetzt.
Als ich meine schreibroutine aufrief kam folgendes zum vorschein:
Erste Zeil ( das sind genau die 10 Zeichen )
Jetzt hab ich das File mit 500 Leerzeichen aufgefüllt und jetzt schreibt 
er schön hinein.
Ich dachte aber dass ich beim rausschreiben den "Buffer" rausschreibe - 
egal was auf der SD-Karte steht, aber offensichtlich muss das File 
gefüllt sein und wenns nur Leerzeichen sind. Nun, das ist nicht ganz so 
schön und ich hab im Augenblick keine Erklärung dafür.

Gruß U

von Sascha W. (sascha-w)


Lesenswert?

Ganz einfach, du legst ein File an die Größe steht im 
Verzeichniseintrag. Du kannst jetzt Daten in den Block der Datei 
schreiben wie du willst und die werden auch abgespeichert nur die Länge 
im Verzeichniseintrag ändert sich natürlich nicht von selbst - das musst 
du auch noch machen.

Sascha

von U. B. (ub007)


Lesenswert?

Hallo Sascha !

Danke für die schnelle Antwort !
Ich hab meine Schaltung hier daheim nicht aufgebaut und komme erst 
Montag wieder dazu, deshalb muss ich quasi das ganze jetzt "auswendig" 
sagen.
Der ehem. Kollege hat sich die Verzeichniseinträge per usart ausgeben 
lassen. Ich kanns nicht genau sagen aber ich vermute dass dann pro 
Datei-Eintrag ein Verzeichniseintrag vorhanden sein müßte. Das sind aber 
nur ein, zwei oder drei Hexzahlen pro Datei die "ausgespuckt" werden.
Wie sollte ich aber bei Ulrich Radigs Library den neuen Eintrag bzw. die 
Länge des Files wieder auf SD zurückschreiben. Ich glaube, da gibts 
keine Funktion dafür.
Folgende Funktionen werden von UR zur Verfügung gestellt:
1
//Prototypes
2
extern unsigned int fat_root_dir_addr (unsigned char *);
3
extern unsigned int fat_read_dir_ent (unsigned int,unsigned char,unsigned long*,unsigned char *,unsigned char *);
4
extern void fat_load (unsigned int,unsigned long *,unsigned char *);
5
extern void fat_read_file (unsigned int,unsigned char *,unsigned long);
6
extern void fat_write_file (unsigned int,unsigned char *,unsigned long);
7
extern void fat_init (void);
8
extern unsigned char fat_search_file (unsigned char *,unsigned int *,unsigned long *,unsigned char *,unsigned char *);
Ich schreibe dann per fat_write_file. Der letzte parameter mit unsigned 
long ist die Blockgröße von 512 Bytes. D.h. hier müßte eine 1 rein, oder 
?
Fantastisch wäre es wenn man irgendwie eine append-Funktion hätte die 
dann den Text immer hinten dran hängt, aber ich glaube das wird mit 
diesen Funktionen nicht so ohne weiteres gehen.

Gruß U

von Sascha W. (sascha-w)


Lesenswert?

U. B. schrieb:
> ...
> Ich schreibe dann per fat_write_file. Der letzte parameter mit unsigned
> long ist die Blockgröße von 512 Bytes. D.h. hier müßte eine 1 rein, oder ?
ja

für das Ändern des Dateieintrags musst du dir was neues basteln!
Dazu könntest du als Grundgerüst die "fat_read_dir_ent" verwenden, der 
einen bestimmten Verzeichniseintrag sucht. Die Nummer des Eintrags 
deines Files kennt erst mal nur die Funktion "fat_search_file" - den 
müsstest du dir also noch mit zurückgeben lassen. Den Teil in 
"fat_read_dir_ent" in dem dann der Dateiname und die Größe ausgelesen 
wird müsstest du durch das speichern der neuen Größe und das Schreiben 
des Blocks auf die SD-Karte ersetzen. Das ganze funktionert natürlich 
nur solange du keinen neuen Cluster brauchst! Die Lib dahingehend zu 
erweitern macht sicherlich zu viel Arbeit, das nehmt Ihr besser eine 
andere Lib die das schon eingebaut hat.

Sascha

von U. B. (ub007)


Lesenswert?

Hallo Sascha !

Vielen Dank ! Das dachte ich mir schon.
Dann hat sich das schon erledigt.

Vielen Dank und Gruß

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.