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