Forum: Mikrocontroller und Digitale Elektronik Datenlogger, Sensordaten speichern während SPI-Übertragung


von Stephan (Gast)


Lesenswert?

Hallo zusammen,

ich bin dabei einen Datenlogger umzusetzen und hänge gerade ideenmäßig 
etwas fest.
Aktueller Stand sieht wie folgt aus:
Es werden Daten mit 1 kHz von 3 Sensoren empfangen und in einem 
Bufferarray zwischengespeichert, wenn das Array voll ist, werden die 
Daten auf eine SD-Karte geschrieben.

Mein Problem ist nun, während des Schreibens auf die SD-Karte werden 
keine weiteren Daten mehr geloggt und mir fehlen dann etwa pro Sekunde 
150 Werte.

Meine bisherige Idee ist:
Innerhalb des Sensorinterrupts die Daten in ein Array zu schreiben und 
wenn das Schreiben auf die SD-karte beendet ist, diese Werte ins 
eigentliche Bufferarray zu übertragen. Dabei stellt sich mir allerdings 
die Frage, ob es mit der SD-Karte Probleme gibt, wenn der Interrupt zu 
lange dauert?

Wenn jemand noch weitere hilfreiche Ideen hat, immer her damit.

Vielen Dank schon im Voraus.

von Gebhard R. (Firma: Raich Gerätebau & Entwicklung) (geb)


Lesenswert?

Hilfreich wäre, wenn du deine CPU angeben würdest.Mit einer vernünftigen 
CPU und einem RTOS kann man "gleichzeitig" ohne weiteres schreiben und 
einlesen. Hab das schon gemacht, war eine ARM-Cortex STM103Z CPU mit 
4bit interface auf die SD-Karte.

Grüsse

von Stephan (Gast)


Lesenswert?

Achso, die CPU ist ein STM32F407, die SD-Karte enthält außerdem ein 
FAT32 Dateisystem und wird über SPI beschrieben.

von Gebhard R. (Firma: Raich Gerätebau & Entwicklung) (geb)


Lesenswert?

STM32F407 und über SPI schreiben? Das ist Schwachsinn. Nütz doch das 
eingebaute Interface. Geht mit der orig. Treiberbibliothek wunderbar. 
Ein Filesystem würd ich nur im Falle einer Wechsel-SD-Karte benützen.

Grüsse

von Stephan (Gast)


Lesenswert?

Scheinbar habe ich noch nicht genug Infos über meinen aktuellen Status 
erklärt. :)

Also das SPI-Interface muss ich nutzen, da die SD-Karte, bei der von mir 
verwendeten Plattform, leider damit verdrahtet ist und somit SDIO nicht 
in Frage kommt. Außerdem habe ich ca. 2 Wochen versucht eine Übertragung 
per DMA zur SD-Karte zum Laufen zu bringen. Ich habe mir die 
DMA-Register im Core angesehen und dort werden die nötigen Bits nicht 
gesetzt, obwohl der Code den ich verwendet habe, auf dem 
STM32F4-Discovery problemlos lief. Da ich mich nicht ewig damit 
aufhalten konnte, habe ich vom DMA erstmal Abstand genommen. Weiterhin 
benötige ich ein Filesystem auf der SD-Karte, da die Daten anschließend 
am Rechner ausgewertet werden sollen.

von Falk B. (falk)


Lesenswert?

@ Stephan (Gast)

>Es werden Daten mit 1 kHz von 3 Sensoren empfangen und in einem
>Bufferarray zwischengespeichert, wenn das Array voll ist, werden die
>Daten auf eine SD-Karte geschrieben.

Fast richtig.

>Mein Problem ist nun, während des Schreibens auf die SD-Karte werden
>keine weiteren Daten mehr geloggt und mir fehlen dann etwa pro Sekunde
>150 Werte.

Man muss Multitasking machen, wie fast immer.

>Innerhalb des Sensorinterrupts die Daten in ein Array zu schreiben und
>wenn das Schreiben auf die SD-karte beendet ist, diese Werte ins
>eigentliche Bufferarray zu übertragen.

