LibUsbDotNet UsbDevice.ControlTransfer hangs



我有一个C#.Net Winforms应用程序,它使用LibUsbDotNet通过"DFU_DNLOAD"传输将固件编程到USB设备(Atmel AVR32)中,这是一种特殊的控制传输。这一切都有效,但是:一种特定类型的传输会导致设备擦除其内部闪存,但无法在正确的时间内发送ACK。

当这种情况发生时,我的LibUsbDotNet连接将无法修复地断开,这将导致一切失败。

我的代码执行以下操作:

int TransferToDevice(byte request, short value, byte[] data)
{
var setup = new UsbSetupPacket(
(byte)(UsbCtrlFlags.Direction_Out | UsbCtrlFlags.RequestType_Class | UsbCtrlFlags.Recipient_Interface),
request,
value,
0,
(short)data.Length);
int n;
IntPtr unmanagedPointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(data.Length);
System.Runtime.InteropServices.Marshal.Copy(data, 0, unmanagedPointer, data.Length);
// UsbDevice obtained else-where
if (!UsbDevice.ControlTransfer(ref setup, unmanagedPointer, data.Length, out n))
{
n = 0;
}
System.Runtime.InteropServices.Marshal.FreeHGlobal(unmanagedPointer);
return n;
}
// In order to do a "DFU_DNLOAD", the method above is used as follows:
TransferToDevice(DFU_DNLOAD, Transactions++, data); // "data" is the payload
// where DFU_DNLOAD is:
private const byte DFU_DNLOAD    = 1;
// Transactions is 
short Transaction = 0;

上述代码有效(设备正确接收到"DFU_DNLOAD"消息),但缺少ACK是问题所在。一旦发生错误,每次尝试与设备通信(即使我试图重新初始化所有内容)都会失败,直到设备断开连接并重新插入。。。

当这个错误发生时,我希望能够以某种方式重置或重新初始化USB连接。目前,我只能通过退出应用程序并手动重新启动来重新建立与设备的通信。

这个问题从未得到我满意的解决,最终使用纯C在LibUSB的顶部实现了我自己的"DFU"协议,并对其进行了p/Invoke,完全避免了LibUsbDotNet。。。这个解决方案似乎奏效了。

只是猜测,但如果数据是短数组,则应该调整的缓冲区大小

int numberOfValues = data.Length;
int size = Marshal.SizeOf(typeof(short)); 
IntPtr unmanagedPointer = Marshal.AllocHGlobal(numberOfValues*size);
if (unmanagedPointer == IntPtr.Zero)
throw new OutOfMemoryException("Unable allocate memory");

最新更新