Leitfaden zur Entwicklung von USB-Geräten
Inhaltsverzeichnis
- Hintergrund
- Was ist USB?
- USB-Kabel
- Hinweise zu USB-C
- Datenübertragung über ein differentielles Paar
- USB auf der PCB
- Die verschiedenen USB-Geschwindigkeiten
- Kurzer Hinweis zu Geschwindigkeiten auf der PCB
- Protokoll- und Software-Schichten
- USB-Geräteklassen und wie der Host sie verwendet
- Ein serielles Port-Gerät bauen
- STM32-Mikrocontroller und Nucleo-Board
- Einrichten des tatsächlichen USB-Ports
- Schreiben der Software
- Flashen und Ausführen
- Fazit
Hintergrund
- USB-Geräte sind nützlich, um die Funktionen eines Computers zu erweitern.
- Das Ziel dieses Artikels ist es, den Prozess des Bauens eines USB-Geräts von Anfang bis Ende zu erläutern.
Was ist USB?
- USB ist ein Industriestandard für Datenaustausch und Stromversorgung.
- USB ist ein serieller Bus, bei dem Bits einzeln übertragen werden.
- USB ist mehr als nur ein Verbindungsstandard und umfasst auch ein Kommunikationsprotokoll.
USB-Kabel
- Eine USB-2.0-Verbindung hat vier Hauptleitungen:
- +5V-Leitung: versorgt das Gerät vom Host aus mit Strom.
D-- und D+-Leitungen: übertragen als differentielles Paar jeweils 1 Bit.
GND-Leitung: dient als Masse.
Hinweise zu USB-C
- USB-C kann in beide Richtungen eingesteckt werden.
- USB-C gibt weder Geschwindigkeit noch Version an.
Datenübertragung über ein differentielles Paar
- Ein differentielles Paar nutzt zwei Leitungen, um ein einzelnes Bit zu übertragen.
- Differentielle Paare sind vorteilhaft, um Spannungsschwankungen bzw. Störrauschen zu unterdrücken.
USB auf der PCB
- Wenn ein USB-Anschluss auf einer PCB hinzugefügt wird, müssen die differentiellen Paare gleich lang geführt werden.
- Die Leiterbahnen des differentiellen Paars sollten nahe beieinander liegen.
- Eine bestimmte Impedanz muss eingehalten werden.
Die verschiedenen USB-Geschwindigkeiten
- USB 2.0 kann mit Full Speed (12 Mbit/s) und High Speed (480 Mbit/s) arbeiten.
- Host und Gerät handeln beim Verbindungsaufbau die Geschwindigkeit aus.
Kurzer Hinweis zu Geschwindigkeiten auf der PCB
- Bei Full Speed kann man bei Impedanz und Leiterbahnlänge weniger streng sein.
Protokoll- und Software-Schichten
- USB funktioniert ähnlich wie ein Netzwerk und besitzt verschiedene Endpunkte und Konfigurationen.
- Der Host erkennt und verwendet USB-Geräte über Treiber.
USB-Geräteklassen und wie der Host sie verwendet
- Betriebssysteme erkennen verschiedene USB-Geräteklassen.
- Dazu gehören zum Beispiel Massenspeichergeräte oder serielle Geräte.
Ein serielles Port-Gerät bauen
- Es wird ein einfaches USB-Gerät mit seriellem Port gebaut.
- Verwendet werden ein STM32-Mikrocontroller und ein Nucleo-Board.
STM32-Mikrocontroller und Nucleo-Board
- Verwendet wird das Board NUCLEO-F103RB.
- Das Board besteht aus einem Programmer und einem Mikrocontroller.
Einrichten des tatsächlichen USB-Ports
- Der USB-Port wird eingerichtet, und ein Jumper wird so gesetzt, dass eine externe 5V-Stromversorgung verwendet wird.
- Die Pins
PA12 und PA11 werden als USB_DP und USB_DM konfiguriert.
- Am Pin
PA12 wird ein 1,5-kΩ-Widerstand als Pull-up angeschlossen.
Schreiben der Software
- In STM32CubeIDE wird der USB-Gerätemodus konfiguriert.
- Es wird ein serielles Port-Gerät eingerichtet, damit der Host es erkennt.
- In der Routine
CDC_Receive_FS wird Code geschrieben, um eine LED einzuschalten.
Flashen und Ausführen
- Der Code wird gebaut und mit STM32CubeProgrammer auf das Board geflasht.
- Das Board wird mit externer 5V-Versorgung verbunden, und die LED wird über den seriellen Port gesteuert.
Fazit
- Es wurde ein USB-Gerät mit seriellem Port von Anfang bis Ende gebaut.
- Der viele Boilerplate-Code und die UI-basierte Konfiguration in STM32CubeIDE können unpraktisch sein.
- Die Verwendung eines Linux-basierten SoC könnte ein saubererer Ansatz sein.
Meinung von GN⁺
- Boilerplate-Code in STM32CubeIDE: Es wird viel Boilerplate-Code erzeugt, was Code-Reviews erschweren kann.
- Linux-basierter Ansatz: Mit einem Linux-SoC sind standardisiertere APIs und eine sauberere Trennung des Codes möglich.
- Impedanz und Leiterbahnlänge: Für schnelle USB-Verbindungen muss auf Impedanz und Leiterbahnlängen geachtet werden.
- Vorteile differentieller Paare: Differentielle Paare helfen dabei, Spannungsrauschen zu unterdrücken und ermöglichen dadurch eine stabile Datenübertragung.
- Auswahl des Mikrocontrollers: Je nach Projekt ist die Wahl des passenden Mikrocontrollers wichtig. Neben STM32 gibt es viele weitere Optionen.
1 Kommentare
Hacker-News-Kommentare
Meinung zur Verwendung von ST-Mikrocontrollern: Ein guter Artikel zur USB-Nutzung, aber stark auf ST-Mikrocontroller fokussiert. In letzter Zeit bietet das ESP32-Ökosystem einen einfacheren Plug-and-Play-Ansatz. Für Einsteiger sind grundlegende USB-Controller-ICs besser geeignet als Arbeit im High-Speed-Bereich.
Erfahrung mit USB-Compliance-Tests: Als ich vor langer Zeit USB-Compliance-Tests gemacht habe, gab es viele Probleme beim Inrush-Current-Test. Man konzentriert sich leicht auf High-Speed-Digitaldesign, aber bei Compliance-Tests sind die kleinen Details wichtig.
Tipps zu USB-C: Der CC-Pin muss mit dem passenden Widerstand verbunden werden. Bei USB 2.0 sind differentielles Routing und Impedanz kein großes Problem. Direkte Verbindungen mit ähnlicher Länge reichen aus.
Vorschlag für Alternativen zu STM32: Wenn das Löten von ARM-Prozessoren schwierig ist, kann man auch kleinere Controller oder die VUSB-Bibliothek in Betracht ziehen. Wenn man Arduino-artige Programmierung bevorzugt, lassen sich viele Boards leicht als USB-Gerät verwenden.
ESP32 und günstige Hacking-Methoden: Ich nutze meist ESP32, aber man kann auch das Controller-Board aus einer ausrangierten USB-Tastatur verwenden, um günstig und robust einen benutzerdefinierten Controller zu bauen.
Unterstützung für den Empfang von mehr als 64 Byte auf STM32: Eine Frage dazu, wie sich Frames mit mehr als 64 Byte empfangen lassen. Die im Referenzhandbuch beschriebene Konfiguration ist schwierig, weil es sich nicht um ein allgemeines Register handelt.
Erfahrung beim Schreiben von Bare-Metal-USB-Code: Bare-Metal-USB-Code auf einem MCU zu schreiben ist komplexer als SPI oder I2C. Es ist besser, die vom Hersteller bereitgestellte Software so weit wie möglich zu nutzen. Für schnelle Übertragungen sollte man Bulk-Transfers verwenden und Probleme auf der Host-Seite prüfen.
Erstellung virtueller USB-Geräte: Mit einem Raspberry Pi wurde ein virtuelles USB-Gerät erstellt und mit einem PC verbunden. Es wird verwendet, um eine MTP-Kamera zu emulieren und damit Software zu täuschen.
Frage zu Entwicklungsboards mit USB-3-Unterstützung: Ich möchte einen USB-C-Monitor-Sink prototypisieren, finde aber kaum ein Board mit genug Leistung, um DisplayPort empfangen zu können.
Kosten der USB-Nutzung: USB ist nicht kostenlos. Um eine Vendor ID zu erhalten, muss man eine einmalige Gebühr von 6.000 US-Dollar zahlen.