Forum: Mikrocontroller und Digitale Elektronik SD-Karte mit sporadischen Schlafpausen?


von Falk B. (falk)


Lesenswert?

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

von chris (Gast)


Lesenswert?

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.

von Jim M. (turboj)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

@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.

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

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.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Nimm doch einfach mal ne andere Karte.

von Falk B. (falk)


Lesenswert?

@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.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Ins nächste Kaufland. Ich glaube die haben bis 22 Uhr samstags offen. 
Oder n Tanke etwas teurer eben.

von chris (Gast)


Lesenswert?

Probier mal erst anfangen zu schreiben wenn Buffer 1/3 Voll sind, ob
sich dann ein Unterschied abzeichnet.

von Jim M. (turboj)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

@ 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.

von Falk B. (falk)


Lesenswert?

@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.

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Ahhh, hier der 2. Anhang.

von Davis (Gast)


Lesenswert?

Das Problem solltest du im elm-chan Forum posten: 
http://elm-chan.org/fsw/ff/bd/

von Falk B. (falk)


Lesenswert?

@ 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!

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

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.

von Falk B. (falk)



Lesenswert?

@ 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?

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

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.

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.