pololu / pololu-usb-sdk

Example code for making your own PC applications that control Pololu USB Devices.
Other
29 stars 24 forks source link

Port to .NET Standard for W10 IoT on Raspberry Pi #1

Open dllama opened 6 years ago

dllama commented 6 years ago

Hello, I am trying to port the SMC lib to .NET Standard so I can run it on W10 IoT.

Porting SMC and compiling it with .NET Standard succeeded but I get the bellow error from the UsbWrapper dependency when connecting to a device.

Any ideas / help to resolve would be much appreciated. If the UsbWrapper could be available on GitHub as open source it would also be helpful.

Thank you, Douw

System.Exception: There was an error connecting to the device. ---> System.ComponentModel.Win32Exception: Unabled to create a handle for the device. at Pololu.WinusbHelper.Winusb.listConnect(IntPtr listHandle, Byte index, Guid deviceInterfaceGuid) at Pololu.WinusbHelper.Winusb.connect(Guid deviceInterfaceGuid, Int32 deviceInstance) at Pololu.UsbWrapper.UsbDevice..ctor(DeviceListItem deviceListItem) --- End of inner exception stack trace --- at Pololu.UsbWrapper.UsbDevice..ctor(DeviceListItem deviceListItem) at Pololu.SimpleMotorController.Smc..ctor(DeviceListItem deviceListItem) at SmartTank.UWP.SettingsPage.TestMotor(String serialNumber) at SmartTank.UWP.SettingsPage.PortTestButton_Click(Object sender, RoutedEventArgs e)

DavidEGrayson commented 5 years ago

Hello, Douw. Can you get the NativeErrorCode property of the Win32Exception that was thrown? It might give a little more information about what went wrong. There is code in this repository that shows how to get NativeErrorCode and format a nice error message.

dllama commented 5 years ago

@DavidEGrayson, it did not give anymore detail, but here is the better format: There was an error connecting to the device. Unabled to create a handle for the device. Error code 0x0.

The inner exception code is: System.ComponentModel.Win32Exception (0x80004005): Unabled to create a handle for the device.

DavidEGrayson commented 5 years ago

Unfortunately, there was a bug in UsbWrapper: when it called CreateFile to open a handle to a USB device, and CreateFile failed, it was not properly recording the error code in the exception it threw. I have fixed that in version 1.5.2 of the library, which is now available in this repository (as a precompiled DLL). I also have added the source code of UsbWrapper_Windows to this repository, which might help you figure out what is going on.

Please let me know what you find out. I'd be particularly interested to know what the error code from CreateFile really is and whether you are able to get around it.

dllama commented 5 years ago

@DavidEGrayson, the new error is: Unable to create a handle for the device (\\?\usb#vid_1ffb&pid_00a1&mi_02#6&3a5eb940&0&0002#{756291c5-51a5-417a-bf39-bd4df9c0b1df}).

Will debug some more and let you know what I find.

DavidEGrayson commented 5 years ago

What is the NativeErrorCode (i.e. the error code generated by CreateFile)?

dllama commented 5 years ago

It fails on listDestroy without a NativeErrorCode, here:

[DllImport("setupapi.dll", SetLastError = true)]
static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
dllama commented 5 years ago

@DavidEGrayson, sorry, the above was not the issue.

The error occur in the listConnect method. I found why the NativeErrorCode is 0, the memory is cleared before the last Win32 error is retrieved. I added errorX before the memory clear function and can now see that it is in fact error code 5.

image

DavidEGrayson commented 5 years ago

Odd, in .NET 3.5 I am pretty sure that Marshal.FreeHGlobal does not change the error code. Anyway, the error code 5 is ERROR_ACCESS_DENIED so the advice you see a few lines below applies: you should make sure you close all existing handles to the device before opening a new one, because only one can exist at a time.

dllama commented 5 years ago

@DavidEGrayson, the issue does not seem to be open handles, but rather the version of .NET Standard used by UWP. Running the same simple code on a console app works, but fails on UWP even when they reference the same .NET Standard libs. I am busy trying to see if I can get around this.