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
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.
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
> 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
Ü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.
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
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
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.
>>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
>>>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.
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.
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
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.
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.
>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.
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
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.
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.
Hallo Andreas, danke für deine Info. Werde mich dann mal weiter umschauen Gruss
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.
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.
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
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?).
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.