提高 Linux 中所有设备的 USB 轮询率?

Mik*_*nce 7 linux usb

我刚刚遇到了这个调整,它允许将 USB 鼠标的轮询率提高到 1KHz。是否可以实现对其他USB设备(或所有USB设备)同样的提升?我是一名认知科学研究员,我使用键盘和游戏手柄(通常是有线 xbox 360 游戏手柄)进行人工输入实验,其中增加的轮询率意味着更好的响应时间测量精度。

mos*_*ain 5

如果您愿意编译自己的内核,drivers/hid/usbhid/hid-core.c则可以选择修改。
我有一个类似的问题,因为我想改变我的键盘和绘图板的轮询率,所以我已经修改了我的 hid-core.c 一段时间了。

似乎较新的内核(4.12 及更高版本)已经有 usbhid.jspoll 参数,但仍然没有键盘参数。

对于 4.12 以上的内核,我修改了 hid-core.c 如下,使 mousepoll 影响它处理的所有设备:

--- a/linux-4.11-original/drivers/hid/usbhid/hid-core.c
+++ b/linux-4.11/drivers/hid/usbhid/hid-core.c
@@ -1081,9 +1081,14 @@ static int usbhid_start(struct hid_device *hid)
                               hid->name, endpoint->bInterval, interval);
                }

-               /* Change the polling interval of mice. */
-               if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
+               /* Change the polling interval of mice.
+               EDIT 2016-09-03: poll everything with mousepoll
+                */
+               if (/*hid->collection->usage == HID_GD_MOUSE &&*/ hid_mousepoll_interval > 0) {
+                       printk(KERN_INFO "%s: Changed interval to mousepoll: %d -> %d\n",
+                              hid->name, interval, hid_mousepoll_interval);
                        interval = hid_mousepoll_interval;
+               }
Run Code Online (Sandbox Code Playgroud)

对于 4.12 及更高版本,我对其进行了不同的修改,因为我不想破坏正在运行的 usbhid.jspoll:

--- a/linux-4.12.4-original/drivers/hid/usbhid/hid-core.c
+++ b/linux-4.12.4/drivers/hid/usbhid/hid-core.c
@@ -56,6 +56,10 @@ static unsigned int hid_jspoll_interval;
 module_param_named(jspoll, hid_jspoll_interval, uint, 0644);
 MODULE_PARM_DESC(jspoll, "Polling interval of joysticks");

+static unsigned int hid_elsepoll_interval;
+module_param_named(elsepoll, hid_elsepoll_interval, uint, 0644);
+MODULE_PARM_DESC(elsepoll, "Polling interval of non-mouse non-joysticks");
+
@@ -1083,15 +1087,31 @@ static int usbhid_start(struct hid_device *hid)
                }

                /* Change the polling interval of mice and joysticks. */
+               /* EDIT 2017-08-03:
+                       added elsepoll
+                       always print to KERN_INFO when one of mousepoll, jspoll, elsepoll takes effect.
+               */
                switch (hid->collection->usage) {
                case HID_GD_MOUSE:
-                       if (hid_mousepoll_interval > 0)
+                       if (hid_mousepoll_interval > 0) {
+                               printk(KERN_INFO "%s: Changed interval to mousepoll: %d -> %d\n",
+                                      hid->name, interval, hid_mousepoll_interval);
                                interval = hid_mousepoll_interval;
+                       }
                        break;
                case HID_GD_JOYSTICK:
-                       if (hid_jspoll_interval > 0)
+                       if (hid_jspoll_interval > 0) {
+                               printk(KERN_INFO "%s: Changed interval to jspoll: %d -> %d\n",
+                                      hid->name, interval, hid_jspoll_interval);
                                interval = hid_jspoll_interval;
+                       }
                        break;
+               default:
+                       if (hid_elsepoll_interval > 0) {
+                               printk(KERN_INFO "%s: Changed interval to elsepoll: %d -> %d\n",
+                                      hid->name, interval, hid_elsepoll_interval);
+                               interval = hid_elsepoll_interval;
+                       }
Run Code Online (Sandbox Code Playgroud)

现在要在游戏手柄和键盘上获得 1000Hz(1ms 间隔)轮询:

  • 如果内置或不确定:将usbhid.mousepoll=1或添加usbhid.jspoll=1 usbhid.elsepoll=1到内核​​命令行并重新启动。

  • 如果模块:写options usbhid mousepoll=1options usbhid jspoll=1 elsepoll=1/etc/modprobe.d/usbhid.conf

如果您刚刚rmmod usbhid;modprobe usbhid修改了上面的文件,您需要拔出并重新插入 USB 设备以实际更改其轮询间隔,即使内核消息似乎另有暗示

重新启动或重新加载 usbhid 后,要验证它是否正常工作,请拔下并重新插入 USB 设备,然后dmesg |grep poll
在最后几行中运行像这样的 Expect:

[476243.420106] daskeyboard: Changed interval to elsepoll: 10 -> 1
[476243.497161] daskeyboard: Changed interval to elsepoll: 10 -> 1
[476251.633110] USB Gamepad : Changed interval to jspoll: 17 -> 1
[476260.726864] Wacom Co.,Ltd. Intuos PS: Changed interval to elsepoll: 2 -> 1
[476260.730403] Wacom Co.,Ltd. Intuos PS: Changed interval to elsepoll: 2 -> 1
Run Code Online (Sandbox Code Playgroud)

这里的设备是04d9:20130810:0003056a:030e


har*_*ymc 2

我不知道有什么通用机制。我认为必须调整内核或相应驱动程序的源代码。

I-PAC/键盘编码器轮询率主题的 答案给了我们一线希望:

在Linux上,可以设置USB鼠标轮询速率,几乎所有鼠标都可以以500Hz轮询工作。没有官方支持提高其他 HID 设备的轮询速度(我假设 I-PAC 是标准 HID 设备),但通过对 drivers/usb/input/hid-core.c进行简单修改,您可以提高轮询率对于那些也一样。我以 250Hz 的频率测试了我的 USB 键盘,它工作得很好,但我还没有测试过其他键盘,而且它可能无法与所有设备兼容。