Linux, PC und Hardware


Prof. Jürgen Plate

Standard-Schnittstellen

Universal Serial Bus

USB steht für "Universal Serial Bus" (Universeller Serieller Bus) und ist ein Industrie-Standard, um periphere Geräte an den Computer anzuschließen. Die Entwicklung hat bereits Anfang der 90er Jahre begonnen, dümpelte jedoch einige Jahre vor sich hin. Es dauert noch bis 1996, bis sich USB auf dem Markt meldete, und erst 1998 mit der Version 1.1 begann sich USB langsam durchzusetzen. Mehr und mehr Computer haben USB-Schnittstellen und mit Windows 98 kam das erste Windows, das USB voll unterstützt. Beteiligt an der Entwicklung sind Firmen wie Intel, Apple, Compaq oder Microsoft. Inzwischen ist USB mit den Versionen 1.1 und 2.0 ein Standard mit hoher Marktdurchdringung.

USB-Grundlagen

Warum verwendet man USB? Gründe gibt es viele: Neben der inzwischen großen Marktverbreitung spricht vor allem die einfache Installation und Handhabung auf Benutzerseite dafür. Zwar sind die Steckverbinder nicht der Weisheit letzter Schluss und auch die Datenübertragungsrate wesentlich geringer als beim Netzwerk, aber die Vorteile überwiegen in vielen Anwendungsfällen: Hot plugging, Plug-and-Play sowie der Verzicht auf weitere I/O-Ports, DMA- und Interrupt-Kanäle. Die Installation ist zumindest auf USB-tauglichen Windows-Plattformen idiotensicher. USB-Geräte steckt man einfach während des Betriebs ein. Sofortiger Einsatz ist möglich, ein nerviger Reboot entfällt, und es lassen sich bis zu 127 Geräte anschließen. Zudem vermeiden USB-Geräte Ressourcenkonflikte. Der Controller im PC benutzt zwar generell einen Interrupt und 32 I/O-Ports, doch die angeschlossenen USB-Geräte belegen keine weiteren System-Ressourcen. Die Stromversorgung von bis zu 500 mA je USB-Port wird auch gleich mitgeliefert und erlaubt somit eine Vielfalt an Funktionen und Anwendungsmöglichkeiten zur Erweiterung von Schnittstellen. Durch die Kaskadierung von USB-Hubs lässt sich, wie bei Netzwerken, eine baumartige Struktur erzielen. Die maximale Länge eines Kabelsegmentes beträgt fünf Meter. Die Daten werden als Differenz-Signal mit einer Geschwindigkeit von 12 Mbit/s oder 1,5 Mbit/s übertragen. Bei USB 2.0 ist ausserdem eine Highspeed-Übertragung mit 480Mbit/s spezifiziert. Da USB-2.0 zu USB-1.1-Geräten abwärtskompatibel ist, gibt es an neueren Rechnern keine USB-1.1-Schnittstellen mehr.

Die Vorteile von USB:

Standardstecker
PinNameFarbeBeschreibung
1VCCRot+5 V
2D-WeißData -
3D+GrünData +
4GNDSchwarzMasse
Mini- und Microstecker
PinNameFarbeBeschreibung
1VCCRot+5 V
2D-WeißData -
3D+GrünData +
4IDkeineUnterscheidung von
Micro-A- und Micro-B-Stecker:
Typ A: Masse, Typ B: nicht verbunden
5GNDSchwarzMasse

USB besitzt aber auch Nachteile:

Eigenschaften von USB 1.1:

Eigenschaften von USB 2.0:

USB-Signale

Die Signale auf den beiden Leitungen, D+ und D-, sind Differenzsignale mit Spannungspegeln von 0 und 3,3 Volt. Die Versorgungsspannung am USB kann bis zu 5,25 V betragen und bei starker Belastung bis auf 4,2 V abfallen. Man unterscheidet zwischen Geräten mit eigenem Netzteil und solchen, die über den USB versorgt werden. In vielen Fällen können beide Betriebsarten gewählt werden. Viele Geräte besitzen eine Netzteilbuchse, die zur Schonung des versorgenden PC mit einem externen Netzteil verbunden werden kann. Nach den USB-Spezifikationen ist die Stromaufnahme aus dem Bus automatisch begrenzt.

