Hallo allerseits, bin gerade dabei mich in die USB-Kommunikation einzuarbeiten, zwischen einem Mikrocontroller STM32F103 und dem PC, dort mit LibUSB. Ich bin auch schon so weit, dass ich Pakete zu und von einem Control-Endpoint und Bulk-Endpoint übertragen kann. Noch nicht ganz klar ist mir allerdings, wie ich die Endpoints geschickt für meine Anwendung nutze. Der Mikrocontroller soll als Datenlogger funktionieren, geloggte Daten dann per USB an den Computer übertragen werden und auch eine Konfiguration von PC-Seite aus soll möglich sein (Kanäle, Logging-Intervall, Dauer...). Ich denke für die Konfigurationen und Statusabfragen benutze ich einfach einen Control-Endpoint (DefaultCEP?) und verwende dann unterschiedliche Werte in bRequest z.B. je nach Datentyp und übertrage die Werte in wValue oder in einem Datenblock. Wie gehe ich dann aber bei größeren Datenmengen vor, also bspw wenn ich die geloggten Daten übertragen möchte, der Bulk-Transfer hat ja keine "Parameter" wie bRequest, wValue usw? Schickt man vorher eine Anfrage an einen Control-Endpoint, der die Bulk-Übertragung vorbereitet? Oder bastelt man sich das im Bulk-Packet z.B. am Anfang der Daten selber zusammen? Über Control-Endpoints lassen sich ja auch Datenblöcke übertragen, warum dann überhaupt noch Bulk-Endpoints? Vielen dank schonmal!
:
Bearbeitet durch User
Wie man ein eigenes USB-Gerät konkret anspricht ist doch nicht Teil der Spezifikation?
Sinnvollerweise spricht dein Gerät das Protokoll einer gut definierten Geräteklasse wie CDC oder Speicherstick. Dann sind Treiber auf verschiedenen Plattformen bereits vorhanden.
Florian L. schrieb: > Sinnvollerweise spricht dein Gerät das Protokoll einer gut definierten > Geräteklasse wie CDC oder Speicherstick. Letzteres wäre "Mass Storage Class" (MSC). Ist aber erstens nicht ganz trivial, denn als Protokoll darüber muss man einen nennenswerten Teil der SCSI-Spezifikation implementieren, außerdem ist sowas nur für statische Daten gut. Der Grund ist: ein Host, der ein MSC einbindet, hat über den Speicher die volle Kontrolle und darf beispielsweise beliebig Daten im Cache behalten. Dass sich die Daten "unter seinen Füßen" dynamisch ändern (wie es bei Logdaten typisch der Fall wäre), ist dabei nicht vorgesehen. Angesichts der Aufgabenstellung klingt mir CDC (Communication Device Class) durchaus auch angebracht, zumal mittlerweile nun endlich sogar Windows damit "aus der Dose raus" klar kommt und einen Klassentreiber hat. Je nach Anwendungsfall kann man die Daten dabei auch komplett in ASCII austauschen und dann auf dem Host für die Tests ein normales Terminalprogramm benutzen. Da CDC früher bei Windows nicht als Klassentreiber ohne weiteres vorhanden war, sind viele Leute auch auf ein Human Interface Device (HID) ausgewichen. Es ist zwar völlig widersinnig, was dabei alles zu einem "Human Interface" wurde (beispielsweise sind die Programmiergeräte für ARM Cortex-M so standardisiert), aber dafür brauchte man eben keine extra Treiber. Der Control Endpoint ist nur für die Steuerung da, nicht für den eigentlichen Datenaustausch. Er ist der einzige, der in beiden Richtungen benutzt werden kann, und für die einzelnen Klassen hat er recht genau spezifizierte Steuersequenzen, die man implementieren muss.
Maxe schrieb: > Über Control-Endpoints lassen sich ja auch Datenblöcke übertragen, warum > dann überhaupt noch Bulk-Endpoints? Wegen der Geschwindigkeit. Für Control Transfers sind 10% der Bandbreite (1.2 MBit max) bei Full Speed vorgesehen. Selbst 0 Bytes Nutzdaten besteht ein Control Transfer aus einem 8 Byte Setup Paket (out) + Status (in) + Overhead. Trotzdem kann man mit Control Only Devices einiges machen. Ich habe damit z.B schon FW Updates realisiert. Wenn du mit Bulk Transfers arbeiten willst musst du das ein Protokoll implementieren. Max Durchsatz erreichst du wenn du immer volle 64 Bytes überträgst. Jeder Short Transfer verlangsamt die Sache. Unter optimalen Bedingungen erreicht man etwa 13 Bulk Transfers pro Frame. Das dürfte aber mit dem F103 nur schwer machbar sein. (Double Buffer?) Welches Protokoll du bei Bulk verwendest liegt an dir. Du kannst ja mal das MSC Bulk only Protokoll anschauen oder die USB Midi Kodierung anschauen.
:
Bearbeitet durch User
Hier scheint ein Controller mit USB vorgegeben zu sein. Um einfach etwas zu loggen moeglicherweise ueberzogen. Allenfalls ist ein USB-UART etwas einfacher. Denn es ist ja nicht nur die Controllerseite, sondern auch die PC Seite. Man muss isch nur um das Protokoll kuemmern, der USB Teil ist schon da. Allenfalls gibt's schon eine UART Impmenentation fuer den F103 Bei einem USB UART sind die Treiber schon Teil des Betreibssystems. Bei der gezeigten Loesung noch nicht. Soweit mir bekannt, muss man mit etwas Pech bei jedem neuen Windows Anpassungen am Treiber vornehmen. War aber trotzdem interessant von der unterliegenden Struktur zu hoeren.
:
Bearbeitet durch User
Purzel H. schrieb: > Bei einem USB UART sind die Treiber schon Teil des Betreibssystems. Bei > der gezeigten Loesung noch nicht. Wenn er ein CDC implementiert, dann ist der Klassentreiber mittlerweile (seit Windows 10) mittlerweile sogar in Windows angekommen – alle anderen Betriebssysteme konnten das schon 10 Jahre früher "aus der Dose raus". Ist also eher kein Argument. Beispiele für CDC sollte es für die STM auch geben, das muss man sich also nicht komplett neu von den Hacken ablaufen. Irgendwelche privaten Protokolle ("vendor specific") würde ich allerdings auch nicht implementieren, wenn es nicht unbedingt sein muss. Da der TE etwas von erfolgreichen Experimenten mit libusb schreibt, vermute ich, dass er gar kein Windows hat. Damit wäre das Treiberargument eh hinfällig, selbst für private Protokolle.
Danke für die Antworten! Florian L. schrieb: > Sinnvollerweise spricht dein Gerät das Protokoll einer gut definierten > Geräteklasse wie CDC oder Speicherstick. Jörg W. schrieb: > Angesichts der Aufgabenstellung klingt mir CDC (Communication Device > Class) durchaus auch angebracht,[...] So wie ich das verstehe stellt die CDC-Klasse nur eine paket- oder byteweise Punkt-zu-Punkt-Verbindung dar, ich müsste also wieder eine Kommunikationsschicht drüberbauen. Da würde ich dann lieber direkt in USB etwas eigenes machen und die Setup-Daten bei der Übertragung nutzen. Florian L. schrieb: > Dann sind Treiber auf > verschiedenen Plattformen bereits vorhanden. Es scheint, dass LibUSB-Treiber bei aktuellen Systemn auch vorhanden sind (WinUSB unter Windows). Unterstützt wohl nicht alles, was unter USB möglich wäre, hier aber ausreichend. Jörg W. schrieb: > Der Control Endpoint ist nur für die Steuerung da, nicht für den > eigentlichen Datenaustausch. Er ist der einzige, der in beiden > Richtungen benutzt werden kann, und für die einzelnen Klassen hat er > recht genau spezifizierte Steuersequenzen, die man implementieren muss. Du meinst den Default Control Endpoint? Bei meinen Versuchen haben auch andere Endpoints in beide Richtungen funktioniert, vielleicht habe ich dich aber auch falsch verstanden. Was die Klassen angeht, würde ich ja keine vorgegebene verwenden, sondern für bDeviceClass den Wert 0xFF wählen, also eine 'eigene' Klasse. Thomas Z. schrieb: > Maxe schrieb: >> Über Control-Endpoints lassen sich ja auch Datenblöcke übertragen, warum >> dann überhaupt noch Bulk-Endpoints? > > Wegen der Geschwindigkeit. Für Control Transfers sind 10% der Bandbreite > (1.2 MBit max) bei Full Speed vorgesehen. Selbst 0 Bytes Nutzdaten > besteht ein Control Transfer aus einem 8 Byte Setup Paket (out) + > Status (in) + Overhead. Trotzdem kann man mit Control Only Devices > einiges machen. Ich habe damit z.B schon FW Updates realisiert. > > Wenn du mit Bulk Transfers arbeiten willst musst du das ein Protokoll > implementieren. Bereitet man den Bulk-Transfer dann sinnvollerweise mit einem Control-Transfer vor, also überträgt darüber bspw. die 'Bedeutung' des nachfolgenden Bulk-Transfers und die Menge der Daten? Oder baut man das eher in das Bulk-Paket direkt mit ein? Ich denke beides sollte prinzipiell gehen. > Welches Protokoll du bei Bulk verwendest liegt an dir. Du kannst ja mal > das MSC Bulk only Protokoll anschauen oder die USB Midi Kodierung > anschauen. OK, ich schau mir das mal an. "Bulk only" heißt dann vermutlich, dass dort kein Control-Endpoint für die Metadaten der Bulk-Transfers verwendet wird? > Max Durchsatz erreichst du wenn du immer volle 64 Bytes > überträgst. Jeder Short Transfer verlangsamt die Sache. Unter optimalen > Bedingungen erreicht man etwa 13 Bulk Transfers pro Frame. Das dürfte > aber mit dem F103 nur schwer machbar sein. (Double Buffer?) Die Geschwindigkeit spielt am Schluss wahrscheinlich auch nicht die große Rolle, schneller wie eine Serielle soll es aber schon sein. Purzel H. schrieb: > Hier scheint ein Controller mit USB vorgegeben zu sein. Um einfach etwas > zu loggen moeglicherweise ueberzogen. Allenfalls ist ein USB-UART etwas > einfacher. Klar, das wäre einfacher, aber hier gehts ja speziell um USB.
Jörg W. schrieb: > Wenn er ein CDC implementiert, dann ist der Klassentreiber mittlerweile > (seit Windows 10) mittlerweile sogar in Windows angekommen Der Klassentreiber ist in Windows auch schon immer* enthalten gewesen, nur aus irgendwelchen komplett hirntoten Gründen brauchte man zur Nutzung eine zum jeweiligen Gerät passende *.inf-Datei, die bei den letzten paar Windows-Generationen auch noch mit einer *.cat-Datei signiert sein musste, was einem das Selbsterstellen verunmöglichte. Aus der langen Liste der strunzdebilen Fehlentscheidungen im Hause Microsoft war das eine besonders erfreuliche. Wie gesagt, der eigentliche Treiber ist schon immer vorhanden gewesen (usbser.sys) *) genauer: Seit Windows 2000.
Maxe schrieb: > Jörg W. schrieb: >> Angesichts der Aufgabenstellung klingt mir CDC (Communication Device >> Class) durchaus auch angebracht,[...] > > So wie ich das verstehe stellt die CDC-Klasse nur eine paket- oder > byteweise Punkt-zu-Punkt-Verbindung dar, ich müsste also wieder eine > Kommunikationsschicht drüberbauen. Serialisierer gibt's wie Sand am Meer. > Da würde ich dann lieber direkt in > USB etwas eigenes machen und die Setup-Daten bei der Übertragung nutzen. Würde ich nicht machen. Extrawürste sind immer teuer. Aber mach, wenn du denkst. > Es scheint, dass LibUSB-Treiber bei aktuellen Systemn auch vorhanden > sind (WinUSB unter Windows). WinUSB ist was anderes als libusb. Du musst mit sowas wie Zadig dann das Gerät explizit auf libusb zuweisen. Wenn du dagegen WinUSB nimmst, hast du die libusb-OS-Abstraktion nicht mehr, die hat ihr eigenes API. (Letztlich haben die anderen OSe auch wieder ein OS-abhängiges API unter der libusb drunter, aber bei denen muss man nicht diesen Entweder-oder-Zirkus veranstalten.) > Du meinst den Default Control Endpoint? Bei meinen Versuchen haben auch > andere Endpoints in beide Richtungen funktioniert, vielleicht habe ich > dich aber auch falsch verstanden. Ist meiner Meinung nach nicht garantiert außer für den default control EP. > Die Geschwindigkeit spielt am Schluss wahrscheinlich auch nicht die > große Rolle, schneller wie eine Serielle soll es aber schon sein. Ist die Frage, was "eine Serielle" für dich ist. :-) Schneller als 9600 Bd wirst du auch mit CDC allemal, auch schneller als 115200 Bd. Seriell gibt's aber inzwischen auch gern mit 1 oder 2 MBaud (Ankopplung von MCUs über FTDI zum Beispiel). Harald K. schrieb: > Wie gesagt, der eigentliche Treiber ist schon immer vorhanden gewesen > (usbser.sys) Aber eben nicht bequem nutzbar, so wie das alle anderen OSe die ganze Zeit schon angeboten haben. Am Ende haben die Leute dann HID gemacht, weil Microsoft ja dort gezwungen war, einen offenen Klassentreiber anzubieten – macht sich schlecht, wenn man für den Anschluss von Maus oder Tastatur extra erst noch ein .inf File installieren muss …
Maxe schrieb: > So wie ich das verstehe stellt die CDC-Klasse nur eine paket- oder > byteweise Punkt-zu-Punkt-Verbindung dar, ich müsste also wieder eine > Kommunikationsschicht drüberbauen. Eine solche Kommunikationsschicht brauchst du in jedem Fall, auch wenn du dein eigenes Ding machst. Letztendlich ist CDC ja auch nur 2 x Bulk ohne irgendwelche Filter. Die Com Schnittstelle entsteht erst viel weiter oben in der Treiberschicht. Bautrate und ser. Interface brauchst du nicht mal zu implementieren. Dann gehts auch schneller. Es existiert hier im Forum Code (ursprünglich von W.S.) der das auch für den F103 demonstriert. Im OS sind das dann nur noch ReadFile / WriteFile Aufrufe.
Jörg W. schrieb: > Würde ich nicht machen. Extrawürste sind immer teuer. Aber mach, wenn du > denkst. Deswegen frag ich ja hier. Wahrscheinlich ist es am Besten, mal den Code von einem OpenSource-Projekt anzuschauen. Stichworte gab es ja schon. >> Es scheint, dass LibUSB-Treiber bei aktuellen Systemn auch vorhanden >> sind (WinUSB unter Windows). > > WinUSB ist was anderes als libusb. Du musst mit sowas wie Zadig dann das > Gerät explizit auf libusb zuweisen. Wenn du dagegen WinUSB nimmst, hast > du die libusb-OS-Abstraktion nicht mehr, die hat ihr eigenes API. LibUSB kann wohl WinUSB nutzen. Ich habe auch Zadig benutzt, die WinUSB-Erkennung soll aber auch über einen speziellen Deskriptor funktionieren. > Ist die Frage, was "eine Serielle" für dich ist. :-) Schneller als 9600 > Bd wirst du auch mit CDC allemal, auch schneller als 115200 Bd. Seriell > gibt's aber inzwischen auch gern mit 1 oder 2 MBaud (Ankopplung von MCUs > über FTDI zum Beispiel). Mir gings ja nicht um CDC, dass das schnell ist, ist klar. Thomas Z. schrieb: > Eine solche Kommunikationsschicht brauchst du in jedem Fall, auch wenn > du dein eigenes Ding machst. Ich dachte eben man benutzt dafür die Request-Parameter. Aber anscheinend ist das eher für 'offizielle' Anfragen üblich, also von definierten Geräteklassen. > Es existiert hier im Forum Code (ursprünglich von W.S.) der das auch für > den F103 demonstriert. Im OS sind das dann nur noch ReadFile / WriteFile > Aufrufe. Danke, da such ich auch mal danach.
Maxe schrieb: > LibUSB kann wohl WinUSB nutzen. Ich habe auch Zadig benutzt, die > WinUSB-Erkennung soll aber auch über einen speziellen Deskriptor > funktionieren. https://www.mikrocontroller.net/articles/USB-Tutorial_mit_STM32#Konfiguration_der_PC-Seite
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.