www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Messwerte per USB auf PC: Geschwindigkeit?


Autor: Borislav Bertoldi (boris_b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Ich habe vor Messwerte vom Mikrocontroller (STM32) über die USB 2.0 
Schnittstelle an den PC zu senden. So weit funktioniert auch alles, aber 
nun versuche die Geschwindigkeit etwas zu erhöhen.

Der Sendecode sieht zur Zeit so aus:

SendByte(b);
b++;
waitMs(1000);

Es werden also zyklisch die Zahlen von 0 bis 255 an den PC gesendet, 
jeweils im Sekundentakt. Empfangen wird das ganze über ein Terminal 
Programm (Stichwort virtueller COM Port).

Wenn ich nun die Sendegeschwindigkeit erhöhe, kann ich bis zu 1ms delay 
runtergehen. Kleinere Werte sorgen dann dafür, dass nicht mehr alle 
Zahlen ankommen (es fehlen zwischendurch einfach welche).

Nun mein Frage:
Woran könnte das liegen? Es kann ja nicht sein, dass ein USB 2.0 nur 
1000 Byte pro Sekunde schafft, oder? Das Ding ist ja eigentlich bis 480 
MBit spezifiziert, wenn ich mich recht erinnere...

Gruß,
Boris

Autor: astroscout (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kenne deinen Mikrocontroller jetzt nicht genau, aber die 450 MBit 
sind lediglich die theoretisch höchste Datenrate, die mit USB 2.0 
erreicht werden kann.
Das heißt jedoch nicht, dass dein Mikrocontroller diese Geschwindigkeit 
auch wirklich erreichen kann!

Mal als Anregung (ich bin mir nicht ganz sicher, ob das geht):
Vielleicht kannst anstatt immer genau eine festgelegte Zeit zu warten, 
solange warten, wie der Mikrocontroller zum übertragen eines Bytes 
benötigt. Evtl. wird bei deinem Mikrocontroller dann ein Flag gesetzt, 
das anzeigt, ob er noch am senden ist. Das müsste man allerdings im 
Datenblatt mal recherchieren.

Autor: Julian O. (juliano)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meines Wissens nach ist es ziemlich unsinnig per USB einzelne Bytes zu 
übertragen. Der STM müsste eigentlich intern einen Buffer haben (512 
Byte?). Es sollte sinnvoller sein erst diesen Buffer zu füllen und dann 
am Stück zu senden

Autor: Borislav Bertoldi (boris_b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber USB ist doch eine serielle Schnittstelle. Da sollte es doch keinen 
unterschied machen, ob die Daten aus dem Buffer seriell weggesendet 
werden, oder ob ich manuell in meiner Schleife seriell sende?

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Boris B. schrieb:
> Woran könnte das liegen? Es kann ja nicht sein, dass ein USB 2.0 nur
> 1000 Byte pro Sekunde schafft, oder? Das Ding ist ja eigentlich bis 480
> MBit spezifiziert, wenn ich mich recht erinnere...
USB 2.0 kann 480MBit. Das heisst aber nicht das das Gerät das auch 
macht. Ich bin zwar kein Experte für die STM32, aber soweit ich weiss 
kann der (wie glaub ich alle Cortex M3) nur Full-Speed, also 12 MBit.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Außerdem ist das Protokoll bei USB paket-orientiert. Wenn du nur ein 
Byte schickst, ist das total ineffizient. Sinnvollerweise sollte man 
einen ganzen Block in der Größe des Endpoint Buffers schicken. Bei USB 
2.0 HighSpeed erreicht man die maximale Geschwindigkeit von etwa 40MB/s 
im BULK Modus nur, wenn man immer die Pakete voll ausnutzt (512 Byte) 
und so schnell anliefern kann, dass der Controller einen Microframe mit 
10 bis 11 vollen Paketen voll packen kann. Bei 10 Paketen zu je 512 Byte 
pro MicroFrame erreicht man 512 x 10 x 8000 = 40960000 Byte/s 
Datendurchsatz. Mit schnellen Controllern wie z.B. dem Cypress FX2 ist 
das zu schaffen. Der FT2232H kann das wohl mit aktuellem Treiber 
mittlerweile auch.

Autor: Nico (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Außerdem ist das Protokoll bei USB paket-orientiert. Wenn du nur ein
>
> Byte schickst, ist das total ineffizient.

Genau so schaut es aus, was du zur Zeit machst ist für jedes einzelne 
Byte ein eigenes Datenpaket zu schnüren mit entsprechendem overhead! Du 
solltest die Größe deines Endpoint-Buffers ausnutzen und dann erst 
senden.

Aber warum verwendest du überhaupt ein Delay? Frage doch die 
entsprechenden Flags ab oder nutze wenn es das gibt entsprechende 
Interrupts, wenn die Buffer wieder frei sind. Damit bist du auch an der 
max. Geschwindigkeit und musst nicht ausprobieren wie weit du mit deinem 
Delay runter kannst.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
USB ist nicht einfach eine serielle Schnittstelle.  USB ist ein Bus mit 
vielen Teilnehmern und einem komplizierten Protokoll, das in 
1-ms-Intervallen abläuft.  Genau diese Intervallfrequenz hast Du soeben 
entdeckt (1 kHz).  In diesem Abstand pollt, vereinfacht gesagt, der 
USB-Host seine Teilnehmer.  Haben die dann nur 1 Byte abzuliefern, wird 
in einem Intervall nur dieses übertragen.

Du hast noch ein Problem:  Du sendest fortlaufende Byte-Werte und 
schreibst, dass bei Überschreitung der 1 kHz welche fehlen.  In diesem 
Fall müsste aber Deine Senderoutine blockieren, bis sie ihr Byte 
losgeworden ist (und so den Durchsatz beschränken).  Dass Werte verloren 
gehen, weil sie zu schnell kommen, darf in einer sauberen Senderoutine 
nicht passieren. Sie muss den Flaschenhals nach hinten durchreichen.

Idealerweise würde die Senderoutine, wenn ein Byte noch nicht abgesendet 
ist und ein neues kommt, das Paket vergrößern.  Kann sie das nicht, muss 
sie blockieren, um Datenverlust wie Deinen zu verhindern.

Autor: Michael K. (michael007)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auf welche Geschwindigkeit hast Du denn überhaupt deinen COM Port 
eingestellt?

Autor: Borislav Bertoldi (boris_b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den vielen Input :-)
Ihr habt da einige wichtige Aspekte aufgezeigt, die mir bisher nicht 
bewusst waren. Ich werde dann mal versuchen zu puffern und größere 
Pakete zu versenden. Warum die Senderoutine nicht blockiert, werde ich 
mir auch mal anschauen.

@Michael:
Der COM-Port steht momentan auf 115200 Baud. Das müsste ja eigentlich 
schnell genug sein... (~14.000 Byte/s?)

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.