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?
>Und falls dieser Ausweg: wieviele Dateien können es denn im >Hauptverzeichnis sein? Bei FAT16 512 Dateien. Bei FAT32 bis keine Cluster mehr zur Verfügung stehen.
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.
H.joachim Seifert schrieb: > Leider muss ich zwischendurch auch immer wieder was von der Karte lesen, > kann die Datei also nicht einfach offen halten. Ich kenne jetzt den Code von ElmChan nicht, aber warum darf die die Datei nicht offen bleiben? Gibts noch andere Tasks/Threads die auf der SD-Karte schreiben? MfG Klaus
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 }
Datei offen lassen und das hier hätte es wohl auch getan;) FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
Wenn du eine "kleine" Karte hast, kannst du sie neu formatieren mit mehr Sektoren pro Cluster.
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.)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.