Forum: Mikrocontroller und Digitale Elektronik USB Bulk Transfer Ablauf optimieren


von USBman (Gast)


Lesenswert?

Ich habe eine einfache USB-Konfiguration aus Host und Client (ein FTDI), 
wobei der Client große Datenmengen an den Host per "Bulk Transfer" 
überträgt. Der Bus ist also ansonsten frei und unbelastet.

Ich möchte gerne die Paketgröße optimieren, da ich sie selbst bestimmen 
kann. Laut http://www.beyondlogic.org/usbnutshell/usb4.shtml#Bulk werden 
bei USB 2.0 Full Speed in einem Bulk Transfer entweder 8, 16, 32 oder 
maximal 64 Bytes übertragen.

Und daß eine Datenübertragung fertig ist, scheint wohl signalisiert zu 
werden, indem entweder ein Bulk Transfer mit weniger als 64 Bytes 
gesendet wird, oder falls der Datenblock durch 64 teilbar war ein leerer 
Bulk Transfer.

Außerdem scheint mir, daß die ersten beiden Bytes eines Blocks 
reserviert sind (Wofür?), so daß maximal 62 Bytes übertragen werden 
können.

Meine Überlegung ist nun: Am besten teile ich meine gesamten Daten in 
Pakete zu maximal 30 Bytes auf, denn dann wird jeweils genau ein Bulk 
Transfer durchgeführt und kein zusätzlicher Bulk Transfer ist nötig als 
Endemarkierung.

Oder ich nehme n*62+30, damit eben der letzte Bulk Transfer weniger als 
64 Bytes hat, aber so viele wie möglich.


Sind meine Überlegungen so richtig oder habe ich etwas entscheidendes 
übersehen?

Werden die einzelnen 64-Byte-Bulk-Transfers ohne Lücke hintereinander 
übertragen (solange der Bus ansonsten frei ist)?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

USBman schrieb:

> Ich möchte gerne die Paketgröße optimieren, da ich sie selbst bestimmen
> kann. Laut http://www.beyondlogic.org/usbnutshell/usb4.shtml#Bulk werden
> bei USB 2.0 Full Speed in einem Bulk Transfer entweder 8, 16, 32 oder
> maximal 64 Bytes übertragen.

Wobei „Full Speed“ 12 Mbit/s sind, also das, was es schon in USB 1.1
gab.  USB 2.0 „High Speed“ kann auch 512 Bytes.

Die Angabe „ein FTDI“ ist dahingehend nicht eindeutig, es gibt von
FTDI sowohl Klassiker mit Full Speed, aber auch High-Speed-Devices.

> Außerdem scheint mir, daß die ersten beiden Bytes eines Blocks
> reserviert sind (Wofür?), so daß maximal 62 Bytes übertragen werden
> können.

FTDI-typisch wird in den ersten beiden Bytes eines IN-Pakets immer
der Modem-/Leitungsstatus übertragen.

> Werden die einzelnen 64-Byte-Bulk-Transfers ohne Lücke hintereinander
> übertragen (solange der Bus ansonsten frei ist)?

Soweit ich weiß schon.  Insofern tust du dir keinen Gefallen, große
Datenblöcke zu klein zu zersplittern, denn für jeden neuen Transfer
musst du dann meines Wissens auf den Beginn eines neuen Frames warten,
die bei Full Speed im Raster von 1 ms gestartet werden.

von USBman (Gast)


Lesenswert?

Vielen Dank für die Antworten, Jörg. Es ist ein FTDI mit „Full Speed“, 
insofern ist hier 64 Bytes wirklich das Maximum pro Bulk Transfer und da 
der FTDI immer die 2 Bytes ergänzt, sogar nur 62 Bytes.

Jörg W. schrieb:
> Soweit ich weiß schon.  Insofern tust du dir keinen Gefallen, große
> Datenblöcke zu klein zu zersplittern, denn für jeden neuen Transfer
> musst du dann meines Wissens auf den Beginn eines neuen Frames warten,
> die bei Full Speed im Raster von 1 ms gestartet werden.

