【问题标题】:LibUsbDotNet USBEndpointReader DataReceived event is not firing when I expect it toLibUsbDotNet USBEndpointReader DataReceived 事件在我期望的时候没有触发
【发布时间】:2014-05-12 16:07:55
【问题描述】:

我有一个 USB 设备,我需要通过 LibUsbDotNet 从中读取数据。

如果我在成功打开设备后使用以下代码...

    protected UsbEndpointReader _libUsbReader = null;
    protected UsbEndpointWriter _libUsbWriter = null;

.

        IUsbDevice wholeUsbDevice = PhysicalLibUSBDevice 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.

            // Select config #1
            wholeUsbDevice.SetConfiguration(1);

            // Claim interface #0.
            wholeUsbDevice.ClaimInterface(0);
        }


        // Create the reader and writer streams
        _libUsbReader = PhysicalLibUSBDevice.OpenEndpointReader(LibUsbDotNet.Main.ReadEndpointID.Ep01);
        _libUsbWriter = PhysicalLibUSBDevice.OpenEndpointWriter(LibUsbDotNet.Main.WriteEndpointID.Ep02);

        _libUsbReader.DataReceivedEnabled = true;
        _libUsbReader.DataReceived += OnDataReceived;
        _libUsbReader.ReadThreadPriority = System.Threading.ThreadPriority.Highest;
        _libUsbReader.ReadBufferSize = 32;

并定义方法:

    private void OnDataReceived(object sender, EndpointDataEventArgs e)
    {
        Console.WriteLine("Data received");
    }

事件永远不会触发。我知道我的代码正在接收数据包,因为我连接了一个 USB 分析器并且可以看到它们进入。

如果我更改代码以消除对事件回调的依赖,而是在后台线程上使用下面的循环来读取阅读器对象

while(true)
{
     ErrorCode ec = ErrorCode.None;
     Thread.Sleep(5);
     int bytesRead;
     byte[] buffer = new byte[32];
     ec = _libUsbReader.Read(buffer, 1000, out bytesRead); 
     if(bytesRead>0) Console.WriteLine("Data Received");
}

然后一切正常。

我尝试过使用我初始化的顺序、值等,但仍然没有得到任何乐趣。如果我使用 DataReceived 事件,谁能建议为什么事件没有触发?

我正在使用 LibUsbDotNet 2.2.8。

【问题讨论】:

  • 该事件可以触发,但不是每次都触发,在我的试用中 3 次中的 1 次。你的 while(true) 代码救了我,非常感谢。

标签: c# .net usb libusbdotnet


【解决方案1】:

我知道这是旧的,但在你的代码中:

...
_libUsbReader.DataReceivedEnabled = true;
_libUsbReader.DataReceived += OnDataReceived;
_libUsbReader.ReadThreadPriority = System.Threading.ThreadPriority.Highest;
_libUsbReader.ReadBufferSize = 32;
...

我在DataReceived 之后设置了DataReceivedEnabled(不确定这是否会有所不同)。

另外,我不会更改线程优先级和ReadBufferSize。后者默认为 4096。当数据到达时,事件的EndpointDataEventArgs 参数具有Count 属性,其中包含实际接收到的字节数。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    请尝试这样:

    _libUsbReader.DataReceived += mEp_DataReceived;
    
    private void mEp_DataReceived(object sender, EndpointDataEventArgs e) 
    {
        try
        {
            Invoke(new OnDataReceivedDelegate(OnDataReceived), new object[] { sender, e });
        }
        catch
        {
            closeDevice();
        }
    }
    

    【讨论】:

      【解决方案3】:

      打开端点读取时,应将端点类型定义为interrupt,否则Datarecieve事件不会触发。 (可选定义读缓冲区的大小)

      在您的代码中,您只需要修改这一行:

      _libUsbReader = PhysicalLibUSBDevice.OpenEndpointReader(LibUsbDotNet.Main.ReadEndpointID.Ep01, 64, EndpointType.Interrupt);
      

      【讨论】:

        【解决方案4】:

        我认为解决方案是您应该在事件中读取端点内容(或丢弃它)。我遇到了同样的问题,只在控制台打印我只输入了 1 次的消息。当我使用读取命令处理端点上的数据时,问题似乎解决了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多