簡體   English   中英

LibUSBDotNet:使用USB設備一段時間后出現奇怪的錯誤

[英]LibUSBDotNet: Strange errors after working with USB device for awhile

我在WPF應用程序中使用LibUSBDotNet庫,該應用程序與簡單的USB設備通信。 我只是將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);

然后寫入設備的過程:

byte[] update = { 0x21, some_code_generated_byte, some_code_generated_byte };
int bytesWritten;

if (MyUsbDevice != null)
{
     ec = writer.Write(update, 2000, out bytesWritten);
}

我對使用USB比較陌生,但我到目前為止這一切都很有效。 但是,經過一段時間,不時地嘗試再次寫入設備時,我會得到以下兩個錯誤之一:

Win32Error:GetOverlappedResult Ep 0x01
31:The parameter is incorrect.

Win32Error:PipeTransferSubmit Ep 0x01
87:The parameter is incorrect.

通常我需要重新啟動設備/應用程序幾次才能再次開始工作,然后再過幾個小時就像魅力一樣再次發生...我到目前為止還沒能在測試環境中復制崩潰。

我做了很多研究,試圖找到一個類似於我的問題/解決方案但沒有成功。 我留下的唯一建議是,在某些時候設備沒有足夠的功率,它進入這種錯誤模式,但即使這似乎不太可能,因為它有一個單獨的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);

接下來我正在嘗試向設備發送一些信息。 這是錯誤最終會彈出的地方,我在一個簡單的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(); 
}

那里的“update”是一個字節數組,我用適當的命令發送到我的設備,而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;
    }
}

到目前為止,這幾乎就是這樣。 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(); }

我無法擺脫這個惱人的錯誤,我可以發送第一條消息,但即使我重新連接到設備有沒有治愈:(

EndPoint 0x0x1是我的終端端點0x81是設備但是在收到此錯誤后???? 我不明白為什么沒有usb的托管lib。

         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:

我也遇到了錯誤:

Win32Error:PipeTransferSubmit Ep 0x02
87:The parameter is incorrect.

我發現我使用了錯誤的WriteEndpointId。 請參閱API文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM