www.mikrocontroller.net

Forum: Mikrocontroller und Elektronik Parallelisierung auf µController

Autor: Martin (Gast)
Datum: 16.05.2008 14:11

Moin, moin,

ich stehe gerade vor einem Timingproblem. Ich muss Messwerte samplen und
diese auf einem Speichermedium hinterlegen. Aufgrund der hohen
geforderten Abtastung der Sensoren komme ich jetzt in den kritischen
Bereich. Damit meine ich, dass Schreiben der Daten dauert länger als der
zeitliche Abstand zwischen zwei Abtastungen. Momentan habe ich die
Firmware sequentiell implementiert. Dies bedeutet, während des
Schreibvorgangs kann nicht gesamplet werden. Rein theoretisch könnte er
während des Schreibvorgangs aber schon wieder neue Messwerte aufnehmen
und temporär in einem alternierenden Ringbuffer halten.

Meine Frage ist jetzt, wie schafft man es am saubersten
Prozesse(Messwererfassung vs. Messwertspeicherung) zu parallelisieren?
Habt ihr hier schon Erfahrungen gesammelt? Welche eventuellen
weitergehenden Module könnte ihr für die Lösung des Problems empfehlen?

Danke
Autor: Detlev T. (detlevt)
Datum: 16.05.2008 14:28

Welchen Mikrocontroller willst du überhaupt einsetzen?

Wenn die Daten wirklich schneller ankommen als sie gespeichert werden
können, nützt dir eine "Parallelisierung" allein auch nichts. Da
brauchst du einen ausreichend großen Zwischenspeicher (z.B. RAM). Wie
wäre es mit einem schnelleren Datenspeicher?

Tendenziell würde ich für so eine Aufgabe (zwei Prozesse) wohl noch
keinen Scheduler etc. einsetzen, sondern eine der Aufgaben in eine
Interrupt-Routine auslagern.
Autor: Mike (Gast)
Datum: 16.05.2008 14:31

Hallo Martin,

die Parallelisierung auf einem Mikrocontroller lässt sich auf
verschiedene Arten bewerkstelligen. Die einfachste ist die Verwendung
von Interrupts, d.h. im Hauptprogramm läuft eine Schleife, die auf Daten
wartet und, falls welche vorhanden sind auf das Medium speichert. Die
Sensordaten werden von einer Interruptroutine eingelesen, die entweder
durch einen äusseren Eingang immer dann getriggert wird, wenn der Sensor
neue Daten hat, oder in regelmässigen Abständen durch einen Timer.
Wichtig ist, dass die kurzen "Störungen" durch die Interruptroutine den
Schreibvorgang nicht stören.

Eine Alternative wäre die Verwendung eines
Multitasking-Echtzeitbetriebssystems, was in Deinem Fall aber
wahrscheinlich mit Kanonen auf Spatzen geschossen wäre.

Leider ist es schwer, eine genauere Antwort zu geben, da ich die
Anforderungen Deines Systems (Datenrate, zulässige Latenzzeit, Art des
Speichermediums, verwendeter Controller, Taktfrequenz etc.) nicht kenne.

Gruss
Mike
Autor: Sven (Gast)
Datum: 16.05.2008 14:34

> Rein theoretisch könnte er.....

Hilft so für eine Auskunft nix, wie wäre es mit konkreten
Angaben zu den Messwerten.

bsp. Wieviel Bit die Auflösung ?
Wieviel kb/s oder Mb/s an Messwerten welcher Controller, etc.

Gruß Sven
Autor: yalu (Gast)
Datum: 16.05.2008 14:38

Über welche Schnittstelle werden die Messwerte gelesen? Wie hoch ist
die Samplingrate?

Du könntest die Messwerte vielleicht in einem Timer-Interrupt sampeln
und in den Ringpuffer schreiben. Das Hauptprogramm liest die Daten aus
dem Ringpuffer aus und speichert sie ab.

