Hallo, ich arbeite derzeit an einem Projekt bei dem ich in von einem PC (Linux, low-latency-Kernel) mit bei einem Takt von 1.25 kHz 256 Byte pro Nachricht an einen Mikrocontroller (TI TMS320F28377D) per virtuelle serielle Schnittstelle (USB2-Adapter) schicke. Der Taktgeber ist hierbei eine Industrie-Kamera deren Jitterverhalten ich im Griff habe (avg=0.8 ms, std.dev=60µs). Wenn ich mit 10 Bit rechne komme ich im Schnitt auf eine Datenrate von 3.2 Mbit/s. Laut Doku erreicht der TI bei einer USB2 "High-Speed" Anbindung theoretisch bis zu 12 Mbit/s, d.h. es sollte prinzipiell mit der Hardware möglich sein. Auf der PC-Seite habe ich die serielle Schnittstelle per ttyAMC0 mit Parametern für eine Binärübertragung geöffnet und sende die Daten in einem C-Program mit hoher Prozesspriorität "sudo -E nice -19" jeden Takt in einer per "write(fd,buffer,len)" gefolgt von einem "tcdrain(fd)" alle 1250 Hz raus. Inhaltlich passt die Datenübertragung. Ich habe hierfür in meinen Datenpaketen eine Sequenznummer untergebracht, die der PC hochzählt und die ich auf der Mikrocontroller-Seite prüfe und mit einem Zähler dort abgleiche. Allerdings ist die Performanz schlechter als erwartet. Ich habe auf der PC-Seite ein Histogram über einige Minuten gebildet stelle fest, dass ich im Schnitt ca. 500µs für die Übertragung der 256 Bytes (10 Bit) mit worst-case-Spitzen bis zu 2000 µs erhalte. Beim Average komme ich daher nur auf rund 1 Mbit/s, d.h. mehr als Faktor 3 unter dem, was ich erreichen will. Um den Flaschenhals zu finden, habe ich beide Seiten untersucht. Die Mikrocontroller-Seite sieht gut aus, da ich für das Auslesen und Entpacken der 256 Bytes lediglich 60-70 µs benötige. Ich vermute daher, dass der Sender bzw. die Übertragung auf der PC-Seite den Engpass darstellt. Seht ihr eine Möglichkeit wie ich das Ganze PC-seitig beschleunigen kann? Meine erste Überlegung war, dass ich die Hardware nicht als serielle Schnittstelle fahre, sonder per libusb/bulktransfer anspreche. Seht ihr eine Alternative? Die Datenpakete kann ich leider nicht deutlich vergrößern, da ich low-latency sein will und sie möglichst schnell Zeitnah zum Takt von der PC-Seite versenden möchte. Allgemein frage ich mich, was für eine Übertragungstechnologie für meinen Anwendungsfall low-latency, 1.25 Khz/256 Bytes sinnvoll ist. Ich würde mich freuen, wenn ihr mir mit Anregungen helfen könnt. Vielen Dank und schönen Gruß
Der cdc_acm-Treiber ist für größere Datenraten Schrott. Er erreicht weder die ideale Datenrate noch funktioniert er korrekt; kann sein, dass manche Pakete bei hoher Last einfach aus dem Datenstrom gedropt werden, ohne dass Host oder Device das mitbekommen. Nimm lieber libusb, damit bist du viel flexibler und es ist kein besonders großer Aufwand für so eine einfache Anwendung. Ob du damit deine Specs erreichst, kann ich dir nicht sagen, aber ich würde sagen entweder es geht damit oder die Lösung ist prinzipiell nicht geeignet.
:
Bearbeitet durch User
Bulk endpoints haben kein definiertes Zeitverhalten. Wenn du das brauchst, musst du auf einen isochronen endpoint gehen. Das ist aber mit den üblichen Standard Geräteklassen glaub ich nicht drin.
Timo L. schrieb: > Laut Doku erreicht der TI bei einer USB2 > "High-Speed" Anbindung theoretisch bis zu 12 Mbit/s, d.h. es sollte > prinzipiell mit der Hardware möglich sein. das riecht aber nicht nach HS sondern FS sprich USB1 speed. Damit sind die Bulkpakete jeweils 64 byte. Pro Usb Frame musst du also 5 Pakete übertragen um auf die 256b bei 1.25kHz kommen. Alles im Rahmen. Was ich nicht verstehe wo kommen die 3.2MBit her? weil 256b bei 1.25kHz sind ja gerade mal 320kBit also Faktor 10 weniger. 3.2MBit per serial ist sportlich ich würde sagen 1 MBit ist eher drin. was sich ja wohl mit deinen Ergebnissen deckt. die Serielle Verbindung ist übrigens auch eine Bulk Verbindung. Wie sehen die Deskriptoren aus? Thomas
Alternativ eine PCI(e)-RS422/485-Karte, um Dir die USB-Latenz zu ersparen.
Timo L. schrieb: > Meine erste Überlegung war, dass ich die Hardware nicht als serielle > Schnittstelle fahre, sonder per libusb/bulktransfer anspreche. Das wird rein garnix bringen. CDC-ACM benutzt ja auch schon bulk-Kanäle. > Seht ihr > eine Alternative? Wenn überhaupt, dann isochrone Transfers. Die können eine Bandbreite und eine Latenz garantieren (allerdings keine fehlerfreie Übertragung). Das Problem wird aber (neben der fehlenden Fehlerkontrolle) auch damit sein: die garantierte Latenz ist relativ groß und paßt nicht zu deinen Latenzforderungen. Oder anders ausgedrückt: USB taugt wohl nicht für deinen Zweck.
c-hater schrieb: > Das wird rein garnix bringen. CDC-ACM benutzt ja auch schon bulk-Kanäle. Aber der hostseitige CDC-ACM-Treiber enthält Puffer/FIFOs und die Paketierung lässt sich nicht wirklich kontrollieren. Über ein eigenes USB-Protokoll und libusb kann man genau steuern welche Daten wann in ein Paket verpackt und abgeschickt werden. Damit könnte das schon gehen.
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.