【问题标题】:Ruby libusb: Stall errorRuby libusb:停止错误
【发布时间】:2015-09-14 20:52:50
【问题描述】:

所以我一直在玩 PS2 游戏的控制器,Buzz。我已经成功使用 libusb 来轮询和读取按钮,一切都是欢乐和光明的。

问题是,我喜欢使用内置灯来向正在使用它们的人发出信号(特别是向他们展示谁先发出嗡嗡声)。我知道有灯,我知道 PS2 可以随意打开和关闭它们,我知道 someone has managed it with python。所以我开始用 Ruby 中的 libusb 实现他们的代码。

我已经复制了他们正在进行的 SET_CONFIGURATION 调用,但我不断收到此错误:

/home/ajfaraday/.rvm/gems/ruby-2.2.1/gems/libusb-0.5.0/lib/libusb/dev_handle.rb:539:in `submit_transfer': 
error TRANSFER_STALL (LIBUSB::ERROR_PIPE)

我在网上找不到任何关于这个错误是什么的材料,除了它是一个 USB 管道错误,它正在被 libusb 转换为 TRANSFER_STALL。

我也是用python写出来的,上面论坛的具体行,我得到的东西看起来像同样的错误:

usb.core.USBError: [Errno 32] Pipe error

所以我不知道自己做错了什么。我已经成功地对成功响应 (\x00) 进行了相反的调用 (GET_CONFIGURATION)。

这是我的复制脚本(取决于 libusb gem):

require 'libusb'

usb_context = LIBUSB::Context.new
device = usb_context.devices(
  idVendor: 0x054c, idProduct: 0x0002
).first
handle = device.open

puts 'get configuration:'
x = handle.control_transfer(
  :bmRequestType => "10000000".to_i(2),
  :bRequest => 8,
  :wValue => 0,
  :wIndex => 0,
  :dataIn => 1
)  
puts x.inspect

puts 'set configuration:'
x = handle.control_transfer(
  :bmRequestType => "00000000".to_i(2),
  :bRequest => 9,
  :wValue => 0,
  :wIndex => 0,
  :dataOut => "\x00\xFF\xFF\xFF\xFF"
)
puts x.inspect

这是它的输出:

get configuration:
"\x00"
set configuration:
/home/ajfaraday/.rvm/gems/ruby-2.2.1/gems/libusb-0.5.0/lib/libusb/dev_handle.rb:539:in `submit_transfer': error TRANSFER_STALL (LIBUSB::ERROR_PIPE)
    from /home/ajfaraday/.rvm/gems/ruby-2.2.1/gems/libusb-0.5.0/lib/libusb/dev_handle.rb:515:in `control_transfer'
    from sketches/raw_script.rb:22:in `<main>'

看起来管道错误意味着我发送的设置或数据有问题,但我无法在任何地方找到它。

我试过了:

  • 也将不同数量的数据放入 dataOut 属性中。
  • 先分离内核驱动,同时重新打开句柄
  • 将 dataOut 属性表示为数组
  • 在另一台 (linux) 机器上运行它
  • 检查 libusb 源代码(它正在转换 USB 消息,仅此而已)
  • 使用http://www.usbmadesimple.co.uk/ums_4.htm 中定义的不同类型的消息

我将非常感谢任何帮助。这真的应该是可能的,我知道它已经完成了。

【问题讨论】:

  • 我现在没有时间去调试这个,但你的错误似乎来自这里:github.com/larskanis/libusb/blob/master/lib/libusb/…
  • 我已将其追溯到图书馆。不幸的是,它实际上只是告诉我它正在翻译 USB 错误。我可能会更新问题以反映这一点。
  • 我很好奇发送字符串而不是原始字节是否会造成麻烦。如果 dataOut 发送原始字节会发生什么::dataOut =&gt; [0x00, 0xFF, 0xFF, 0xFF, 0xFF]
  • API 调用 :dataOut: rubydoc.info/gems/libusb/LIBUSB%2FDevHandle%3Acontrol_transfer 中的字符串,它不能很好地处理数组... 'control_transfer': undefined method 'bytesize' for [0, 255, 255, 255, 255]:Array (NoMethodError)
  • 这种东西非常依赖于你使用的操作系统,你忽略了。

标签: ruby usb libusb


【解决方案1】:

Libusb 提供了两个名为libusb_set_configurationlibusb_get_configuration 的函数。您应该尝试使用它们而不是滚动您自己的控制转移来做同样的事情。它们记录在这里:

http://libusb.sourceforge.net/api-1.0/group__dev.html

您可以查看您正在使用的 Ruby libusb 绑定的源代码或文档,以了解如何从 Ruby 中调用它们。

此外,对 USB 设备进行配置是一件不寻常的事情。您应该确保操作系统上的驱动程序尚未将设备置于正确的配置中。也许你不需要设置配置。

此外,如果此控制器是 HID,hidapi 库可能比 libusb 更适合。

【讨论】:

  • 也许我试图发送错误的信息,我是按照 python 论坛的引导。你知道我需要发送什么样的 USB 信息来产生 HID 信息吗? (我在这里找到了 HID LED 的参考资料freebsddiary.org/APC/usb_hid_usages.php
  • HID 是一个非常灵活的协议,每个设备都可以为其期望的数据定义不同的格式。此信息位于 HID 报告描述符中。我碰巧不知道您的特定设备的格式。如果你发现了一些基于 libusb 的 Python 代码,那么你应该仔细查看代码调用的 libusb 函数,并在 Ruby 中做同样的事情。请记住,libusb 是一个 C 库,您可能需要查看 Ruby 绑定的源代码和 Python 绑定的源代码以了解发生了什么。
  • 我在计算相关绑定方面的困难相对较小,但在找出要发送的确切消息方面更困难。然而,HID 报告听起来可能是我的下一步行动。
  • 嘿,你知道如何在 ruby​​ 中从 USB 发送和获取文件吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多