Wenn es sich um analoge Daten handelt und der Controller (wie bspw.
die AVRs) über einen periodischen ADC-Modus verfügt, kannst du auch
diesen verwenden. Jede abgeschlossene A/D-Umsetzung löst einen
Interrupt aus, in dem der Messwert in den Ringpuffer geschrieben wird.
Autor: Martin (Gast)
Datum: 16.05.2008 14:49

Hallo,

also, ich habe verschiedenes an Sensorik. ADC, Porteingangänge und
Sensorik über I2C-Bus. Im WorstCase sind es 14 Messkanäle. Die
Abtastrate sollte für einzelne Sensoren bei 5kHz liegen. Ich habe einen
ARM7 den ich mit 55MHz laufen lasse. Als Speichermedium habe ich eine
SD-Karte. Messwerte werden als in eine FAT32 Datei geschrieben. Ich
glaube aber, dass das FAT System ein Killer ist.

Gruss
Autor: Jochen Müller (taschenbuch)
Datum: 16.05.2008 16:29

Martin,

Wenn der zeitliche Flaschenhals das schreiben der Daten ist, dann nützen
Dir auch Ints oder andere Tricks nichts. Auch ein Ringbuffer würde sich
zukreiseln, wenn Du nicht mindestens genau so schnell schreiben wie
lesen kannst.
Das geht nur, wenn Du zwischendurch Pausen beim Einlesen der Werte hast,
in denen der Bufferinhalt geschrieben wird. Dann allerdings wäre ein
Ringbuffer die richtige Wahl.

Und ja: FAT auf SD Karte ist garantiert der Killer. Ganz besonders, weil
Du die physikalische Schreibzeit niemals kalkulieren kannst, die kann je
nach allen möglichen Umständen immer anders sein, die Karte macht da was
sie will.

Jochen Müller
Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite
Datum: 16.05.2008 16:48

5 kHz? Da sollten sich der Prozessor und die SD-Karte langweilen, du
darfst nur nicht den Fehler machen jeden Messwert einzeln zu schreiben.
Lies die Messwerte in einem Interrupt, schieb sie dort in einen FIFO
(Ringpuffer), und schreib sie erst auf die Karte wenn sich ein paar
ganze Blöcke (n*512 Byte) angesammelt haben. Wenn du für das Schreiben
dann noch DMA verwendest hat der Prozessor überhaupt nichts mehr zu tun.
Autor: Jochen Müller (taschenbuch)
Datum: 16.05.2008 17:15

>>5 kHz? Da sollten sich der Prozessor und die SD-Karte langweilen,

Das klingt erstmal nach reichlich Zeit. Aber es sind nur weniger als
1ms.
Und das ganze auch noch geteilt durch 14 Kanäle, wie der OP schrieb.
Mit FAT Verwaltung -von der niemand weiss wie gut die programmiert ist-
schafft die SD-Karte das einfach nicht.

Und auf jeden Fall bleibt es dabei, dass das Timing Verhalten der SD
nicht konkret zu kalkulieren ist.

Jochen Müller
Autor: holger (Gast)
Datum: 16.05.2008 17:37

>>>5 kHz? Da sollten sich der Prozessor und die SD-Karte langweilen,

>Und das ganze auch noch geteilt durch 14 Kanäle, wie der OP schrieb.
>Mit FAT Verwaltung -von der niemand weiss wie gut die programmiert ist-
>schafft die SD-Karte das einfach nicht.

5kHz bei sagen wir mal 2 Byte pro Kanal. Ergibt 10kB/s pro Kanal.
Mal 14 also 140kB/s. Das machen fast alle Karten mit und der ARM
langweilt sich.

Folgendermassen sollte man das hinkriegen:

Nimm zwei Puffer a 1kB. Der Puffer1 wird per Interrupt gefüllt.
Wenn er voll ist wird auf Puffer2 umgeschaltet. Puffer1 wird dann
auf die Karte geschrieben. Das ganze immer im Wechsel.

Bei 1kB Puffer hast du 7.3ms Zeit Puffer1 auf die SD zu
schreiben bevor Puffer2 voll ist. Wenn das nicht reicht
nimmst halt 2kB pro Puffer. Sollte beim ARM kein Problem sein.
Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite
Datum: 16.05.2008 17:45

Ja, das wäre die einfache Variante des Ringpuffers. Sollte völlig
ausreichen, zumal man ja bei den meisten ARMs mehr als genug RAM zur
Verfügung hat.
Autor: Martin (Gast)
Datum: 16.05.2008 21:32

Hallo,

vielleicht nochmal vorab, jedes Samplepackage(auch bei nur einem
Messkanal) besteht aus mindestens 14Byte(1Byte Paketlänge + 4Byte
Prozessorticks + 4Byte Samplenumber + 1 Byte ChannelID + 2 Byte Data).
Für die Anwendung ist die exakte Zeitzugehörigkeit extrem wichtig.
Deshalb der gewaltige Overhead.

Die Thematik mit dem Ringpuffer habe ich schon implementiert. Wovor ich
ein wenig abschrecke ist das Erstellen der Messpakete innerhalb der ISR.
Sowas ist nach meinen bisherigen Erfahrungen eher kritisch.
Ich kann die Aussagen von "Jochen Müller" nur bestätigen. Habe schon
einige Versuche mit SD und FAT gemacht. Die realle Datenrate ist
zeitlich schwierig vorherzusagen. Ich benutze die FAT Library FatFS und
erreiche in Abhängigkeit von der Buffergröße Datenraten von 100kB bis
800kB. Es ist aber deutlich erkennbar, das während des Schreibvorgangs
mitunder größere zeitliche Varianzen von bis zu 500ms erkennbar sind.
Diese Dinge sind sporadisch, man erkennt also kein festes zeitliches
Fenster.

Gruss
Autor: Tom (Gast)
Datum: 16.05.2008 21:42

Da kannst du schon mal ausrechnen, wieviel RAM du brauchst:
5 kHz x 14 Samples x 14 Byte x 500ms Wartezeit = 500 kByte.
Solche großen Buffer lassen sich auch schön effizient auf eine SD-Karte
schreiben.
Autor: Andreas Kaiser (a-k)
Datum: 16.05.2008 21:50

Wenn FAT, dann ja wohl weil ein PC die Daten irgendwann lesen soll. Denn
sonst wäre FAT ja überflüssig und das Problem gegessen. Wobei man mit
PCs sicherlich auch SDs ohne FAT-Format lesen kann.

Wenn also FAT sein muss, dass sollte es eine Variante sein, die nicht
erst in der kritischen Phase die Allokation der Datenblöcke durchführen
muss. Denn das ist der schwer vorhersehbare Teil davon. Das lässt sich
beispielsweise machen, indem man die SD-Card vorher fest mit
FAT-Verwaltung und einem einzigen sie komplett belegenden Containerfile
formatiert. Die Daten liegen dann an bekannter Stelle sequentiell in dem
Containerfile und damit an bekannter Stelle auf der SD-Card, und der
Controller kann so schnell schreiben wie die Karte hergibt, weil er die
FAT selber überhaupt nicht benötigt.
Autor: holger (Gast)
Datum: 16.05.2008 23:58

>Es ist aber deutlich erkennbar, das während des Schreibvorgangs
>mitunder größere zeitliche Varianzen von bis zu 500ms erkennbar sind.
>Diese Dinge sind sporadisch, man erkennt also kein festes zeitliches
>Fenster.

Das kann ich jetzt leider nur bestätigen.
Ich hab mit 5 Karten mal die maximalen Busy Zeiten gemessen.
Auch mit FatFs (elm-chan) auf LPC2138.
Ging von 40ms bis 310ms.

Präzises Timing mit SD Karten ist unmöglich.
Autor: Martin (Gast)
Datum: 17.05.2008 08:43