Nicht ganz. Du braucht ein FIFO, das kann man in Software aufbauen. 
Das ist etwas anders als dein Bufferlösung, wenn gleich ähnlich.

Deine Sensoren müssen über priorisierte Interrupts angesprochen werden 
und dürfen logischerweise NICHT am SPI für die SD-Karte dranhängen 
sondern separate IOs nutzen. Wenn das nicht geht, wird es ziemlich 
aufwändig.

von Gebhard R. (Firma: Raich Gerätebau & Entwicklung) (geb)


Lesenswert?

Das SDIO interface und DMA sind 2 verschiedene Paar Schuhe.Es 
funktioniert auch ohne DMA bestens. Falls du wirklich über die SPI 
schreiben willst, mußt du dir überlegen, wo und wann der Schreibvorgang 
unterbrochen werden darf (interrupts sperren).Möglicherweise kannst du 
den Eingangsdatenstrom über DMA buffern.

Grüsse

von Stephan (Gast)


Lesenswert?

Vorweg schon mal vielen Dank für die schnellen Antworten.

@ Falk
Wie meinst du das mit Multi-Tasking? Hab noch keine Erfahrung mit der 
Umsetzung davon.
Ein FIFO wäre ja nur dann hilfreich, wenn ich die Blockierung durch den 
Schreibvorgang auf die SD-Karte umgehen könnte, oder?
Und zu den Sensoren, die hängen an separaten I/Os zweimal I2C und einmal 
SPI. Im Moment habe ich sie so getaktet, dass einer der Sensoren per 
Interrupt ein Flag setzt. In der State-Machine wird dann zu gegebener 
Zeit die Ausleseroutinen für alle angestoßen, damit ich einen zeitlichen 
Bezug der einzelnen Werte zueinander habe.

@ Gebhard
Genau die Unterbrechung der SPI-Übertragung zur SD-Karte ist der Punkt 
bei dem ich nicht weiß, ob man das einfach machen kann und wenn ja, wie 
lange das dauern darf. Das Buffern der Sensorwerte über DMA wäre eine 
Möglichkeit, allerdings sehe ich da schon wieder Lawinen an Problemen 
auf mich zurollen, da mein letzter DMA Versuch auf diesem Board nicht 
wirklich von Erfolg gekrönt war.

von Gebhard R. (Firma: Raich Gerätebau & Entwicklung) (geb)


Lesenswert?

>Genau die Unterbrechung der SPI-Übertragung zur SD-Karte ist der Punkt
>bei dem ich nicht weiß, ob man das einfach machen kann und wenn ja, wie
>lange das dauern darf.

Das musst du durch Versuche herausfinden

>da mein letzter DMA Versuch auf diesem Board nicht
>wirklich von Erfolg gekrönt war

denken,schreiben & testen

Schau dir mal einfach die STM Beispiele an, da kann man vieles ableiten 
bzw. 1:1 verwenden.

Grüsse

von c-hater (Gast)


Lesenswert?

Stephan schrieb:

> Es werden Daten mit 1 kHz von 3 Sensoren empfangen und in einem
> Bufferarray zwischengespeichert, wenn das Array voll ist, werden die
> Daten auf eine SD-Karte geschrieben.

Wieviele Bits sind das denn pro Messung? 1024 oder noch viel mehr?

Weil: mit den üblichen 16Bit langweilt sich bei der Aufgabe sogar ein 
AVR @20MHz noch ziemlich...

> Innerhalb des Sensorinterrupts die Daten in ein Array zu schreiben und
> wenn das Schreiben auf die SD-karte beendet ist, diese Werte ins
> eigentliche Bufferarray zu übertragen.

Sowas macht man mit Double-Buffering. Einfach zwei gleich große Arrays, 
in eins werden die Daten reingeschrieben, während (quasi-) gleichzeitig 
aus dem anderen die Daten gelesen und auf den Datenträger geschrieben 
werden.

