Author Topic: Is Microsoft's WinUSB driver slower than its HID driver for the same HID device?  (Read 8835 times)

redrock

  • Member
  • ***
  • Posts: 1
I am a USB newbie attempting to read data from a Logitech gamepad HID device. Of course, if I wanted to use this device in a real project I would simply use DirectInput, but I am trying to learn about USB host-side programming by reading data from this gamepad.

I have coded up two solutions to read data from this device, one using HIDAPI and one using WinUSB, both in native code. HIDAPI in Windows is essentially c code wrapping all the necessary SetupDi_, HidD_, and HidP_ Win32 functions. I am also timing my access to the device's input data in both solutions using the Win32 'QueryPerformanceCounter()' function. In my HIDAPI solution, I time the 'ReadFile()' function, which I believe is performing the actual interrupt transfer. In my WinUSB solution, I time the 'WinUsb_ReadPipe()' function, which I believe performs the interrupt transfer in WinUSB land.

When I plug in the gamepad device, Windows chooses the 'hidclass.sys' driver (as reported in the device manager). Using my HIDAPI solution, I get back the gamepad data using this driver at an average rate of around 0.01 milliseconds per interrupt transfer. I suppose this is a reasonable data rate for this device (though I don't really know).

In order to use my WinUSB solution, I created a WinUSB device driver installer using the libusbK Info Wizard, then installed the WinUSB driver. After doing so, the device manager reports the driver for my gamepad device as 'winusb.sys', along with several other drivers in the stack. With this driver in place, I can access the device data using the WinUsb_ functions in Win32. Oddly, using this solution I get back the gamepad data at an average rate of around 3 to 4 milliseconds per interrupt transfer, a couple of orders of magnitude slower than using the HIDAPI solution.

My question is, why is there such a difference in the data rate between my two solutions? Is the difference accounted for by Microsoft's HID driver versus their WinUSB driver? Or is likely that I'm just using the api's incorrectly, given that my USB knowledge is just a couple of weeks old? What other possiblities might account for the difference?

Thanks for any help and insights.

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
The HID driver continuously requests data from a HID's interrupt IN endpoint according to the max latency value stored in the endpoint descriptor. ReadFile doesn't cause any traffic on the bus. It just reads data that is already in the buffer or waits for data to arrive if it's not already there.

The WinUSB driver doesn't request any interrupt IN data until an application asks for it. That's why it can be slower to respond.

Tsuneo

  • Frequent Contributor
  • ****
  • Posts: 145
Windows HID driver queues two interrupt IN requests (TD) on the host controller, so that interrupt IN transfers repeat without delay.

To emulate this behavior on WinUSB,
- Open the HID device using CreateFile with FILE_SHARE_READ | FILE_SHARE_WRITE (3rd), FILE_FLAG_OVERLAPPED (6th) for asynchronous read.
- Assign RAW_IO PipePolicy to the interrupt IN pipe
- Prepare two pairs of buffer and OVERLAPPED structure
- Put twice WinUsb_ReadPipe with above buffer and OVERLAPPED pairs, without waiting for the completion of the first read call.
- When an asynchronous (OVERLAPPED) call completes, put another WinUsb_ReadPipe immediately.

Tsuneo
« Last Edit: March 18, 2013, 09:26:44 pm by Tsuneo »