2016-07-22 5 views
1

Ich arbeite daran, ein USB-Peripheriegerät zu entwickeln, das sich gelegentlich mit einem Windows-PC verbindet und einige KB Daten in jede Richtung überträgt. Es wird eine benutzerdefinierte PC-Anwendung geben, die die Datenübertragung unter Verwendung eines proprietären Protokolls (d. H. Für die USB-Nutzdaten) steuert.Müssen Treiber für USB-Peripheriegeräte geschrieben werden?

Ich sehe unter dem folgenden Link, dass Microsoft beschreibt, wie einen Treiber für ein USB-Gerät schreiben. Brauche ich einen?

Developing Windows client drivers for USB devices

Die PC-Anwendung ist die einzige Anwendung, die wir wissen wollen, wie man mit dem Gerät zu kommunizieren, so gibt es keine Notwendigkeit für einen Fahrer von einem Standpunkt Application Sharing.

Kann ich das benutzerdefinierte Protokoll direkt in die Anwendung brennen, die Anwendung "Raw USB" zum Gerät sprechen lassen und auf einen separaten Treiber verzichten?

Antwort

2

"Raw USB", nein, das geht nicht aus einer Anwendung.

Aber weil Sie das Gerät auch steuern, können Sie es als eine der Geräteklassen erscheinen lassen, für die Windows einen Gerätetreiber bietet, der generisch genug ist, um alles zu tun, was Sie wollen.

Diese Geräteklassen sind HID (Human Interface Device) und "WinUSB". Von diesen ist HID plattformübergreifend, aber in seiner Fähigkeit begrenzt, WinUSB ermöglicht Hochleistungs-Datenübertragungen sowie Interrupt-Endpunkte.

Anleitungen zum Einstellen des Geräts String-Deskriptoren, so dass Windows sie automatisch an den Fahrer WinUSB bindet sind on MSDN

A WinUSB Gerät ist ein Universal Serial Bus (USB) Gerät, dessen Firmware bestimmte Microsoft-Betriebssystem definiert (OS) Funktionsdeskriptoren, die die kompatible ID als "WINUSB" melden.

Der Zweck eines WinUSB-Geräts besteht darin, Windows zu ermöglichen, Winusb.sys als den Funktionstreiber des Geräts ohne eine benutzerdefinierte INF-Datei zu laden. Für ein WinUSB-Gerät müssen Sie keine INF-Dateien für Ihr Gerät verteilen, wodurch der Treiberinstallationsprozess für Endbenutzer vereinfacht wird.

+0

fand ich diesen informativen , auch. https://en.wikipedia.org/wiki/WinUSB –

+0

Warum haben die Leute Angst davor, Gerätetreiber zu schreiben? Was ist daran so kompliziert? Sicher wird ein Fahrer nicht 100,000 Codezeilen richtig sein? – quantum231

1

Es gibt eine andere Art und Weise keine Notwendigkeit, mit zu schreiben Treiber zu schreiben, was Sie wollen Gerät Writefile Funktion: WinUSB, wie dies zu tun:

  • WinUsb.h Fügen
  • hinzufügen WinUsb.lib zu der Liste der verknüpften Bibliotheken.
  • in Usb100.h einige Makros.
  • Verwenden Sie die GUID der Geräteschnittstelle, um den Gerätepfad abzurufen. Die richtige GUID ist diejenige, die Sie in der INF angegeben haben, die zur Installation von WinUsb.sys verwendet wurde.
  • Erhalten Sie ein Handle zu den Geräteinformationen, indem Sie die GUID der Geräteschnittstelle übergeben, die Sie in dem INF zu SetupDiGetClassDevs definiert haben. Die Funktion gibt ein HDEVINFO-Handle zurück.
  • Rufen Sie SetupDiEnumDeviceInterfaces auf, um die Geräteschnittstellen des Systems zu nummerieren und Informationen zu Ihrer Geräteschnittstelle abzurufen.
  • Rufen Sie SetupDiGetDeviceInterfaceDetail auf, um detaillierte Daten für die Geräteschnittstelle zu erhalten.
  • Rufen Sie die GetDevicePath-Funktion auf, um den Gerätepfad abzurufen.
  • Übergeben Sie den Gerätepfad an CreateFile, um eine Dateikennung für das Gerät zu erhalten. Verwenden Sie ReadFile und Write File, um mit dem Gerät zu kommunizieren!
  • Übergeben Sie das Dateihandle zu WinUsb_Initialize, um WinUSB zu initialisieren, und ein WinUSB-Punkt zu erhalten. Sie verwenden das WinUSB-Handle des Geräts, um das Gerät zu identifizieren, wenn Sie WinUSB-API-Funktionen aufrufen, nicht das Dateihandle des Geräts.