Oh je. Das gibt einen völlig neuen Aspekt!

Pro ms gibt es ein theoretisches Maximum: 12000Bit/ms=1500Bytes/ms

Ein Bulk Transfer hat noch Overhead (einerseits den Handshake beim Start 
und andererseits pro Block mindestens die CSC16). Aber wieviel ist es 
genau?

Dann könnte ich nämlich rechnen: 1500Bytes/(64+Overhead (min. 2))=22

Daraus würde folgen, daß ein Datenblock theoretisch maximal 21*62+30 = 
1332Bytes groß sein sollte, wenn der nächste Datenblock gleich beim 
nächsten Frame übertragen werden soll.

Aber ich habe gelesen, daß man selbst beim freiem USB Bus real keine 22 
Bulk Transfers pro ms bekommt, da er wohl einen Teil für Retries und 
Sonstiges freihält. Wieviel kann man also real bekommen?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

USBman schrieb:
> Wieviel kann man also real bekommen?

Das kannst du wohl nur messen.

von USBman (Gast)


Lesenswert?

Jörg W. schrieb:
> USBman schrieb:
>> Wieviel kann man also real bekommen?
>
> Das kannst du wohl nur messen.

Das hängt ja davon ab,

1) wie groß der Overhead pro Bulk Transfer ist,

2) wie groß der Overhead beim Initialisieren eines neuen Transfers ist 
und

3) wie Bandbreite für Retries und Sonstiges freigehalten wird.

Gibt es hierzu Dokumentation? Oder weiß jemand diese Zahlen?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Pump doch einfach mal einen Sack voller Daten rüber und miss, wie lange
sie brauchen.

von USBman (Gast)


Lesenswert?

Das könnte ich machen, aber ich möchte das Ganze theoretisch voll 
durchsteigen.

von Thomas (Gast)


Lesenswert?

Dafür gibt es die spec auf USB.org.
Generell 10% der Bandbreite ist reserviert für Control Transfers
Wenn ich mich richtig erinnere ist der Max payload 9 Bulk Transfers bei 
1.1
Aus Anwendersicht schickst du einfach deinen kompletten Buffer in einem 
Rutsch
Der Rest macht der USB Stack. Der ist dafür zuständig die Pakete passend 
aufzuteilen.
Thomas

von Jim M. (turboj)


Lesenswert?

USBman schrieb:
> Ich habe eine einfache USB-Konfiguration aus Host und Client (ein FTDI),
> wobei der Client große Datenmengen an den Host per "Bulk Transfer"
> überträgt. Der Bus ist also ansonsten frei und unbelastet.

Nur die "Großen" FTDIs mit H Suffix können soviele Daten überhaupt 
aufnehmen, dass man einen USB Full Speed Bus ernsthaft belasten kann. 
Die laufen aber auch mit High Speed!

Die kleinen haben IIRC nur ein 6 MHz Quarz oder entsprechenden 
Oszillator. Da kommen selbst mit MPSSE nicht genug Daten zusammen. 
Außerdem haben die FTDIs selbstverständlich FIFOs eingebaut, was..

> Ich möchte gerne die Paketgröße optimieren, [...]

..zuverlässig verhindert.

Mit USB Bulk Transfers muss man sich nur dann rumschlagen, wenn man auch 
einen µC mit eingebauter USB Hardware verwendet.

von USBman (Gast)


Lesenswert?

Thomas schrieb:
> Aus Anwendersicht schickst du einfach deinen kompletten Buffer in einem
> Rutsch
> Der Rest macht der USB Stack. Der ist dafür zuständig die Pakete passend
> aufzuteilen.

Ich möchte so gut an Echtzeit herankommen, wie es mit Bulk Transfer 
geht. Deswegen wollte ich meine Daten zuvor in kleinere Happen 
aufteilen, ohne den Bus zu überschätzen.


