2017-12-27 22 views
0

특정 장치 용 Windows 용 usb 드라이버를 작성하고 싶습니다. 인터넷 검색 Windows WDFinstructions를보고 대상 PC를 설정했습니다. 첫 번째 예제 프로젝트 중 하나는 universal Hello World 드라이버 (KMDF)입니다.Windows 용 USB 드라이버 작성

https://docs.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/writing-a-very-small-kmdf--driver

의 예는 아주 쉬운 것 같다,하지만이 오류와 함께 종료 : 나는이 주제에 새로 온 사람 때문에

Driver Deployment Task Failed: Driver Preparation

Driver Deployment Task Failed: Driver Install

것은, 내가 여기에 누군가가 도움이 될 수 있다면 부탁 woukd 나를 나는 VS2017과 최신 WDF 두 컴퓨터에서 Windows 10을 사용합니다.

두 번째 질문은 전체 USB 드라이버 주제에 관한 것입니다. 좋은 모범 사례 프로젝트 나 자세한 지침은 어디에서 찾을 수 있습니까?

답변

1

질문 2 : USB 드라이버 예제는 here (커널 및 사용자 모드 드라이버)입니다.

+0

좋아요. 감사합니다 :) .inf 파일로 약간 연주했고, 어떻게 작동하는지 아이디어를 얻고 있다고 생각합니다. 현재로서는 UMDF 또는 KMDF가 필요하거나 그 둘 모두가 필요하다는 사실이 분명하지 않습니다. 이미지에 따르면 둘 다 필요하지만 WinUSB를 사용하고 싶습니다. [이미지] [1] [1] : https://i.stack.imgur.com/PBNV1.png –

+0

응용 프로그램 아키텍처에 따라 다릅니다. [Here] (https://msdn.microsoft.com/en-us/library/windows/hardware/ff540215(v=vs.85) .aspx)는 경우에 따라 사용법을 설명하는 문서입니다. WinUSB를 사용하려면 [IOCTL] (https://msdn.microsoft.com/en-us/library/windows/hardware/ff540046 (v = vs.85) .aspx # winusb)을 사용하여 WinUSB와 통신 할 수 있습니다. 정상적인 응용 프로그램 (UMDF로 옮길 수있는 프로토 타입을 만들 수 있다고 생각합니다). – nowaqq

+0

내 머리가 담배를 피우고 있습니다. ^^ 좋아, 필자는 WinUSB 템플릿을 사용하고 장치 특정 값을 변경하여 드라이버를 "빌드"할 수있었습니다. 드라이버가 대상 PC에서 작동하지만 장치에 표시가 없습니다. 음, .inf 파일은 WinUSB를 사용하도록 OS에 알려주지 만 문제는 없습니다. 드라이버 프로젝트에 추가 파일을 추가하지 않았습니다. 다음 단계에서는 Windows.Devices.Usb 클래스를 사용하여 장치에 액세스하려고했습니다. 나는 appmanifest에 usb 기능을 추가했다. 그러나 UsbDevice.GetDeviceSelector (vid, pid)에 의해 반환 된 문자열은 작동하지 않습니다. 그래서 나는 무엇인가 놓치고 있냐? –

0

WinUSB를 사용해보세요 - 드라이버를 쓸 필요가 없습니다! 는 응용 프로그램에서 WinUSB API를 사용하려면

  • 는 WinUsb.h
  • 응용 프로그램에 링크 된 라이브러리 목록에 WinUsb.lib를 추가 포함합니다.
  • Usb100.h에는 유용한 매크로에 대한 선언이 포함되어 있습니다.
  • 장치 인터페이스 GUID를 사용하여 장치 경로를 가져옵니다. 올바른 GUID는 WinUsb.sys를 설치하는 데 사용 된 INF에 지정된 GUID입니다.
  • INF에 정의한 장치 인터페이스 GUID를 SetupDiGetClassDevs로 전달하여 장치 정보 집합에 대한 핸들을 가져옵니다. 이 함수는 HDEVINFO 핸들을 반환합니다.
  • SetupDiEnumDeviceInterfaces를 호출하여 시스템의 장치 인터페이스를 열거하고 장치 인터페이스에 대한 정보를 얻습니다.
  • 장치 인터페이스에 대한 자세한 데이터를 얻으려면 SetupDiGetDeviceInterfaceDetail을 호출하십시오.
  • GetDevicePath 함수를 호출하여 장치 경로를 가져옵니다.
  • 장치 경로를 CreateFile에 전달하여 장치의 파일 핸들을 가져옵니다. ReadFile 및 Write File을 사용하여 장치와 통신하십시오!
  • 파일 핸들을 WinUsb_Initialize에 전달하여 WinUSB를 초기화하고 WinUSB 핸들을 가져옵니다. 장치의 파일 핸들이 아닌 WinUSB API 함수를 호출 할 때 장치의 WinUSB 핸들을 사용하여 장치를 식별합니다. 장치의 속도를 얻기 위해

    • WinUsb_QueryDeviceInformation : 사용 기능 - 고급 솔루션을

    .

  • WinUsb_QueryInterfaceSettings를 사용하여 해당 인터페이스 설명자를 가져옵니다. WinUSB 핸들은 첫 번째 인터페이스에 해당합니다.
  • WinUsb_QueryPipe는 각 끝점에 대한 정보를 가져옵니다.
  • WinUsb_WritePipe는 버퍼를 장치에 씁니다. 기본 동작 : 길이가 0 인 쓰기는 스택 아래로 전달됩니다.전송 길이가 최대 전송 길이보다 큰 경우 WinUSB는 요청을 최대 전송 길이의 작은 요청으로 나누고이를 순차적으로 전송합니다. 기능과 정보
  • 더 : http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/winusb_howto.docx

디버깅을 위해 당신은 아마 필요 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과 USBPcap 플러그인.

기타 예 : http://searchingforbit.blogspot.com/2012/04/winusb-communication-with-stm32-part-1.html. 샘플 템플릿은 Visual Studio와 함께 제공됩니다.

또한 .inf 파일을 작성해야합니다. -

USB와 통신하는 또 다른 쉬운 방법 libusb를-는 Win32 https://sourceforge.net/projects/libusb-win32/

내 간단한 콘솔 응용 프로그램은 장치에 청크를 보냅니다

#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; } 
}