Laden...

HID Gerät mit ReadFile und WriteFile gleichzeitig

Letzter Beitrag vor 10 Tagen 5 Posts 151 Views
HID Gerät mit ReadFile und WriteFile gleichzeitig

Ich steuere ein HID Gerät über die Windows ReadFile und WriteFile Funktionen

        [LibraryImport("kernel32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
       [return: MarshalAs(UnmanagedType.Bool)]
       private static partial bool ReadFile(IntPtr hFile, IntPtr lpBuffer, int nNumberOfBytesToRead,
           out int lpNumberOfBytesRead, int lpOverlapped);
       [LibraryImport("kernel32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
       [return: MarshalAs(UnmanagedType.Bool)]
       private static partial bool WriteFile(IntPtr hFile, IntPtr lpBuffer, int nNumberOfBytesToWrite,
           out int lpNumberOfBytesWritten, int lpOverlapped);

Den "Dateinamen" habe ich erfragt und das funktioniert an und für sich ganz gut.

Mit den Hid Funktionen habe ich Probleme.

        [LibraryImport("hid.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
       [return: MarshalAs(UnmanagedType.Bool)]
       protected static partial bool HidD_SetOutputReport(IntPtr DeviceHandle, IntPtr ReportBuffer, int ReportBufferLength);
       [LibraryImport("hid.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
       [return: MarshalAs(UnmanagedType.Bool)]
       protected static partial bool HidD_GetInputReport(IntPtr DeviceHandle, IntPtr ReportBuffer, int ReportBufferLength);

Also doch Read/Write.

Nun ist ReadFile aber ein blockierender Aufruf. Solange ich immer ordentlich was zum Gerät schicke und dann auf die Antwort warte, geht das auch gut. Nun möchte ich aber gerne permanent in einem Thread auf Daten vom Gerät warten. Da ich das Gerät auch selber programmiere, kann ich dort "einfach mal" Notifikationen schicken.

Wenn ich nun aber in meinem Empfangsthread in der ReadFile Funktion stecke, funktioniert WriteFile (aus dem Main Thread) nicht. Geht das überhaupt? Oder muss man da mit overlapped arbeiten? Dann komme ich ja direkt aus der ReadFile Funktion zurück. Ich bin mir aber nicht sicher, ob da nicht "intern" doch irgend etwas blockiert.

Hat da jemand einen Tip?

Bei einem einfachen File kann man einfach via Open entsprechende Flags mitgeben, die gleichzeitiges Lesen und Schreiben ermöglichen.
Die Flags musst Du bei einem HID Gerät aber selbst interpretieren.

Ich benutze ja die CreateFileW Funktion. Auch wenn ich dort Read und Write Sharing angebe, funktioniert es nicht

                PortFileHandle = CreateFileW(idDescriptor.DevicePath, EFileAccess.Read | EFileAccess.Write, 
                                          EFileShare.Read | EFileShare.Write,
                                          IntPtr.Zero,   //Keine Security Attribute
                                          ECreationDisposition.OpenExisting,
                                          EFileAttributes.Device,
                                          IntPtr.Zero);  //keine Template Datei

In meinem Empfangsthread bin ich in

                    if (ReadFile(PortFileHandle!, RxBufferHandle.AddrOfPinnedObject(), ReportSize+1, out nByteRead, 0) == false)

und beim Senden hängt er dann im

                if (WriteFile(PortFileHandle, TxBufferHandle.AddrOfPinnedObject(), nBytes, out nByteWritten, 0) == false)

Es scheint für mich einfacher, meine Anwendung so umzustricken, dass mein Gerät immer exakt eine Antwort schickt, nachdem es eine Anfrage bekommen hat. Dann muss ich halt zwischen den normalen Kommandos ein "Hast du was für mich" Kommando schicken. Dann kann ich blockierend warten. Das noch mit einem Timer absichern, der beim Zuschlagen den Port schließt (dann komme ich ja hoffentlich aus ReadFile zurück, obwohl ich mir da im Moment nicht sicher bin).

Ich weiß aber nicht, was du mit "Flags selbst interpretieren" meinst.

Zitat von AmpelB

Ich weiß aber nicht, was du mit "Flags selbst interpretieren" meinst.

Die Flags

EFileAccess.Read | EFileAccess.Write,
EFileShare.Read | EFileShare.Write

muss Dein "Provider" auch verstehen können. Prinzipiell kann man Handles zwar mit Shared Mode erzeugen, aber der Gegenpunkt muss das auch verstehen.

Gibt zB auch FileSysteme, die man mit Open/Create zwar ansprechen kann, aber die einfach kein Shared-Mode unterstützen; ähnliches eben mit HIDs.

Der Gegenpunkt ist ja ein USB Client Gerät, welches vom USB Stack des Windows PCs verwaltet wird. Mein Gerät meldet sich ja mit entsprechenden USB Dsscreptoren an. USB ist ja prinzipiell Full Duplex. Ich finde in den Descriptoren auch keine Einstellung, ob der Windows PC in seiner File-Interface-Implementierung gleichzeitiges Lesen/Schreiben unterstützen soll oder nicht.

Auf dem Gerät habe ich auch keine Probleme. Dort sind Senden und Empfangen quasi unabhängig. Wenn ich was schicke, muss ich halt nur auf die Benachrichtigung warten, dass es übertragen wurde, bevor ich was neues über diesen Endpunkt schicken kann.