Für anspruchsvollere Lösungen - Einsatz Funktionen:

  • WinUsb_QueryDeviceInformation des Geräts Geschwindigkeit zu erhalten.
  • WinUsb_QueryInterfaceSettings, um die entsprechenden Schnittstellen-Deskriptoren zu erhalten. Das WinUSB-Handle entspricht der ersten Schnittstelle.
  • WinUsb_QueryPipe ruft Informationen zu jedem Endpunkt ab.
  • WinUsb_WritePipe schreibt den Puffer auf das Gerät - Standardverhalten: Schreibvorgänge mit der Länge Null werden im Stapel weitergeleitet. Wenn die Übertragungslänge größer als eine maximale Übertragungslänge ist, teilt WinUSB die Anforderung in kleinere Anforderungen maximaler Übertragungslänge und übergibt sie seriell.
  • mehr Funktionen und Informationen: http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/winusb_howto.docx

Für Debugging-Zwecke Vermutlich müssen: winusbtrace_tool https://blogs.msdn.microsoft.com/usbcoreblog/2010/02/05/how-to-generate-and-view-a-winusb-debug-trace-log/; Wireshark https://www.wireshark.org mit USBPcap Plugin.

Andere Beispiel: http://searchingforbit.blogspot.com/2012/04/winusb-communication-with-stm32-part-1.html. Beispielvorlage wird mit Visual Studio geliefert.

Sie müssen auch Kenntnisse über das Schreiben von .inf-Dateien haben.

Eine weitere einfache Möglichkeit mit USB zu kommunizieren - libusb-win32 https://sourceforge.net/projects/libusb-win32/

Meine einfache Konsolenanwendung sendet Chunks Gerät (Rohdaten schreiben sofort Gerät unter Umgehung des Stack):

#include "stdafx.h" 
#include <SetupAPI.h> 
#include <Hidsdi.h> 
#include <devguid.h> 
#include <winusb.h> 
#include <usb.h> 
#pragma comment(lib, "hid.lib") 
#pragma comment(lib, "setupapi.lib") 
#pragma comment(lib, "winusb.lib") 
#include <iUString.h> 


iString<char> DevicePath; 
bool     WinusbHandle_Open=false; 
bool     DeviceHandle_Open = false; 
WINUSB_INTERFACE_HANDLE WinusbHandle; 
HANDLE     DeviceHandle; 
UCHAR usb_out_buffer[64]; 
DEFINE_GUID(GUID_DEVCLASS_WINUSB, 0x88bae032L, 0x5a81, 0x49f0, 0xbc, 0x3d, 0xa4, 0xff, 0x13, 0x82, 0x16, 0xd6); 
DEFINE_GUID(GUID_DEVCLASS_STL, 0xf177724dL, 0x74d3, 0x430e, 0x86, 0xb5, 0xf0, 0x36, 0x89, 0x10, 0xeb, 0x23); 
GUID winusb_guid; 
GUID stl_guid; 

bool connectusb(); 
void disconnectusb(); 




