Mandalex

Hier eine ausführliche englische Dokumentation. Der folgende Text wurde aus dieser Dokumentation herausgearbeitet. Um USB wirklich verstehen zu können, muss der gesamte Text gelesen werden, einige Sachen werden erst weiter unten im Text erklärt.

USB ist die Abkürzung für "Universal Serial Bus". Dies ist eine Art der Verkabelung von Peripheriegeräten, die sehr bequem, sicher und schnell ist. Ausserdem hat sich USB in grundsätzlich allen modernen Betriebssystemen eingebürgert, wodurch Kompatibilitätsprobleme zu einem grossen Teil gelöst werden konnten.

Hardware

Ein USB-Kabel besitzt stets nur 4 Leitungen:

Anschluss-NummerFarbe des KabelsBedeutung
1rotVcc (Stromversorgung)
2weissD- (Datenleitung negativ)
3grünD+ (Datenleitung positiv)
4schwarzGND (Stromabfluss)

Durch die Anschlüsse 1 und 4 wird das Gerät mit Strom (maximal 500 mA) versorgt. Reicht dies nicht aus, so muss das Gerät eine eigene Stromversorgung besitzen. Die Datenleitungen senden ein sogenanntes differenitelles 1, wenn die Spannung von D+ 200 mV grösser ist als D-. Eine differentielle 0 wird übertragen, wenn die Spannung von D+ 200mV kleiner ist als D-. Bei Low- und Full-Speed-Geräten wird ein differentielles 0 als J und ein differentielles 1 als K bezeichnet. Bei High-Speed-Geräten sind diese Terme vertauscht. Sind beide Datenleitungen auf einem niedrigen Level (kleiner als 0.3 V), so wird ein sogenanntes Single-Ended-0 (SE0) übertragen.

Da kein Taktsignal existiert, werden die Daten nach dem NRZI-Condierungs-Verfahren gesendet: Nach 6 Einsen wird automatisch (Hardware) eine 0 in den Bit-Strom eingefügt. Ein 1-Bit wird versendet, indem die Polarität unverändert bleibt, ein 0-Bit wird gesendet, indem die Polarität wechselt. Beim Empfänger wird dasselbe Verfahren in umgekehrter Reihenfolge ausgeführt.

Es gibt 4 Varianten von Steckern für ein USB-Kabel, wovon zwei jedoch nur die Mini-Ausführungen der anderen beiden sind. Die Mini-Ausführungen werden beispielsweise für Kameras oder PDAs benötigt, welche keinen Platz für einen grossen Steckplatz haben.

Stecker A

Stecker A zeigt stets in Richtung Computer (Host), der das Gerät ansteuern soll.

Stecker A
Stecker B

Stecker B zeigt stets in Richtung Gerät, das angeschlossen werden soll.

Stecker B

Varianten und Versionen von USB

Von Anfang an waren drei Arten einer USB-Verbindung geplant:

Low Speed mit 1.5 Mbit/s:

Die einfachste Variante des USB wird verwendet für billigere und einfachere Geräte wie Maus, Tastatur, elektronisches Zeichenbrett, Datenübertragung von Computer zu Handys, PDAs und anderem. Der B-Stecker ist meistens im Peripheriegerät fest verdrahtet. Das Kabel von Low-Speed-Geräten ist weder verdrillt, noch abgeschirmt, was sich in einer maximalen Kabellänge von 3 Metern niederschlägt. Diese Verbindungsart ersetzt sozusagen den ADB von Apple-Computern bzw den PS2-Anschluss von PCs.

Full Speed mit 12 Mbit/s:

Diese Variante hat sich durchgesetzt für Digital-Photoapparate, Scanner und andere Geräte, die eine relativ grosse Daten-Übertragungsrate voraussetzen. Die Datenleitungen sind verdrillt und das Kabel ist abgeschirmt, weshalb diese Kabel bis 5 Meter lang sein können. Diese Verbindungsart ersetzt Anschlüsse wie Parallel, Seriell, SCSI.

High Speed mit 480 Mbit/s: (erst ab USB 2.0)

Diese Version hat mittlerweile Einzug in den Computern gefunden. Sie wird benötigt für Digitalkameras externe Massenspeicher usw, also Geräte, die eine sehr hohe Datenübertragungs-Rate benötigen. Das Kabel kann wiederum bis zu 5 Meter lang sein.