Wenn z.B. jede ms 93 Bytes entstehen und ich "schicke das in einem 
Rutsch" per FTDI, dann würden daraus jede ms drei Bulk Transfers werden: 
62+31+0

Ich könnte aber auch alle 2ms 186 Bytes schicken, dann hätte ich 
62+62+62+0 also vier Bulk Transfers. Ergo 33% gespaart.


Jim M. schrieb:
> Nur die "Großen" FTDIs mit H Suffix können soviele Daten überhaupt
> aufnehmen, dass man einen USB Full Speed Bus ernsthaft belasten kann.

Hier http://www.ftdichip.com/FT-X.htm gibt es auch einige, die bis zu 
1MByte/s übertragen können.


Jim M. schrieb:
> Außerdem haben die FTDIs selbstverständlich FIFOs eingebaut, was..
>> Ich möchte gerne die Paketgröße optimieren, [...]
> ..zuverlässig verhindert.

Man kann z.B. den Time-Out konfigurieren, wann ein Bulk Transfer 
gestartet wird.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

USBman schrieb:
> Deswegen wollte ich meine Daten zuvor in kleinere Happen aufteilen, ohne
> den Bus zu überschätzen.

Egal, was du tust: es wird langsamer werden, als wenn du es gleich
dem FTDI überlässt.

von Thomas (Gast)


Lesenswert?

Du kannst den Bus nicht überschätzen. Deine Überlegungen sind falsch.
Die Aufteilung macht sowieso der USB Stack bzw in deinem Fall der ftdi 
Treiber.
Da hast du keinen Einfluss. Im Gegenteil short Pakets bremsen den Bus.
Die Packet Größe wird im deskriptor festgelegt die ist fix. Alle 
Transfers die kleiner als diese Paket size sind sind per def. short 
Pakets und stoppen den Transfer.
Bei einem freien Bus kannst du max 9 64Byte pro ms auf die Reise 
schicken.
Das entspricht in etwa 500 kbytes pro sec und ist das was unter 
optimalen Bedingungen unter 1.1 möglich ist. Du kannst die spec nicht 
überlisten.
Echtzeit und Bulk ist übrigens ein Widerspruch in sich. Für Echtzeit ist 
ISO vorgesehen. Du musst dein Konzept überdenken.
Thomas

von USBman (Gast)


Lesenswert?

Thomas schrieb:
> Bei einem freien Bus kannst du max 9 64Byte pro ms auf die Reise
> schicken.
> Das entspricht in etwa 500 kbytes pro sec und ist das was unter
> optimalen Bedingungen unter 1.1 möglich ist.

Ich habe Benchmarks unter "Full Speed" gesehen, wo bis 1MByte/s 
übertragen wurde, also 16 Bulk Transfers/ms.

Das liegt noch deutlich unter dem einzigen Wert, den ich finden konnte, 
daß bei Bulk Transfer die tatsächliche Datenrate bis an 88.74% der 
nominellen Rate (12MBit/s) heranreichen kann, also 1331Bytes/ms.

Und letztere Zahl deckt sich wiederum wunderbar mit der von mir oben 
berechneten.


Thomas schrieb:
> Die Aufteilung macht sowieso der USB Stack bzw in deinem Fall der ftdi
> Treiber.

Mein eigener Treiber läuft, daher kann ich auf der untersten Ebene 
eingreifen.


Thomas schrieb:
> Die Packet Größe wird im deskriptor festgelegt die ist fix.

Hm, sie ist wie in meinem Anfangspost geschrieben entweder 8, 16, 32 
oder
maximal 64 Bytes. Vielleicht denkst Du an etwas anderes?


Thomas schrieb:
> Echtzeit und Bulk ist übrigens ein Widerspruch in sich. Für Echtzeit ist
> ISO vorgesehen.

