Author Topic: Another Question on c# Generic Hid v5.0 using filestreams  (Read 18277 times)

GaryM

  • Member
  • ***
  • Posts: 5
Another Question on c# Generic Hid v5.0 using filestreams
« on: January 13, 2012, 11:26:36 pm »
I have been using this code example as a basis for a GUI to communicate with an embedded device I am developing.  Been using it for several months as I add capabilities to the GUI and embedded device and it has worked GREAT.  Many runs have been over a solid week with no issues

A few days ago, I figured it was time to handle device removal and attachment.  One thing I ran into was after reattaching and running FindTheHid and trying to read interrupt reports, I would get the following exception:

"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

on the following statement
fileStreamDeviceData.BeginRead(inputReportBuffer, 0, inputReportBuffer.Length, new AsyncCallback(GetInputReportData), inputReportBuffer);

So I spent way too much time trying to debug this.  Finally decided to go back to the original generic_hid example and run it in the following manner.

1.) Start Generic HID GUI
2.) Enter my vendor and product ID
3.) Click on "Find Device" --- device found fine
4.) Click on "Send and Receive Data->Once" -- report read correctly
5.) Physically Disconnect/Reconnect Device
6.) Either Do "Find My Device followed by Once", or just do "Once"

Doing this recreates the problem/exception

I did spend time researching this on this forum but got the impression that the streams version was updated to include issues found earlier but was a little confused as some of the bugs seemed to imply it was stream related.

Any ideas?

Love your books Jan!

Gary


GaryM

  • Member
  • ***
  • Posts: 5
Re: Another Question on c# Generic Hid v5.0 using filestreams
« Reply #1 on: January 13, 2012, 11:45:39 pm »
On a side note, I added a button to my GUI which simply calls the Close Connection Function.  Once I am up and running and reading reports, clicking this button causes the same behavior once I call FindTheHid and start trying to read reports again.

Gary

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Another Question on c# Generic Hid v5.0 using filestreams
« Reply #2 on: January 14, 2012, 01:05:36 pm »
I'll take a look at it, but my guess would be that it has to do with leaving something open that needs to be closed on detach.

Jan

GaryM

  • Member
  • ***
  • Posts: 5
Re: Another Question on c# Generic Hid v5.0 using filestreams
« Reply #3 on: January 14, 2012, 04:11:55 pm »
Thanks for the quick response.

Yes, that is what I think is going on as well,  it appears that fileStreamDeviceData and hidHandle never get set to null when closing.  Not sure what this means.  I am by no means a c# or .net person.

        private void CloseCommunications()
        {
            // The next attempt to communicate will get new handles and FileStreams.
            myDeviceDetected = false;

            if (fileStreamDeviceData != null)
            {
                fileStreamDeviceData.Close();
            }

            if ((hidHandle != null) && (!(hidHandle.IsInvalid)))
            {
                hidHandle.Close();
            }


        }

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Another Question on c# Generic Hid v5.0 using filestreams
« Reply #4 on: January 16, 2012, 05:19:32 pm »
I did this:

1.) Start Generic HID GUI
2.) Enter my vendor and product ID
3.) Click on "Find Device" --- device found fine
4.) Click on "Send and Receive Data->Once" -- report read correctly
5.) Physically Disconnect/Reconnect Device
6.) Either Do "Find My Device followed by Once", or just do "Once"

and didn't get the error you're seeing.

You could try placing a breakpoint at CloseCommunications and see if everything closes properly.

Here are a couple of suggested fixes that aren't on the web version of the code yet:

http://www.janaxelson.com/forum/index.php?topic=696.msg2584#msg2584
http://www.janaxelson.com/forum/index.php?topic=708.msg2634#msg2634

Jan
« Last Edit: July 25, 2014, 10:50:33 am by Jan Axelson »

GaryM

  • Member
  • ***
  • Posts: 5
Re: Another Question on c# Generic Hid v5.0 using filestreams
« Reply #5 on: January 16, 2012, 08:44:08 pm »
Spent about 30 hours debugging this without success, monitored the hidHandle and fileStreamDeviceData and nothing looked out of the ordinary, both looked identical before and after reconnecting after the disconnection. Tried literally hundreds of things with no success including the first link you posted.  The second link does not compile as posted (looking at MSDN, it seems like it should but doesnt) so I used this instead

IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt64() + 4);

That being said, none of this worked.

So I read the post about having issues with HidP_GetValueCaps so I commented that out of Hid.cs->GetDeviceCapabilities and it all works fine.