Um zwischen den einzelnen Varianten zu unterscheiden, existieren Speed-Identifications, welche in obigem Link nachzulesen sind.

Kommunikation zwischen den Geräten

Die Kommunikation mit USB-Geräten geht folgendermassen vor sich:

Alle USB-Geräte werden im sogenannten Polling-Modus betrieben, was bedeutet, dass nicht die Geräte selbst berechtigt sind, Daten unkontrolliert zu senden (wie bei Interrupts), sondern dass nur der Host die Daten explizit anfordern kann, worauf das entsprechende Gerät dann antwortet.

Die Daten werden mittels Paketen übertragen. Um diese Pakete an die richtigen Stellen weiterzuleiten, werden folgende Bestandteile benötigt: SYNC, PID, ADDR, ENDP, CRC und EOP.

SYNC (8 Bit): Dient zur Synchronisierung mit dem anzusprechenden Gerät: Diese Synchronisation muss bei allen Paketen gesendet werden.

76543210
00000001

PID (8 Bit): Dient zur Festlegung des Paket-Typs:

76543210
p0p1p2p3~p0~p1~p2~p3

p0 bis p3 sind die einzelnen Bits der folgenden Tabelle, ~p0 bis ~p3 sind die jeweiligen invertierten 0-1-Werte. Dadurch werden folgende Pakettypen möglich:

PakettypPIDBeschreibung
Token0001 1110OUT (Auf Gerät schreiben)
1001 0110IN (Von Gerät lesen)
0101 1010SOF (Start of Frame)
1101 0010SETUP (Initialisierungsbefehle)
Data0011 1100DATA0
1011 0100DATA1
0111 1000DATA2
1111 0000MDATA
Handshake0010 1101ACK
1010 0101NACK
1110 0001STALL
0110 1001NYET
Special1100 0011PRE
1100 0011ERR
1000 0111Split
0100 1011Ping

ADDR (7 Bit): Dient zur Festlegung des Zeilgerätes: Jedes Gerät erhält eine Nummer von 1 bis 127, wodurch es eindeutig indetifizierbar wird. Hat ein Gerät noch keine Nummer, so antwortet es auf die Nummer 0.

ENDP (4 Bit): ENDP dient zur Identifikation der von einem USB-Gerät angebotenen Funktionen. Beispielsweise könnte eine Tastatur zwei Funktionen anbieten: eine, welche die Tastenbetätigungen zurückgibt und eine, welche die Steuerung der Lämpchen für NumLock, ScrollLock und CapsLock empfängt. Bei jedem Gerät muss der ENDP 0 fest eingebaut sein, welcher bei Anfrage den Status des Gerätes zurückgibt. Low-Speed-Geräte können nur 2 zusätzliche ENDP anbieten.

Die ADDR- und ENDP-Bits werden auch als 11-Bit-Frame-Number zusammengefasst.

CRC (5 bit oder 16 bit): Der CRC-Check wird bei einigen Paketen durchgeführt (Fehlerdetektion). Daten-Pakete benutzen einen CRC16, alle Token-Pakete einen CRC5.

EOP: Dient zur Festlegung des Endes des Paketes. Dieses EOP steht am Ende jedes Paketes. Das EOP wird erreicht durch ungefähr 2 SE0 und ein anschliessendes J (siehe oben).

Der Aufbau der verschiedenen Paket-Typen

Token-Pakete:

Bits76543210
SYNC00000001
PIDxx01xx10
ADDRxxxxxx1
ENDPxxxx
CRC5xxxxx
EOP...xxx...

Ein IN-Paket informiert das Gerät, dass der Host Informationen lesen will.
Ein OUT-Paket informiert das Gerät, dass der Host Informationen senden will.
Ein SETUP-Paket ist der Header für Kontrolldaten.
Ein SOF-Paket wird vom Host versendet und zwar alle 0.5 bis 1.5 Millisekunden.

Daten-Pakete:

Bits76543210
SYNC00000001
PIDxx11xx00
Datenxxxxxxxx
...
xxxxxxxx
CRC16xxxxxxxx
xxxxxxxx
EOP...xxx...

Als Daten-Pakete werden DATA0 und DATA1 verwendet. Im Daten-Bereich können 0 bis 1023 Bytes übermittelt werden.

Handshake-Pakete:

Bits76543210
SYNC00000001
PIDxx10xx01
EOP...xxx...

Ein ACK wird versendet, wenn das Paket korrekt angekommen ist.
Ein NAK wird versendet, wenn das Gerät momentan nichts senden kann. Dies bedeutet normalerweise, dass das Gerät die Anfrage zwar verstanden hat, jedoch an dieser noch zu kauen hat. Ein NAK wird also standartmässig gesetzt, sobald das Gerät die Anfrage verstanden hat. Erst wenn die Funktion ausgeführt werden konnte, wird dieses wieder gelöscht und das korrekte Resultat bereitgestellt.
Ein STALL wird versendet, wenn das Gerät vom Host neu aufgesetzt werden muss (Es ist ein Fehler aufgetreten).

Kontroll-Strukturen

Die Kommunikation zwischen den Geräten funktioniert immer vom Host aus. So hat also auch jedes Gerät für jeden ENDP je einen IN- und einen OUT-Puffer (von normalerweise 8 Bit). Das OUT beinhaltet stets das, was vom Host gesendet wurde und das IN das, was vom Host gelesen werden soll. Die Kontroll-Strukturen legen fest, wie die Übermittlung der Daten vom Host zum Gerät und umgekehrt verläuft.

Setup

Um eine Gerät zu initialisieren, wird das Setup-Schema angewendet: Zuerst sendet der Host ein SETUP-Paket an die zu überprüfende ADDR. Die angesprochene Funktion (ENDP) des festgelegten Gerätes erwartet nun vom Host als nächstes ein DATA0-Paket, worin beschrieben ist, was genau initialisiert werden soll (Siehe unten). Hat das Gerät alle Daten korrekt bekommen (CRC und PID sind fehlerfrei), so sendet es ein ACK, ansonsten nichts.

Je nach Inhalt des DATA0-Pakets erwartet dieselbe Funktion nun weitere Kontroll-Befehle. Um den Datenfluss zu kontrollieren, können ein oder mehrere Datenpakete versendet werden. Um wieviele Daten es sich handelt, wird ebenfalls im DATA0-Paket des Setups festgehalten. Sind es mehr Daten als die maximale Länge eines Datenpakets erlaubt, so werden sie in mehreren Paketen gesendet, wovon alle die maximale Länge haben ausser dem letzten.

Hier muss noch angefügt werden, dass eine Funktion eines beliebigen Gerätes nur entweder als Sender oder als Empfänger dienen kann (deshalb sind bei Low-Speed-Geräten auch 2 ENDP erlaubt). Je nachdem, was die betreffende Funktion anbietet, muss auch das entsprechende überprüft werden.

Datenfluss Sender (Funktion -> Host):

Der Host sendet ein IN-Token. Erhält die Funktion dieses Paket nicht oder enthält es Fehler, so ignoriert es die weiteren Schritte und tut nichts. Falls das Paket korrekt ankam, so kann die Funktion entweder ein DATA-Paket zur Kontrolle ausgeben, oder durch ein STALL-Paket anzeigen, dass das Gerät einen Fehler hat oder ein NAK, um anzuzeigen, dass die Funktion noch nicht bereit ist, um eine Antwort auf die Anfrage zu liefern. Der Host liest nun das Resultat aus und antwortet, falls ein DATA-Paket gesendet wurde, mit einem ACK.

Datenfluss Empfänger (Host -> Funktion):

Der Host sendet ein OUT-Token, wodurch die Funktion nun ein DATA-Paket erwartet, welches der Host auch gleich als zweites sendet. Kam eines dieser Pakete nicht korrekt bei der Funktion an, so wird nichts zurückgegeben. Des weiteren reagiert die Funktion genau gleich, wie bei der obigen Kontrolle (Funktion -> Host)

Nach bestimmten Befehlen muss die Übertragungsprozedur noch abgeschlossen werden, damit das Gerät wieder auf andere Befehle reagieren kann. Je nachdem, was getan wurde (je nachdem, ob die Funktikon als Sender oder als Empfänger arbeitet) muss hier noch mitgeteilt werden, ob alles glatt gelaufen war. (Kleine Anmerkung: in der oben aufgeführten englischen Dokumentation sind die Zeichnungen aus Versehen vertauscht)

Abschluss für Sender:

Bei einer Sende-Funktion muss der Host der Funktion melden, dass alle Daten korrekt angekommen sind. Dies geschieht mittels einem OUT-Token und einem anschliessenden DATA0-Paket mit der Länge 0. Wiederum kann die Funktion mit einem ACK, STALL oder NAK antworten. Danach sollte die Prozedur abgeschlossen sein.

Abschluss für Empfänger:

Der Host muss die Funktion fragen, ob alle Daten korrekt angekommen sind. Deshalb sendet er ein IN-Token. Die Funktion gibt entweder ein NAK (noch nicht bereit), ein STALL (Fehler) oder ein DATA0-Paket der Länge 0 zurück. Erhält der Host dieses DATA0-Paket, so sendet er noch ein ACK und damit ist die Prozedur abgeschlossen.

Interrupt-Transfer

Da USB im polling-Modus betrieben wird, gibt es keine eigentlichen Interrupts. Ein Gerät kann jedoch, wenn es Aufmerksamkeit erfordert, ein Interrupt-Paket bereitlegen, welches sofort nach dem Erhalt eines IN-Tokens an den Host zurückgegeben wird. Der Host antwortet darauf mit einem ACK und führt den Interrupt aus. Soll kein Interrupt ausgeführt werden, so legt die Funktion ein NAK bereit.

Möchte der Host ein Interrupt auf einem USB-Gerät erwirken, so sendet er einfach ein OUT-Paket gefolgt von einem DATA-Paket. Das Gerät antwortet dann mit einem ACK, falls der Interrupt ausgeführt werden kann und mit einem STALL oder NAK, wenn das Gerät einen Fehler hat oder nicht bereit ist.

Asynchroner Transfer

Beim asynchronen Transfer werden Daten ohne Handshake übergeben. Will der Host lesen, so sendet er ein IN-Paket und erwartet ab nun lauter DATA-Pakete von dem Gerät. Will der Host schreiben, so sendet er ein OUT-Paket und gleich darauf alle DATA-Pakete, die er senden will. Das Gerät hat keine Möglichkeit irgendwelche Fehlermeldungen zurückzugeben. Es kann also durchaus passieren, dass Datenverlust auftritt.

Synchroner Transfer (Bulk)

Beim synchronen Transfer wird für jedes Paket, das gesendet wird, überprüft, ob es korrekt angekommen ist und je nachdem ein ACK oder ein NAK gesendet.

Konfigurationen

Jedes Gerät muss sich beim Host zu erkennen geben können. Ein Gerät muss also seine gesamte Funktionalität kennen und die entsprechenden Konfigurationen dem Host übermitteln können. Beispielsweise können einige Geräte sowohl mit eigener Stromversorgung, als auch mit dem maximal 500mV des USB-Netzwerkes arbeiten. Je nachdem, was gerade möglich ist, muss dem Host also übermittelt werden, welche Konfiguration gerade aktiv ist. Tatsächlich existiert für viele USB-Geräte jedoch gerade mal eine Konfiguration, obschon durch dieses System eine enorme Flexibilität möglich wäre.

Device-Descriptor

Die Informationen sind als Baum in einem Gerät gespeichert. Zuoberst (Wurzelknoten) steht jeweils der Device-Descriptor. Dieser beinhaltet folgende Daten:

BytesOffsetNameInhalt
10bLengthGrösse des Descriptors in Bytes
11bDescriptorTypeDescriptor-Typ (0x01)
22bcdUSBUSB-Version als packed-BCD mit folgendem Format: JJMN wobei JJ die Hauptnummer und M und N jeweils Sub-Nummern der vorangehenden sind. Version 1.0 hat also den Code 0x0100, Version 1.1 den Code 0x0110 und Version 2 den Code 0x0200
14bDeviceClassKlassen-Code
15bDeviceSubClassSubklassen-Code
16bDeviceProtocolProtokoll-Code. Die letzten drei Grössen dienen dem System, um den richtigen Klassen-Treiber zu aktivieren. Wenn Klassen-Code gleich 0, dann definiert jedes Interface seinen eigenen Klassen-Code. Wenn Klassen Code gleich 0xff, so ist der Code Vendor-spezifisch.
17bMaxPacketSizeMaximale Paketgrösse für ENDP 0. Mögliche Werte sind 8, 16, 32 und 64.
28idVendorVendor-ID
210idProductProdukt-ID. Die letzten beiden Grössen dienen ebenfalls dem System, um den korrekten Treiber zu aktivieren.
212bcdDeviceDiese Zahl hat dasselbe Format wie die USB-Version. Sie bezeichnet die Version des Gerätes.
114iManufacturerString-Index für Hersteller
115iProductString-Index für Produkt
116iSerialNumberString-Index für Seriennummer Die letzten drei Werte dienen dazu, um das Gerät genauer zu beschreiben. Falls diese Strings nicht existieren, sollten sie NULL sein.
117bNumComfigurationsAnzahl Konfigurationen

