Aumentar a taxa de polling USB em todos os dispositivos no linux?

7

Eu acabei de encontrar esse ajuste que permite aumentar a taxa de pesquisa de um mouse usb para 1KHz. É possível obter o mesmo aumento para outros dispositivos USB (ou todos os dispositivos USB)? Eu sou um pesquisador em ciência cognitiva e conduzo experimentos usando teclados e gamepads (geralmente um gamepad xbox 360 com fio) para a entrada humana, onde uma taxa de pesquisa maior significaria melhor precisão de medição dos tempos de resposta.

Mike Lawrence
fonte
Os teclados USB possuem um atraso de pesquisa?
pjc50

Respostas:

2

Não conheço nenhum mecanismo geral. Acredito que é preciso ajustar as fontes do kernel ou o respectivo driver.

Um raio de esperança é dado por esta resposta para o fio Taxa de pesquisa do I-PAC / codificador do teclado :

No Linux, é possível definir a taxa de pesquisa do mouse USB e quase   todos os ratos podem trabalhar com polling de 500Hz. Não há suporte oficial para   maior velocidade de polling de outros dispositivos HID (e eu assumo que o I-PAC   é um dispositivo HID padrão), mas com uma simples modificação drivers / usb / input / hid-core.c Você também pode aumentar a taxa de pesquisa. Eu sondo meu teclado USB a 250Hz e ele funciona perfeitamente,   mas eu não testei outros teclados, e é provável que não   trabalhe com todos os dispositivos.

harrymc
fonte
3

Se você está disposto a compilar seu próprio kernel, modificando drivers/hid/usbhid/hid-core.c é uma opção.
Eu tive um problema semelhante, como eu quero mudar a taxa de pesquisa do meu teclado e tablet de desenho, então eu modifiquei o meu hid-core.c já há algum tempo.

Parece que os kernels mais recentes (4.12 e posteriores) já possuem o parâmetro usbhid.jspoll, mas ainda não há parâmetros para teclados.

Com os kernels anteriores a 4.12, modifiquei o meu hid-core.c da seguinte maneira, fazendo o mousepoll afetar todos os dispositivos que ele manipula:

--- 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;
+               }

E para as versões 4.12 e superiores eu modifiquei de forma diferente, pois não queria quebrar o trabalho 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;
+                       }

Agora, para obter uma votação de 1000Hz (intervalo de 1 ms) em gamepads e teclados:

  • se incorporado ou inseguro: adicionar usbhid.mousepoll=1 ou usbhid.jspoll=1 usbhid.elsepoll=1 para a linha de comando do kernel e reinicie.

  • se módulo: escrever options usbhid mousepoll=1 ou options usbhid jspoll=1 elsepoll=1 para /etc/modprobe.d/usbhid.conf

Se você acabou de rmmod usbhid;modprobe usbhid Depois de modificar o arquivo acima, você precisa desconectar e reconectar um dispositivo USB para alterar seu intervalo de pesquisa. mesmo que as mensagens do kernel pareçam sugerir o contrário .

Depois de reiniciar ou recarregar o usbhid, para verificar se está funcionando, desconecte e reconecte os dispositivos USB e execute dmesg |grep poll
Espere algo assim nas últimas linhas:

[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

Os dispositivos aqui são 04d9:2013, 0810:0003 e 056a:030e

user2179798
fonte
você não precisa recompilar o kernel inteiro apenas para recompilar o módulo usbhid
Suici Doga
você deve enviar isso como um patch na lista de discussão do kernel
Suici Doga