Ist der aktuelle Eingabepuffer voll, werden die Puffer einfach 
getauscht, indem die jeweiligen Pointer der Eingabe- und Ausgaberoutine 
umgeswitched werden. Nix umkopieren, das ist sinnlose Verschwendung von 
Rechenzeit.

Voraussetzung, daß das Double-Bufferung funktioniert, ist natürlich, daß 
der Ausgabetask (gemittelt über die Größer eines Puffers) immer 
schneller ist, als die Daten auf der Eingabeseite reinkommen. Ist das 
nicht der Fall, muß man die Puffer vergrößern, bis diese Bedingung 
erfüllt ist. Ist das nicht möglich, taugt die Schreibroutine nix 
und/oder der Speicher ist zu knapp.

von Stephan (Gast)


Lesenswert?

@ c-hater
Der Ausgabetask ist leider genau das Problem, es dauert ca. 30ms bis die 
Daten auf die SD-Karte geschrieben sind. In der Zeit verpasse ich dann 
30 Messewerte pro Sensor von je 3x16Bit. Ich habe jetzt versucht einen 
zwischenbuffer in der ISR zu füllen, wenn gerade ein Schreibvorgang 
aktiv ist und diese Werte anschließend wieder in den eigentlichen Buffer 
zu schreiben. Dabei bricht allerdings, wie schon vermutet, die 
Kommunikation mit der SD-Karte ab.

von Falk B. (falk)


Lesenswert?

@Stephan (Gast)

>Der Ausgabetask ist leider genau das Problem, es dauert ca. 30ms bis die
>Daten auf die SD-Karte geschrieben sind. In der Zeit verpasse ich dann
>30 Messewerte pro Sensor von je 3x16Bit.

Sehr lange.

>Ich habe jetzt versucht einen
>zwischenbuffer in der ISR zu füllen, wenn gerade ein Schreibvorgang
>aktiv ist

So muss man es machen.

> und diese Werte anschließend wieder in den eigentlichen Buffer
>zu schreiben.

Wieso? Die kann man DIREKT in den Puffer schreiben. Natürlich richtig 
(tm).
Sourcecode?

 Dabei bricht allerdings, wie schon vermutet, die
>Kommunikation mit der SD-Karte ab.

Hmm, das kann aber auch ein Programmfehler sein. Die Kommunikation mit 
der SD-Karte läuft per SPI, das kann man auf Byteebene unterbrechen, die 
bytes schreibt das SPI-Modul ohne CPU-Arbeit. Wie groß die Timeouts des 
übergeordneten Protokolls sind, weiß ich nicht. ABER! Millionen Kameras 
schreiben kontinuierlich Videodaten auf SD-Karte und das klappt auch 
ohne Quad-Core CPU. Dann kriegst du das auch hin.

von Bavaria (Gast)


Lesenswert?

@Stephan:
Nur nochmal zur Klarstellung: Deine SD-Karte und deine Sensoren
hängen am gleichen (!) SPI oder an 2 unterschiedlichen Interfaces?

Was genau sind deine 30ms? Ist es die Zeit, eine Datei zu öffnen,
ein paar Daten zu schreiben und wieder zu schließen?
(bzw. wahlweise irgendwann zu öffnen, Daten zu schreiben
und dann irgendwann zu schließen)?
Die Zeit kann aber noch viel größer werden,
wenn der SD-Karte langsam die unbenutzten Sektoren ausgehen...

Ist das ein kommerzielles Projekt oder etwas im Hobby-Bereich?
Würde Dir/Euch offizieller Support bei der Umsetzung weiterhelfen?
Wo bist Du denn in etwa?

von Stephan (Gast)


Lesenswert?

@Bavaria
>Ist das ein kommerzielles Projekt oder etwas im Hobby-Bereich?
Das Projekt ist Teil meiner Masterarbeit. Ich möchte die Sensordaten mit 
einer mobilen Plattform aufnehmen und sie anschließend am Rechner mit 
Matlab verarbeiten, daher die SD-Karte.

