In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly explains "how to use Linux input". Friends who are interested might as well take a look. The method introduced in this paper is simple, fast and practical. Now let the editor take you to learn how to use Linux input.
Input devices all have something in common: interrupt driver + character IO. Based on the idea of layering, the Linux kernel extracts the public part of these devices and designs the input subsystem based on cdev. All devices built using the input subsystem use the main device number 13. At the same time, the input subsystem also supports the automatic creation of device files, which are created under "/ dev/input/" by blocking IO read and write mode. This is shown in the following figure. From the bottom up, the input subsystem in the kernel is divided into device driver layer, input core layer and event processing layer. Because each input device reports different events, in order for the application layer to identify the reported events well, the kernel also encapsulates a standard interface for the application layer to describe an event, which is in "/ include/upai/linux/input".
The device driver layer is not only the implementation of specific hardware, but also the main part of driver development.
The input core layer mainly provides some API for the device driver layer to call, and the data reported by the API device driver layer can be passed to the event processing layer.
The event processing layer is responsible for creating device files and passing reported events to user space.
The use of input
The input object describes an input device, including events that it may report, which are described by bitmaps. The corresponding tools provided by the kernel help us build an input object. You can refer to the kernel document "Documentation/input/input-programming.txt", which has a detailed description of the use of the input subsystem.
/ / input device object struct input_dev {const char * name; unsigned long evbit [bits _ TO_LONGS (EV_CNT)]; unsigned long Keybit [bits _ TO_LONGS (KEY_CNT)]; unsigned long relbit [bits _ TO_LONGS (REL_CNT)]; unsigned long absbit [bits _ TO_LONGS (ABS_CNT)]; unsigned long mscbit [bits _ TO_LONGS (MSC_CNT)] Unsigned long Ledbit [bits _ TO_LONGS (LED_CNT)]; unsigned long Sndbit [bits _ TO_LONGS (SND_CNT)]; unsigned long Fffbit [bits _ TO_LONGS (FF_CNT)]; unsigned long SWbit [bits _ TO_LONGS (SW_CNT)]; unsigned long key [bits _ TO_LONGS (KEY_CNT)]; unsigned long led [bits _ TO_LONGS (LED_CNT)] Unsigned long snd [bits _ TO_LONGS (SND_CNT)]; unsigned long SW [bits _ TO_LONGS (SW_CNT)]; struct input_handle _ rcu * grab; struct device dev; struct list_head hacking list; struct list_head node;}
Struct input_dev
The name is not the device name. The device name of the input subsystem is specified in the subsystem source code, not this.
Input event bitmap, EV_KEY,EV_REL, etc supported by 129mura-> device
For keystroke events, the input sub-event bitmap supported by the device
For relative coordinate events, the relative coordinate sub-event bitmap supported by the device
For absolute coordinate events, the absolute coordinate sub-event bitmap supported by the device
-- 134murl-> supported subevent bitmaps for hybrid devices
-- 180Mel-> indicates that this is a device.
-- 182 h_list-- > h_list is a linked list used to link related handle
-- 183 input_dev-- > node is used to link linked lists of other APIs.
Allocation / release
/ / drivers/input/input.c / / create an input object struct input_dev * input_allocate_device (void); / / release an input object void input_free_device (struct input_dev * dev)
Initialization
Initializing an input object is the main task of writing a driver using the input subsystem. The kernel specifies some common input events for common input devices in the header file "include/uapi/linux/input.h". These macros and arrays are our tools for initializing input objects. These macros are used for both event parsing and event registration in user space, and can be regarded as the communication protocol between driver and user space, so it is very important to understand the significance of them. In the input subsystem, the occurrence of each event is described by event (type)-> subevent (code)-> value (value). For example, the key event-> keystroke F1 subevent-> keystroke F1 subevent triggers a high level 1. Note that events and sub-events and values complement each other, and it makes sense to register the sub-event EV_KEY only if you register the event BTN_0.
The following is the event type of the kernel convention, which corresponds to the type domain of the event object in the application layer
The following are the types of keystroke subevents, and you can see the definition of the PC key value
In addition to describing common events, the kernel also provides tools to correctly populate these events into bitmaps that describe events in input objects.
/ / * * / this method is very suitable for registering multiple events simultaneously button_dev- > evbit [0] = BIT_MASK (EV_KEY); button_dev- > keybit [bit _ WORD (BTN_0 | BTN_1)] = BIT_MASK (BTN_0 | BTN_1)
Registration / logout
After initializing an input object, you need to register it with the kernel
/ / register the input object to the kernel int input_register_device (struct input_dev * dev); / / unregister an input object void input_unregister_device (struct input_dev * dev) from the kernel
The driver layer reports events
At an appropriate time (since the input is ultimately represented by an interrupt, so it is usually in the interrupt handler of the driver) the driver can report registered events and multiple events at the same time. Here is the API provided by the kernel
/ / report specified event + sub-event + value void input_event (struct input_dev * dev,unsigned int type,unsigned int code,int value); / / report key value void input_report_key (struct input_dev * dev,unsigned int code,int value); / / report absolute coordinates void input_report_abs (struct input_dev * dev,unsigned int code,int value) / / report synchronization event void input_report_rel (struct input_dev * dev,unsigned int code,int value); / / synchronize all reported void input_sync (struct input_dev * dev)
There are two points to note when reporting an incident:
Report functions will not really report, only when they are ready to report, sync will really report the events of report to the input core.
Input core will adjudicate and then report the event handling layer, so for keystroke events, be sure to report 1 before reporting 0 (or vice versa), not just report 1 or 0, so that the core will think that an event has been mistakenly triggered many times and only reported once, although we have really pressed it many times.
Application layer parsing
The event handling layer will eventually organize all report events driving sync at one time into a struct input_value [] to report to the application layer. When the application layer obtains the reported events from the corresponding device files, you should pay attention to:
The number of received array elements will be one more than the underlying empty element, similar to the * empty element when writing of_device_id [], which should be noted in the application layer when parsing.
The event processing layer does not cache received events, and if new events come, even if the old events are not read, they will be overwritten, so the application needs to read them in time.
As mentioned earlier, macros in "include/uapi/linux/input.h" are common communication protocols between the application layer and the driver layer, so the application layer only needs "include" to use macros when parsing received struct input_value objects.
/ * * The event structure itself * / struct input_event {struct timeval time; _ _ U16 type; _ _ U16 code; _ _ s32 value;}
Input analysis
As mentioned above, the input subsystem uses a three-tier structure to deliver driving events to the application layer. Specifically, each of these three levels consists of a structure chain list. In the device driver layer, the core structure is input_dev; in the input core layer, input_handle; in the event processing layer, and input_handler. The kernel combines the three through linked lists and pointers, and finally realizes the many-to-many mapping between input_dev and input_handler, which can be briefly described in the following figure.
Template
The following template first uses the input subsystem to report keystroke events and then reads them at the application layer.
Input keypad device driver
{key@26 {compatible = "xj4412,key"; interrupt-parent =; interrupts =;};}; static struct input_dev * button_dev; static int button_irq; static int irqflags; static irqreturn_t button_interrupt (int irq, void * dummy) {input_report_key (button_dev, BTN_0, 0) Input_report_key (button_dev, BTN_0, 1); input_sync (button_dev); return IRQ_HANDLED;} static int button_init (void) {request_irq (button_irq, button_interrupt,irqflags, "button", NULL)); button_dev = input_allocate_device (); button_dev- > name = "button"; button_dev- > evbit [0] = BIT_MASK (EV_KEY) Button_dev- > keybit [bit _ WORD (BTN_0)] = BIT_MASK (BTN_0); input_register_device (button_dev); return 0;} static int button_exit (void) {input_free_device (button_dev); free_irq (button_irq, button_interrupt); return 0;} static int key_probe (struct platform_device * pdev) {struct resource * irq_res Irq_res = platform_get_resource (pdev, IORESOURCE_IRQ, 0); if (irq_res) {button_irq = irq_res- > start; irqflags = irq_res- > flags & IRQF_TRIGGER_MASK;} else {return-EINVAL;} return button_init ();} static int key_remove (struct platform_device * dev) {return button_exit () } struct of_device_id of_tbl [] = {{. Compatible = "xj4412,key",}, {},}; MODULE_DEVICE_TABLE (of, of_tbl); struct platform_driver key_drv = {.probe = key_probe, .remove = key_remove, .driver.name = "keydrv", .driver.of _ match_table = of_tbl,}; module_platform_driver_register (key_drv) MODULE_LICENSE ("GPL")
The application layer obtains the key value
# include struct input_event {struct timeval time; unsigned short type; unsigned short code; int value;}; int main (int argc, char * const argv []) {int fd = 0; struct input_event event [3] = {0}; / / 3 examples! The driver uploads two events, the third of which is used to load the empty element int ret = 0; fd = open (argv [1], O_RDONLY); while (1) {ret = read (fd,&event,sizeof (event)); printf ("ret:%d,val0:%d,val1:%d,val12:%d\ n", ret,event [0] .value, event [1] .value, event [2] .value) / / 2!!! , * one is empty sleep (1);} return 0;} at this point, I believe you have a better understanding of "how to use Linux input". You might as well do it in practice! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.