Configuration-Descriptor

Ein Configuration-Descriptor enthält Informationen wie Anzahl mA, die benötigt werden, ob eine eigene Stromversorgung verwendet wird und die Anzahl Interfaces, die das Gerät unter dieser Konfiguration anbietet. Sobald ein solcher Deskriptor geladen wird, wird automatisch der gesamte darunterstehende Baum übergeben

BytesOffsetNameInhalt
10bLengthGrösse des Descriptors in Bytes
11bDescriptorTypeDescriptor-Typ (0x02)
22wTotalLenghtLänge der total zurückgegebenen Daten (gesamter Baum)
14bNumInterfacesAnzahl Interfaces
15bConfigurationValKonfigurations-Nummer
16iConfigurationString-Index für Konfiguration
17bmAttributesBit 7 gesetzt, falls USB-Strom benutzt wird (wurde nur in USB-Version 1.0 benutzt) Bit 6 gesetzt, falls eigene Stromversorgung Bit 5 gesetzt, falls Gerät den Host aufwecken kann
18bMaxPowerAnzahl mA, die benötigt werden.

Interface-Descriptor

Ein Interface-Descriptor ist eine Art Header für die verschiedenen implementierten Funktionalitäten. Beispielsweise könnte ein Multifunktionsgerät Interfaces anbieten für das Fax, den Printer und den Scanner. Diese Interfaces könnnen alle gleichzeitig aktiv sein. Der Host kann jedoch zwischen den Interfaces umschalten. Tatsächlich können sogar mehrere Interfaces für die gleiche Funktionalität erstellt werden. Dazu gibt es im Interface-Descriptor nebst der Interfacenummer und der anzahl Entpoints noch eine Nummer für das nächste alternative Interface.

BytesOffsetNameInhalt
10bLengthGrösse des Descriptors in Bytes
11bDescriptorTypeDescriptor-Typ (0x04)
12bInterfaceNumberInterface-Nummer
13bAlternateSettingnächstes alternatives Interface
14bNumEndpointsAnzahl ENDP für dieses Interface (ohne ENDP 0)
15bInterfaceClassKlassen-Code
16bInterfaceSubClassSubklassen-Code
17bInterfaceProtocolProtokoll-Code. Die letzten drei Werte stehen für Treiber Informationen, die das System zu laden hat.
18iInterfaceString-Index für Index-Beschreibung.

Endpoint-Descriptor

Ein Endpoint-Descriptor schliesslich speichert den Transfer-Typ, die Richtung, das polling-Intervall und die maximale Paketgrösse. Der Endpoint 0 wird nicht durch einen Descriptor beschrieben, er ist standartisiert (Kontroll-Funktion).

BytesOffsetNameInhalt
10bLengthGrösse des Descriptors in Bytes
11bDescriptorTypeDescriptor-Typ (0x05)
12bEndpointAddressBit 7 ist 0 für einen Empfänger und 1 für einen Sender. Die Bits 6 bis 4 sind reserviert (0). Die Bits 3 bis 0 bezeichnen die Nummer des ENDP.
13bmAttributesBits 1 und 0 legen den Transfertyp fest:
00=Kontroll
01=Asynchron
10=Synchron (Bulk)
11=Interrupt
Bits 7 bis 2 sind grunsätzlich reserviert, ausser wenn Asynchron:
Bits 3 und 2: 00=Keine Synchronisation, 01=Asynchron, 10=Adaptiv, 11=Synchron
Bits 5 und 4: 00=Data Edpoint, 01=Feedback Endpoint, 10=Explicit Feedback Data Endpoint, 11=reserved
24wMaxPacketSizeMaximale Paketgrösse
16bIntervalNur für Asynchron und Interrupt: Anzahl Frames, die zwischen den Pollings gewartet werden muss. Ein Frame ist bei einem Low- und Full-Speed-Gerät 1 ms und bei einem High-Speed-Gerät 125 microSekunden.