Man unterscheidet - wie schon erwähnt - zwischen Lowspeed-, Fullspeed und Highspeed-Signalen. Bei einer Lowspeed-Verbindung beträgt die Datenübertragungsrate 1,5 MBit/s, bei einer Fullspeed-Verbindung 12 MBit/s. Die Geschwindigkeit wird vom Master vorgegeben, die angeschlossenen Geräte synchronisieren sich darauf. Die Datencodierung und -decodierung erfolgt durch die USB-Hardware. Die Datenübertragung ist differentiell (D+, D-).
J-Pegel: Differenz zwischen D+ und D- ist positiv (differentielle "1")
K-Pegel: Differenz zwischen D+ und D- ist negativ (differentielle "0")

Es gibt weder Handshake-Signale noch eine eingestellte Baudrate oder eine separate Taktleitung. Der Takt für die Abtastung des übertragenen Datenstroms und das Synchronisiersignal für den Takt werden aus einem Synchronisier-Bitmuster und aus dem Datenstrom selbst generiert. Jede "0" im Bitstrom liefert einen Pegelwechsel und damit ein Signal für die Taktgewinnung.

Nach einer Folge von sechs Einsen ("1") wird automatisch in den Datenstrom eine "0" eingefügt (Bit Stuffing). Damit kommt spätestens nach der sechsten Taktperiode ein Signal für die Takt-Synchronisierung. Jedes Gerät hat spätestens nach sieben Taktperioden Gelegenheit, seinen internen Takt mit dem Bustakt zu synchronisieren. Jedes Datenpaket wird zum Zweck der Synchronisation von einem Sync-Byte angeführt.

Der Host muss das Anstecken eines Geräts bemerken und gleichzeitig die Geschwindigkeitsklasse identifizieren können (Hot Plug-and-Play). Bei Low- und Full-Speed- Geräten ist dies einfach; das Gerät zieht entweder den D- -Pegel oder den D+ -Pegel mit einem Widerstand auf high:

High- oder Full-Speed-Gerät

Low-Speed-Gerät

Für High-Speed-Geräte steht keine weitere Datenleitung zur Verfügung, ausserdem muss sich ein High-Speed-Gerät an einem USB-1.1-Controller wie ein Full-Speed-Gerät verhalten (High-Speed-Geräte sollen auch an einen Full-Speed-Controller anschließbar sein). Deswegen wurde für High-Speed-Geräte die weiter unten beschriebene Anmeldeprozedur spezifiziert.

kein Gerät: D+, D- = low (>2,5us)
Low Speed: D- = high (>2,5us)
Full Speed: D+ = high (>2,5us)
High Speed: verhält sich zunächst wie ein Full-Speed-Gerät (D+ = high), und ist damit von USB-1.1-Controllern/Hubs als Full-Speed-Gerät identifizierbar. Danach identifiziert sich das High-Speed-Gerät durch Abschalten des Pull-Up-Widerstands und aktiviert die 45-Ohm-Abschlusswiderstände an D+ und D-.

USB-Topologie

USB ist trotz des Namens kein echts Bussystem. Bei einem Bus hängen alle Geräte an einer Leitung, wogegen bei USB nur alle Geräte die vom Rechner gesendeten Daten (fast) gleichzeitig empfangen. Bei USB handelt es sich im Grunde um einen sternförmigen Aufbau mit mehreren Zwischenebenen. Jedes Gerät ist über eine eigene Leitung mit dem Computer oder mit einem dazwischen geschalteten Hub verbunden. USB ist also ein sternförmiges Netz von Geräten (Device), die alle von einem Controller (im PC) verwaltet werden.

