我刚刚遇到这个调整可以将 USB 鼠标的轮询率提高到 1 kHz。其他 USB 设备(或所有 USB 设备)是否可以实现同样的提高?
我是一名认知科学的研究员,我使用键盘和游戏手柄(通常是有线的 Xbox 360 游戏手柄)进行实验以进行人机输入,其中轮询率的提高意味着响应时间的测量精度更高。
答案1
我不知道有什么通用的机制。我相信必须调整内核或相应驱动程序的源代码。
一线希望来自这个答案到线程 I-PAC/键盘编码器轮询率:
在 Linux 上,可以设置 USB 鼠标轮询率,几乎所有鼠标都可以使用 500Hz 轮询。目前没有官方支持提高其他 HID 设备的轮询速度(我认为 I-PAC 是标准 HID 设备),但只需对 驱动程序/usb/输入/hid-core.c您也可以增加这些设备的轮询率。我以 250Hz 轮询我的 USB 键盘,它工作正常,但我还没有测试过其他键盘,而且它可能无法在所有设备上使用。
答案2
如果你愿意编译自己的内核,修改drivers/hid/usbhid/hid-core.c
是一个选择。
我遇到了类似的问题,因为我想更改键盘和绘图板的轮询率,所以我修改了我的hid-核心.c已经有一段时间了。
似乎较新的内核(4.12 及以上)已经具有usbhid.jspoll参数,但仍然没有键盘参数。
对于 4.12 之前的内核,我修改了我的hid-核心.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;
+ }
对于 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;
+ }
现在在游戏手柄和键盘上获取 1000 Hz(1 毫秒间隔)轮询:
如果是内置的或者不确定:添加
usbhid.mousepoll=1
或usbhid.jspoll=1 usbhid.elsepoll=1
到内核命令行并重新启动。如果模块:写入
options usbhid mousepoll=1
或options usbhid jspoll=1 elsepoll=1
/etc/modprobe.d/usbhid.conf
如果你rmmod usbhid;modprobe usbhid
在修改上述文件后才这样做,则需要拔下并重新插入 USB 设备才能真正更改其轮询间隔尽管内核消息似乎表明并非如此。
重新启动或重新加载 usbhid 后,为了验证它是否正常工作,请拔下并重新插入 USB 设备并运行dmesg |grep poll
。\ 预计最后几行会出现类似这样的内容:
[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
这里的设备是04d9:2013
,0810:0003
和056a:030e