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
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.
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.
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.
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.
OK Dann werd ich das mal versuchen und Bericht erstatten, sobald ich es geschafft habe. Danke nochmal
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.
>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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.