Ich übertrage von einem STM32F4 per FTDI USB-Kabel Daten an den PC. Diese werden am PC „sortiert“ und als Kurve ausgegeben. Mir ist aber die Anzeige auf dem PC zu langsam. Vielleicht könnt ihr mir helfen wie man da üblicher Weise vorgeht. Hier mal eine kurze Beschreibung wie ich es gelöst haben. Die es werden vom STM32F4 Datenblöcke von 18 Byte Größe mit folgendem Aufbau verschickt: BYTE 1 : Anfang Erkennung „0xff“ BYTE 2: Größe+“Art“ der Daten BYTE 3-14: Daten BYTE 15-18: CRC32 Prüfsumme Am PC gibt es 4 Threads: Thread 1: Mainthread für die Oberfläche Thread 2: FTDI empfangen per “FTD2XX.dll” Thread 3: Datenpakete raus sortieren und CRC32 prüfen Thread 4: Daten verarbeiten und an Mainthread für Anzeige übergeben Am PC programmiere ich mit VS2008 C++/CLI. Mein PC ist schnell genug. VG Deepdiver99
Naja, zuerst sollte man mal überprüfen, was wie lange dauert um rauszufinden was zu langsam ist ... Erst dann kann man beginnen zu optimieren
Die Baudrate ist auf 3.000.000 eingestellt. Sobald vom STM32F4 mehr Datenblöcke geschickt werden fängt die Ausgabe der Kurve auf dem Bildschirm an zu stocken. Teilweise dauert es einige Sekunden bis es weiter geht. Dann aber alles auf einmal. Also am Empfang liegt es nicht. Meine CPU ist super schnell und 16GB RAM sollten auch reichen. Vermute mal das die Verarbeitung zwischen dem empfangen und der Ausgabe nicht effektiv ist. Wie wird sowas sonst in der Praxis gelöst? Bei anderen Systemen werden doch teilweise viel mehr Daten verarbeitet.
Du wirst wohl ein Problem in Deiner Threadsynchronisation haben.
Deepdiver99 schrieb: > Vermute mal das die Verarbeitung zwischen dem empfangen und der > Ausgabe nicht effektiv ist. Ich vermute, daß sich die Threads gegenseitig behindern, so wie du das beschreibst. Der Empfangsthread muß die Daten in einen Buffer schreiben können und parallel dazu muß ein anderer Thread unabhängig davon die Daten aus dem Puffer holen, sie verarbeiten und dann darstellen. Und wenn du sagst, daß während des Datenempfanges keine Aktualisierung der Darstellung erfolgt, dann wird dein Empfangsthread die anderen Threads blockieren.
Sowas dachte ich mir schon. Aber die Vorgehensweise ist erst mal so richtig?
Deepdiver99 schrieb: > Sobald vom STM32F4 mehr Datenblöcke geschickt werden fängt die Ausgabe > der Kurve auf dem Bildschirm an zu stocken. Teilweise dauert es einige > Sekunden bis es weiter geht. Hatte ich auch mal, als ich die Bytes von der Seriellen byteweise abgeholt habe (also zuerst auf EV_RXCHAR gewartet und dann aber immer nur Länge 1 im ReadFile()-Aufruf. Das ging dann mit manchen rs232-Adaptern immer noch problemlos (z.B. ein Arduino-Uno ging problemlos, sogar mit hohem Durchsatz) aber bei nem FTDI-basierten Adapter begann es plötzlich im Sekundentakt zu stottern sobald das Datenvolumen größer wurde, er hing dann jedesmal im WaitForSingleObject() fest obwohl längst neue Daten hätten da sein sollen, kurz danach kamen sie dann alle auf einmal, bis zum Nächsten Hänger. Dann baute ich das um, so daß jedesmal soviele Daten gelesen werden wie da sind, lese sie in meinen eigenen Puffer und entnehme sie später von dort byteweise so wie ich sie brauche. Seitdem erreiche ich den vollen Datendurchsatz ohne Probleme. Also Kurzfassung: Niemals die Bytes einzeln mit ReadFile() lesen, immer in großen Blöcken soviel lesen bis nichts mehr kommt, erst dann erneut warten lassen.
:
Bearbeitet durch User
Hallo, wenn du Daten darstellst z.B. mit 1024 x 768 Pixeln, dann ist ein Bildschirm mit 1k x 16 bit vollgeschrieben, und da weder dein Auge noch dein Verstand mehr als 10 Bilder pro Sekunde erfassen kann, ist dafür eine Datenrate von 20 kB / s ausreichend, warum also überträgst du 300 kB / s? Es kann durchaus sein, dass die Empfangsinterrupts deine CPU-Leistung auffressen, besonders wenn der Treiber schlecht programmiert ist und z.B. für jedes Zeichen einen Interrupt auslöst. Ich halte es daher für möglich, dass die Sache mit niedrigerer Datenrate besser funktioniert, Baudraten sind nicht nach dem Prinzip viel hilft viel festzulegen, sondern das Gesamtsystem sollte ausgewogen sein. Jedenfalls kannst du das mal probieren. Am besten wäre es natürlich, wenn du zuerst mal messen würdest, welcher Thread wieviel CPU-Zeit verbraucht. Du kannst natürlich auch mit Prioritäten spielen, aber das verdeckt eher ein bestehendes Problem als dass es gelöst wird. Georg
10 fps könnten u.U. ruckelig wirken, mehr als 30 sind aber für diesen
Zweck Rechenzeit- und Energieverschwendung. Um eine Begrenzung
umzusetzen, muss man natürlich die Ausgabe vom Einlesen der Daten
komplett entkoppeln und auch den Bildschirminhalt korrekt
synchronisieren. Eine einfache Strategie wäre, die neuesten Daten
anzuzeigen, die vorhanden sind (falls zwischen den Frames nicht genug
reinkommt, um das Bild zu füllen, muss ein Teil der "alten" Daten
verwendet werden, so dass das Bild scrollt). Alternativ könnte man alle
Daten zeigen, ohne etwas zu überspringen; dann hinkt die Anzeige immer
weiter hinterher. Irgendwann ist dann allerdings Schluss, weil der
Buffer nicht beliebig groß sein kann.
> "Diese werden am PC „sortiert“ und als Kurve ausgegeben."
Bei einer hohen Datenrate muss man für eine sinnvolle Anzeige u.U.
"richtig" synchronisieren - ähnlich wie bei einem Oszilloskop - was das
Ganze natürlich komplexer macht.
Alfred war knapp daneben :) Beitrag "Projekt: Virtuelle Instrumente an serielle Schnittstelle" Neueste Version 0.48e
Abdul K. schrieb: > Der aus Mönchengladbach. Wirste hier finden. Du kannst einen vielleicht in die Irre führen! Mann.... :-))
Albert schrieb: > Alfred war knapp daneben :) > > Beitrag "Projekt: Virtuelle Instrumente an serielle Schnittstelle" > > Neueste Version 0.48e Danke für den Link, Albert! Sieht sehr interessant aus, den Thread muß ich mir mal in Ruhe zu Gemüte führen...
Beim anzeigen kann man auch noch Fehler machen. zB -mach pixel hin -refresh -mach pixel hin -refresh -mach pixel hin -refresh -mach pixel hin -refresh .. oder alloziere neues pixel, alles malen, nochmals ein pixel, alles malen, nochmals ein pixel, alles malen Mach dir Gedanken wie die Daten zu so einem Bild gespeichert, so ein Bild aufgebaut und ge-refresht wird.
Deepdiver99 schrieb: > Teilweise dauert es einige > Sekunden bis es weiter geht. Dann aber alles auf einmal. Das deutet nicht wie die anderen Schreiber hier irreführenderweise vermuten wollen auf einen CPU-Engpass hin, das deutet eher deutlich auf ein Synchronisationsproblem und verpasste EV_RXCHAR Events, also das was ich bereits weiter oben schrieb. Wie hoch ist Deine CPU-Auslastung (damit ist ruckzuck geklärt wo man weitersuchen muss). Was sagt der Profiler, wo wird die meiste Zeit verbracht? Könnte man vielleicht mal systematisch vorgehen? Wenn Du keinen Sampling-Profiler hast und zu faul bist Dir endlich einen zu installieren dann geht auch poor-man's profiling: Drück im Debugger auf Pause, schau in den Callstack und schreib Dir auf in welcher Funktion (und wenn Du es ganz genau haben willst in welcher Zeile) jeder Thread gerade war. Mach das 10 bis 100 mal, mach ne Strichliste und Du weißt wo welcher Prozentsatz der Zeit verbraten wird.
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.