【发布时间】:2015-02-10 09:59:46
【问题描述】:
我们有一个基于 TI 的 CC2531 的嵌入式设备,它具有(除了控制 EP0 和一些仅 IN 端点)一个既是 IN 又是 OUT 的端点。我们注意到 windows 发送 OUT 报告的方式和 linux 的方式有所不同。这实际上让我们困惑了很长时间,但我们一直无法找到解释。
在我看来,linux 是按照它应该的方式来做的:OUT 报告是通过与 HID 报告相关联的端点传输的,因为我们从 libusb 获得它:
Item | Dev | EP | Status | Speed |Payload
-----------------+-----+----+--------+-------+-------------------------------
OUT transaction | 13 | 4 | ACK | FS | 64 bytes (90 13 00 00 00 00 ..
另一方面,Windows 通过控制端点 (EP0) 发送它。我们使用 setup API 找到具有我们需要的用途的设备,为 IN 和 OUT 打开它,并使用相同的文件描述符进行读取和写入。 EP4 IN 报告可以通过这个文件描述符很好地接收,但是通过相同的文件描述符写入报告,最终会在 EP0:
Item | Dev | EP | Status | Speed |Payload
-------------------+-----+----+--------+-------+-------------------------------
Class request OUT | 25 | 0 | OK | FS | 64 bytes (90 13 00 00 00 00 ..
(抱歉,(暂时)无法发布图片。我手动复制了 Ellisys 报告)
嵌入式设备不检查在哪个 EP 上接收到 OUT 报告(即,在处理 HID 事件时,EP0 上的 SET 报告将汇集到与其他端点上发现的 OUT 报告相同的功能),因此它会以任何方式响应。
我的问题是:这两种方法都正确吗?如果不正确,哪个正确,哪个不正确?会不会是我们描述符中的错误触发了 Windows 上的这种行为?
为了完整:这是我们的描述符:http://tny.cz/ac745a8f(从供应商标识中删除以让我的老板高兴:))
在 Windows 上放大报告:(高兴!我现在可以拍照了 :))
整个交易:
Windows 上使用的库:hid.lib、hidclass.lib 和 setupapi.lib。在编写报告时,我们使用函数 HidP_SetUsageValueArray 和 HidD_SetOutputReport。 PHIDP_PREPARSED_DATA 和 HIDP_CAPS 可通过函数 HidD_GetAttributes、HidD_GetPreparsedData 和 HidP_GetCaps 找到。使用 SetupDiEnumDeviceInterfaces 找到设备的文件路径。如果我们找到具有正确 VID、PID、caps.UsagePage 和 caps.Usage 的设备,那就是我们使用的设备。
在 linux 上它有点棘手,因为我不是实现 linux 代码的人。我能说的是使用 libusb-1.0.9,使用 libusb_open_device_with_vid_pid 打开设备,使用 libusb_fill_interrupt_transfer 和 libusb_submit_transfer 发送报告。我看到 libuwand_fill_interrupt_transfer 接受一个端点作为参数,所以我认为只使用来自 libusb_open_device_with_vid_pid 的句柄并将正确的参数作为端点传递,libusb 就会找出将报告放在哪里。
【问题讨论】:
-
Endpoint 0 是为控制传输保留的,因此在有效负载之前必须有一个 8 字节的 SETUP 数据包发送,带有 bRequestType、bRequest、wValue 等参数。你能发布那个 SETUP 数据包的值吗?有了这些信息,我们就可以查看 HID 规范并查看 Windows 发送的请求以及它是否有效。此外,您使用什么驱动程序/库堆栈在 Linux 和 Windows 上发送数据? Windows 使用的端点可能取决于驱动程序(例如 hidusb.sys)和您用来与驱动程序通信的库(例如 libusb)以及您的代码。
-
“嵌入式设备不检查在哪个 EP 上收到了 OUT 报告”:这对我来说听起来很不寻常。这是如何运作的?端点 0 上发送的控制传输的结构比普通中断或批量端点上的数据复杂得多,因此首先需要特殊代码来处理端点 0 数据。
标签: linux windows usb endpoint hid