Universal Serial Bus — Änderungen 7364 → 7365

Zeile 1: Zeile 1:
 
{{EMEJMM}}
 
{{EMEJMM}}
 +
{{Achtung|Text=An diesem Artikel wird derzeit vor allem von [[Benutzer:XanClic|XanClic]] aktiv gearbeitet. Melde dich daher entweder im [[IRC]] oder auf der [[Diskussion:Universal Serial Bus|Diskussionsseite]], bevor du ihn veränderst (wenn ich nicht im IRC bin, dann kannst du ihn auch verändern, weil ich dann sehr wahrscheinlich gar nicht online bin).}}
 
{{TODO|Nein, sie ist noch nicht komplett, man kann es aber schonmal sagen: Low- und Full-Speed werden hier detailliert beschrieben, High-Speed in den meisten Fällen auch relativ genau, wäre aber zu verbessern. Zu SuperSpeed jedoch fehlt jegliche Information (außer den bekannten Consumerinfos, die man auch von Wikipedia bekommen kann), das wäre aber schon nett.}}
 
{{TODO|Nein, sie ist noch nicht komplett, man kann es aber schonmal sagen: Low- und Full-Speed werden hier detailliert beschrieben, High-Speed in den meisten Fällen auch relativ genau, wäre aber zu verbessern. Zu SuperSpeed jedoch fehlt jegliche Information (außer den bekannten Consumerinfos, die man auch von Wikipedia bekommen kann), das wäre aber schon nett.}}
  
Zeile 443: Zeile 444:
 
Hinweis: Man könnte sich fragen, warum der Host nach dem nicht angekommenen ACK ein IN sendet, wenn er doch alle Daten hat. Wir nehmen hier an, dass er eben noch nicht alle Daten hat und ein weiteres Paket erwartet. Wenn er allerdings bereits alle Daten empfangen hätte, würde er die Übertragung einfach beenden und das Gerät würde anhand der verstreichenden Zeitspanne bemerken, dass etwas nicht stimmt und somit seine Daten verwerfen.
 
Hinweis: Man könnte sich fragen, warum der Host nach dem nicht angekommenen ACK ein IN sendet, wenn er doch alle Daten hat. Wir nehmen hier an, dass er eben noch nicht alle Daten hat und ein weiteres Paket erwartet. Wenn er allerdings bereits alle Daten empfangen hätte, würde er die Übertragung einfach beenden und das Gerät würde anhand der verstreichenden Zeitspanne bemerken, dass etwas nicht stimmt und somit seine Daten verwerfen.
  
−
Es gibt für die verschiedenen Transferarten verschiedene Regeln, wann das Toggle-Bit auf einen definierten Zustand gesetzt wird. Bei Controltransfers wird das SETUP-Paket mit DATA0 versendet, danach gelten die normalen Regeln, bis zum Handshake, das immer mit DATA1 versehen wird. Das Toggle-Bit von Bulkendpunkten wird auf 0 gesetzt, sobald die aktuelle Konfiguration gewechselt wird, gleiches gilt für Interruptendpunkte.
+
Es gibt für die verschiedenen Transferarten verschiedene Regeln, wann das Toggle-Bit auf einen definierten Zustand gesetzt wird. Bei Controltransfers wird das SETUP-Paket mit DATA0 versendet, danach gelten die normalen Regeln, bis zur Statusphase, deren Paket immer mit DATA1 versehen wird. Das Toggle-Bit von Bulkendpunkten wird auf 0 gesetzt, sobald die aktuelle Konfiguration gewechselt wird, gleiches gilt für Interruptendpunkte.
  
 
====== Isochronous ======
 
====== Isochronous ======
Zeile 464: Zeile 465:
  
 
=== Controltransfers ===
 