Hierzu hatte ich schon geschrieben, daß außer einem Host und einem 
Client es keine weiteren Geräte gibt, der Bus also ansonsten unbenutzt 
ist. Unter solchen Bedingungen kann ich sehr wohl so etwas wie 
"Echtzeit" erreichen, wenn ich weniger als 20ms Latenz ansetze.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

USBman schrieb:
> Das liegt noch deutlich unter dem einzigen Wert, den ich finden konnte,
> daß bei Bulk Transfer die tatsächliche Datenrate bis an 88.74% der
> nominellen Rate (12MBit/s) heranreichen kann, also 1331Bytes/ms.

Wo findest du diesen Wert?

Ich finde im USB-Standard 1216 Bytes/ms.  Das ist aber eher ein
theoretisches Maximum denn ein praktisch irgendwie erreichter Wert.

Natürlich ist das mit einer Endpoint-Größe von 64 Bytes.  Ich verstehe
gar nicht, warum du, wenn es dir auf Datendurchsatz ankommst, die
kleineren potenziell in Frage kommenden Werte immer wieder vorkramst,
es ist doch sonnenklar, dass es damit nur schlechter werden kann (und
die Tabelle im Standard zeigt das auch deutlich).

von USBman (Gast)


Lesenswert?

Jörg W. schrieb:
> Ich verstehe
> gar nicht, warum du, wenn es dir auf Datendurchsatz ankommst, die
> kleineren potenziell in Frage kommenden Werte immer wieder vorkramst

Sorry, das lasse ich besser mal.


Jörg W. schrieb:
> (und die Tabelle im Standard zeigt das auch deutlich)

Welche Tabelle? Ich habe z.B. die "Universal Serial Bus Specification" 
Revision 2.0 vom 22. April 2000 hier.


Jörg W. schrieb:
> Wo findest du diesen Wert?

https://de.wikipedia.org/wiki/Universal_Serial_Bus#Datenraten
und dann 6. Anmerkung unter der Tabelle

von Thomas (Gast)


Lesenswert?

Nun dann mach das einfach. Ist ja so einfach. Zeige mir das Design was 
über einen Endpoint mehr als 9 Transfers unter FS macht.
Ich kann dir nur empfehlen die USB spec zu lesen. Dort sind diese Dinge 
beschrieben.
Erreichst du mi deinem Treiber überhaupt die 500 kbytes pro sec? Der 
Demo Bulk Treiber im winddk schaffe diese jedenfalls gerade so......
USB 1.1 bedeutet 12 Mbit am root Hub der damals 2 Ports hatte ergo 6Mbit 
pro Port.
Daraus ergeben sich die 500kbytes wenn man den Overhead abzieht. Dies 
ist genau das was die USB 1.1 spec beschreibt.
Unter 2.0 ist das etwas anderes nur bringt dir das nichts da deine 
Transfers von usbd.sys nach 1.1 abgewickelt werden.

Ich verstehe nicht warum du die spec ignorieren willst. Oder wird das so 
ein Device was manchmal funktioniert. Von dehnen gab es viele und diese 
haben anfangs zum schlechten Ruf von USB beigetragen.

Thomas

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

USBman schrieb:
> Welche Tabelle?

5-9, Seite 54

: Bearbeitet durch Moderator
von USBman (Gast)


Lesenswert?

Jörg W. schrieb:
> USBman schrieb:
>> Welche Tabelle?
>
> 5-9, Seite 54

Ja, danke! Die Tabelle liefert genau die Antwort auf meine obige Frage:

USBman schrieb:
> Aber ich habe gelesen, daß man selbst beim freiem USB Bus real keine 22
> Bulk Transfers pro ms bekommt, da er wohl einen Teil für Retries und
> Sonstiges freihält. Wieviel kann man also real bekommen?

19 64-Byte Bulk Transfers sind also pro ms maximal möglich (19*64=1216 
Bytes).