int main() 
{ 
    DWORD n; 
    DWORD numEvents; 
    HANDLE rHnd;  

WinusbHandle_Open = false; 
DeviceHandle_Open = false; 
winusb_guid = GUID_DEVCLASS_WINUSB; 
stl_guid = GUID_DEVCLASS_STL; 
usb_out_buffer[0] = 0; 
usb_out_buffer[1] = 1; 
usb_out_buffer[2] = 2; 
usb_out_buffer[3] = 3; 

ULONG bytesWritten; 
ULONG timeout; 
timeout = 100; 
rHnd = GetStdHandle(STD_INPUT_HANDLE); 

WinUsb_SetPipePolicy(WinusbHandle, 0x01, PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout); 

timeout = TRUE; 
WinUsb_SetPipePolicy(WinusbHandle, 0x01, AUTO_CLEAR_STALL, sizeof(ULONG), &timeout); 


timeout = TRUE; 
WinUsb_SetPipePolicy(WinusbHandle, 0x01, RAW_IO, sizeof(ULONG), &timeout);//Bypasses queuing and error handling to boost performance for multiple read requests. 


while (true) 
{ 
if ((!WinusbHandle_Open) || (!WinusbHandle_Open)) { if (!connectusb())Sleep(2000); } 
if ((!WinusbHandle_Open) || (!WinusbHandle_Open))continue; 

bytesWritten = 0; 
if (!WinUsb_WritePipe(WinusbHandle, 0x01, &usb_out_buffer[0], 2, &bytesWritten, NULL)) 
{ 
    n = GetLastError(); 
disconnectusb(); 
} 
Sleep(2000); 
} 
disconnectusb(); 
return 0; 
} 




bool connectusb() 
{ 
    BOOL        bResult = FALSE; 
    HDEVINFO       deviceInfo; 
    SP_DEVICE_INTERFACE_DATA   interfaceData; 
    PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL; 
    DWORD n; 
    SP_DEVINFO_DATA devinfo; 
    BYTE devdetailbuffer[4096]; 
    bool found; 

    deviceInfo = SetupDiGetClassDevs(&stl_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 
    if (deviceInfo == INVALID_HANDLE_VALUE) { return false; } 

    found = false; 
    for (n = 0;; n++) 
    { 

     interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); 

     if (!SetupDiEnumDeviceInterfaces(deviceInfo, NULL, &stl_guid, n, &interfaceData)) 
     { 
      n = GetLastError(); 
      break; 
     } 




     detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)devdetailbuffer; 
     detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); 
     devinfo.cbSize = sizeof(devinfo); 
     if (!SetupDiGetDeviceInterfaceDetail(deviceInfo, &interfaceData, detailData, sizeof(devdetailbuffer), NULL, &devinfo)) { printf("SetupDiGetDeviceInterfaceDetail: %u\n", GetLastError()); break; } 
     if (IsEqualGUID(devinfo.ClassGuid, winusb_guid)) 
     { 
      if ((-1 != iStrPos(detailData->DevicePath, "VID_0483")) || (-1 != iStrPos(detailData->DevicePath, "vid_0483"))) 
      { 
       if ((-1 != iStrPos(detailData->DevicePath, "PID_576B")) || (-1 != iStrPos(detailData->DevicePath, "pid_576b"))) 
       { 

        DevicePath = detailData->DevicePath; 
        found = true; 
        break; 
       } 
      } 
     } 
    } 



SetupDiDestroyDeviceInfoList(deviceInfo); 
if (!found)return false; 


DeviceHandle = CreateFile(DevicePath.Buffer() , 
    GENERIC_WRITE | GENERIC_READ, 
    FILE_SHARE_WRITE | FILE_SHARE_READ, 
    NULL, 
    OPEN_EXISTING, 
    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 
    NULL); 

if (INVALID_HANDLE_VALUE == DeviceHandle) { 
    n = GetLastError(); 
} 

if (INVALID_HANDLE_VALUE == DeviceHandle) return false; 
DeviceHandle_Open = true; 



if (!WinUsb_Initialize(DeviceHandle, &WinusbHandle)) 
{ 
    n = GetLastError(); 
    CloseHandle(DeviceHandle); DeviceHandle_Open = false; 
    return false; 
} 



WinusbHandle_Open = true; 
return true; 
} 

void disconnectusb() 
{ 
    if (WinusbHandle_Open) { WinUsb_Free(WinusbHandle); WinusbHandle_Open = false; } 
    if (DeviceHandle_Open) { CloseHandle(DeviceHandle); DeviceHandle_Open = false; } 
} 
Verwandte Themen