Forum: Mikrocontroller und Digitale Elektronik FatFS Daten an die Anfangsposition der Datei schreiben


von af (Gast)


Lesenswert?

Ich möchte so eine Art logfile führen und würde unter FatFS gerne die 
neusten Einträge an den Anfang der Datei einfügen. hier ist mein Code:
1
 
2
int
3
logging_write_entry (char *text, int text_len) {
4
5
  FIL logfile, fsrc;     /* file objects */
6
  DIR dir;       /* Directory object */
7
  FILINFO fno;     /* File information object */
8
  BYTE read_buf[1024];   /* file copy buffer */
9
  BYTE write_buf[1024];
10
  BYTE temp_msg[127];
11
  FRESULT res;         /* FatFs function common result code */
12
  UINT br, bw;         /* File read/write count */
13
14
  int i = 0;
15
  int new_file_size = 0;
16
  int iFileSize = 0;
17
18
  res = f_open(&fsrc, "log5.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE );
19
20
  iFileSize = f_size(&fsrc);
21
  printf("\r\nFile Size: %d", iFileSize);
22
23
  if ((iFileSize + text_len) > MAX_LOGFILE_SIZE) {
24
     // copy logfile.dat to log folder with the current date and rename it to HOUR_MIN_DAY_MONTH_YEAHR.txt
25
26
    printf("\r\nFile is full!");
27
    printf("\r\nFile Size: %d", fsrc.fsize);
28
    f_unlink("log5.txt");
29
30
    return 0;
31
  }
32
  else {
33
    // read file content
34
    res = f_read(&fsrc, read_buf, sizeof(read_buf), &br);
35
    read_buf[br] = '\0';
36
37
    // Create new Enty
38
    sprintf(temp_msg, "%d \t %s\r\n", LocalTime, "ABCDEFGHIJK");
39
40
    // Copy the new Entry in to the write buffer
41
    strcpy(write_buf, temp_msg);
42
43
    // append old data
44
    strcat(write_buf, read_buf);
45
46
    // write new data
47
    res = f_write(&fsrc, write_buf, strlen(write_buf), &bw);
48
    printf("\r\nRes write %d, %d Bytes written", bw);
49
    
50
    printf("\r\n=========================================================");
51
    printf("\r\n%s", write_buf);
52
    printf("\r\n=========================================================");
53
54
    // close file
55
    res = f_close(&fsrc);
56
  }
57
  return 1;
58
}

Aber irgendwie macht die Funktion nicht was die soll. Ich bekomme 
folgende ausgabe:

File Size: 0
Res write 20, 123 Bytes written
=========================================================
1140  ABCDEFGHIJK

=========================================================
File Size: 20
Res write 41, 115 Bytes written
=========================================================
10550  ABCDEFGHIJK
1140  ABCDEFGHIJK

=========================================================
File Size: 61
Res write 82, 115 Bytes written
=========================================================
20550  ABCDEFGHIJK
1140  ABCDEFGHIJK
10550  ABCDEFGHIJK
1140  ABCDEFGHIJK



Man sieh hier, dass beim zweiten Schreiben alles noch logisch erscheint, 
beim dritten mal hat meiner Meinung nach 1140  ABCDEFGHIJK hinter der 
20550  ABCDEFGHIJK Zeile nichts zu suchen.

Irgendwie stehe ich auf dem Schrumpfschlauch, oder die Erkältung macht 
blöd. Sieht jemand den Fehler? Es ist egal, ob ich fputs oder fwrite 
benutze, der Effekt ist gleich.

von BWLnow (Gast)


Lesenswert?

> Irgendwie stehe ich auf dem Schrumpfschlauch, oder die Erkältung macht
> blöd.

Ich kann dir versichern, dass es nicht an der Erkältung liegt.

von Ben j. (scarab)


Lesenswert?

Wie oft willst du Zeilen in die Logfile schreiben und wie groß wird die 
Datei bevor du sie zurück setzt bzw. ausließt & löschst?

von af (Gast)


Lesenswert?

>> Irgendwie stehe ich auf dem Schrumpfschlauch, oder die Erkältung macht
>> blöd.

>Ich kann dir versichern, dass es nicht an der Erkältung liegt.

Häh?

>Wie oft willst du Zeilen in die Logfile schreiben und wie groß wird die
>Datei bevor du sie zurück setzt bzw. ausließt & löschst?
Weiß ich nicht aus dem Kopf, auf jeden Fall ausreichend groß.

von Ben j. (scarab)


Lesenswert?

af schrieb:
>>Wie oft willst du Zeilen in die Logfile schreiben und wie groß wird die
>>Datei bevor du sie zurück setzt bzw. ausließt & löschst?
> Weiß ich nicht aus dem Kopf, auf jeden Fall ausreichend groß.

Das Problem ist das laut Standard ja nur 10.000 Schreibzyklen garantiert 
werden müssen und wenn du 2-3mal pro Sekunde was loggst (was zwecks 
Puffergröße auch physisch geschrieben werden muss) kannst du dir 
ausrechnen wie lange die Karten das mitmachen.

Für Bastler ein kalkulierbares Risiko... für Produkte die verkauft 
werden wirds dann aber ernst.

von holger (Gast)


Lesenswert?

>Das Problem ist das laut Standard ja nur 10.000 Schreibzyklen garantiert
>werden müssen und wenn du 2-3mal pro Sekunde was loggst (was zwecks
>Puffergröße auch physisch geschrieben werden muss) kannst du dir
>ausrechnen wie lange die Karten das mitmachen.

Das ist so erst mal Unsinn. Die Karten haben einen
Mechanismus der Wear Levelling heisst. Wenn ein Sektor
häufiger beschrieben wird, wird er irgendwann automatisch
durch einen anderen ersetzt. Da musst du schon öfter
als ein mal pro Sekunde auf einen Sektor prügeln um zu Lebzeiten
zu erleben das die Karte einen Defekt hat.

>Ich möchte so eine Art logfile führen und würde unter FatFS gerne die
>neusten Einträge an den Anfang der Datei einfügen.

Lass den Quatsch und häng immer hinten dran.
Du machst es dir nur unnötig schwer.

von Karl H. (kbuchegg)


Lesenswert?

ZUm Problem

    // write new data
    res = f_write(&fsrc, write_buf, strlen(write_buf), &bw);


entweder du machst hier das File einmal zu und wieder auf, oder du gehst 
mit einem ftell wieder zurück an den Fileanfang. Durch den 
vorhergehenden f_read schreibst du an den bestehenden File-Inhalt hinten 
drann

hier
    printf("\r\nRes write %d, %d Bytes written", bw);
stimmt die Anzahl der Argumente nicht mit der Anzahl der %d überein. 
Drumm stimmt deine Ausgabe nicht

> File Size: 0
> Res write 20, 123 Bytes written

20 Bytes written

> =========================================================
> 1140  ABCDEFGHIJK
>
> =========================================================
> File Size: 20

daher auch FileSize 20. Passt

> Res write 41, 115 Bytes written

41 Bytes geschrieben

> =========================================================
> 10550  ABCDEFGHIJK
> 1140  ABCDEFGHIJK
>
> =========================================================
> File Size: 61

also sollte die File Size hier auch 41 sein. Ist sie aber nicht. Die 
File Size ist jetzt 20 (von vorher) PLUS die 41 von jetzt: 61


Allerdings hat holger nicht unrecht. Das ist ziemlicher Quatsch, weil du 
eine Menge Speicher brauchst, nur damit du vorne anhängen kannst. Die 
Alternative wäre mit 2 Files zu arbeiten.

von holger (Gast)


Lesenswert?

>oder du gehst
>mit einem ftell wieder zurück an den Fileanfang.

Ich würde fseek nehmen;)

von af (Gast)


Lesenswert?

>Lass den Quatsch und häng immer hinten dran.
>Du machst es dir nur unnötig schwer.
Nö, bei Kontoauszügen ist mir egal wo vorne wo hinten ist, geht es darum 
auf der Webseite was chronologisch anzuzeigen, gehören die neusten 
Einträge nach oben.

>Ich würde fseek nehmen;)
Es geht zwar auch file_close/file_open, wie Karl Heinz sagt, aber fseek 
ist in dem Fall eleganter. Danke, habe gar nicht bedacht, dass der 
Pointer beim Wechseln zw. read/write nicht zurückgesetzt wird.

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.