Author Topic: My software becoming unresponsive + ReadFile  (Read 7354 times)

DavidClarke

  • Member
  • ***
  • Posts: 24
My software becoming unresponsive + ReadFile
« on: May 23, 2019, 10:37:56 pm »
HI
I have made great progress WITH my project.  Thanks FOR your help!

I have been testing my code and run into a bit of a problem I am having trouble tracking down.  My device has 6 buttons.  I am using ReadFile Overlapped plus WaitForSingleObject.  Things basically work right but my application stops receiving data from the device even though my Beagle shows valid activity coming from the device.  I can cause the problem by pressing the buttons very fast.

This is the basic flow of the ReadFile code:

RESULT = HidD_SetNumInputBuffers(FILE_HANDLE, 512)     

DO
 
    RESULT = WaitForSingleObject(MY_OVERLAPPED.hEvent, 3000)

    RESULT = ReadFile(BYVAL FILE_HANDLE,  READ_BUFFER, MY_InputReportByteLength , BYTES_READ, MY_OVERLAPPED)
    Last_Error = GetLastError
    WE GET AN ERROR 997 HERE ERROR_IO_PENDING

    DO SOMETHING WITH READ_BUFFER HERE.

    Result = GetOverlappedResult(BYVAL FILE_HANDLE, MY_OVERLAPPED, BYTES_READ, 0)
    Last_Error = GetLastError
    WE GET AN ERROR 996 HERE ERROR_IO_INCOMPLETE

    HidD_FlushQueue(FILE_HANDLE) 

    ResetEvent(GLOBAL_EVENT_WAIT_FOR_OVERLAPPED_READ)

 LOOP

Is the circular buffer an issue?
I thought error 997 was normal ERROR_IO_PENDING.
Not sure why I am getting error 996 ERROR_IO_INCOMPLETE after reading the data (at least 17 bytes of it) from the circular buffer.

I tried messing around with:

HidD_SetNumInputBuffers(FILE_HANDLE, BYVAL 512)
HidD_SetNumInputBuffers(FILE_HANDLE, BYVAL 65535)

Didn't notice any change.

If I just wait the program returns to being responsive. This loop is in its own thread.
Letting the code cycle through one or two WaitForSingleObject timeout cycle seems to restore operation....

Also, after calling  ReadFile(BYVAL FILE_HANDLE,  READ_BUFFER, MY_InputReportByteLength , BYTES_READ, MY_OVERLAPPED)
I get 0 in BYTES_READ except after it has hung then I get 17...

Any clues?
 


   
« Last Edit: May 23, 2019, 11:02:41 pm by DavidClarke »

DavidClarke

  • Member
  • ***
  • Posts: 24
Re: My software becoming unresponsive + ReadFile
« Reply #1 on: May 24, 2019, 09:21:28 am »
FYI:

[Port6]  :  USB Input Device


Is Port User Connectable:         yes
Is Port Debug Capable:            no
Companion Port Number:            0
Companion Hub Symbolic Link Name:
Protocols Supported:
 USB 1.1:                         yes
 USB 2.0:                         yes
 USB 3.0:                         no

Device Power State:               PowerDeviceD0

       ---===>Device Information<===---
English product name: "Stream Deck Mini"

ConnectionStatus:                 
Current Config Value:              0x01  -> Device Bus Speed: High (is not SuperSpeed or higher capable)
Device Address:                    0x05
Open Pipes:                           2

          ===>Device Descriptor<===
bLength:                           0x12
bDescriptorType:                   0x01
bcdUSB:                          0x0200
bDeviceClass:                      0x00  -> This is an Interface Class Defined Device
bDeviceSubClass:                   0x00
bDeviceProtocol:                   0x00
bMaxPacketSize0:                   0x40 = (64) Bytes
idVendor:                        0x0FD9 = El Gato Software LLC
idProduct:                       0x0063
bcdDevice:                       0x0100
iManufacturer:                     0x01
     English (United States)  "Elgato Systems"
iProduct:                          0x02
     English (United States)  "Stream Deck Mini"
iSerialNumber:                     0x03
     English (United States)  "BL36H1A20046"
bNumConfigurations:                0x01

          ---===>Open Pipes<===---

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x81  -> Direction: IN - EndpointID: 1
bmAttributes:                      0x03  -> Interrupt Transfer Type
wMaxPacketSize:                  0x0200 = 1 transactions per microframe, 0x200 max bytes
bInterval:                         0x01

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x02  -> Direction: OUT - EndpointID: 2
bmAttributes:                      0x03  -> Interrupt Transfer Type
wMaxPacketSize:                  0x0400 = 1 transactions per microframe, 0x400 max bytes
bInterval:                         0x01

       ---===>Full Configuration Descriptor<===---

          ===>Configuration Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x02