Angeschlossene Geräte (Tastatur, Maus, Drucker usw.) werden Funktionen (Functions) genannt. Nach dem Einschalten besitzt ein Gerät die Default-Adresse 0. Bei der Initialisierung - hier Enumeration genannt - wird jedem Gerät eine eigene Adresse zugewiesen. Jedes Gerät besitzt entweder eine eigene Spannungsversorgung (self powered) oder es wird über das USB-Kabel versorgt (bus powered). Vor der Initialisierung darf die Stromaufnahme aus dem USB-Kabel maximal 100 mA und nach der Initialisierung maximal 500 mA betragen.

Beim Reset des USB (oder beim Anstecken eines Gerätes an den Bus), meldet sich jedes Device beim Controller mit der fiktiven Adresse 0 an. Der Controller gibt dem Device eine richtige Adresse (1..127) und liest die Konfiguration aus dem Device aus. In dieser Konfiguration gibt das Device an, wieviele Pufferspeicher (genannt Endpunkte) es besitzt, wie groß diese Puffer sind (max. 64 Byte) und ob das für den Controller Lesepuffer (In) oder Schreibpuffer (Out) sind. Außerdem wird dem Controller gesagt, wie häufig er prüfen soll, ob im Lesepuffer Daten für ihn bereitliegen. Die Konfiguration enthält noch weitere Informationen (beispielsweise über den Strombedarf des Device).

Ein Hub ermöglicht den Anschluß mehrerer Geräte. Ein Hub nimmt Daten von den Geräten entgegen und liefert sie an den Rechner oder an den nächst höheren Hub. Umgekehrt nimmt ein Hub Daten vom Computer entgegen und leitet sie an das richtige Gerät oder den nächst tieferen Hub weiter. Jeder Hub besitzt einen Upstream-Port in Richtung Host und mehrere Downstream-Ports in Richtung der Geräte oder weiterer Hubs. Vom Host gesendete Daten leitet der Hub an alle seine aktiven Downstream-Ports weiter. Daten vom Gerät sendet der Hub nur in Richtung Host. Ein Hub isoliert angeschlossene Full/ Low-Speed-Geräte vom High-Speed-Mode und leitet an diese Geräte gerichtete Daten in der passenden Geschwindigkeit weiter. Außerdem übernimmt der Hub das Power-Managment für die angeschlossenen Geräte. Hubs besitzen eine eigene Spannungsversorgung oder werden über das USB-Kabel versorgt. Zwischen den Computer und ein Gerät lassen sich bis zu sieben Hubs schalten - es gibt also bis zu sieben "Ebenen". In jeder Ebene darf das USB-Kabel 5 m lang sein. Ein Gerät kann also maximal 35 m vom Computer entfernt stehen. Die Daten bewegen sich nur zwischen dem Computer und dem jeweils angesprochenen Gerät. Die USB-Geräte können sich untereinander nicht verständigen.

Die Kontrolle über die Daten hat alleine der Computer. Er fragt regelmäßig alle Geräten ab (Polling). Die Geräte dürfen von sich aus keinerlei Daten senden. Dieses Polling kostet zwar Rechenzeit, erlaubt aber einen einfacheren Aufbau der USB-Geräte. Ein USB-Host besteht somit aus einem einzigen Hostcontroller, einem Root Hub (USB-Anschlüsse am PC), der Systemsoftware und den Gerätetreibern. Den Datenfluß vom Host weg zu den Geräten nennt man "downstream", den Datenfluß in umgekehrter Richtung "upstream". Tauscht der Computer mit einem Gerät Daten aus, baut er immer eine direkte Verbindung dorthin auf, die "Pipe" genannt wird.

Für den Host gibt es derzeit 3 Realisierungs-Varianten:

In einem USB2.0-Host-Controller sind ein oder mehrere UHCI- oder OHCI-Controller für USB1.1 Geschwindigkeitsklassen (Low- und Full-Speed) eingebettet (Companion Host Controller). Eine Routing-Logik bewirkt, dass USB-1.1-Geräte mit UHCI/OHCI-Controllern und USB-2.0-Geräte mit dem EHCI-Controller verbunden werden können. Erkennt ein USB-2.0-Treiber ein angeschlossenes Gerät als Full- oder Low-Speed-Gerät, konfiguriert er die Routing-Logik so, dass dieses Gerät mit den Ports eines Companion USB Host Controllers verbunden wird.

