Forum: PC Hard- und Software USB-wie läuft Übertragung genau ab?


von Wurstesser (Gast)


Lesenswert?

Bin grade dabei mir Wissen über USB anzueignen. Ich möchte verstehen das 
die Geräte am Port von sich geben. Mit der Software "USB-Trace" konnte 
ich z.B. feststellen, das die Daten meiner Maus in einen 8Byte Puffer 
eingelesen werden, bei Klick: 01 00 00 00 00 00 00 00,
beim loslassen: 00 00 00 00 00 00 00 00.
Soweit, so gut. Aber wie wird dieser Puffer genau gefüllt?! Da der Bus 
nur 2 Datenleitungen und keine Taktleitung hat, kann ich es mir nur so 
vorstellen:
Der Maus legt die Daten an, und der Host-Controller fragt sie so lange 
schnell hintereinander ab, bis der Puffer voll ist. Ist das richtig so? 
Wenn ja, wovon hängt der Takt ab mit dem der Controller es einliest? Vom 
USB-Typ(1.0, 2.0, 3.0 ...) oder auch vom jeweiligen Gerät? Was mich auch 
etwas irritiert: andere Geräte (z.B. Gamepad) haben deutlich größere 
Register, und wenn man mehrmals den selben Knopf drückt werden 
allerdings nicht immer die selben Daten gesendet.

von ... (Gast)


Lesenswert?

Ein Teil Deiner Fragen wird z.B. hierdrin beantwortet:
http://www.usb.org/developers/devclass_docs/HID1_11.pdf
Für den Rest mußt Du mal selber auf http://www.usb.org suchen.

von Ralf (Gast)


Lesenswert?

> Der Maus legt die Daten an, und der Host-Controller fragt sie so lange
> schnell hintereinander ab, bis der Puffer voll ist. Ist das richtig so?
Nein, nicht richtig:
1. Es gibt EINEN (und nur einen) Master am USB. Er FRAGT nach, ob ein 
Gerät Daten für ihn hat. Das heisst, die Maus legt die Daten nicht von 
sich aus auf den Bus, sondern nur, wenn sie gefragt wird.

> Wenn ja, wovon hängt der Takt ab mit dem der Controller es einliest? Vom
> USB-Typ(1.0, 2.0, 3.0 ...) oder auch vom jeweiligen Gerät?
Beides. 1.0/1.1 unterstützen 1.5MBit und 12MBit Übertragungsrate, 2.0 
zusätzlich 480MBit und 3.0 zusätzlich 5GBit.
Das Gerät teilt dem Bus über einen Pull-Up-Widerstand an EINER (und nur 
einer) der beiden Datenleitungen mit, ob es sich um ein Low-Speed 
(1.5MBit) oder Full-Speed (12MBit) Gerät handelt.
Ein High-Speed Gerät (480MBit) meldet sich grundsätzlich als 
Full-Speed-Gerät an, und schaltet sich danach in den High-Speed-Modus, 
wenn es der entsprechende USB-Controller unterstützt.
Wie es bei 3.0 aussieht weiss ich grad nicht, mit 3.0 hab ich mich noch 
nicht beschäftigt.

> Was mich auch etwas irritiert: andere Geräte (z.B. Gamepad) haben
> deutlich größere Register, ...
Was meinst du mit Register? Kann es sein dass du eigentlich die 
Datenpakete meinst? Die maximale Größe der Pakete hängen vom Speed 
(Low/Full/High/...) ab. Die tatsächliche Größe hängt davon ab, was das 
Gerät tatsächlich braucht. Es macht keinen Sinn, 1024-Byte Pakete zu 
senden, wenn davon nur 16 Byte gebraucht werden.

> ...und wenn man mehrmals den selben Knopf drückt
> werden allerdings nicht immer die selben Daten gesendet.
Ohne die Daten bzw. das Gamepad zu kennen ist eine genaue Aussage jetzt 
schwierig. Ich könnte mir aber vorstellen, dass es evtl. davon abhängig 
ist, wie lange die Taste gedrückt ist oder ob nebenbei noch andere 
Tasten gedrückt werden.