=== Controltransfers ===
−
Ein Controltransfer beginnt mit einer Setupstage, danach folgt die Datenstage und zuletzt kommt noch eine Handshakestage, die aber nichts mit den Handshakepaketen zu tun hat. Die in der Setupstage verwendeten Datenpakete sind immer DATA0, danach alterniert der Wert (DATA0/DATA1) und das letzte Paket ist immer DATA1. Daraus ergibt sich ein Gesamttransfer wie der dieses Beispiel, das den Device-Descriptor eines Geräts einliest, wobei hier für den Endpunkt 0 eine maximale Paketgröße von 8 Byte angenommen wird:
+
Ein Controltransfer beginnt mit einer Setupphase, danach folgt die Datenphase und zuletzt kommt noch eine Statusphase. Die in der Setupphase verwendeten Datenpakete sind immer DATA0, danach alterniert der Wert (DATA0/DATA1) und das letzte Paket (Statusphase) ist immer DATA1. Daraus ergibt sich ein Gesamttransfer wie der dieses Beispiel, das den Device-Descriptor eines Geräts einliest, wobei hier für den Endpunkt 0 eine maximale Paketgröße von 8 Byte angenommen wird:
  
 
{| {{Prettytable}} cellpadding="5"
 
{| {{Prettytable}} cellpadding="5"
Zeile 485: Zeile 486:
 
{{USB-Transfer|dir=out|type=DATA1}}
 
{{USB-Transfer|dir=out|type=DATA1}}
 
{{USB-Transfer|dir=in|type=ACK}}
 
{{USB-Transfer|dir=in|type=ACK}}
−
{{USB-Transferanmerkung|text=Handshakephase abgeschlossen.}}
+
{{USB-Transferanmerkung|text=Statusphase abgeschlossen.}}
 
|}
 
|}
  
−
Wie man sieht, ist das letzte Datenpaket ein Paket ohne Inhalt. Hier wird immer die entgegengesetzte Richtung der Datenstage genommen (IN in der Datenstage → OUT in der Handshakestage und umgekehrt). Mit diesem wird noch einmal bestätigt, dass alle Daten korrekt empfangen wurden und auch korrekt interpretiert werden können (falls nicht, kommt ein STALL).
+
Wie man sieht, ist das letzte Datenpaket ein Paket ohne Inhalt. Hier wird immer die entgegengesetzte Richtung der Datenphase genommen (IN in der Datenphase → OUT in der Statusphase und umgekehrt). Mit diesem wird noch einmal bestätigt, dass alle Daten korrekt empfangen wurden und auch korrekt interpretiert werden können (falls nicht, kommt ein STALL).
  
 
Hier nochmal die Zusammenfassung eines Controltransfers:
 
Hier nochmal die Zusammenfassung eines Controltransfers:
Zeile 498: Zeile 499:
 
| Daten || IN/OUT || Je nach in der Setupphase angegebenen Richtung werden nun Daten ein- oder ausgegeben. Ist die Länge der Datenphase im SETUP-Paket als 0 angegeben worden, existiert diese Phase nicht. Das erste Datenpaket der Datenphase ist immer DATA1, da das Toggle-Bit beim SETUP-Paket auf 0 gesetzt war.
 
| Daten || IN/OUT || Je nach in der Setupphase angegebenen Richtung werden nun Daten ein- oder ausgegeben. Ist die Länge der Datenphase im SETUP-Paket als 0 angegeben worden, existiert diese Phase nicht. Das erste Datenpaket der Datenphase ist immer DATA1, da das Toggle-Bit beim SETUP-Paket auf 0 gesetzt war.
 
|-
 
|-
−
| Handshake || OUT/IN || Umgekehrt zur in der Datenphase verwendeten Richtung (oder der Richtung, die verwendet worden wäre, wenn es keine Datenphase gab) wird nun ein IN- bzw. OUT-Paket gesendet. Dies dient als nochmalige Versicherung, dass das Gerät die Anfrage auch verstanden und verarbeitet hat. In der Handshakephase wird immer DATA1 eingesetzt.
+
| Status || OUT/IN || Umgekehrt zur in der Datenphase verwendeten Richtung (oder der Richtung, die verwendet worden wäre, wenn es keine Datenphase gab) wird nun ein IN- bzw. OUT-Paket gesendet. Dies dient als nochmalige Versicherung, dass das Gerät die Anfrage auch verstanden und verarbeitet hat. In der Statusphase wird immer DATA1 eingesetzt.
 
|}
 
|}
  
Zeile 626: Zeile 627:
  
 
=== Wiederholung ===
 
