3

私は、LibUsbDotNet を使用して、特別な種類の制御転送である「DFU_DNLOAD」転送を使用してファームウェアを USB デバイス (Atmel AVR32) にプログラムする C# .Net Winforms アプリケーションを持っています。これはすべて機能しますが、デバイスが内部フラッシュを消去する特定の種類の転送は、正しいタイミングで 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」プロトコルを実装することになり、LibUsbDotNetを完全に回避してP/Invokeを実行しました...このソリューションは機能しているようです。

于 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 に答える