-1

我在 C# 中使用 WinUSB 与使用批量传输的 PIC4550 通信,并且遇到了一个奇怪的问题。

当前代码可以正常工作,但仍然包含一些我想删除的调试 Console.Write() 行,因为它们使代码变得混乱。删除它们并使用调试器单步执行代码也可以正常工作。

不幸的是,当我删除调试行时,代码停止工作。“结果”字节数组返回为 null,并引发 null 引用异常。

这里发生了什么?

    public static ulong GetBulkData(Device d, ref byte[] result)
    {

        byte _inPipe = 0x81;
        ulong bufferlength = 64;


        NativeOverlapped gOverlapped = new NativeOverlapped();
        GCHandle pinnedOverlap = new GCHandle();

        gOverlapped.InternalLow = IntPtr.Zero;
        gOverlapped.InternalHigh = IntPtr.Zero;
        gOverlapped.OffsetLow = 0;
        gOverlapped.OffsetHigh = 0;
        gOverlapped.EventHandle = Win32.CreateEvent(IntPtr.Zero, true, false, IntPtr.Zero);
        pinnedOverlap = GCHandle.Alloc(gOverlapped, GCHandleType.Pinned);



        ulong lengthtransferred = 0;
        Array.Clear(result, 0, result.Length);
        GCHandle pinnedBuffer = GCHandle.Alloc(result, GCHandleType.Pinned);
        Win32.WinUsb_ReadPipe(d._handle, _inPipe, pinnedBuffer.AddrOfPinnedObject(), bufferlength, ref lengthtransferred, pinnedOverlap.AddrOfPinnedObject());
        int hr = Win32.GetLastError();

        bool bResult = (hr == 0);
        pinnedOverlap.Free();
        if (bResult)
        {
            foreach (byte b in result)
                Console.Write(" " + b);
            return lengthtransferred;
        }
        else
        {
            Console.WriteLine("USB Error Code " + hr);
            uint pLength = 0;
            // Deal with the error code
            switch (hr)
            {
                case Win32.ERROR_IO_PENDING:
                    // Asynchronous I/O is still in progress... wait for it to complete
                    int evt = Win32.WaitForSingleObject(gOverlapped.EventHandle, 10);
                    switch (evt)
                    {
                        case Win32.WAIT_OBJECT_0:

                            // I/O completed.
                            // Check on the results of the asynchronous read and update the nBytesRead
                            bResult = Win32.WinUsb_GetOverlappedResult(d._handle, pinnedBuffer.AddrOfPinnedObject(), out pLength, true);
                            if (bResult)
                            {

                                // Success
                                Console.WriteLine("USB overlap received");
                            }

                            break;

                        case Win32.WAIT_TIMEOUT:
                        default:

                            // I/O error or timeout.  Cancel outstanding I/O.
                            Win32.CancelIo(d._handle);
                            break;
                    }
                    break;

            }
            pinnedBuffer.Free();
            return pLength;
        }

    }
4

2 回答 2

0

它可能与以下行有关:

foreach (byte b in result)
            Console.Write(" " + b);
        return lengthtransferred;

目前您只在 foreach 中写入控制台,您可能还需要删除 foreach 循环

于 2015-12-23T22:24:58.657 回答
0

解决方案,适用于以后遇到此问题的任何人。看起来这是一个时间问题。bResult 返回为真,因为传输成功,但信息实际上并没有放入我使用 GCHandle 引用的字节数组中。

解决方案是通过将重叠句柄更改为空指针来强制 Winusb 同步传输。WinUsb_ReadPipe 行已更改为:

    Win32.WinUsb_ReadPipe(d._handle, _inPipe, pinnedBuffer.AddrOfPinnedObject(), bufferlength, ref lengthtransferred, IntPtr.Zero);

而且效果很好。

这篇文章的启发

于 2016-01-07T00:45:38.953 回答