Hallo, es geht mal wieder um USB aus VB oder VC++. Hab ein paar Fragen, die ich trotz Suche im Forum leider beantworten konnte. Oder ich bin zu blöd zum Suchen. 1. Gibt es eine universelle DLL bzw. ein universelles Objekt, ähnlich dem COM-Port-Objekt aus VB, mit dem man auf USB zugreifen kann? Frei verfügbar natürlich, denn dass es das in "teuer" gibt, weiss ich latürnich!!! 2. Falls 1. verneint werden muss, gibt es die Möglichkeit, über die WinAPI auf USB zuzugreifen? Wenn ja, wie? Links erwünscht! Danke! Ralf
1. Nein, gibt es nicht. Allerdings gibt es Bausteine von SiLabs, Profilic oder FTDI, die Dir die normale serielle Schnittstelle nachbilden. Auch gibt es für diese Chips eigene APIs zur Kommunikation vom Hertsller. 2. Über API geht das natürlich. Das geht sogar ganz genau so, wie das mit der normalen Seriellen auch geht: CreateFile, ReadFile, WriteFile, DeviceIoControl und CloseHandle. Wie Du die drei mittigen Funktionen anwendest, ist abhängig vom verwendeten Gerät. Sofern Du noch etwas mehr mit dem USB vorhast, kann ich nur dringend raten, ein Buch zu lesen. Jan Axelson hat in seinem 'Handbuch für Entwickler' übrigens auch einige Beispiele für VB und VC.
zu 1: KERNEL32.DLL :-) zu 2: Das USB Gerät verwenden wie eine Datei: => CreateFile(),ReadFile(),WriteFile(),CloseHandle() Das Größte Problem dabei ist den entsprechenden "Dateinamen"=Symbolic-Link zu finden. => SetupDi* Funktionen aus der setupapi.dll/lib Je nach Endpunkt (Lesen/Schreiben) im USB-Gerät gibt es dann verschiedene "PIPE"s ("PIPE00"/"PIPE01"). Gruss
> Je nach Endpunkt (Lesen/Schreiben) im USB-Gerät gibt es dann > verschiedene "PIPE"s ("PIPE00"/"PIPE01"). Aus der Sicht des Anwenders stimmt das so nicht. Die Quelle oder das Ziel der Daten bestimmt einzig und allein der Treiber.
@King Stimmt, also darauf achten welches PIPE<xx> für lesen und schreiben verwendet werden muß. Fällt mir gerade ein - ohne PIPE kann der Endpunkt 0 = Controlkanal angesprochen werden. Gruss
Man muß darauf achten, welchen Treiber man verwendet. Ich habe hier zum Beispiel einen Treiber, der ganz ohne Angabe einer Pipe EP3 zum Schreiben/ Lesen verwendet (das weiß ich deswegen so genau, weil Treiber und Gerät von mir sind).
Ach ja, bei HIDs habe ich auch noch nie mit PIPEs 'gefummelt'. Trotzdem wird von EP1 gelesen und auf EP2 geschrieben.
Erstmal danke für die Beiträge. Hätte nicht gedacht, dass in so kurzer Zeit so viele zusammenkommen grins Okay, also über API. Muss ich mir erstmal beibringen. Ist das arg schwer?!? @René: Kannst du deinen Code hier posten? Ralf
Hi! Windows macht USB nur kompliziert und es existiert doch eine einfache Möglichkeit, USB-Geräte zu verwalten: Die Bibliothek heißt LIBUSB und ist für mehrere Betriebssysteme erhältlich (auch WIN32). Mit nem beiliegenden Tool generiert man einfach nen eigenen Treiber (.ini) für das entsprechende Gerät und lässt das Gerät mit den neuen Treiber laufen. Mit der C-Bibliothek oder ner DLL stehen alle USB-Funktionen zur Verfügung (Lesen schreiben auf Endpoints, Descriptoren, ...). Hab auch vor kurzen so ein Projekt durchgeführt welches unter www.ime.jku.at/tusb publiziert ist (Vermerk auf die Doku bzw. Präsentation). Hoffe, ich konnte etwas helfen mfg Weichinger Klaus www.weinga-unity.at.tt
Es hätte ja alles so einfach sein können. Ich habe auch versucht ein HID Device anzusprechen, mit den oben genannten Funktionen. Allerdings habe ich da ein paar Probleme. 1. Mein Device wird ordnungsgemäß gefunden. Es wird auch ein gültiger Handle mit CreateFile erzeugt. 2. WriteFile() und ReadFile schlägt fehl. Fehler 1784: Der angegebene Benutzerpuffer ist für den Vorgang ungültig??? unsigned char buffer[]={0,'e','s','t','T','e','s','t'};; unsigned long num; WriteFile(handle,buffer,8,&num,NULL)); Was kann das sein?
> Es hätte ja alles so einfach sein können. Es ist so einfach. > Was kann das sein? Der Länge des Puffers, den Du zu schreiben versuchst, stimmt nicht mit der tatsächlichen Länge überein. Die Längen müssen exakt stimmen. Bei Reports, die einen Identifier benötigen, ist das Länge + 1. Wie sieht denn der überhaupt InputReport-Descriptor aus?
> Wie sieht denn der überhaupt InputReport-Descriptor aus?
Da Du Daten zum Gerät übertragen möchtest, muß aus "Input"
logischerweise "Output" werden.
also das mit dem WriteFile habe ich inzwischen hinbekommen. Es lag wirklich an der Puffergröße, aber bei Readfile haberts noch. Hier ist also der Report Descriptor. Den habe ich mir aus verschiedenen App-Notes, vor allem aber aus der Projektarbeit von Klaus Weichinger (sehr Aufschlussreich, siehe oben) zusammengestellt: usb_configuration = { { 9, CONFIGURATION, CONF_LENGTH, NB_INTERFACE, CONF_NB, CONF_INDEX, CONF_ATTRIBUTES, MAX_POWER}, { 9, INTERFACE, INTERFACE_NB, ALTERNATE, NB_ENDPOINT, INTERFACE_CLASS, INTERFACE_SUB_CLASS, INTERFACE_PROTOCOL, INTERFACE_INDEX }, { 9, HID, 0x1101, 0, 1, REPORT, 0x2e00 }, { 7, ENDPOINT, ENDPOINT_NB_1, EP_ATTRIBUTES_1, EP_SIZE_1, EP_INTERVAL_1 }, { 0x06,0xA0, 0xFF, /* Usage Page (User Defined) */ 0x09,0xA5, /* Usage (Vendor defined) */ 0xA1,0x01, /* Collection (Application) */ 0x09,0xa6, // Input Report 0x09,0xA7, 0x15,0x80, /* Logical Minimum (-128) */ 0x25,0x7F, /* Logical Maximum (127) */ 0x75,0x08, /* Report Size (8 bit) */ 0x95,0x08, /* Report Count (8 byte) */ 0x81,0x02, /* Input (Data, Variable, Absolute) */ // output report 0x09, 0xA9, 0x15,0x80, /* Logical Minimum (-128) */ 0x25,0x7F, /* Logical Maximum (127) */ 0x75,0x08, /* Report Size (8 bit) */ 0x95,0x08, /* Report Count (8 byte) */ 0x91,0x08, /* Output (Data, Variable, */ // Feature report 0x09, 0xAA, 0x15,0x80, /* Logical Minimum (-128) */ 0x25,0x7F, /* Logical Maximum (127) */ 0x75,0x08, /* Report Size (8 bit) */ 0x95,0x08, /* Report Count (8 byte) */ 0xB1,0x02, /* Output (Data, Variable, */ 0xC0 /* End Collection */ } Ich habe einen Interrupt In Endpoint 1, der alle 10ms abgefragt werden sollte (was aber anscheinend auch nicht gemacht wird). Ein Aufruf wie folgt: unsigned char buffer[10]={0,'e','s','t'};; unsigned long num; ReadFile(m_HIDComm.HidHandle,buffer,10,&num,NULL); verschwindet im Nirvana, es werden keine Daten gelesen. Es wird aber auch keine Anforderung an den MC gesendet. Ist das korrekt so? Wenn ich also ein Readfile Request, bekomme ich keinen Fehler. Allerding habe ich den Puffer auf 10 (8+ 2 Bytes) gesetzt, sonst kam der bekannte Fehler 1784. Was ist da komisch? Beste Grüße Joerg
So, wie ich das sehe, benötigst Du einen Buffer der Größe 8+1 Byte. Das erste Byte muß dabei vor dem Lesen genullt werden. Wie groß der Buffer tatsächlich zu sein hat, erfährst Du übrigens von HidP_GetCaps. BTW: Das Abfragen alle 10 ms funktioniert auch ohne das eine Anwendung läuft, die das Gerät bedient; das geht ganz und gar ohne Dein Zutun. Für mich hört sich das im Momement an, als hättest Du noch einen dicken Bock in Deiner Firmware. Um sicherzugehen, solltest Du auf alle Fälle einen Protokoll-Analyzer zu Hilfe nehmen. Dann siehst Du sofort, was da passiert. Da Du über die Enumeration bereits hinaus bist, sollten auch die reinen Software-Lösungen taugen. Allerdings kann ich da nichts empfehlen, da ich die selber nicht verwende (mir steht ein in Hardware gegossener Analyzer zur Verfügung).
@ King Das glaube ich auch, das mit dem Bock meine ich. Aber es ist mir sehr mystisch, was der Treiber macht. Irgendwie scheint der die empfangenen Daten zu Filtern und für ihn uninteressante Dinge wegzuwerfen. Übrigens funktioniert Readfile zwar nicht, aber Hid_GetFeature funtkioniert. Dabei wird ein Get_Report Control Request ausgeführt. Aber wieso geht das nicht mit ReadFile??? Vielen Dank für deine Antworten. Beste Grüße Joerg
Da wird definitiv nichts gefiltert. Der Host fragt Deinen Controller im angegebenen Intervall ab und speichert den kompletten Report in einem Ringbuffer. Wieviele Reports in diesem Buffer gespeichert werden, kannst Du mit HidD_SetNumInputBuffers einstellen. ReadFile holt sich dann die Daten aus diesem Buffer, sofern vorhanden. Wenn das bei Dir nicht funktionieren will, kann es z.B. daran liegen, daß Du die Requests lediglich NACKst. Oder vielleicht sendest Du Daten in einer Länge, die sich nicht mit dem Descriptor deckt. Auch wenn ich mich wiederhole, aber schau Dir das mit einem Protokoll Analyzer an, z.B.: http://sourceforge.net/projects/usbsnoop/ Ob der gut oder schlecht ist, kann ich, wie gesagt, nicht beurteilen. Ich verwende ihn selber nicht. Aber ganz sicher ist das besser als gar nichts.
@Weinga-Unity - snaky.1gmx.at Kannst Du mir ein Angebot für dein "TUSB3210 Testaufbau" zu kommen lassen???
bei mir ist es genau umgekehrt: ReadFile klappt super, das was ich mit den µC an einen Endpunkt (bei mir EP1) lade, wird vom PC angefordert und visualisiert. aber WriteFile klappt nicht. meine host-anwendung fängt dann an "abzuschmieren". dann klappt nicht mal readFile mehr. und obwohl ich GetLastError() aufrufe, wird kein fehler angezeigt. die host-anwendung ist mit vb geschrieben. bei ReadFile hab ich den overlapped-modus aktiviert wegen dem multithreading. bei WriteFile nicht, könnte es daran liegen?
übrigens benutze ich als µC einen PSoC. ist super leicht handzuhaben. und vorallem kann man in kurzer zeit eine usb-gerät/application programmieren. ich bin begeistert
> die host-anwendung ist mit vb geschrieben. bei ReadFile hab ich den > overlapped-modus aktiviert wegen dem multithreading. bei WriteFile > nicht, könnte es daran liegen? Das verstehe ich nicht. Overlapped wird bei CreateFile mit dem Flag FILE_FLAG_OVERLAPPED aktiviert und nirgendwo anders. Einmal aktiviert gilt das für WriteFile ebenso wie für ReadFile. Mir ist es ein absolutes Rätsel, wie Du bei diesen Funktionen etwas aktivieren/ deaktivieren willst. Beachten mußt Du aber, daß wenn Du mit FILE_FLAG_OVERLAPPED arbeitest, der letzte Parameter nicht genullt werden darf: "If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL." Quelle (Beschreibung des letzten Parameters): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/writefile.asp?frame=true Außerdem verstehe ich nicht, wie und wo Du GetLastError aufrufst, wenn doch während des WriteFile-Aufrufes die Anwendung abschmiert.
> übrigens benutze ich als µC einen PSoC. ist super leicht > handzuhaben. und vorallem kann man in kurzer zeit eine usb- > gerät/application programmieren. ich bin begeistert Ich verwende nicht den PSoC. Ich habe einen Controller, für den es vom Hersteller bereits eine fix und fertige HID Firmware gibt. Da mußt Du gar nichts mehr programmieren. Ich bin begeistert.
sorry, dass ich mich unverständlich ausgedrückt habe. das wenn ich mit FILE_FLAG_OVERLAPPED arbeite den letzte Parameter nicht nullen darf, weiß ich auch. Das sind einer meiner aufrufe der api, vielleicht versteht man besser was ich meine: Public Function OpenForRead(FileName As String) As Long OpenForRead = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READWRITE, SA, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0) End Function Public Function OpenForWrite(FileName As String) As Long OpenForWrite = CreateFile(FileName, GENERIC_WRITE, FILE_SHARE_READWRITE, SA, OPEN_EXISTING, 0, 0) End Function ...... GetLastError rufe ich wie folgt auf: Success = WriteFile(WriteHandle, Sample_Rate(0), 2, BytesWritten, 0) If (Success = 0) Then Message.Text = "Error " & GetLastError() & " sending command to device" Call CloseProcessMonitoringDevice Exit Sub Else 'anweisungen.... End if ich denke es liegt an meiner firmware, werde mir noch mal den hid report descriptor anschauen.
>Ich verwende nicht den PSoC. Ich habe einen Controller, für den es >vom >Hersteller bereits eine fix und fertige HID Firmware gibt. Da mußt >Du >gar nichts mehr programmieren. Ich bin begeistert. dann verrate uns doch welchen controller du benutzt :)
Wer oder was ist Sample_Rate(0) und was steht da drin? Bist Du sicher, daß das Gerät nur ein einziges Byte an Nutzdaten erwartet (das geht, ist dann aber doch ziemlich ungewöhnlich)?
> dann verrate uns doch welchen controller du benutzt :)
SiLabs C8051F320, im Moment schaue ich mir auch den F345 an.
Ausführliche Samples gibt es aber inzwischen von so ziemlich jedem
Hersteller.
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.