【usb】linux kernel USB keyboard driver analysis--special key conversion and reporting

1. Overview

Take the USB keyboard driver in the Linux5.10 kernel as an example to analyze: https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.10.tar.gz
file path:linux-5.10/drivers/hid/usbhid/usbkbd.c

Two, explore

Entrance

  • First, let's look directly at usb_kbd_probeline 335 of this function usb_fill_int_urb, where the USB interrupt transfer request is filled. That is to say, this variable is filled with a lot of parameters later kbd->irq. Then set the callback function of this transmission usb_kbd_irq, that is to say, when a key value is reported, it will be usb_kbd_irqprocessed with a function.

usb_kbd_irq

  • We can see that the parameter of this function is a urb (USB request block), indicating the request to complete the transfer this time. Looking at lines 117 and 118, the function is called input_report_keyto report the key value to the input subsystem. The first parameter of this function represents the device, the second parameter represents the key value, and the third parameter represents whether the key is pressed or released.
	for (i = 0; i < 8; i++)
		input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
  • The second parameter usb_kbd_keycode[i + 224], here usb_kbd_keycodeis an array, which is used to convert the key value reported by the keyboard into a key value that the input subsystem can recognize . The principle of conversion is that usb_kbd_keycodethe subscript of the array represents the key value reported by the keyboard, and the value of the corresponding position represents the key value reported to the input subsystem after conversion. So the meaning here is to i+224convert the key value reported by the keyboard into the corresponding key value of the input subsystem.

  • So which key does this i+224represent? Since i is a loop variable, it starts from 0 to 7. So i+224 is actually 224~231. So we just need to figure out 224~231which keys these values ​​represent.

  • By referring to Section 10 of HID Usage Tables10 Keyboard/Keypad Page (0x07) , we can know that when the keyboard reports 04, it represents the letter a. as follows:
    insert image description here

  • So we continue to look up the table, and the conversion of hexadecimal E0 to decimal is 224, which represents the left CTRL key. So the above 224~231is, respectively E0~E7, represent LeftControl, LeftShift,. . . . . .
    insert image description here

  • Let's go back to the code again, usb_kbd_keycode[i + 224]which means will LeftControl, LeftShift,. . . . . . The key values ​​reported by the eight keyboards are converted into key values ​​defined by the input subsystem.

  • Above we know the principle of key-value conversion, so how do we know whether this key has been pressed? Let's see next (kbd->new[0] >> i) & 1, shift the new[0] element to the right by i bits, and then add 1. What do you mean? By referring to Section 8.3 of the USB HID protocol , we can know that the USB will report CTRL, SHIFT, ALT and other keys through an 8-bit bitmap. details as follows:
    insert image description here

  • That is to say, each bit in this type of variable represents a key. If this bit is 0, it means that the key corresponding to this bit has not been pressed; if it is 1, then the key corresponding to this bit has been pressed new[0]. unsigned charThe key represented by each bit is as in the table above.

3. Summary

To sum up, the for loop in lines 117 and 118 checks each bit of the new[0] element in turn to determine whether the key corresponding to the bit is pressed. And the key value is converted into the key value defined by the input subsystem through the usb_kbd_keycode table, and then reported to the input subsystem.

4. References

HID Usage Tables 1.4
USB HID protocol

Guess you like

Origin blog.csdn.net/C2681595858/article/details/129445755
usb
usb