Generell gibt es dann noch sogenannte USB-Klassen für die Geräte. Ein(e) 
Festplatte/USB-Stick gehört zur MassStorageDevice-Klasse, ein(e) 
GamePad/Maus zur HumanInterfaceDevice-Klasse, ein Drucker zur 
Printer-Klasse, usw.
Die Klasse definiert den Datenaufbau und solche Sachen. Deswegen braucht 
man für solche Geräte keinen Treiber installieren, da der PC dann schon 
anhand der Klasse einen "generischen" Treiber installieren kann (ist 
beim OS mit dabei).

Zur Einführung in USB solltest du diese beiden Seiten mal anschauen:
http://www.usbmadesimple.co.uk/
http://www.lvr.com/usb.htm

Ralf

von Andreas B. (andreas_b77)


Lesenswert?

Wurstesser schrieb:
> Da der Bus
> nur 2 Datenleitungen und keine Taktleitung hat

Die Übertragung ist differentiell, die Leitungen D+ und D- damit 
zusammen nur eine einzige Datenleitung. Ein serieller Bus im 
Halbduplex-Betrieb eben.

Der Takt ist im Datensignal enthalten und wird vom jeweiligen Empfänger 
zurückgewonnen.

von Mike S. (drseltsam)


Lesenswert?

USB Beschreibungen hat das Netz doch nun wie Sand am Meer!

von Albert .. (albert-k)


Lesenswert?

Ich erkläre grundlegendes USb nur mal grob und gehe genauer auf die HID 
Klasse (Maus, tastatur, etc.) ein:

USB ist ein BUS der nur einen Master, Host genannt, besitzt. Alle 
anderen Geräte die am Host angeschlossen sind nennen sich Slaves, von 
denen es maximal 127 Stück geben darf. Die Slaves werden vom Host 
gefragt ob sie Daten senden möchten oder nicht. Seien dies nun eigene 
Daten, antworten auf Anfragen des Host etc., es wird alles vom Host 
Initiiert.

USB verfügt über folgende 3 Geschwindigkeitsspezifikationen:
- Low Speed: bis 1,5MBit/sec (USB 1.0/1.1/2.0/3.0)
- Full Speed: bis 12MBit/sec (USB 1.0/1.1/2.0/3.0)
- High Speed: bis 480MBit/sec(USB 2.0/3.0)
- Super Speed: bis 5Gbit/sec (USB 3.0)

Soviel mal Grundlegendes. bei genaueren fragen zu Endpoints, den 
unterschiedlichen Transferarten, etc. kannst du gerne genauer 
nachfragen.

Nun zur HID Klasse:
USB definiert verschiedene Klassen (Mass Storage, Communications, Audio, 
HID, etc.). Mäuse fallen unter die Klasse HID (Human Interface Device). 
Zur verfügung stehen bei deiner Maus (die meisten Mäuse laufen nach dem 
1.1 Standard) Control und Interrupt transfers zur Verfügung. 
Controltransfers werden hauptsächlich für Statusanfragen- antworten und 
zur Übertragung gerigner Datenmengen verwendet. Bei Low Speed dürfen nur 
8 Byte Packete verwendet werden (respiktive 800Byte/Sekunde). Bei 
Full-Speed 8, 16, 32, 64 Byte Packete (respiktive bis zu 64kByte/sec).

Interrupt Transfers bedeuten folgendes: Es wird innerhalb einer vom 
Slave definierten zeitlichen Grenze (bsw. 30ms) nachgefragt ob der Slave 
neue Daten hat. Es kann also sein das dies mal nur 10ms, 17ms oder auch 
die vollen 30ms sind. Aber nie über der definierten Grenze. Die 
Datenmengen sidn gleich wie bei den Control Transfers.

Ein USb Slave wird über seine Deskriptoren definiert, derer gibt es 
folgende:
- Device Deskriptor
- Configuration Deskriptor
- Interface Deskriptor
- String Deskriptor
- Report Deksriptor (nur bei HID)

Um denn Aufbau deienr gesendeten Datenpackete zu verstehen ist für die 
der Report Deskriptor entscheidend. Dieser gibt nämlich an wie die vom 
Slave an den Host gesendeten Daten strukturiert sind. Bei einer Maus hat 
man bsw. 3 Tasten, sowie eine x und Y Koordinate (für ganz einfache 
Mäuse). Bevor überhaupt irgend etwas passiert wird der Host den Slave 
nach diesem Deskriptor fragen um zu wissen wo was drinnen steht und wie 
die Daten aussehen. Eine Taste kann dabei z.b. nur aus einem Bit 
bestehen (für gedrückt/ nicht gedrückt), oder aber auch bsw. aus einem 
8Bit Wert um zu identifizieren wie stark sie gedrückt wurde (Beim 
Gamepad bsw. um zu zeigen wie stark das Auto im Spiel beschleunigen 
soll).