Jeder Datentransfer ist über Transaktions-Deskriptoren beschrieben, man spricht auch von virtuellen Datenkanälen, sogenannten "Pipes", die der Host einrichtet. Jede Pipe beginnt im Pufferbereich des Arbeitsspeichers und endet in einem Endpunkt (Endpoint EP) eines Geräts. Ein Endpunkt im Gerät ist ein Sende/Empfangs-FIFO. Die Eigenschaften eines Endpunkts sind im Endpoint-Descriptor festgelegt. Dieser ist in jedem Gerät fest abgespeichert.

Damit der Host die Configuration auslesen kann, besitzt jedes Interface einen EP0, der für die Konfiguration zuständig ist. Dieser ist der einzige Endpunkt, der sowohl ausgelesen als auch beschrieben werden kann, alle anderen Endpunkte beherrschen nur eine Datenrichtung. Der EP0 kann auch für den Datentransfer mitbenutzt werden, er bietet jedoch nur eine geringe Datenrate von 800 Byte/s. Alle anderen Endpunkte sind uni-direktional (senden oder empfangen). Die im EP0 übertragenen Daten sind als Standard-Device-Requests definiert. Die zum EP0 aufgebaute Pipe ist eine "Message" Pipe. Low-Speed-Geräte unterstützen nur Control- und Interrupt-Endpunkte.

Jedes USB-Gerät kann mehrere Endpunkte und mehrere Pipes unterstützen. Die Adressierung auf dem Bus erfolgt über eine 7-Bit-USB-Adresse und im Gerät über eine 4-Bit-Endpunkt-Nummer. Am Bus sind dadurch maximal 127 Geräte und Hubs anschließbar. Die Endpunkt-Nummer ermöglicht die Realisierung verschiedener adressierbarer Funktionen innerhalb eines USB-Geräts. Ein Endpunkt ist eindeutig definiert durch seine Nummer und seine Richtung. Pro Gerät sind daher neben dem EP0 noch 15 IN- und 15 OUT-Endpunkte möglich. Bezugspunkt für die Richtung des Datentransfers ist der Host:

Ein großer Vorteil von USB ist die automatische Erkennung (Plug and Play) neu angeschlossener Geräte. Das Betriebssystem muss dazu in der Lage sein, Informationen von einem Gerät abzufragen, um dann den passenden Treiber zu laden und das Gerät entsprechend anzusprechen. Ein neues Gerät wird dabei angemeldet (Enumeration), es erhält eine Bus-Adresse und wird durch einen speziellen Treiber unterstützt. Die Enumeration wird völlig selbstständig vom Betriebssystem ausgeführt. Den Anschluss eines neuen Gerätes erkennt der Hub Pull-Up-Widerstand der Datenleitung. Nun laufen folgende Schritte ab:
  1. Der Hub informiert den Host über das neu angeschlossene Gerät.
  2. Der Host erfragt vom Hub den Port des neuen Geräts.
  3. Der Host schaltet per Befehl diesen Port ein und führt einen Bus-Reset aus.
  4. Der Hub erzeugt ein Reset-Signal (10 ms) und gibt den Versorgungsstrom für das Gerät frei.
  5. Das Gerät ist nun bereit und antwortet auf der Default-Adresse 0.
  6. Der Host weist dem Gerät eine eigene Bus-Adresse zu.
  7. Der Host liest alle Konfigurations-Informationen aus dem Gerät.
  8. Der Host weist dem Gerät eine der möglichen Konfigurationen zu.
Die Geschichte ist recht komplex und jedes Gerät braucht seinen Treiber. Im Gegensatz zu Nicht-USB-Komponenten wird der Treiber eben nicht beim Booten oder gar manuell geladen, sondern vom USB-Subsystem automatisch aktiviert, wenn das Gerät am Bus auftaucht. Irgendwann stehen dann wieder die Standard-Dateifunktionen zum Ansprechen des Geräts zur Verfügung.