Dort ist auch der gesamte Overhead angedeutet. Wunderbar.

17 wurden in den von mir genannten Benchmarks real erreicht.


Thomas schrieb:
> Erreichst du mi deinem Treiber überhaupt die 500 kbytes pro sec? Der
> Demo Bulk Treiber im winddk schaffe diese jedenfalls gerade so......
> USB 1.1 bedeutet 12 Mbit am root Hub der damals 2 Ports hatte ergo 6Mbit
> pro Port.

Von Windows habe ich nichts gesagt. Und hier geht es um USB 2.0, nicht 
1.1 da mußt Du mal ein bischen die Doku lesen, um den Unterschied zu 
verstehen. Wenn ich "Full Speed" USB 2.0 schreibe, ist alles gesagt.

Ein guter Host mit mehreren Ports teilt seine Bandbreite nicht durch die 
Anzahl der Ports, sondern liefert dem Port, der Bandbreite braucht, so 
viel wie gefordert und möglich. Bei nur einem benutzen Port dann eben 
bis zu 12MBit. Du redest da über irgendeinen Sonderfall von Anno 
Dazumal. Warum muß denn jede ernstgemeinte Frage hier immer torpediert 
werden?

Meine Hard- und Software läuft schon seit Monaten an verschiedenen 
Geräten, jetzt wollte ich die gefundenen Grenzen theoretisch 
hinterfragen, weil ich die Dinge gerne durch und durch verstehe.

von USBman (Gast)


Lesenswert?

USBman schrieb:
> Jörg W. schrieb:
>> Wo findest du diesen Wert?
>
> https://de.wikipedia.org/wiki/Universal_Serial_Bus#Datenraten
> und dann 6. Anmerkung unter der Tabelle

Der Wert 88.74% stammte auch aus Tabelle 5-10 auf S.55 (512*13/7500) und 
ist daher nur für High Speed gültig. Für Full Speed, wie Du, Jörg 
richtig sagst, die Tabelle 5-9 und damit 64*19/1500 = 81%.

Das könnte man in der wikipedia-Fußnote natürlich mal präzisieren.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

USBman schrieb:
> Das könnte man in der wikipedia-Fußnote natürlich mal präzisieren.

Mach doch: genau dafür ist das doch ein Wiki.

von USBman (Gast)


Lesenswert?

Noch eine Ergänzung:

Der Unterschied von 88.7% zu 81% (=7.7%) wird fast vollständig durch den 
Anteil an Overhead-Bytes pro Bulk Transfer erklärt, der zwischen Full 
und High Speed besteht:

High Speed: 512/(512+55) = 90.3%

Full Speed: 64/(64+13) = 83.1%

=7.2%

von USBman (Gast)


Lesenswert?

Jörg, Jim und auch Thomas, vielen Dank für die Gedankenanstöße. Mir hat 
die Diskussion hier viel geholfen und ich bin jetzt schlauer als am 
Anfang.

von Jim M. (turboj)


Lesenswert?

Thomas schrieb:
> Erreichst du mi deinem Treiber überhaupt die 500 kbytes pro sec? Der
> Demo Bulk Treiber im winddk schaffe diese jedenfalls gerade so......
> USB 1.1 bedeutet 12 Mbit am root Hub der damals 2 Ports hatte ergo 6Mbit
> pro Port.
> Daraus ergeben sich die 500kbytes wenn man den Overhead abzieht. Dies
> ist genau das was die USB 1.1 spec beschreibt.

Nö. Schreibt sie nicht. Da wird übrigens nix aufgeteilt, solange da 
nicht zufällig 2 Devices den Bus zugleich auslasten.

Deine 500 kBit/s kommen von zu schwachem USB Gerät oder hirntotem 
Windoof Programmierer. M$ ist mal nicht schuld, die 1MBit/s erreicht 
deren Mass storage Treiber.

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
Noch kein Account? Hier anmelden.