String-Descriptor

Was noch bleibt sind die String-Deskriptoren. Darin werden die genauen Bezeichnungen von den Geräten, Interfaces, usw. festgehalten. Die Strings liegen in Unicode vor. Jeder Index, der in den oben aufgeführten Deskriptoren nicht benutzt wird, muss 0 enthalten. Der Index 0 beinhaltet folgende Definitionen:

BytesOffsetNameInhalt
10bLengthGrösse des Descriptors in Bytes
11bDescriptorTypeDescriptor-Typ (0x03)
22wLANGID[0]Code-Null-Sprache
24wLANGID[1]Code-Eins-Sprache
26wLANGID[2]Code-x-Sprache

Die Sprachen sind international für USB festgelegt. Die folgenden Deskriptoren definieren die eigentlichen Strings:

BytesOffsetNameInhalt
10bLengthGrösse des Descriptors in Bytes
11bDescriptorTypeDescriptor-Typ (0x03)
n2bStringString der Länge n

Das SETUP-Paket

Nun kommt noch die Beschreibung des SETUP-Paketes (Siehe oben), womit die Geräte erst angesprochen und initialisiert werden können. Der Host schickt dabei das SETUP-Token an die entsprechende Adresse und erwartet allgemein eine Antwort innerhalb von 5 Sekunden. Für spezifische Anfragen sind andere Ablaufzeiten vorgesehen:

Geräte ohne eigenen Speicher müssen innerhalb von 50 ms antworten.
Geräte mit eigenem Speicher müssen innerhalb von 500 ms antworten und jedes weitere Paket muss wiederum maximal 500 ms nach dem ersteren gesendet worden sein. Die Status-Abfrage muss innerhalb von 50 ms erfolgt sein.
Der SetAddress-Befehl muss innerhalb von 50 ms erfolgt sein. Danach hat das Gerät noch 2 ms Zeit, um die Adresse tatsächlich zu ändern.

Diese Einschränkungen haben für den normalen Gebrauch kaum Auswirkungen, erzeugt jedoch für das Testen von Geräten einige Probleme.

Jede Statusanfrage enthält ein 8-Byte langes Datenpaket, worin folgende Anfragen enthalten sind:

BytesOffsetNameInhalt
10bmRequestTypeBit 7: Transferrichtung 0: vom Host, 1: zum Host
Bits 6 und 5: Typ: 00=Standart, 01=Klasse, 10=Vendor, 11=reserviert
Bits 4 bis 0: angesprochener Teil: 0=Gerät, 1=Interface, 2=ENDP, 3=anderes, 4 bit 31: reserviert
11bRequestArt der Anfrage (siehe unten)
22wValueParameter
24wIndexParameter
26wLegnhtgibt die Anzahl Daten an, die beim folgenden Übertragungstest gesendet werden

Geräte-Anfragen:

Was der Wert bRequest beinhaltet hängt vom Hersteller und Programmierer ab, es gibt jedoch einige Anfragen, die auf jedem Gerät implementiert sein müssen:

bmRequestTypebRequestwValuewIndexwLengthDaten
1000 00000x00 GET_STATUS002Geräte-Status
0000 00000x01 CLEAR_FEATUREModus00-
0000 00000x03 SET_FEATUREModus00-
0000 00000x05 SET_ADDRESSAdresse00-
1000 00000x06 GET_DESCRIPTORTyp+Index0 oder SpracheLängeDeskriptor
0000 00000x07 SET_DESCRIPTORTyp+Index0 oder SpracheLängeDeskriptor
1000 00000x08 GET_CONFIG001Konfigurations-Wert
0000 00000x09 SET_CONFIGWert00-

