Hallo Allerseits, ich habe hier ein kleines Projekt ATmega64 @ 16 MHz, 5V, 64K XMEM, SD-Karte über Pegelwandler am SPI. FatFs von ELM Chan Micro SD-Karte von Kingston SDC4/8GB, Typ SD HC Ich schreibe nun dauerhaft mit ~22kB/s auf die SD-Karte (Recorder), zum Puffern wird im SRAM ein FIFO per Software gebildet. Das geht soweit sehr gut, die SD-Karte kann mit 90-500kB/s beschrieben werden, je nach Blockgröße. Meistens ist der FIFO nur wenig gefüllt, so um die 1-2kB. Nun kommt es jedoch sporadisch so ca. alle 5min vor, dass mein überaus reichlicher FIFO (32kB!) fast überläuft! Das sind ~1,5s Blockade!!! Ich hab hier im Forum und an anderen Orten was von 100-300ms Verzögerung gelesen, wenn die SD-Karte mit Wear Leveling etc. beschäftigt ist. OK, aber 1,5s? Nach bestem Wissem und Gewissen ist mein Teil der Software OK, wenn man die Schreibzugriffe auskommentiert und durch äquivalente Wartezeiten ersetzt läuft der FIFO nicht mal ansatzweise über. Theoretich könnte noch ein Problem im FatFs von Elm Chan sein, das halte ich aber für wenig wahrscheinlich. Ausserdem nutze ich wie bei ELM Chan gezeigt Cluster Preallocation und die Cluster Link Map Table, damit während des Schreibens keine zusätzlichen Aktionen im FAT gemacht werden müssen. Bleibt die SD-Karte. Ich werde mal noch andere organisieren und testen. Was meint ihr dazu? Noch andere Ideen bezüglich Störgrößen und Verzögerungen? MfG Falk
Ja, kenne ich, bin auch kürzlich auf das Problem gestoßen. Speziell bei class10 Karten. Ich habe dann eine class4 Karte gefunden welche besser ist. Abgesehen davon, wenn du größere Daten schreibst geht es besser, dann erreiche ich auch bei class10 ca 9MB/sec . Wenn aber in verschiedenen Bereichen geschrieben wird, bzw nur kleiner Datensatz, dann dauert es sehr lange, bzw hat die Karte lange aussetzter. Dies bei class10, bei class4/6 sind diese Aussetzer aber immer auf 300ms limitiert gewesen, zumindest bei mir. Kann aber von der FS Implementation abhängen, wie oft diese Aussetzer zustandekommen.
Falk Brunner schrieb: > dass mein überaus > reichlicher FIFO (32kB!) fast überläuft! Das sind ~1,5s Blockade!!! Musst Du auch FAT-Sektoren schreiben? Sind auf der Karte alte und große Dateien drauf? Es könnte durchaus passieren, das er die 1,5 Sekunden nach dem nächsten freien Cluster in der FAT sucht, wenn zwischendurch ein paar GB durch andere Dateien belegt sind. Die FAT ist 1 MByte groß auf der 8GB SD Karte - das dauert einen Moment bis er sie durchgelesen hat.
@Jim Meba (turboj) >Musst Du auch FAT-Sektoren schreiben? Ich nicht, bestenfalls die Lib von ELM Chan. http://elm-chan.org/fsw/ff/00index_e.html > Sind auf der Karte alte und große Dateien drauf? Nein, die Karte ist neu und fast leer. >Es könnte durchaus passieren, das er die 1,5 Sekunden nach dem nächsten >freien Cluster in der FAT sucht, wenn zwischendurch ein paar GB durch >andere Dateien belegt sind. Sollte auch nicht sein, weil isch schon schrieb "Ausserdem nutze ich wie bei ELM Chan gezeigt Cluster Preallocation und die Cluster Link Map Table, damit während des Schreibens keine zusätzlichen Aktionen im FAT gemacht werden müssen." > Die FAT ist 1 MByte groß auf der 8GB SD >Karte - das dauert einen Moment bis er sie durchgelesen hat. http://elm-chan.org/fsw/ff/en/lseek.html Wenn ich das richtg verstehe, wird estmal eine leere Datei mit maximaler Größe angelegt, dabei werden auch alle Cluster zugewiesen und in die FAT eingetragen. Danach werden sogar die Cluster der Datei in der Cluster Link Table im RAM gespeichert, sodass man für die Zuordnung der Daten kaum noch FAT-Zugiff braucht, man schreibt nur noch die Daten in die Sektoren. Wie gesagt, ich schreibe mit ~ 22kB/s konstant auf die Karte, macht ~1,3MB/min. Ca. nach jeweils 5min tritt der Effekt auf, macht als ~6,5MB. In der Zeit sind schon ~ 203 Cluster geschrieben worden (FAT32, 32KB cluster size). Und nur da soll es klemmen? Glaub ich nicht.
Ich hab mal bissel Debugging eingebaut und mir den FIFO Füllstand mitgeschrieben, wenn er > 0x1000 wurde. Siehe Anhang. Das sieht mir recht systematisch aus. Die kurzen Zeitabstände sind immer recht genau 191s, die großen 387s.
@Abdul K. (ehydra) Benutzerseite
>Nimm doch einfach mal ne andere Karte.
Würde ich gern tun, hab aber im Moment keine andere. Nur noch eine 2.
vom gleichen Typ. OK, ich probiers.
Ins nächste Kaufland. Ich glaube die haben bis 22 Uhr samstags offen. Oder n Tanke etwas teurer eben.
Probier mal erst anfangen zu schreiben wenn Buffer 1/3 Voll sind, ob sich dann ein Unterschied abzeichnet.
Falk Brunner schrieb: > Micro SD-Karte von Kingston Die schreiben nur ihren Namen auf Karten verschiedener OEMs. Ich würde eher zu Sandisk raten, und da auch eher zu 2 GB wenn der Platz reicht. Falk Brunner schrieb: > Die kurzen Zeitabstände sind immer recht genau > 191s, die großen 387s. Die 191 Sekunden ergeben bei etwa 22KB/s in etwa die 4 MByte einer Page (AU Size). Die 387 Sekunden ergeben sich aus zweimal 191. Kann es sein dass Dein Programm versucht, mehrere Sektoren auf einmal über eine Pagegrenze hinaus zu schreiben? Das darf IMO länger dauern. Die öffentlich verfügbare Spezifikation ist sehr vage, impliziert aber dass das Schreiben von 16 KB Blöcken - die an den Pagegrenzen ausgerichtet sind - am schnellsten geht. Beim Schreiben im Dateisystem muss man aber beachten, dass physiche Blöcke gemeint sind und nicht logische. Probieren könnte auch mal einfach alle Blöcke einzeln zu schreiben. So erwischt man garantiert keine Pagegrenze.
Hier mal die andere Karte vom gleichen Typ, sieht auch sehr regelmässig aus, wenn gleich die Abstände anders sind. Kurze Lücken sind ebenfalls 192s lang, die großen hier jedoch 579s. Hmmm? Am Montag werd ich mal ein oder zwei andere Typen besorgen, Sandisc & Co. Vielleicht ist eine ältere, kleinere und offizell langsamere Karte hier besser, weil sie nicht so einen riesigen Zwischenpuffer bzw. Pagegrößen hat und damit die Schreibpausen deutlich kleiner sind. Oder die Karte ist einfach billig gebaut und hat keine Doppelpufferung, sodass, wie Jim Meba vermutet, bei einem Schreibzugriff auf eine komplette Page erstmal alles steht.
@ chris (Gast) >Probier mal erst anfangen zu schreiben wenn Buffer 1/3 Voll sind, ob >sich dann ein Unterschied abzeichnet. Hmmm, machbar, würde ich aber eher vermeiden. Ausserdem ist der Puffer sehr klein im Verhältnis der Datenmenge, welche zwischen zwei solcher Aussetzer entsteht.
@Jim Meba (turboj) >> Micro SD-Karte von Kingston >Die schreiben nur ihren Namen auf Karten verschiedener OEMs. Ich würde >eher zu Sandisk raten, und da auch eher zu 2 GB wenn der Platz reicht. 2GB reichen, 8GB gabs halt billig ;-) >Die 191 Sekunden ergeben bei etwa 22KB/s in etwa die 4 MByte einer Page >(AU Size). Die 387 Sekunden ergeben sich aus zweimal 191. Klingt nach einer heißen Spur! >Kann es sein dass Dein Programm versucht, mehrere Sektoren auf einmal >über eine Pagegrenze hinaus zu schreiben? Das darf IMO länger dauern. Das macht die Lib von ELM Chan, soweit ich weiß interessiert sie sich nur für Sektoren und Cluster, Pagegrößen des Speichermediums werden nicht berücksichtigt. >Die öffentlich verfügbare Spezifikation ist sehr vage, impliziert aber >dass das Schreiben von 16 KB Blöcken - die an den Pagegrenzen >ausgerichtet sind - am schnellsten geht. Die lib hat nur einen bescheidenen Puffer von 1 Sektor a 512 Byte, es werden immer einzelne Sektoren geschrieben. 16 Blcöke könnte man mit Aufwand erreichen, aber ein Ausrichtung an Pagegrenzen ist AFAIK nicht machbar. >Probieren könnte auch mal einfach alle Blöcke einzeln zu schreiben. So >erwischt man garantiert keine Pagegrenze. Wie gesagt, ich habe keinen Direktzugriff auf die SD-Karte, will ich auch nicht. Die Lib von ELM Chan ist sehr gut und nimmt mir die "Drecksarbeit" ab.
@ Davis (Gast) >Das Problem solltest du im elm-chan Forum posten: >http://elm-chan.org/fsw/ff/bd/ Danke für den Tip. Ich habe es überflogen, aber nichts zu dem Problem gefunden. Aber einen guten, FUNKTIONIERENDEN Tip zu einem anderen Problem. http://elm-chan.org/fsw/ff/bd/?show=1215 Damit kann ich meinen Workaround rausschmeißen, ich muste die Funktion f_lseek() in eine extra Datei auslagern und getrennt ohne Optimierung (-O0) übersetzen. Mit der geänderten Schreibweise geht es auch mit -Os!
Versuchs mal mit einem kleineren FIFO, falls nicht schon geschehen. Dann werden die Blöcke kleiner, dafür aber öfter. Vielleicht wird der Controller der Karte bei sehr großen Blöcken zu ineffizient bei der Verwaltung.
@ Abdul K. (ehydra) Benutzerseite >Versuchs mal mit einem kleineren FIFO, falls nicht schon geschehen. Dann >werden die Blöcke kleiner, dafür aber öfter. Das mache ich doch schon, ist auch anwendungsbedingt. Ausserdem ist nocht ein Sektorpuffer im FatFS selber drin, d.h. es werden IMMER ganze Sektoren geschrieben, manchmal als Einzelsektoren, manchmal als Multiwrites. > Vielleicht wird der >Controller der Karte bei sehr großen Blöcken zu ineffizient bei der >Verwaltung. Eher bei kleinen. Siehe Anhang. Schreibtest 105MB. Die Dateigröße wurde vorher auf Maximum expandiert (Preallocation), damit sind alle Daten in der FAT eingetragen. Ebenso wurde wieder die Cluster Link Table eingelesen, damit braucht man auch keine FAT-Zugriffe mehr während des Schreibens. Zuerst mit 32kB/Aufruf. Die Abstände der Peaks sind exakt 4MB Datenvolumen, wie schon vermutet. Bei 16kB Blockgröße werden die Peaks merkwürdigerweise kleiner? Warum? Aber kurz vor Schluß erwischt es mich dann doch, es gibt einen 900ms Peak. Warum? Wenn ich meine Applikation nachbilde, sprich 500B / 20ms schreibe, ist meist alles im Lot, keine bösen Peaks bis 1s? Zum Testen hab ich erstmal nur 10MB geschrieben, da müsste aber mindestens zweimal die 4MB Grenze überschritten werden. Hmmm, vielleicht ist doch noch ein Bug in meiner Applikation?
Und die Karte wurde wie oft benutzt? Vielleicht irgendwas mit ECC aktiv. Könnte mir vorstellen, daß er ECC-Errors zwar on-the-fly erkennt, aber nur langwierig in Software reparieren kann. Keiner weiß was. Nimm ne völlig andere Karte. Kann natürlich irgendwo auch Software-Problem sein. Nur dann würde das doch auch anderen auffallen. Rein zur Sicherheit würde ich auch noch auf einen Einbruch der Versorgungsspannung prüfen. Man weiß ja nie.
Ok, hier nochmal eine Meldung zum Thema. Ich hab jetzt endlich mal eine andere Karte probiert, 4GB von FUJI. Damit läuft es deutlich besser. In der realen Applikation kam es nur einmalig zu einem maximalen FIFO-Füllstand von 7kB,das entspricht ca. 300ms Blockade, sonst war der FIFO immer recht leer, bei 128MB Dateigröße, welche in ca. 1,5h geschrieben wurde. Ein Test ohne Applikation zeigt die Zugriffszeiten wie im Anhang, einmal mit 32k Blöcken und einmal sehr applikationsähnlich mit 450 Byte Blöcken. Damit ist gezeigt, dass die SD-Karten verschiedene Puffer- und Schreibverfahren nutzen und bisweilen große Unterschiede haben. Die FUJI hat zwar des öfteren mal einen Burst mit Zugriffszeiten von ca. 80ms, aber hier kann die Karte scheinbar den Löschvorgang für neue Sektoren/Pages deutlich besser puffern bzw. verteilen, wogegen die Kingston Kart dort hart gegen die Wand fährt und erstmal laaaange Pause macht (4MB Sektor löschen?).
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.