Moin, moin,

Die Aussage von Andreas ist richtig. Die Daten sollen hinterher am PC
analysiert werden.

@a-k
Habe mal noch ein paar weitergehende Fragen zu deiner Antwort

>Wobei man mit
>PCs sicherlich auch SDs ohne FAT-Format lesen kann.

Welche Möglichkeiten siehst du hier?


>Das lässt sich
>beispielsweise machen, indem man die SD-Card vorher fest mit
>FAT-Verwaltung und einem einzigen sie komplett belegenden Containerfile
>formatiert.

Meinst du damit, dass man im Vorfeld z.B. eine Datei(data.txt) mit 30MB
anlegt und dann die Messwerte in dieses File schreibt? Aber dann würde
ich ja trotzdem wieder die FAT Library brauchen.


Wäre über Anregungen dankbar

Gruss
Autor: Wolfgang Mües (Gast)
Datum: 17.05.2008 08:56

Wobei ich zu bedenken gebe, dass die Größe der einzelnen
wegzuschreibenden Datenblöcke eine entscheidende Rolle für die
Geschwindigkeit spielt. Ich habe neulich ein Paper gesehen, bei dem
jemand das Verhalten genauer untersuchte. Die Schreibgeschwindigkeit
stieg bis 64 KByte Blockgröße linear an und blieb dann konstant.
Autor: Andreas Kaiser (a-k)
Datum: 17.05.2008 09:57

Martin wrote:

> Welche Möglichkeiten siehst du hier?

Ich habe noch keine SDs so gelesen, aber das dürfte nicht anders sein
als bei Floppy-Disks, und da habe ich das vor langer Zeit schon gemacht.
Das File "\\.\A:" bezeichnet unter Windows die Floppy als Raw Device,
d.h. formatfrei wird alles von vorne bis hinten gelesen. Allerdings
werden sich diverse Microsoft-Tools dabei weigern, musst du ggf. mit
eigenem Programm ran. Unter Linux ist es noch viel einfacher.

Will du darauf auch schreiben, musst du das Device allerdings dazu
sperren: DosDevIOCtl(..., IOCTL_DISK, DSK_LOCKDRIVE, ...).

> Meinst du damit, dass man im Vorfeld z.B. eine Datei(data.txt) mit 30MB
> anlegt und dann die Messwerte in dieses File schreibt?

Im Grunde ja, aber ohne FAT-Lib.

Du würdest das File nicht jedesmal per FAT-Lib anlegen. Sondern ein
einziges Mal in der Entwicklungsphase und daraus den Inhalt der so
erzeugten Verwaltungsstrukturen der FAT gewinnen (Info zum
FAT-Filesystem findet sich im Internet). Was sich auch per PC erledigen
lässt, sie oben.

Diese Verwaltungsinformation besteht aus ein paar Blöcken vorneweg und
der FAT selber, die dabei recht schematisch aussieht. Wenn dann ein SD
Medium formatiert werden muss, schreibst du einfach diesen Kram exakt so
drauf und hast damit ein FAT-formatiertes Medium von genau definiertem
Inhalt, von dem der Controller nun implizit weiss, dass das
Containerfile an Block 1234 anfängt und 60000 Blöcke gross ist. Eine
FAT-Lib wird dazu also nicht benötigt. Die Timestamp von dem Container
ist dabei natürlich nicht aktuell, auch die Anzahl geschriebener Bytes
nicht, aber damit solltest du leben können.
Autor: Martin (Gast)
Datum: 17.05.2008 10:03

Hallo Andreas,

danke für deine Info. Werde mich dann mal weiter umschauen

Gruss
Autor: Andreas Kaiser (a-k)
Datum: 17.05.2008 10:07