Datenübertragungsmodi

USB 2.0 kennt vier Datenübertragungsarten:

Transfer TypeControl InterruptIsochronous Bulk
USB 1.1XX --
USB 2.0XX XX
Datenbytes/Millisekunde pro Transfer
(full speed)
832, in dreizehn 64-Byte Transfers 6410231216, in neunzehn 64-Byte Transfers
Datenbytes/Millisekunde pro Transfer
(low speed)
24, in drei 8-Byte Transfers 0.8, 8 Bytes in 10 msverbotenverboten
Reservierte Bandbreite10%90%
Int. & Iso. gemeinsam
90%
Int. & Iso. gemeinsam
keine
Fehlerkorrekturjaja jaja
Garantierte Datenrateneinnein janein
Garantierte Latezzeit
(max. Zeit zwischen Transfers)
neinja janein

Die einem Endpoint zugeordnete Transferart ermittelt der Gerätetreiber aus den jeweiligen Deskriptoren (Gerät "sagt", welchen Transfer es benötigt).

Initialisierung (Bus Enumeration)

Das Initialisieren oder Konfigurieren eines Geräts am USB wird mit Enumeration bezeichnet. Ein Gerät durchläuft dabei vier der sechs Gerätezustände:

Powered Default Addressed Configured.

Die beiden anderen Zustände sind: Attached (Hub versorgt Gerät nicht mit Strom) und Suspended (Gerät erkennt mindestens 3ms auf dem Bus keine Aktivität und reduziert die Stromaufnahme). Das Anstecken oder Abziehen eines Geräts am Bus wird, wie erwähnt, durch den Hub erkannt und dem Host gemeldet. Der Host fragt den Hub ab (Full-Speed- oder Low-Speed-Gerät, Port-Adresse) und führt dann die Enumeration in folgenden Schritten durch:

  1. Anstecken des Geräts am Hub bzw. Einschalten des Systems
  2. Port Enable durch den Hub, Hub liefert max. 100mA ans Gerät („Powered“)
  3. Hub erkennt Geschwindigkeitsklasse des Geräts über die Signalleitungen D+, D-
  4. Hub informiert Host über Interrupt-Kanal
  5. Hub setzt Gerät zurück: D+ und D- auf logisch Null, danach ist Gerät im Zustand „Default“. Gerät ist jetzt für Control-Transfers zum EP0 bereit.
  6. Host ermittelt über GetDescriptor die maximale Paketgrösse des Kanals (Adr=0, EP0)
  7. Host weist Geräteadresse zu über SetAddress („Addressed“)
  8. Host liest Deskriptoren über GetDescriptor
  9. Host ermittelt aus den Deskriptoren die Ressourcen-Auslastung durch das Gerät (FIFO-Größe, Polling-Intervalle, Stromaufnahme)
  10. Host lädt einen Gerätetreiber
  11. Host weist über den Gerätetreiber eine Konfiguration zu mit SetConfiguration („Configured“)
Nach dem Ende der Enumeration werden Interrupt-Endpunkte zyklisch abgefragt und Isochrone Endpunkte jede Millisekunde angesprochen.

Nach einem "Power-on-Reset" arbeiten alle USB-Geräte auf Adresse 0 (Default). Es sind alle Downstream-Ports deaktiviert, die folgenden Standard-Device-Requests sieht nur der Hub1. Zuerst wird der Hub1 enumeriert, dann fragt der Host den Interrupt-Endpunkt des Hub1 ab und erkennt, daß weitere Geräte an den Downstream-Ports von Hub1 angeschlossen sind. Sukzessive schaltet der Host die Ports des Hub1 frei und enumeriert die Geräte.

Bus-Kommunikation