>Nur nochmal zur Klarstellung: Deine SD-Karte und deine Sensoren
>hängen am gleichen (!) SPI oder an 2 unterschiedlichen Interfaces?
Ja, Sensoren und SD-Karten hängen an unterschiedlichen IOs, also sollte 
es dahingehend keine Probleme geben.

>Was genau sind deine 30ms?
Wie sich die 30ms zusammensetzen, kann ich leider nicht genau 
nachvollziehen. Ich nutze FatFS und öffne während der Initialisierung 
meiner Plattform eine Datei auf der SD-Karte, in die dann Daten per 
f_sync geschrieben werden, wenn der Buffer voll ist. Die Verzögerung ist 
im Moment relativ konstant bei 30ms, aber du hast natürlich recht, dass 
sie auch mal wesentlich länger sein kann. Habe ab und zu Werte im 
Bereich von 120ms gesehen. Darauf kann man ja mit einem genügend großen 
Buffer reagieren.


@Falk
>Die kann man DIREKT in den Puffer schreiben.
Ich dachte mir die ISR möglichst klein zu halten und habe daher darauf 
verzichtet die eingehenden Rohdaten direkt in der ISR umzurechnen und in 
den eigentlichen Buffer zu schreiben, da dies mehrere Divisionen und 
Multiplikationen bräuchte. Wenn du jetzt natürlich sagst das ist kein 
Problem, dann wäre es einen Versuch wert.

von Falk B. (falk)


Lesenswert?

@ Stephan (Gast)

>>Die kann man DIREKT in den Puffer schreiben.
>Ich dachte mir die ISR möglichst klein zu halten und habe daher darauf
>verzichtet die eingehenden Rohdaten direkt in der ISR umzurechnen und in
>den eigentlichen Buffer zu schreiben, da dies mehrere Divisionen und
>Multiplikationen bräuchte.

Das kann ja keiner wissen, auch ich nicht. Also braucht man 
möglicherweise einen zweistufigen Puffer. Die ISR schreibt die Rohdaten 
in den 1. Puffer. Dort werden sie von einem normalen Task/Funktion 
ausserhalb der ISR umgerechnet und in den 2. großen Puffer geschrieben.

>Wenn du jetzt natürlich sagst das ist kein
>Problem,

Nö, ich kenn ja keine Details. Ich nahm an, dass die Daten nicht 
großartig umgerechnet werden müssen. Allerding ist auch das Umrechnen 
ggf. in der ISR möglich und man spart sich die zwei Puffer und die 
zusätzliche Komplexität der Software. Wichtig ist nur, dass die ISR 
kürzer als ihre Periodendauer ist, sprich, bei 1kHz Aufnahmefrequenz 
muss sie logischerweise kürzer als 1ms sein, gefühlt würde ich sagen 
nicht mehr als 900us. Bissel Luft braucht man ja noch für das normale 
Programm ;-). Siehe Interrupt. Die Forderung, "ISR so kurz wie nur 
möglich" ist zu dogmatisch und an der Praxis vorbei.

> dann wäre es einen Versuch wert.

Wir reden, wie so oft in diesem Forum, aneinander vorbei. Ohne die 
wichtigen Informationen zu Randbedingungen kann man da nur schlecht 
Empfehlungen abgeben.

Um zu prüfen, ob deine SD-Karte beim Zugriff Unterbrechungen verträgt, 
kann man es einfach so machen, dass man eine einfache Testdatei auf die 
SD-Karte schreibt und in der ISR einfach ein Pause von X us macht, 
einfach als Stresstest. Keine Sensordaten verarbeiten. Damit gibt es 
dort auch keine Programmfehler, aber eben die Unterbrechung. 
Möglicherweise gibt es nur einige kleine, kurze Passagen in den Funktion 
zum Schreiben auf SD-Karte, welche keine Unterbrechung verkraften, die 
muss man finden und dort KURZ die Interrupts sperren.

MFG
Falk

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.