SD-Karte + seek-time

OP #2276416
Lesenswert?

Benutze mehr oder weniger die Sourcen von ElmChan (ziemlich genial 
übrigens).
Das ganze für einen Datenlogger. Funktioniert auch so weit, allerdings 
wird der Kartenzugriff im Lauf der Zeit (mit zunehmender Dateigrösse) 
immer länger.
Bei nur 5MB (500MB sollen es werden) Dateigrösse dauert seek inzwischen 
3Mio Takte, also mit 11.059MHz fast 0,3s (gegenüber 2ms bei 100kB). Das 
ist deutlich zulang, da an der SPI auch der CAN-Controller hängt (dessen 
Interrupt während der Kartenkommunikation gesperrt wird).
Leider muss ich zwischendurch auch immer wieder was von der Karte lesen, 
kann die Datei also nicht einfach offen halten.
Irgendwelche Ideen (ausser entsprechend viele kleine Dateien anlegen, 
das wäre der letzte Ausweg).
Und falls dieser Ausweg: wieviele Dateien können es denn im 
Hauptverzeichnis sein?
(Firma: TravelRec.) Persönliche Seite #2276649
Lesenswert?

H.joachim Seifert schrieb:
> Irgendwelche Ideen (ausser entsprechend viele kleine Dateien anlegen,
> das wäre der letzte Ausweg).

Dem Controller viel RAM verpassen und die FAT in´s RAM kopieren und von 
dort aus die Sektoren auff der Karte direkt anspringen, ohne jedes Mal 
die FAT neu lesen zu müssen. Das Problem wird sein, dass die Karte 
zunehmend fragmentiert und die schnellen Multi-Block-Befehle nicht mehr 
angewendet werden können. Somit hat man viel Overhead gegenüber den 
Nutzdaten und der Kartencontroller wird durch die ständige 
neuadressierung einzelner Sektoren schnarchlangsam.
OP #2282077
Lesenswert?

So, quick&dirty:
f_seek wird nur am Programmstart durchgeführt und alle Daten nach 
file_bak geschrieben, funktioniert bestens. Schreibfunktion benötigt nur 
4ms

void log_to_file()
{  GICR&=~(1<<INT1);      //disable exint1
   f_open(&file,path,FA_WRITE);
   GICR|=(1<<INT1);      //enable exint1

   file.csect=file_bak.csect;
   file.curr_clust=file_bak.curr_clust;
   file.dir_ptr=file_bak.dir_ptr;
   file.dir_sect=file_bak.dir_sect;
   file.dsect= file_bak.dsect;
   file.flag=  file_bak.flag;
   file.fptr=  file_bak.fptr;
   file.fs =   file_bak.fs;
   file.fsize= file_bak.fsize;
   file.id   = file_bak.id;
   file.org_clust= file_bak.org_clust;

   GICR&=~(1<<INT1);      //disable exint1
   f_write(&file,buffer,strlen(buffer),&nbytes);
   GICR|=(1<<INT1);      //enable exint1

   file_bak.csect=file.csect;
   file_bak.curr_clust=file.curr_clust;
   file_bak.dir_ptr=file.dir_ptr;
   file_bak.dir_sect=file.dir_sect;
   file_bak.dsect= file.dsect;
   file_bak.flag=  file.flag;
   file_bak.fptr=  file.fptr;
   file_bak.fs =   file.fs;
   file_bak.fsize= file.fsize;
   file_bak.id   = file.id;
   file_bak.org_clust= file.org_clust;

   GICR&=~(1<<INT1);      //disable exint1
   f_close(&file);
   GICR|=(1<<INT1);      //enable exint1
}
Moderator Persönliche Seite #2282576
Lesenswert?

H.joachim Seifert schrieb:
>... Schreibfunktion benötigt nur 4ms ...

Das mag oft so zügig sein aber sehr wahrscheinlich nicht immer. Tests 
mit vielen vielen Aufrufen der "Logdatensatzschreibroutine" mit dem in 
der Endanwendung zu erwartenden kürzesten Zeitinvervall und Ermittlung 
des Laufzeitmaximums sollten folgen.


(Betr. seek und flush (sync) vgl. FatFs Dokumentation - aber darauf 
wurde von holger bereits hingewiesen.)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren