Input subsystem-architecture, driver, application, and input subsystem

Source: Internet
Author: User

Input subsystem-architecture, driver, application, and input subsystem
I. input subsystem architecture

The input subsystem consists of drivers in the driver layer, input core in the input subsystem, and event handler in the event processing layer.

An input event is sent to the system by entering the device, such as moving the mouse, pressing the keyboard, and so on through device driver-> input core (handler-> event function) -> event handler-> user space is sent to the application in the order of user space.

An output event is sent to the input device through the system, and is sent to the input device through user space-> event handler-> input core (dev-> event function)-> device driver

1. Driver function layer: responsible for dealing with underlying hardware devices, converting the responses of underlying hardware devices to user input into standard input events, and then sending them to the input system core layer.

2. Input System core layer: Implemented by driver/input. c and related header files. It provides the device driver layer interface and the event processing layer to the interface.

3. The event processing layer distributes events reported by hardware devices to user spaces and kernels.


The structure is as follows:



2. Compile the functions required by the input driver

1) contains the header file <linux/input. h>, which is the interface of the input subsystem and provides the necessary definition messages.

2) Input_allocate_device ()

An Input device structure is assigned and its bit field is set to tell the input subsystem what events it can generate or receive.

3) input_register_device (struct input_dev * dev)

Add the dev struct to the input_dev_list global linked list.

Use input_attach_handler (struct input_dev * dev, struct input_handler * handler) to find the corresponding handler,

Input_attach_handler actually calls input_match_device (const struct input_device_id * id, struct input_dev * dev)

Once input_attach_handler finds the corresponding handler, execute handler-> connect

4) input_report_key (struct input_dev * dev, unsigned int code, int value)

5) input_sync (struct input_dev * dev)

Tells the receiver of an event that is a complete message so far. For example, if we obtain the values of x and y on touch screen and want to use them as an event, add input_sync to the values of report x and y.

6) Other event types, output event processing

Other events include:

EV_LED: LED light used as the keyboard

EV_SND: Used as the keyboard buzzer

It is similar to a keyboard event, except that the keyboard event is INPUT_PASS_TO_DEVICE, and the output event is INPUT_PASS_TO_HANDLERS. If your driver needs to process these events, the corresponding bits in evbit must be set and a callback function must be implemented.

Struct input_dev * button_dev;

Button_dev-> event = button_event; this is the callback function for processing the output event.



Iii. Example of input driver implemented by common buttons
/*drivers->input core->event handlerfunction: this file is button driverdate: 20150101author: lei_wang*/#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/irq.h>#include <asm/irq.h>#include <asm/io.h>#include <mach/regs-gpio.h>#include <mach/hardware.h>#include <linux/interrupt.h>#include <linux/gpio.h>#include <linux/input.h>static struct input_dev *button_dev;static irqreturn_t button_intr(int irq, void *dev_id){int val;val = s3c2410_gpio_getpin(S3C2410_GPG(0));//printk(KERN_INFO "key value is %d\n", val);input_report_key(button_dev, BTN_0, val);input_sync(button_dev);return IRQ_RETVAL(IRQ_HANDLED);}static int __init button_init(void){int ret;ret = request_irq(IRQ_EINT8, button_intr, IRQ_TYPE_EDGE_BOTH, "button0", NULL);if (ret) {printk(KERN_ERR "%s request failed\n", __func__);return -ENODEV;}button_dev = input_allocate_device();if (!button_dev) {printk(KERN_ERR "button.c: Not enough memory\n");free_irq(IRQ_EINT8, NULL);return -ENOMEM;}button_dev->name = "button0";button_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY);button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);ret = input_register_device(button_dev);if (ret) {printk(KERN_ERR "button.c: Failed to register device\n");input_free_device(button_dev);free_irq(IRQ_EINT8, NULL);return -ENODEV;}printk(KERN_INFO "button init ok!\n");return 0;}static void __exit button_exit(void){input_unregister_device(button_dev);input_free_device(button_dev);free_irq(IRQ_EINT8, NULL);printk(KERN_INFO "button exit ok!\n");}module_init(button_init);module_exit(button_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Realsil Luckywang");


Makefile is as follows:

obj-m = button.oKERNELDIR ?=/home/lei/linux-2.6.32.2modules:$(MAKE) -C $(KERNELDIR) M=$(shell pwd) modulesclean:rm -rf *.o *.mod.c *.order *.symvers


Include/linux/bitops. h defines

# Define BIT (nr) (1UL <(nr ))

# Define BIT_MASK (nr) (1UL <(nr) % BITS_PER_LONG ))

# Define BIT_WORD (nr)/BITS_PER_LONG)

# Define BTN_0 0x100

Button_dev-> evbit [0] = BIT_MASK (EV_KEY );

Button_dev-> keybit [BIT_WORD (BTN_0)] = BIT_MASK (BTN_0 );

Note:

1) 0x100 indicates that BTN_0 is 0x100 (bit 256) bits in all bits.

BIT_WORD (BTN_0) indicates the number of arrays of bit 256 in the keybit array (8th)

BIT_MASK (BTN_0) indicates the value of bit 256 in the first array of the keybit array (bit0 of the first array)

2) event type -- encoding code -- value

Evbit is an array of events. The evbit event array contains many event types, such as key and abs.

The event key contains many specific codes, such as BTN_0 and BTN_TOUCH.

There are also many specific event abs codes such as ABS_X and ABS_Y.

Different codes have different values.


In addition, http://blog.csdn.net/ylyuanlu/article/details/6704744 this blog for the following very detailed

1) Registration of struct input_dev and struct handler in the input subsystem

2) how to match struct input_dev and struct input_handler (similar to matching between device and driver)

3) event handling process



4. Application corresponding to the example
/*20150101just a simple input test codelei_wang*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#include <linux/input.h>int main(){int fd;int version;int ret;struct input_event ev;fd = open("/dev/input/event1", O_RDONLY);if (fd < 0) {printf("open file failed\n");exit(1);}ioctl(fd, EVIOCGVERSION, &version);printf("evdev driver version is 0x%x: %d.%d.%d\n",version, version>>16, (version>>8) & 0xff, version & 0xff);while (1) {ret = read(fd, &ev, sizeof(struct input_event));if (ret < 0) {printf("read event error!\n");exit(1);}if (ev.type == EV_KEY)printf("type %d,code %d, value %d\n", ev.type, ev.code, ev.value);}return 0;}
The above is just a simple application test. When you press K1, the serial port terminal displays the input dev-reported key message.

There are also a lot of content called by ioctl that has not been tested. For details, refer to this blog article.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.