3

我有一个 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 连接。目前我只能通过退出我的应用程序并手动重新启动它来重新建立与设备的通信。

4

2 回答 2

1

这从来没有让我满意地解决,最终使用纯 C 在 LibUSB 上实现了我自己的“DFU”协议,然后 P/Invoke 完全避免了 LibUsbDotNet……这个解决方案似乎有效。

于 2013-02-22T15:02:15.040 回答
0

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

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");
于 2012-10-26T03:08:15.097 回答