=== Wiederholung ===
−
Im ersten [[#Controltransfers|Controltransfer-Abschnitt]] wurde bereits gezeigt, dass jeder Controltransfer aus zwei oder drei Phasen besteht: Setup, Daten, Handshake. Die Datenphase ist dabei optional. Das Setuppaket gibt an, was das Gerät tun soll, ob es eine Datenphase gibt, in welche Richtung sie geht und welche Daten dabei ausgetauscht werden sollen.
+
Im ersten [[#Controltransfers|Controltransfer-Abschnitt]] wurde bereits gezeigt, dass jeder Controltransfer aus zwei oder drei Phasen besteht: Setup, Daten, Status. Die Datenphase ist dabei optional. Das Setuppaket gibt an, was das Gerät tun soll, ob es eine Datenphase gibt, in welche Richtung sie geht und welche Daten dabei ausgetauscht werden sollen.
  
 
=== Setuppaket ===
 
=== Setuppaket ===
Zeile 660: Zeile 661:
  
 
==== Standardrequests ====
 
==== Standardrequests ====
 +
===== GET_STATUS =====
 +
Gibt den Status des ausgewählten Empfängers zurück.
 +
 +
{| {{Prettytable}}
 +
! Feld !! Wert
 +
|-
 +
| bmRequestType ||
 +
* 00000000b
 +
* 00000001b
 +
* 00000010b
 +
|-
 +
| bmRequest || 0
 +
|-
 +
| wValue || 0
 +
|-
 +
| wIndex ||
 +
* Gerät: 0
 +
* Interface: Interface-ID
 +
* Endpunkt: Endpunkt-ID
 +
|-
 +
| wLength || 2
 +
|}
 +
 +
In der Datenphase wird dann der Status des Empfängers in zwei Bytes zurückgegeben.
 +
 +
Empfänger ist ein Gerät:
 +
* Bit 0: Gesetzt, wenn das Gerät derzeit seinen Strom von einer externen Quelle bezieht, gelöscht, wenn es seinen Strom vom Bus bezieht.
 +
* Bit 1: Gibt an, ob das Gerät derzeit Remote-Wakeup durchführen kann (Bit wäre dann gesetzt und sonst gelöscht).
 +
* Alle anderen Bits sind reserviert.
 +
 +
Empfänger ist ein Interface:
 +
* Alle Bits sind reserviert.
 +
 +
Empfänger ist ein Endpunkt:
 +
* Bit 0: Ist gesetzt, wenn der Endpunkt derzeit gestallt, also gesperrt ist. Dies tritt meist aufgrund eines Funktionsfehlers auf, der nur durch den USB-Treiber wieder aufgehoben werden kann (per CLEAR_FEATURE).
 +
* Alle anderen Bits sind reserviert.
 +
 
===== CLEAR_FEATURE =====
 
===== CLEAR_FEATURE =====
 
Hebt einen bestimmten Zustand eines Geräts, Interfaces oder Endpunkts auf.
 
Hebt einen bestimmten Zustand eines Geräts, Interfaces oder Endpunkts auf.
Zeile 684: Zeile 722:
  
 
Es gibt keine Datenphase.
 
Es gibt keine Datenphase.
 +
 +
Mögliche Zustände sind:
 +
* 0: ENDPOINT_HALT (für Endpunkte), wenn dieser Zustand gesetzt ist (vgl. [[#GET_STATUS|GET_STATUS]]), reagiert der Endpunkt auf jeden Transfer mit einem STALL-Handshake. Dieser Zustand kann nur durch ein ClearFeature(ENDPOINT_HALT) wieder aufgehoben werden, dabei wird das Data-Toggle-Bit der entsprechenden Pipe auf 0 gesetzt.
 +
* 1: DEVICE_REMOTE_WAKEUP (für Geräte), gibt an, ob das Gerät ein Remote-Wakeup durchführen darf. ClearFeature(DEVICE_REMOTE_WAKEUP) verbietet dies.
 +
 +
===== SET_FEATURE =====
 +
Setzt einen bestimmten Zustand eines Geräts, Interfaces oder Endpunkts und ist somit das Gegenteil zu CLEAR_FEATURE.
 +
 +
{| {{Prettytable}}
 +
! Feld !! Wert
 +
|-
 +
| bmRequestType ||
 +
* 00000000b
 +
* 00000001b
 +
* 00000010b
 +
|-
 +
| bmRequest || 3
 +
|-
 +
| wValue || Zu setzender Zustand
 +
|-
 +
| wIndex ||
 +
* Gerät: 0
 +
* Interface: Interface-ID
 +
* Endpunkt: Endpunkt-ID
 +
|-
 +
| wLength || 0
 +
|}
 +
 +
Es gibt keine Datenphase.
 +
 +
Mögliche Zustände sind:
 +
* 0: ENDPOINT_HALT (für Endpunkte), per SetFeature(ENDPOINT_HALT) kann ein schwerwiegender Fehler sozusagen simuliert werden (wobei sich mir der Sinn dessen bis heute verschließt).
 +
* 1: DEVICE_REMOTE_WAKEUP (für Geräte), SetFeature(DEVICE_REMOTE_WAKEUP) erlaubt ein Remote-Wakeup vom Gerät.
 +
* 2: TEST_MODE (für Geräte), dessen genaue Bedeutung mir unbekannt ist.
  
 
===== SET_ADDRESS =====
 
===== SET_ADDRESS =====
−
Legt die USB-Adresse eines Geräts fest. Diese Adresse nimmt es erst nach der Handshakephase an (die findet also noch mit der alten Adresse statt).
+
Legt die USB-Adresse eines Geräts fest. Diese Adresse nimmt es erst nach der Statusphase an (die findet also noch mit der alten Adresse statt).
  
 
{| {{Prettytable}}
 
{| {{Prettytable}}
Zeile 722: Zeile 794:
  
 
In der Datenphase wird dann der Descriptor zum Host gesendet.
 
In der Datenphase wird dann der Descriptor zum Host gesendet.
 +
 +
===== SET_DESCRIPTOR =====
 +
In Einzelfällen kann es wünschenswert sein, auch einen Descriptor zu verändern oder hinzuzufügen. Dafür gibt es diesen Request, welcher allerdings optional ist (vom Gerät also per STALL-Handshake abgewiesen werden kann).
 +
 +
{| {{Prettytable}}
 +
! Feld !! Wert
 +
|-
 +
| bmRequestType || 00000000b
 +
|-
 +
| bRequest || 7
 +
|-
 +
| wValue || Typ des Descriptors im höherwertigen Byte und Index im niederwertigen
 +
|-
 +
| wIndex || ID der Sprache bei Stringdescriptoren, sonst 0
 +
|-
 +
| wLength || Descriptorlänge
 +
|}
 +
 +
In der Datenphase muss der Host dann den neuen Descriptor an das Gerät übermitteln.
  
 
===== GET_CONFIGURATION =====
 
===== GET_CONFIGURATION =====
Zeile 755: Zeile 846:
 
|-
 
|-
 
| wIndex || 0
 
| wIndex || 0
 +
|-
 +
| wLength || 0
 +
|}
 +
 +
Es gibt keine Datenphase.
 +
 +
===== GET_INTERFACE =====
 +
Dieser Request ermittelt die derzeitige alternative Einstellung für ein bestimmtes Interface.
 +
 +
{| {{Prettytable}}
 +
! Feld !! Wert
 +
|-
 +
| bmRequestType || 10000001b
 +
|-
 +
| bRequest || 10
 +
|-
 +
| wValue || 0
 +
|-
 +
| wIndex || Interface-ID
 +
|-
 +
| wLength || 1
 +
|}
 +
 +
In der Datenphase überträgt das Gerät dann ein Byte, welches die ID der derzeit aktiven alternativen Einstellung des Interfaces enthält.
 +
 +
===== SET_INTERFACE =====
 +
Mit diesem Request wird eine alternative Einstellung für ein Interface festgelegt.
 +
 +
{| {{Prettytable}}
 +
! Feld !! Wert
 +
|-
 +
| bmRequestType || 00000001b
 +
|-
 +
| bRequest || 11
 +
|-
 +
| wValue || ID der zu setzenden alternativen Einstellung
 +
|-
 +
| wIndex || Interface-ID
 
|-
 
|-
 
| wLength || 0
 
| wLength || 0
Zeile 985: Zeile 1.114:
 
| Endpunkt || Endpoint
 
| Endpunkt || Endpoint
 
|-
 
|-
−
| Flusskontrolle || Flow control
+
| Flusskontrolle || Flow controls
−
|-
 
−
| Handshakephase || Handshake stage
 
 
|-
 
|-
 
| Konfiguration || Configuration
 
| Konfiguration || Configuration
Zeile 994: Zeile 1.121:
 
|-
 
|-
 
| Setupphase || Setup stage
 
| Setupphase || Setup stage
 +
|-
 +
| Statusphase || Status stage
 
|}
 
|}
  
Zeile 1.011: Zeile 1.140:
 
|-
 
|-
 
| Flow control || Flusskontrolle
 
| Flow control || Flusskontrolle
−
|-
 
−
| Handshake stage || Handshakephase
 
 
|-
 
|-
 
| Periodic || Periodisch
 
| Periodic || Periodisch
 
|-
 
|-
 
| Setup stage || Setupphase
 
| Setup stage || Setupphase
 +
|-
 +
| Status stage || Statusphase
 
|}
 
|}