Author Topic: USB HID - loss of reports  (Read 10463 times)

jeff648

  • Member
  • ***
  • Posts: 1
USB HID - loss of reports
« on: September 11, 2013, 01:59:23 pm »
Hello,

I am a newbie and I have build a system with a microcontroller talking with a host in USB.

The device transmits a report of 20 bytes to the host each second on the USB port. The enumeration is OK. I use HID and all works fine when I use the

ReadFile code written in C# by Jan Axelson:

Marshal.StructureToPtr(HidOverlapped, unManagedOverlapped, false);

success = ReadFile(ReadHandleToUSBDevice, unManagedBuffer, inputReportBuffer.Length, ref numberOfBytesRead, unManagedOverlapped);
                  
if (!success)
{
                     
   result = WaitForSingleObject(eventObject, 3000);
   switch (result)
   {
      case WAIT_OBJECT_0:
         success = true;
         GetOverlappedResult(ReadHandleToUSBDevice, unManagedOverlapped, ref numberOfBytesRead, false);
         break;
      case WAIT_TIMEOUT:
         CancelIo(ReadHandleToUSBDevice);
         break;
      default:   
         CancelIo(ReadHandleToUSBDevice);
         break;
   }
}
                                 
if (success)
{
   Marshal.Copy(unManagedBuffer, inputReportBuffer, 0, numberOfBytesRead);
   .........................
}



The problem is the other commands of the thread are not responsive, due to the 3000 ms blocking delay.

I don't understand why this delay is mandatory.

When I decrease the delay to 1 or 2 ms I sometimes loss reports.

I also loss reports if I modify the code to avoid the delay:


Marshal.StructureToPtr(HidOverlapped, unManagedOverlapped, false);

success = ReadFile(ReadHandleToUSBDevice, unManagedBuffer, inputReportBuffer.Length, ref numberOfBytesRead, unManagedOverlapped);
                  
if (!success)
{
   CancelIo(ReadHandleToUSBDevice);     
}
                                 
if (success)
{
   Marshal.Copy(unManagedBuffer, inputReportBuffer, 0, numberOfBytesRead);
   .........................
}

My questions are why this delay, how can I avoid it and how prevent loss of reports.



Thank you for your help

jeff





Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: USB HID - loss of reports
« Reply #1 on: September 11, 2013, 03:53:04 pm »
The HID driver continuously requests reports from the interrupt IN endpoint and stores received reports in a buffer. If the buffer is full when a new report arrives, the driver drops the oldest report.

A blocking ReadFile will wait until a report is available or a timeout.

The latest versions of my HID code use events that trigger when data is received so the application doesn't have to wait for data:

http://www.lvr.com/hidpage.htm#MyExampleCode

You can increase the number of reports the HID driver's buffer can store with HidD_SetNumInputBuffers. See my example code.

ReadFile (and I think Filestream reads) can retrieve multiple reports at once if the function call's buffer is large enough to fit multiple reports and multiple reports are available.