Zur Kommunikation über den Bus dienen Datenpakete. Davon gibt es zwei Arten, zum Übermitteln von Control- und Steuerungsinformationen oder zum Datentransfer. Beide sind aber im Grunde gleich aufgebaut: Zur zeitlichen Synchronisation der Geräte sendet der Host periodisch ein Paket SOF (Start-of-Frame-Token) bzw. uSOF (bei high Speed) auf den Bus. Damit wird der Bus in Zeitintervalle (Frames) von 1 ms (SOF bei Full Speed) bzw. von 0,125 ms (uSOF bei High Speed) eingeteilt. SOF (uSOF)-Tokens entfallen bei Low-Speed-Anschlüssen. Nicht jedes Gerät überträgt Daten in jedem Frame. Der Host-Controller-Treiber verteilt die Datentransfers für die verschiedenen Geräte auf die einzelnen Zeitintervalle (Scheduling der Transaktionen).

Da ein USB-Gerät von sich aus weder einen Transfer starten noch per Interrupt einen Transfer anfordern kann, kann man für ein Gerät nur eine Pseudo-Interrupt-Fähigkeit herstellen: Ordnet man einem Gerät einen Interrupt-Endpunkt zu, dann wird es periodisch im Millisekundenabstand vom Host abgefragt und kann so Transferanforderungen dem Host bekanntmachen.

Der Hostadapter selbst ist jedoch interrupt-fähig, d. h., er kann von der CPU Bedienung anfordern. Das Anwender-Programm startet einen Datentransfer, indem es beim USB-Geräte-Treiber einen Transfer anfordert. Es wird eine Verbindung ("Pipe") etabliert und die Daten werden übertragen. Damit keine Daten verloren gehen, muß jedes USB-Gerät einen Datenpuffer haben, dessen Größe sich nach dem typischen Datenaufkommen und nach seiner Datentransferrate richtet. Ebenso sind Pufferspeicher auf der Host-Seite notwendig, um Daten eines Geräts zwischenspeichern zu können für den Fall, dass die Daten nicht schnell genug zum Arbeitsspeicher der CPU übertragen werden.

Der Datentransfer vom Host zu den Geräten erfolgt im sogenannten Broadcast-Modus, d. h. die Daten werden über die Hubs an alle Geräte verteilt. Nur das Gerät, das die eigene Adresse im Token-Paket erkennt, antwortet. Eine direkte Kommunikation zwischen zwei Geräten ohne Beteiligung des Host ist nicht möglich, sie muss grundsätzlich über den Host laufen.

Software-Schichten

Die Steuerung/Abfrage von USB-Geräten erfolgt über "USB Device Requests", auf die jedes Gerät reagieren muß. Eine Untermenge davon sind die "Standard Device Requests". Device Requests übergibt der Geräte-Treiber in Form von I/O-Request-Packets IRPs an den Bus- Treiber. Alle Requests werden mit SETUP-Token über den bidirektionalen Control-Endpunkt EP0 abgewickelt.

Beim "GetStatus"-Request wird beispielswesie der Device-Status vom Host abgeholt (Datentransferrichtung=IN). Zusätzlich zu den Standard-Device-Requests unterstützt jedes Gerät noch gerätespezifische Requests. In vielen Fällen sind dies Befehle aus den SCSI-Befehlssätzen der SCSI-3-Norm.

Paket-Formate

Die Informationsübertragung erfolgt in Paketen, deren allgemeines Format der folgenden Grafik entspricht:

Der Host sendet periodisch ein Start-of-Frame-Token (SOF) als Zeitmarke USB und erzeugt damit Zeitfenster: 1 ms im Full Speed Mode (SOF), 0,125 ms im High Speed Mode (uSOF). Die Frame Number (11 Bit) wird bei jedem SOF hochgezählt (modulo 2048). Im High-Speed-Mode erhöht der Host die-Frame Number nur nach jedem achten uSOF.

Das SOF wird im Full-Speed-Mode gesendet. Low-Speed-Ports können daher kein SOF empfangen, deshalb wird das SOF vom Hub in eine spezielle Signalisierung EOP umgewandelt (Low-Speed-Keep-Alive: Auf die beiden zum Low-Speed-Gerät führenden Signaladern D+/D- wird für 2 Low-Speed-Taktzyklen Low-Pegel angelegt).