wTotalLength:                    0x0029  -> Validated
bNumInterfaces:                    0x01
bConfigurationValue:               0x01
iConfiguration:                    0x00
bmAttributes:                      0xA0  -> Bus Powered
  -> Remote Wakeup
MaxPower:                          0x96 = 300 mA

          ===>Interface Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x04
bInterfaceNumber:                  0x00
bAlternateSetting:                 0x00
bNumEndpoints:                     0x02
bInterfaceClass:                   0x03  -> HID Interface Class
bInterfaceSubClass:                0x00
bInterfaceProtocol:                0x00
iInterface:                        0x00

          ===>HID Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x21
bcdHID:                          0x0110
bCountryCode:                      0x00
bNumDescriptors:                   0x01
bDescriptorType:                   0x22 (Report Descriptor)
wDescriptorLength:               0x00AD

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x81  -> Direction: IN - EndpointID: 1
bmAttributes:                      0x03  -> Interrupt Transfer Type
wMaxPacketSize:                  0x0200 = 1 transactions per microframe, 0x200 max bytes
bInterval:                         0x01

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x02  -> Direction: OUT - EndpointID: 2
bmAttributes:                      0x03  -> Interrupt Transfer Type
wMaxPacketSize:                  0x0400 = 1 transactions per microframe, 0x400 max bytes
bInterval:                         0x01


Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: My software becoming unresponsive + ReadFile
« Reply #2 on: May 24, 2019, 10:24:20 am »
What happens if you wait for the previous ReadFile to complete before requesting another one?

DavidClarke

  • Member
  • ***
  • Posts: 24
Re: My software becoming unresponsive + ReadFile
« Reply #3 on: May 24, 2019, 11:20:50 am »
Hi Jan,

Are you suggesting looping Result = GetOverlappedResult until it succeeds?

Or are you saying something like WaitForSingleObject?

The thing that strikes me as odd is that:

I am WaitForSingleObject until MY_OVERLAPPED.hEvent = GLOBAL_EVENT_WAIT_FOR_OVERLAPPED_READ signals there is data to be read.

Then I RESULT = ReadFile(BYVAL FILE_HANDLE,  READ_BUFFER, MY_InputReportByteLength , BYTES_READ, MY_OVERLAPPED)    and I would have thought that would just put the data in the READ_BUFFER - But it errors and says ERROR_IO_PENDING.  I have only sent 1 button press (17 bytes of data) why doesn't it just give me the data?  I would understand if there was a big stream of zillions of bytes arriving.  But 17?

Is the data supposed to arrive as part of ReadFile or do I need to only do a ReadFile after GetOverlappedResult reports the synchronous is over?

I thought this would be the easy part of my project! 

DavidClarke

  • Member
  • ***
  • Posts: 24
Re: My software becoming unresponsive + ReadFile
« Reply #4 on: May 24, 2019, 01:49:39 pm »
Hi Jan,

I was just looking at some of your code Generic_hid_cs_46.  It looks like you are calling ReadFile before you call WaitForSingleObject then calling GetOverlappedResult then doing Copy(nonManagedBuffer, inputReportBuffer, 0, numberOfBytesRead)

is the order supposed to be

ReadFile
WaitForSingleObject
GetOverlappedResult ??

I cant see where you call ResetEvent(object) to non signaled state.

I also see you create your eventObject eventObject = FileIO.CreateEvent(IntPtr.Zero, false, false, "");    with false for ManualReset and InitialState to signaled - how does it get changed to non-signaled?





« Last Edit: May 24, 2019, 01:59:00 pm by DavidClarke »

DavidClarke

  • Member
  • ***
  • Posts: 24
Re: My software becoming unresponsive + ReadFile
« Reply #5 on: May 24, 2019, 02:08:03 pm »
PROBLEM SOLVED!

Thanks to your code!

   DO


    RESULT = ReadFile(BYVAL FILE_HANDLE,  READ_BUFFER, MY_InputReportByteLength , BYTES_READ, MY_OVERLAPPED)

    RESULT = WaitForSingleObject(MY_OVERLAPPED.hEvent, 5000)

    Result = GetOverlappedResult(BYVAL FILE_HANDLE, MY_OVERLAPPED, BYTES_READ, 0)
 
  LOOP

NO  ResetEvent(GLOBAL_EVEN
T_WAIT_FOR_OVERLAPPED_READ)  -  Using CreateEvent(BYVAL 0, BYVAL %FALSE, BYVAL %FALSE, BYVAL 0)    - Opposite of what I was doing!

Thanks again!
David

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: My software becoming unresponsive + ReadFile
« Reply #6 on: May 24, 2019, 02:59:41 pm »
Happy to hear it's working! Thanks for reporting what you found!