Du kannst das auch mit FAT-Lib machen, indem du vorneweg per FAT-Lib die
SD komplett löschst (sonst droht Fragmentierung), das File anlegst und
dann den Inhalt an der Lib vorbei daraufhin analysiert, wo das File
liegt. Hat gegenüber der vorher beschriebenen Methode den Vorteil, dass
es bei SDs unterschiedlicher Grösse funktioniert. In beiden Fällen musst
du dich natürlich etwas in den Aufbau eines FAT-Filesystems einlesen.
Autor: Andreas Kaiser (a-k)
Datum: 17.05.2008 10:19

Andreas Kaiser wrote:

> Will du darauf auch schreiben, musst du das Device allerdings dazu
> sperren: DosDevIOCtl(..., IOCTL_DISK, DSK_LOCKDRIVE, ...).

Sorry, dieser Teil des Codes war für OS/2... Ich weiss nicht mehr, ob
man unter Windows irgendwas für's Schreiben tun muss oder ob das ohne
geht. Lesen jedenfalls geht wie beschrieben.
Autor: Martin (Gast)
Datum: 17.05.2008 20:53

Hallo,

habe noch Verständnisprobleme. Schreibe mit dem µC die Blöcke
entsprechend auf die SD-Karte(z.B. @ Sektor 1000, @ Sektor 1001, usw.)
Hierfür gibt es spezielle SD Kommandos. Kann die Blöcke auch
ordnungsgemäß wieder mit dem µC auslesen. Jetzt habe ich aber Probleme,
die selben Blöcke am PC auszulesen.
Ich lese die Daten wie im Artikel
http://support.microsoft.com/kb/q100027/ beschrieben. Im ersten Block
finde ich die allgemeinen Informationen. Gehe ich jetzt aber zu den
Sektoren 1000, ... kann ich meine geschriebenen Blöcke nicht erkennen.
Mache ich noch einen gedanklichen Fehler?

Gruss
Autor: I_ H. (i_h)
Datum: 18.05.2008 00:39

Martin wrote:
> Hallo,
>
> vielleicht nochmal vorab, jedes Samplepackage(auch bei nur einem
> Messkanal) besteht aus mindestens 14Byte(1Byte Paketlänge + 4Byte
> Prozessorticks + 4Byte Samplenumber + 1 Byte ChannelID + 2 Byte Data).
> Für die Anwendung ist die exakte Zeitzugehörigkeit extrem wichtig.
> Deshalb der gewaltige Overhead.


Du kannst das doch sicher so abspeichern, dass du das aus weniger Daten
rekonstruieren kannst. Lass die Kanäle einfach in einem vorgegebenem
Raster abtasten (reihum Kanal 1 bis 14), aus dem Zeitstempel vom ersten
Kanal, der Abtastrate und der Anzahl der Kanäle kannst du doch wunderbar
den exakten Zeitpunkt für jeden Kanal zurückrechnen.
Wichtig ist nur, dass du die ADC Werte in einem festen Zeitraster
anfertigst.

Dann hast du für 14 Werte 1Byte Paketlänge (kannst du auch weglassen,
ganz am Anfang einmal speichern wieviele Kanäle abgetastest werden),
4Byte Prozessornummer, 4Byte Samplenummer (auch redundant, oder lässt du
unterwegs samples weg?? - wär auch wurscht, hast ja Zeitstempel) und
schließlich 28 Byte Daten aufsteigend für Kanal 1 bis 14.

Das macht dann nur noch 2.65 Byte pro Sample, bzw. weniger als 1/5tel
der Ausgangsdatenrate. Einzige Anforderung ist, dass du bei jeder
Messung alle Kanäle hintereinander mit festem Zeitabstand durchmisst.

Kann man auch noch weiter reduzieren (Samplenummer und Paketlänge
weglassen, dafür vor jeden Datensatz einen Header der Auskunft über
Anzahl Samples und Reihenfolge und Anzahl der aufgezeichneten Kanäle
gibt), aber unter 2 Byte / Sample geht dann nur noch mit Kompression
(... hat der ADC wirklich 16 Bit?).

Antwort schreiben

Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
  • Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net