【问题标题】:User mode USB isochronous transfer from device-to-host从设备到主机的用户模式 ​​USB 同步传输
【发布时间】:2011-11-01 09:00:42
【问题描述】:

我目前正在尝试从用户空间与 USB 音频设备进行交互。我目前已经完全枚举了设备,并且我已经设置了接口并将替代接口设置为接口非零带宽替代接口。

首先我不得不说我不能使用像 libusb 这样的东西。我需要通过 Linux 的 USB 设备文件系统来执行此操作。

据我所知,我已准备好开始接收同步数据。但是,我几乎找不到有关如何进行同步传输的信息。

据我所知,我需要填充一个 usbdevfs_urb 结构,但我完全不确定如何填充这个结构。

此外,一旦我填写了这个结构,我是否认为我需要调用以下内容:

int retSubmit   = ioctl( fd, USBDEVFS_SUBMITURB, &usbRequest );

然后一旦提交,我可以等待请求完成使用

USBDEVFS_REAPURBNDELAY

在 REAPURBNDELAY 的情况下,我需要传递的参数到底是什么?

我是不是在正确地吠叫?

任何信息将不胜感激。

提前致谢!

编辑:

我尝试按如下方式进行同步传输:

usbdevfs_urb&   urbRequest      = *(usbdevfs_urb*)malloc( 384 );
urbRequest.type                 = USBDEVFS_URB_TYPE_ISO;
urbRequest.endpoint             = mpEndpoint->GetEndpointAddress();//mpEndpoint->GetEndpointIndex();
urbRequest.status               = 0;
urbRequest.flags                = USBDEVFS_URB_ISO_ASAP;
urbRequest.buffer               = pData;
urbRequest.buffer_length        = 0;
urbRequest.actual_length        = 0;
urbRequest.start_frame          = 0;
urbRequest.number_of_packets    = 1;
urbRequest.error_count          = 0;
urbRequest.signr                = 0;
urbRequest.usercontext          = pData;

usbdevfs_iso_packet_desc* pIsoPacketDesc    = &urbRequest.iso_frame_desc[0];
pIsoPacketDesc->length          = 384;
pIsoPacketDesc->actual_length   = 0;
pIsoPacketDesc->status          = 0;

不幸的是,这给了我一个 -28 (ENOSPC) 的错误。

<7>[ 3184.243163] usb 1-1: usbfs: usb_submit_urb returned -28

我不明白为什么没有足够的 USB 总线带宽。只有 1 个 USB 端口,我的设备是唯一插入其中的设备。

有什么想法吗?

【问题讨论】:

  • @Jim Clay 因为有问题的特定平台是 android,我已经有一个打开的文件描述符,由于权限,我不能使用 libusb 打开设备 ...
  • 嗨 Goz,我目前正在尝试解决相同的问题 - android 上的同步传输,避免使用 libusb。有什么方法可以发布工作代码示例吗?我目前的症结是结构定义和请求值。你在哪里采购这些?提前致谢。
  • @Gusdor:它相当复杂。基本上,我从usb.org 提供的文档中解决了所有问题......在某些时候,我实际上可能会转而做一个与android usb api一起工作的同步传输的android样式api。不过,它的工作量很大,我宁愿不花时间,除非我能找人付钱;)我有一个传递给我的 libusb 版本,虽然不需要 root ...
  • 别担心,@Goz。我在周末开始插入 USB 音频规范。它比它读起来更难,所以我相信我会到达那里。删除 HID 驱动程序仍然是“专业提示”,谢谢!
  • @Goz 我还有一个问题,因为我仍在尝试破解 iso 传输。 ioctl 将 errno 设置为“2”。这显然不是 ioctl 的有效代码,但它让我怀疑我的端点地址或文件描述符不正确。我已经阅读了有关编组文件描述符以在本机代码中使用的有趣内容,但是 FileDescriptor 类和 Parcel API 使对该问题的查询变得复杂。我正在调用 USBConnection.getFileDescriptor():int。这是正确的吗?

标签: c linux usb


【解决方案1】:

好吧,事实证明问题是由于安卓操作系统放置了一个 HID 驱动程序来处理 HID 控件。这似乎阻塞了带宽。从 HID 接口分离这些驱动程序会释放带宽,从而允许同步传输继续进行。

您可以通过以下操作分离内核驱动程序:

usbdevfs_ioctl command;
command.ifno        = mpInterface->GetInterfaceNumber();
command.ioctl_code  = USBDEVFS_DISCONNECT;
command.data        = NULL;

int ret = ioctl( fd, USBDEVFS_IOCTL, &command );

否则我所做的是正确的。

【讨论】:

    【解决方案2】:

    我知道您不使用 libusb 的唯一原因是您无法自己打开 USB 设备,但您确实有一个指向它的文件描述符。

    如果这一切都是正确的,你为什么要尝试重新实现 libusb 中的所有内容,而不是仅仅重新实现将文件描述符作为参数和你的结构 usb_device* 的 usb_open() 函数。您可以从 libusb usb_open() 源代码中获取大部分代码,其余部分使用 libusb。

    【讨论】:

    • 我不明白您对 LGPL 的问题,您是否正在开发专有软件?如果是这种情况,您仍然可以将其与 LGPL 库链接,而不是 GPL 库。如果我没记错的话,你唯一的义务就是提供一种与另一个库链接的方法。如果您正在分发动态链接的二进制文件,那么您没有问题。如果您要提供静态链接的二进制文件,则必须提供二进制文件的目标文件,以便人们可以轻松地重新链接到其他东西。
    • 唉,我无法做出这样的选择。
    • 碰巧我一直在试验 libusb。我植根了我的设备,并且可以提交 ISOC 请求。然后……你猜怎么着?错误号=28 :(
    • 破解了。如果您有兴趣找出问题所在,请参阅我的回答!
    【解决方案3】:

    我为用户模式 ​​USB 同步传输编写了一个 Java 类:UsbIso

    它使用JNA 通过IOCTL 调用访问USBFS API。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-31
      • 2022-12-16
      • 2012-07-14
      • 1970-01-01
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      • 2012-07-05
      相关资源
      最近更新 更多