Forum: Mikrocontroller und Digitale Elektronik Verzögerung beim schreiben auf SD-Karte


von Wolfgang R. (eg61ejub)


Lesenswert?

Hallo,

ich will die Daten von drei Sensoren (ADXL345, L3G4200D, BMP085) über 
SPI auf eine SD-Karte speichern. Dabei verwende ich den Code von 
elm-chan für FatFs.

Der Ablaufplan sieht so aus, dass ich 4 mal den Beschleunigungssensor 
und das Gyroskop (alle 10 ms = 100 Hz) und 1 mal das Barometer alle 40 
ms (25 Hz) abfrage.

Es funktioniert auch alles einwandfrei, ABER hin und wieder braucht das 
Schreiben auf SD-Karte (was die Funktion f_sync erledigt) 5 mal so lange 
als normal.
Normal: 5-6 ms
Hin und wieder: 28-32 ms (Hin und wieder = nicht im selben Abstand, z.B. 
jedes 500. mal)

Ich versuch seit 1 Woche die Ursache zu identifizieren.
1.) An der SPI sollte es nicht liegen, da die ansonsten funktioniert.
2.) Die SD-Karte hat ja intern einen Controller, der die Daten schön im 
Speicher der Karte ablegt (salopp gesagt). Dabei könnte es passieren, 
dass er sich den Platz im Speicher sucht und eben hin und wieder dafür 
länger braucht.

Jetzt zu meinen Fragen:
1.) Woher kommt die Verzögerung?
2.) Wie kann ich sie ausschalten?

Grüße
eg61ejub

von Tastkopf (Gast)


Lesenswert?

Schuld daran ist die SD Karte. Ob man das Problem lösen kann weis ich 
nicht. Mein Workaround sieht so aus das der Zwischenpuffer einfach recht 
groß gewählt ist um auch diesen speziellen Fall abzufangen.

von Jim M. (turboj)


Lesenswert?

Was ist das für ein Kartentyp? Hier hatten wir Verzögerungen im Worst 
case bis etwa 300ms - aber den Typ weiss ich nicht mehr genau.

Außerdem muss man IMO gelegentlich einen FAT-Sektor neu schreiben.

Ausschalten kann man das gar nicht - man braucht genügend Pufferspeicher 
um den Worst case abzufangen.

von Wolfgang R. (eg61ejub)


Lesenswert?

Erstmal danke für die schnellen Antworten.

Kartentypen hab ich die Transcend microSDHC CLASS 6 und die SanDisk 
microSDHC CLASS 4 probiert und bei beiden sind die gleichen "delays" zu 
erkennen. Also ungefähr gleiche Abstände und selbe Dauer (ca. 30 ms).

Das mit dem Zwischenpuffer versteh ich so, dass ich nicht nach jedem 
Durchlauf (alle 40 ms) auf SD-Karte speichern sollte, sondern besser 
alle 400 ms z.B. oder noch besser wäre das komplett auszureizen um 
möglichst selten zu speichern und damit den "Spezialfall" zu minimieren.
Verbessert mich bitte, wenn ich mich täusche.

von Tastkopf (Gast)


Lesenswert?

jain, du solltest nicht direkt von deinen sensoren auf die sd karten 
speichern, sondern von den sensoren in einen buffer und den gelegentlich 
im huntergrund leer machen. Ein eigener niederpriorer task falls du ein 
RTOS verwendest, ansonsten halt von hand synchronisieren das du vom 
Buffer auf die SD Karte und in von den sensoren in den Buffer schreiben 
quasi gleichzeitig tun kannst.

von Wolfgang R. (eg61ejub)


Lesenswert?

OK

Dann werd ich das mal versuchen und Bericht erstatten, sobald ich es 
geschafft habe.

Danke nochmal

von Stefan++ (Gast)


Lesenswert?

Hallo,

das Ganze liegt wahrscheinlich am Dateisystem (FAT).
Sektorgroesse (= kleinste Speichereinheit) ist bei fast allen SD-Cards 
512 Byte und die Clustergrösse ist dann ein Vielfaches bis zu 32kByte 
bei FAT16.
Vor bzw. nach Beschreiben eines Clusters muss die FAT bemüht werden um 
einen neuen Cluster zu allozieren und als besetzt zu kennzeichnen und 
mit dem vorhergehenden zu verlinken. Und genau dieser Vorgang braucht 
dann mehr Zeit (lesen aus der FAT und freien Cluster suchen, ändern der 
FAT, zurüchschreiben). Dieser Vorgang ist nicht Sache des Contollers in 
der SD-Card sondern die muss der Prozessor erledigen.

Abhilfe gibts eigentlich nur durch Puffern und der gleichzeitigen 
Abkoppelung des Speicherns und der Verwaltung des FS vom sonstigen 
Programmfluss.

von holger (Gast)


Lesenswert?

>das Ganze liegt wahrscheinlich am Dateisystem (FAT).

Das spielt sicher auch eine Rolle. Fakt ist aber das
manchmal das schreiben von Sektoren sehr lange dauert.
300ms habe ich da auch schon gemessen. Die Verzögerungen
durch das FAT Handling kommen dann noch dazu.

von Wolfgang R. (eg61ejub)


Lesenswert?

Um diesen Thread abzuschließen und für andere, die ein ähnliches Problem 
haben, erkläre ich kurz meine Lösung:

In meiner main loop wartet das Program und speichert hin und wieder mit 
der f_sync.
Alles andere (Sensordaten abholen, Zwischenspeichern (nicht in einem 
FIFO, aber schon auf dem MSP), mit Hilfe von f_printf auf SD-Karte 
schreiben (nicht speichern) und auch der Ablaufplan, also in welcher 
Reihenfolge die Daten abgeholt werden und in welchen Abständen) läuft in 
der ISR (Interrupt Service Routine).
Der Interrupt kommt vom MSP Timer und wird alle 5 ms ausgelöst.

Probleme dabei:
1.) Wenn die Funktionen in der ISR länger als 5 ms brauchen, da dabei 
ein Interrupt übersprungen werden könnte und sich das Auslesen dadurch 
verzögert.
--- Ich hatte bei ca. 10.000 Funktionsaufrufen nur einmal den Fall, dass 
eine Funktion 12 ms gebraucht hat (ansonsten maximal 4 ms). Diese 
einmalige Ausnahme vernachlässige ich.
2.) Die Plattform soll am Ende mit den Daten aus 5 Sensoren arbeiten. 
Der jetzige Code funktioniert nur für 3 Sensoren (Beschleunigungsmeter, 
Gyroskop, Barometer). Sobald ein weiterer Sensor hinzu kommt braucht der 
Interrupt Handler zu lange.
--- Besser wäre die Interrupts von den jeweiligen Sensoren zu verwenden.
3.) Die Verzögerung tritt weiterhin auf und falls man genau während so 
einer Verzögerung abschaltet gehen Daten verloren (im 
Millisekundenbereich).
--- Ist aber sehr unwahrscheinlich, dass man so einen Moment trifft und 
die verlorenen Daten sind gering.


Das ganze Projekt ist ein Prototyp und es gibt viele Stellen an denen 
Soft-, aber auch Hardware, optimiert werden können.

Da meinem Chef der Quellcode passt ist das Thema für mich vorerst 
erledigt und falls ich am Ende noch Zeit habe (Bachelorarbeit) optimiere 
ich den Code noch.

Danke für die Hilfe!

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.