mmv*_*sbg 5 c# wpf usb libusb libusbdotnet
我在与简单 USB 设备通信的 WPF 应用程序中使用 LibUSBDotNet 库。我只向设备发送 3 个字节作为命令,没有预期的响应,我的代码就像一个魅力:
MyUsbFinder = new UsbDeviceFinder(vid, pid);
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
wholeUsbDevice.SetConfiguration(1);
wholeUsbDevice.ClaimInterface(0);
}
writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
Run Code Online (Sandbox Code Playgroud)
然后是写入设备的过程:
byte[] update = { 0x21, some_code_generated_byte, some_code_generated_byte };
int bytesWritten;
if (MyUsbDevice != null)
{
ec = writer.Write(update, 2000, out bytesWritten);
}
Run Code Online (Sandbox Code Playgroud)
我对使用 USB 还比较陌生,但到目前为止我已经掌握了一切,而且一切正常。但是,一段时间后,在尝试再次写入设备时,我会时不时地遇到以下两个错误之一:
Win32Error:GetOverlappedResult Ep 0x01
31:The parameter is incorrect.
Win32Error:PipeTransferSubmit Ep 0x01
87:The parameter is incorrect.
Run Code Online (Sandbox Code Playgroud)
通常我需要重新启动设备/应用程序几次,然后它才能再次开始工作,然后在它再次发生之前又像魅力一样工作了几个小时......到目前为止,我也无法在测试环境中复制崩溃.
我做了很多研究,试图找到与我类似的问题/解决方案,但没有成功。我留下的唯一建议是,在某些时候设备没有足够的电量,它会进入这种错误模式,但即使这样似乎也不太可能,因为它有一个单独的 12V 电源,它所做的只是打开和关闭几个继电器...
我还尝试用大量连续命令一个接一个地淹没设备,包括垃圾命令,但它仍然可以正常工作并且行为正常,只是稍后会崩溃。
欢迎任何建议或想法,谢谢!
编辑:经过多次尝试后,我仍然无法确定问题的根本原因,但我设法达到了代码正常工作的程度,并且能够使用尝试重置设备的重新连接功能从 OverlappedResult 错误中恢复一旦开始失败。我在下面发布了一些代码,希望有人能够缩小问题的范围并确定错误的原因。
初始化期间的一些代码:
UsbDeviceFinder MyUsbFinder;
UsbDevice MyUsbDevice;
IUsbDevice wholeUsbDevice;
MyUsbFinder = new UsbDeviceFinder(vid, pid);
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// This is a "whole" USB device. Before it can be used,
// the desired configuration and interface must be selected.
// I think those do make some difference...
// Select config #1
wholeUsbDevice.SetConfiguration(1);
// Claim interface #0.
wholeUsbDevice.ClaimInterface(0);
}
writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
Run Code Online (Sandbox Code Playgroud)
接下来我尝试向设备发送一些信息。这是错误最终会弹出的地方,我在一个简单的 try/catch 块中将其作为异常捕获:
ErrorCode ec = ErrorCode.None;
if (MyUsbDevice != null)
{
ec = writer.Write(update, 2000, out bytesWritten);
if (ec != ErrorCode.None)
{
//now try to reconnect to the device, dispose writer first
writer.Dispose(); // I think this also helps to reestablish the connection and get rid of the error
if (this.reconnect())
{
//reconnected, try to write to the device again
ec = writer.Write(update, 2000, out bytesWritten);
if (ec != ErrorCode.None)
{
//log the error
}
}
}
}
else //there's no connection to the device, try to reconnect and update again
{
//now try to reconnect to the device, dispose writer first
//writer.Dispose();
if (this.reconnect())
updateRelayController();
}
Run Code Online (Sandbox Code Playgroud)
在那里,“更新”是一个字节数组,我使用适当的命令将其发送到我的设备,而 updateRelayController 实际上是具有上面将命令写入 USB 设备的代码片段的函数。最后,这是我的 reconnect() 函数,它可以在 99% 的情况下重新建立与设备的连接,而无需手动重新启动设备和插入/拔出 USB 电缆等:
public bool reconnect()
{
//clear the info so far
if (MyUsbDevice != null)
{
writer.Dispose();
wholeUsbDevice.ReleaseInterface(0);
wholeUsbDevice.Close();
MyUsbDevice.Close();
UsbDevice.Exit();
}
//now start over
MyUsbFinder = new UsbDeviceFinder(vid, pid);
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
// If the device is open and ready
if (MyUsbDevice == null)
{
//log the error
return false;
}
else
{
wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// Select config #1
wholeUsbDevice.SetConfiguration(1);
// Claim interface #0.
wholeUsbDevice.ClaimInterface(0);
}
writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止差不多就是这样。SetConfiguration/ClaimInterface/Dispose 的组合减少了我看到 OverlappedResult 错误的次数,每当发生这种情况时,从我的日志来看,我能够立即恢复并将命令重新发送到设备。正如我上面所说,这是一个解决问题的方法,因为我仍然时不时地收到错误,我仍然不知道为什么,但至少我现在可以继续使用该设备。如果有人有更多见解,很想了解有关此问题的更多信息。谢谢,我希望这会有所帮助!
不是答案!(这只是另一个问题的解决方法。它修复了关闭应用程序时给定的错误)
我在这里写这个是因为它不能作为注释来读取。(对于代码)
我刚刚注释掉了 dispose 代码,如下所示。
#region IDisposable Members
/// <summary>
/// Cancels any pending transfer and frees resources.
/// </summary>
public virtual void Dispose()
{
if (!IsCancelled) Cancel();
//I just commented here.
//int dummy;
//if (!mHasWaitBeenCalled) Wait(out dummy);
if (mPinnedHandle != null) mPinnedHandle.Dispose();
mPinnedHandle = null;
}
#endregion
~UsbTransfer() { Dispose(); }
Run Code Online (Sandbox Code Playgroud)
我无法摆脱这个恼人的错误,我可以发送第一条消息,但即使我成功重新连接到设备,也无法解决:(
端点 0x0x1 是我的端点 0x81 是设备,但收到此错误后???我不明白为什么没有 USB 托管库。
05 FA 28 81 02 00 08 94 32 Win32Error:GetOverlappedResult Ep 0x81
31:
Win32Error:PipeTransferSubmit Ep 0x01
22:
Win32Error:DeviceIoControl code 00222058 failed: LibUsbDriverIO
22:
Win32Error:PipeTransferSubmit Ep 0x01
22:
Win32Error:DeviceIoControl code 00222058 failed: LibUsbDriverIO
22:
Win32Error:PipeTransferSubmit Ep 0x01
22:
Win32Error:DeviceIoControl code 00222058 failed: LibUsbDriverIO
22:
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4328 次 |
| 最近记录: |