Deine Maus wird wohl ein Low-Speed Gerät sein und daher nur 8Byte 
Datenpackete senden.
Dein Gamepad wird höchstwahrscheinlich ein 1.1 oder 2.0 Gerät sein um 
größere Datenpackete für die vielen verschieden Joysticks, Knöpfe, etc. 
zu versenden.

von Wurstesser (Gast)


Lesenswert?

OK. Danke erst mal für die Hilfe. Wie komme ich denn über PC an die 
Daten ran in einem eigenen Programm? Ich bräuchte einen Pointer auf den 
Puffer, wo die Daten eingelesen werden. Aber wo nehme ich den her? 
USBTrace liefert mir keine Addresse dafür, muss ja aber selbst irgendwie 
Zugriff auf die Daten haben, sonst könnte es sie nicht anzeigen. Oder 
brauche ich ein Handle auf den Hostcontroller?

von Christian R. (supachris)


Lesenswert?

Du brauchst die Windows API Funktionen. Für solche Geräte gehts sehr 
einfach über die HID Funktionen. Eventuell hier mal einsteigen: 
http://msdn.microsoft.com/en-us/library/ms645543%28v=vs.85%29.aspx

von Albert .. (albert-k)


Lesenswert?

Wie oben bereits erwähnt liefert Windows (wie es bei Linux aussieht weiß 
ich leider nicht, dürfte aber ähnlich sein) einige API Funktionen zum 
Zugriff auf HID Geräte. Um dir den Einstieg zu erleichtern hier mal die 
Befehlsabfolge mit kurzer Erläuterung:

1. Inkludiere hid.h und setupapi.h
2. Aufruf von HidD_GetHidGuid() um die Guid (Global unique identifier) 
aller angeschlossenen HID Geräte zu erhalten
3. Aufruf von SetupDiGetClassDevs() um weitere Inforamtionen der 
einzelnen HID-Devices zu erhalten.
4. Aufruf von SetupDiEnumDeviceInterface()um einen zeiger auf eine 
Schnittstelle der Devices zu erhalten.
5. Aufruf von SetupDiGetDeviceInterfaceDetail() um den Gerätepfadnamen 
zur Öffnung der Kommunikation zu erhalten.
6. Aufruf von CreateFile() um ein handle für das Gerät zu erhalten.
7. Aufruf von HidD_GetAttributes() um die Hersteller und Produkt-ID des 
Gerätes zu erhalten.
8. Stimmen die Hersteller und Produkt-Api mit deiner gesuchten überein 
kannst du mit dem Handle weiterarbeiten. Ansonsten musst du es über 
CloseFile() wieder schließen und bei Schritt 6 mit dem nächsten Gerät 
fortfahren bis du das richtige gefunden hast.

Im Anschluss kannst du mit ReadFile() und WriteFile() Daten zum 
HID-Device schreiben oder Lesen.

Es gibt fertige library's die dieses ganze Prozedere wesentlich 
vereinfachen. Ich habe eine der man nur die Hersteller- und Produkt-ID 
sowie wenn gewünscht den Namen des Gerätes übergibt und die alles 
weitere selber macht und das passende handle zurückgibt. Im Anschluss 
kann man dan einfach über ReadFile() und WriteFile() arbeiten.
Entweder finde ich sie noch online (war nicht von mir) oder ich suche 
sie zu Hause mal.

von Albert .. (albert-k)


Lesenswert?

Ich habe die von mir verwendete HID API nun gefunden:
http://www.signal11.us/oss/hidapi/

Sie ist sehr simpel gehalten und dient für eifnachen Austausch von 
Reports zwischen Host und Device. Für mehr Funktionalität sollte man 
sich libhid (basiert auf libusb) ansehen. Ist natürlich etwas 
komplizierter aber auch wesentlich mächtiger.

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
Noch kein Account? Hier anmelden.