Perhaps some USB devices cause this error and some dont.  I would like to understand what is going on but after a solid 3+days of this, I think I need a break.

Gary
« Last Edit: January 16, 2012, 10:15:45 pm by GaryM »

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Another Question on c# Generic Hid v5.0 using filestreams
« Reply #6 on: January 16, 2012, 11:07:30 pm »
Yes, my code doesn't use HidP_GetValueCaps and there is no harm in commenting out the call to it.

Jan

vanweric

  • Member
  • ***
  • Posts: 24
Re: Another Question on c# Generic Hid v5.0 using filestreams
« Reply #7 on: January 18, 2012, 05:28:56 pm »
Gary -

I ran into something that might be similar, and wrote about it in this post: http://www.janaxelson.com/forum/index.php?topic=668.0

Long story short, the allocated memory was too small, so HidP_GetValueCaps was overwriting "something else"... I never tracked it down.  I think fixing the definition of the structure will do the trick, but I gave up because I didn't need those results either.

Also, it is safe to do pointer arithmetic in C# without wrapping it with ToIntXX and new IntPtr.  Your line should simply read  IntPtr pDevicePathName = detailDataBuffer + 4;
« Last Edit: July 24, 2014, 09:38:03 am by Jan Axelson »

ksrsrinivasan

  • Member
  • ***
  • Posts: 5
Re: Another Question on c# Generic Hid v5.0 using filestreams
« Reply #8 on: December 10, 2013, 01:22:54 pm »
Just hit this nagging issue on a production system and spent several hours troubleshooting this. It is so hard to pinpoint the cause when the corruption happens on HidP_GetValueCaps and the application crashes elsewhere with an access violation, especially when the point of crash is random. From what I have seen, almost all of the examples and HID source code that I can find on the web got this structure wrong. I had to take a step back and look at MSDN documentation and compare the structures to find the issue. Anyways, below is the structure definition I came up with. Specifically look at the last 8 fields starting at offset 32. That is where all of the code got the data type and field offset wrong.

Code: [Select]
        [StructLayout(LayoutKind.Explicit, CharSet=CharSet.Ansi, Pack=4)]
        public struct HidP_Value_Caps
        {
            [FieldOffset(0)]
            public UInt16 UsagePage;
            [FieldOffset(2)]
            public byte ReportID;
            [MarshalAs(UnmanagedType.I1)]
            [FieldOffset(3)]
            public bool IsAlias;
            [FieldOffset(4)]
            public UInt16 BitField;
            [FieldOffset(6)]
            public UInt16 LinkCollection;
            [FieldOffset(8)]
            public UInt16 LinkUsage;
            [FieldOffset(10)]
            public UInt16 LinkUsagePage;
            [MarshalAs(UnmanagedType.I1)]
            [FieldOffset(12)]
            public bool IsRange;
            [MarshalAs(UnmanagedType.I1)]
            [FieldOffset(13)]
            public bool IsStringRange;
            [MarshalAs(UnmanagedType.I1)]
            [FieldOffset(14)]
            public bool IsDesignatorRange;
            [MarshalAs(UnmanagedType.I1)]
            [FieldOffset(15)]
            public bool IsAbsolute;
            [MarshalAs(UnmanagedType.I1)]
            [FieldOffset(16)]
            public bool HasNull;
            [FieldOffset(17)]
            public System.Char Reserved;
            [FieldOffset(18)]
            public UInt16 BitSize;
            [FieldOffset(20)]
            public UInt16 ReportCount;
            [FieldOffset(22)]
            public UInt16 Reserved2a;
            [FieldOffset(24)]
            public UInt16 Reserved2b;
            [FieldOffset(26)]
            public UInt16 Reserved2c;
            [FieldOffset(28)]
            public UInt16 Reserved2d;
            [FieldOffset(30)]
            public UInt16 Reserved2e;
            [FieldOffset(32)]
            public UInt64 UnitsExp;
            [FieldOffset(36)]
            public UInt64 Units;
            [FieldOffset(40)]
            public Int64 LogicalMin;
            [FieldOffset(44)]
            public Int64 LogicalMax;
            [FieldOffset(48)]
            public Int64 PhysicalMin;
            [FieldOffset(52)]
            public Int64 PhysicalMax;
            // The Structs in the Union
            [FieldOffset(56)]
            public HidP_Range Range;
            [FieldOffset(56)]
            public HidP_NotRange NotRange;
        }

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Another Question on c# Generic Hid v5.0 using filestreams
« Reply #9 on: December 10, 2013, 10:20:30 pm »
Thank you for posting this!