2021. 9. 27. 13:22ㆍLinux
- 목차
input driver
components
1. input core
2. input event driver
3. input device driver
input device driver structure
+--------------+
| Event Driver | input event driver
+--------------+
^
|
v
+------------+
| Input Core | input core
+------------+
^
|
v
+---------------+
| Device Driver | input device driver
+---------------+
structure
- input_event
- input_dev
- input_handler
- psmouse_protocol
- psmouse
kernel programming interfaces
- input_register_device : register a input device to input core
- input_unregister_device
- input_report_rel : create an event (relative move)
- input_report_abs
- input_report_key
- input_sync : collect events into evdev packet and pass it /dev/input/inputX
- input_register_handler : register a special event driver
- sysfs_create_group : create a sysfs node group
- sysfs_remove_group
- tty_insert_flip_char : send a character to tty
- platform_device_register_simple
- platform_device_unregister
+---------+
| console |
+---------+
^
|
----------------------------------------+-----------
KERNEL |
+--------------------+
| virtual terminal |
+--------------------+
^
|
+---------------+ +--------------------+
| INPUT CORE | ---> | Input Event Driver |
+---------------+ +--------------------+
|
v
+--------------------+
| INPUT DEV DRV |
+--------------------+
^
|
+--+---+
| | |
Serio ... SPI.. GPIO
evdev interface
evdev : general input event driver
/include/linux/input.h
struct input_event {
struct timeval time;
__u16 type; <- event type for an input device (in touch screen case, "EV_SYN | EV_KEY | EV_ABS")
__u16 code;
__s32 value;
};
1. register
input_register_device
2. @ INTR. hdlr
input_event (throughout such as input_report_key)
...
input_sync --> input_event(dev, EV_SYN, SYN_REPORT, 0) --> input_pass_event --> handler->event
to see event interface & device info.
use files under
- /proc
- /sys
ex.
ls -al /proc/bus/input
...
H: Handler=kdb event0 <-- device file node
ls -al /dev/input/- <-- to see event interface devices
..../dev/input/event0
...
ex. virtual mouse
app (coord.c) ------> sysfs (/dev/devices/platform/vms/coordinates) ----> vms.c (virtual mouse driver)
To see the kind of an event driver,
application have to use ioctl of /dev/input/eventX to check what kind of this event is.
coord.c application console - gpm
| ^
v |
/sys/.../vms/coordinates /dev/input/eventX
------------------------------------------------------------------------------
| ^ Kernel
v |
+--------------------------+ +------------+ +-------+
| vms.c (virtual mouse drv)| <----- | input core | -----> | evdev |
+--------------------------+ +------------+ +-------+
drivers/input/evdev.c
(@ init, input_register_handler(input_handler evdev_handler))
into input_table[]
input_inject_event(client->evdev->handle, EV_REP, REP_DELAY, ...)
input_inject_event(client->evdev->handle, EV_REP, REP_PERIOD, ...)
ex. vms.c
struct input_dev *vms_input_dev;
struct platform_device *vms_dev;
ssize_t
write_vmx(...)
{
sscanf(buffer, "%d%d", &x, &y);
input_report_rel(vms_input_dev, REL_X, x); --> input_event --> input_handle_event
...
input_sync(); --> input_pass_event (have multiple event be one set <- used by /dev/input/eventX)
: use evdev input_handler (already input_indect_event was called at evdev.c)
evdev_event @ evdev.c (pass incoming event to all connected clients)
}
DEVICE_ATTR(coordinates, 0644, NULL, write_vms);
@ init
vms_dev = platform_device_register_simple("vms", -1, NULL, 0);
sysfs_create_group(&vms_dev->dev.kobj, &vms_attr_group);
...
vms_input_dev = input_allocate_device();
set_bit(EV_REL, vms_input_dev->evbit);
input_register_device(vms_input_dev); <-- create input_handler
@ cleanup
input_unregister_device(vms_input_dev);
sysfs_remove_group(&vms_dev->dev.kobj, &vms_attr_group);
platform_device_unregister(vms_dev);
verificaton program
use this program to verify an input device driver, before using it by any application,
int main(..)
{
struct input_event event_buf[EVENT_BUF_NUM]; // 64
char *str_device = "/dev/input/event0"; // or event1
int evt_fd = open(str_device, O_RDONLY);
read_byte = read(evt_fd, event_buf, sizeof(struct input_event)*EVENT_BUF_NUM);
for EVENT_BUF_NUM
check
print event_buf[i].type/value/code
}
when pressing key, touch or some other input devices,
then, type/value/code are shown
(refer 138p)
Touch ex.
@ touch driver handler
input_event --> input_handle_event --> dev->event or input_pass_event
evdev event interface를 사용하지 않고
전용 event driver로 처리되는 키보드, mouse등은, input_register_handler로 input_handler를 등록해야 함.
static struct input_handler my_evt_hdr = {
.event = evt_hdr,
.name = "mydrv",
...
};
@ init
input_register_handler(&my_evt_hdr);
...
evbug module
/drivers/input/evbug.c
dump input event set (struct input_event)
keyword.c
keyboard event driver (drivers/char/keyboard.c)
character driver..
because
linked to virtual terminal
'Linux' 카테고리의 다른 글
compat IOCTL (0) | 2021.09.27 |
---|---|
virtual address space (0) | 2021.09.27 |
System call (0) | 2021.09.27 |
Ioremap 코드 분석 (0) | 2021.09.27 |
Linux의 kmalloc과 vmalloc에 대해서 (0) | 2021.09.27 |