Hallo miteinander Momentan arbeite ich gerade an einer USB-Kommunikation. Das ganze ist in ein Frame verpackt und wird über den FTD2xx Treiber angesprochen Jetzt habe ich das Problem, dass in einer while-Schlaufe das Frame gesendet wird (Kommunkikation läuft in einem BackgroundWorker). 5kBytes als Nutzdaten werden innerhalb von ~20 Milisekunden beim MCU empfangen, ausgewertet und verarbeitet. Das ganze Protokoll, welches aus ENQ, SOH, Command, NUM + PAR, ACK, ACK EOT besteht, benötigt aber > 50ms?! 6 zusätzliche Bytes benötigen solange wie 7kByte? Hat jemand schon mal etwas ähnliches Erlebt, und weiss, wie ich es beheben kann? Besten Dank für die Hilfe MFG Patrick
Könnte an der niedrigen Priorisierung von USB Trabnsfers im OS liegen. Wir haben hier auch USB 2.0 HighSpeed Geräte, da macht Windows selbst bei kontinuierlichem Streaming immer mal Pausen von bis zu 50ms zwischen Transfers. Ist zwar relativ selten, tritt aber sporadisch auf. Auch manchmal, wenn gar nix anderes läuft und die Prozessorlast gegen 0 geht.
schon mal an die ganzen Puffer im Windows-Treiber gedacht? Wenn du nur 1 Byte verschickst wartet der Treiber sicherlich mit dem verschicken bis noch mehr Daten kommen bzw. bis ein Timer abgelaufen ist... Vielleicht kannst du Padding hinzufügen, damit schneller gesendet wird? Musst du halt am Mikrocontroller ausfiltern...
ein_unwissender schrieb: > bzw. bis ein Timer abgelaufen > ist... In etwa so ist das auch mit dem Timeout gedacht. Dieses habe ich aber auf 0 zurückgedreht. Jetzt erreiche ich immerhin schon konstant eine Übertragungsgeschwindigkeit, die etwa 1/7 der Entgeschwindigkeit ist. Wie könnte man die Priorität eines Programmes respektive des USB erhöhen, damit diese Operationen Zeitlich gesehen "genau" dann ablaufen, wann ich es will, und nicht, wann windows es möchte (Ich weiss, dass das jetzt nicht zusammenpasst, aber ich denke auch im MCU styl). Besten Dank für die Hilfe MFG Patrick
>Wie könnte man die Priorität eines Programmes respektive des USB >erhöhen, damit diese Operationen Zeitlich gesehen "genau" dann ablaufen, >wann ich es will, und nicht, wann windows es möchte (Ich weiss, dass das >jetzt nicht zusammenpasst, aber ich denke auch im MCU styl). Das kannst du nicht. USB ist nicht Echtzeit tauglich.
> ENQ, SOH, Command, NUM + PAR, ACK, ACK EOT
Ich versteh nicht ganz wann da jetzt wer was sendet und Ack't, aber
generell gelten zwei Sachen:
- die Treiber der seriellen Schnittstelle, sowie insbesondere der USB
sind darauf optimiert mit hoher Datenrate relativ grosse Pakete zu
uebertragen (Serielle Schnittstelle fuer Modems)
- die Latenzen sind dagegen ziemlich hoch. Ein einzelner Transfer bspw
an die serielle Schnittstelle macht ne ganze Menge mit Events zum
Treiber. Dh da muessen Threads vom Scheduler aufgeweckt werden usw.
Allein die zeitliche Stueckelung mit der der Scheduler arbeitet liegt in
der Groessenordnung von 10ms. Und alles das fuer ein Byte Acknowledge
ist halt sehr ineffizient.
Also am Besten:
- moeglichst grosse Pakete uebertragen
- dein Protokoll auf moeglichst wenig "Hin- und Her" (zB Acks)
optimieren
So die grobe Aussage ;)
Der Trick bei USB heisst: Queueing Also, wenn Du ein Protokoll auf der anderen Seite laufen hast, welches viel Pingpong oder sogar (quasi-) vollduplex arbeitet, kriegst du mit folgender Strategie hohe Durchsaetze: Alles was zunaechst zu schreiben ist, schreiben, dann einen grossen Block lesen, und alle ACKs, etc. verarbeiten. Der FTDI-Chip puffert ja ein paar Byte in seinem FIFO ab, solange du das nicht volllaufen laesst, ist gut. Wenn das Protokoll allerdings so gestrickt wird, dass erst nach einer gewisen Zeit nach dem ACK wieder Daten geschickt werden duerfen, gehts so nicht, und du solltest dir ein besseres Protokoll ueberlegen. Gruesse, - Strubi
Also ich habe heute gerade mit dem FT2232H von FTDI 32MByte pro Sekunde erreicht. Das ist schon ganz ok. Ich habe mit 65k Byte großen Blöcken gearbeitet, damit der Overhead möglichst klein ist. Jedoch verwendet FTDI nur 512 Bytes große Endpoints und dann auch nur 2 davon obwohl die 4kByte im Chip besitzen. Zu Christian R. Ich habe auch mal die TXE Leitung untersucht. Bei mir sind bis jetzt noch keine längeren Pausen als 600µS vorgekommen. Ich habe den FTDI Chip an einem Notebook und einen Deshtop PC angeschlossen. Beide haben keinen Unterschied angezeigt. Zudem teste ich es gerade unter Vista 64 Bit.
>Jedoch verwendet FTDI nur 512 Bytes große Endpoints und dann auch nur 2 >davon
obwohl die 4kByte im Chip besitzen.
Im HS-Modus kann ein Bulk EP nur maximal 512 Bytes haben, da kann FTDI
nichts dafür ;-)
Zwei EPs (einer IN einer OUT) reichen vollkommen aus um aktuelle
Host-Controller auszulasten. Wichtig ist hierbei möglichst große Puffer
zu verwenden (64KB sind eher schon das Minimum) und immer mehrere
I/O-Operationen ausführen um den Host-Controller zu beschäftigen.
Leider ist die FTD2XX-API was das betrifft sehr eingeschränkt und noch
eher auf die FS-Devices ausgerichtet.
Strubi schrieb: > Wenn das Protokoll allerdings so gestrickt wird, dass erst nach einer > gewisen Zeit nach dem ACK wieder Daten geschickt werden duerfen, gehts > so nicht, und du solltest dir ein besseres Protokoll ueberlegen. Hmmm... OK, bei einem Streaming MUSS zwingend eine Anfrage kommen, und dann die Daten. Ich habe auch schon an grössere Datenmengen gedacht, aber da steht mir der MCU (dsPIC30F6012A mit 8k RAM) im Weg. Momentan läuft es so, dass ich sobald beim Ring-Buffer die Hälfte der Werte abgearbeitet sind, ein ENQ and den PC schicke, damit dieser mir wieder neu 2.4kByte schickt, um die "verbrauchte" Hälfte zu erneuern. Dazu kommt, dass ich nicht das ganze RAM nutzen kann: Fette Arrays mit 800 Plätzen (2 mal 16Bit und 3 mal 8Bit) ist das Maximum was ich erreiche, befor der Compiler meckert, dass er den restlichen Speicher nicht allocieren kann. So gehen mir ~25% verloren, da ich diesen nicht Nutzen kann. Ich könnte es so anpassen, dass ich vom MCU ein ENQ erhalte, und dann ohne weitere Steuerbytes leich die 2.4kByte schende. Strubi schrieb: > Alles was zunaechst zu schreiben ist, schreiben, dann einen grossen > Block lesen, und alle ACKs, etc. verarbeiten. Und was würde passieren, falls eine der Parteien plötzlich ein Fehler registriert oder sonst irgend etwas hat? Das geschrieben wäre weg.... Johann schrieb: > Ich habe auch mal die TXE Leitung untersucht. Bei mir sind bis jetzt > noch keine längeren Pausen als 600µS vorgekommen. TXE kommt bei mir nicht vor, da ich einen FT245 verwende. Das Auswerten übernimmt ein 16Bit MCU mit 128MHz... zudem wird die entsprechende Funktion in einer for-Schleife gleich ein paar mal abgearbeitet, damit dieses möglichst flott geht. Mit dem KO habe ich mal versucht, ein wenig die Zeiten zu messen: der PC erhält ein ENQ, danach startet er das Frame mit einem ENQ für den MCU. dieser bestätigt die Empfangsbereitschaft mit einem ACK. Danach werden 2.4kBytes vom PC versendet. Zwischen dem 2. ENQ und dem grossen Block, vergehen zwischen 380us bis 4ms. Duchrschnittlich wären es etwa 1.1ms. Durch diese Verzögerung kann ich auch nicht die Stream-Menge verdoppeln auf die ganze Puffer-Grösse, da ich dann eine Verzögerung der Daten von bis zu 4ms erhalte. Dies darf aber nicht sein. der MCU muss kontinuierlich Daten zur Verfügung haben. Besten Dank für die Hilfe. MFG Patrick
Strubi schrieb: > Alles was zunaechst zu schreiben ist, schreiben, dann einen grossen > Block lesen, und alle ACKs, etc. verarbeiten. Diesen Rat habe ich beherzigt und jetzt die Frame-Zeit so auf ca 8ms verkleinert. Dies reicht locker da der MCU dies Datenmenge in etwa 14ms verarbeitet hat. Somit hat der USB Treiber eine kleine Pause von ~5-6ms. MFG Patrick
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.