Beim GET_STATUS wird das Gerät 2 Bytes zurückgeben, von welchen momentan erst die untersten beiden Bits gebraucht werden. Bit 0 besagt, ob das Gerät eine eigene Stromversorgung besitzt, und das Bit 1 besagt, ob das Gerät den Host aufwecken darf.
Das CLEAR_ und SET_FEATURE können das Gerät entweder in den Aufweck-Modus oder in den Test-Modus versetzen (bzw sie davon befreien).
SET_ADDRESS wird benötigt, wenn ein Gerät frisch angeschlossen wurde. Dann nämlich hat das Gerät die Nummer 0 und muss erst eine gültige Adresse bekommen.
SET_ und GET_DESCRIPTOR dienen dazu, um die Funktionalität des Gerätes abzufragen. Es können dabei entweder Geräte-, Konfigurations- oder String-Deskriptoren geladen werden (Interface- und ENDP-Deskriptoren werden mit den Konfigurations-Deskriptoren mitgeliefert). Der Typ entspricht den Typen, die bei den Deskriptoren eingetragen sind (siehe oben). Für String-Deskriptoren muss zusätzlich eine Sprache angegeben werden.
GET_ und SET_CONFIGURATION dient zum Setzen von bestimmten Konfigurationen.

Interface-Anfragen:

bmRequestTypebRequestwValuewIndexwLengthDaten
1000 00010x00 GET_STATUS0Interface2Geräte-Status
0000 00010x01 CLEAR_FEATUREModusInterface0-
0000 00010x03 SET_FEATUREModusInterface0-
1000 00010x0a GET_INTERFACE0Interface1alternatives Interface
0000 00010x11 SET_INTERFACEalternatives SetInterface0-

Für den Wert von wIndex wird nur das untere Byte benötigt, um die Interface-Nummer einzutragen.

GET_STATUS gibt momentan erst den Wert 0x0000 zurück, ist aber für zukünftike Funktionen reserviert.
CLEAR_ und SET_FEATURE sind ebenfalls noch reserviert.
GET_ und SET_INTERFACE dienen zum Erreichen von alternativen Interfaces (siehe oben)

ENDP-Anfragen:

bmRequestTypebRequestwValuewIndexwLengthDaten
1000 00100x00 GET_STATUS0ENDP2Geräte-Status
0000 00100x01 CLEAR_FEATUREModusENDP0-
0000 00100x03 SET_FEATUREModusENDP0-
1000 00100x12 SYNCH_FRAME0ENDP2Frame-Nummer

Für den Wert von wIndex wird nur das untere Byte benötigt. Bit 7 gibt die Transferrichtung an und die Bits 3 bis 0 die Nummer des ENDP.

GET_STATUS gibt 2 Bytes zurück, bei denen nur das unterste Bit relevant ist. Dieses zeigt an, ob der ENDP einen Fehler aufweist oder nicht.
CLEAR_ und SET_FEATURE sind dazu da, um ein ENDP in den Fehlerzustand zu versetzen, oder ihn davon zu befreien.
SYNCH_FRAME gibt die Frame-Adresse zurück.

Geräteerkennung

Was passiert, wenn ein USB-Gerät eingesteckt wird? Dieser Prozess, welcher Enumeration genannt wird, ist im Normalfall nicht geregelt, es gibt jedoch einige Dinge, die in einer gewissen Reihenfolge passieren müssen. Hier ist das Beispiel, wie Windows Geräte erkennt:

  1. Der Controller erkannte, dass ein neues Gerät angeschlossen wurde, indem sich die Spannung auf den beiden Datenleitungen änderte (wie genau, weiss ich nicht). Der Controller wartet darauf 100ms, sodass der Stecker vollständig eingesteckt werden kann und das Gerät ausreichend mit Strom versorgt ist.
  2. Windows bekommt nun vom Controller die Meldung, dass sich ein neues Gerät angeschlossen hat und auf die Adresse 0 initialisiert ist.
  3. Windows fragt nach 64 Bytes vom Device-Deskriptor. (Ist kein Schreibfehler, siehe Dokumentation)
  4. Sobald die ersten 8 Bytes gelesen wurden, wird das Gerät wieder auf NULL gesetzt.
  5. Nun wird dem Gerät eine neue Adresse zugeteilt.
  6. Nochmals wird der Device-Deskriptor angefordert (diesmal unter der neuen Adresse) und vollständig geladen.
  7. Der Konfigurations-Deskriptor wird angefordert. Jedoch werden nur die ersten 9 Bytes beachtet.
  8. Die Anzahl Bytes des gesamten Deskriptor-Baumes wird herausgelesen und dieselbe Anzahl vom Konfigurations-Deskriptor angefordert.
  9. Falls irgendwelche String-Deskriptoren aufgetreten sind, werden diese noch angefordert.
  10. Windows sucht nach Treibern.

Quelle: USB in a Nutshell