Ein Gerät, das kein SOF oder Low-Speed-Keep-Alive EOP empfängt, geht in den Schlaf-Modus (Suspend Mode) mit verringerter Stromaufnahme (ca. 0,5 mA). Das SOF-Token geht an alle Geräte.

Befehls-Pakete (mit SETUP-Token) enthalten eine Geräteadresse und eine Endpunktadresse. Nur Geräte, die ihre Adresse in einem Paket erkennen, dürfen reagieren. Dasselbe gilt für IN- und OUT-Token.

Die Nutzdaten werden in DATA0- und DATA1-Paketen übertragen. Sind es größere Datenmengen, werden – aus Gründen einer eventuellen Fehlerbehandlung - immer abwechselnd DATA0- und DATA1-Pakete verwendet. Maximal sind pro Paket 1024 Byte Nutzdaten (Full Speed) bzw. xxxx Byte (High Speed) übertragbar. Die Nutzdaten sind über eine 16Bit-CRC-Information gesichert. Der Empfang von Nutzdaten wird über ein ACK-Paket (erfolgreich) oder eine NAK-Packet (nicht erfolgreich) quittiert. Über das STALL-Paket fordert ein Gerät die Hilfe des Host an wenn es z. B. weder Daten empfangen noch senden kann.

Konfigurationen

Jedes Gerät muss vom Host erkannt werden. Es muss also die eigene Funktionalität kennen und die entsprechenden Konfigurationen dem Host übermitteln. Beispielsweise können einige Geräte mit eigener Stromversorgung arbeiten (self-powered) oder vom USB versorgt werden (bus-powered). Das Gerät teilt dem Host seine Konfiguration über den Device-Deskriptor mit. Dieser Deskriptor enthält alle wichtigen Daten über das Gerät wie z. B. Gerätetyp, Hersteller-ID, Produkt-ID, Seriennummer und unterstützte USB-Version. Dieser Devicedeskriptor ist aber nicht der einzige Deskriptor; der USB-Standard definiert einige weitere Typen von Deskriptoren, welche in einem hierarchischen Zusammenhang stehen:

Bei vielen USB-Geräten existiert jedoch oft nur eine Konfiguration, obwohl 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 dem Format JJMN,
wobei JJ die Hauptnummer und M und N jeweils Sub-Nummern der vorangehenden sind.
USB 1.0 0x0100, USB 1.1 0x0110 und USB 2.0 0x0200
14bDeviceClassKlassen-Code
15bDeviceSubClassSubklassen-Code
16bDeviceProtocolProtokoll-Code. Die letzten drei Grössen dienen dem System, um den richtigen Klassen-Treiber zu aktivieren.
Bei Klassen-Code 0 definiert jedes Interface seinen eigenen Klassen-Code.
Bei Klassen-Code 0xff ist der Code Vendor-spezifisch.
17bMaxPacketSize Maximale Paketgrösse für ENDP 0. Mögliche Werte sind 8, 16, 32 und 64.
28idVendorVendor-ID
210idProductProdukt-ID
212bcdDeviceVersion des Gerätes (Format wie USB-Version).
114iManufacturerString-Index für Hersteller oder NULL.
115iProductString-Index für Produkt oder NULL.
116iSerialNumberString-Index für Seriennummer oder NULL.
117bNumComfigurationsAnzahl Konfigurationen

Configuration-Descriptor

Ein Configuration-Descriptor enthält Informationen über den aktuellen Zustand des Geräts, beispielsweise, ob eine eigene Stromversorgung verwendet wird oder 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 = 1: Bus-powered (nur USB 1.1),
Bit 6 = 1: self-powered,
Bit 5 = 1: Gerät darf den Host aufwecken
18bMaxPowerbenötigter Strom (mA).

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 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 standardisiert (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.

String-Descriptor

Darin werden die genauen Bezeichnungen der Geräte, 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

Zum vorhergehenden Abschnitt Zum Inhaltsverzeichnis Zum nächsten Abschnitt

Copyright © FH München, FB 04, Prof. Jürgen Plate
Letzte Aktualisierung: 18. Dec 2007