Открыть сервис

файлы устройств /dev/input/event

файлы устройств /dev/input/event — это специальные символьные файлы в операционных системах семейства Linux, предоставляющие интерфейс для чтения событий от устройств ввода (клавиатур, мышей, тачпадов, джойстиков, сенсорных экранов и других). Они являются частью подсистемы ввода ядра Linux (Input Subsystem) и служат основным способом взаимодействия пользовательских приложений с аппаратными устройствами ввода на уровне событий.

Архитектура подсистемы ввода

Подсистема ввода в Linux представляет собой трехуровневую иерархию, обеспечивающую абстракцию аппаратного обеспечения и унифицированный доступ к нему.

Уровни подсистемы

  • Аппаратный уровень (Device Drivers): Драйверы устройств, взаимодействующие непосредственно с физическим оборудованием через шины (USB, PS/2, I²C, Bluetooth и др.). Они регистрируют устройство в ядре и сообщают о необработанных событиях (например, нажатие клавиши, изменение координат мыши).
  • Ядро (Input Core): Центральный модуль (input.c), который управляет регистрацией устройств, обработкой событий и их маршрутизацией. Он получает события от драйверов и передает их зарегистрированным обработчикам — как в пространство ядра, так и в пространство пользователя.
  • Пространство пользователя (User Space): Интерфейсы, через которые приложения получают доступ к событиям. Основным интерфейсом являются файлы устройств /dev/input/event (символьные файлы с мажорным номером 13, минорным номером 64+). Также существуют другие интерфейсы, такие как /dev/input/mice (для мышей), /dev/input/js (для джойстиков, устаревший) и интерфейс evdev.

Роль файлов /dev/input/event*

Файлы /dev/input/event* предоставляют прямой, небуферизованный доступ к потоку событий ввода от конкретного устройства. Каждое физическое устройство ввода (или виртуальное, созданное программно) получает свой собственный файл, например /dev/input/event0, /dev/input/event1 и так далее. Нумерация не является фиксированной и может меняться при перезагрузке системы или подключении/отключении устройств.

Структура события

Каждое событие, передаваемое через файл /dev/input/event*, представляет собой структуру фиксированного размера, определенную в заголовочном файле <linux/input.h>. Структура struct input_event имеет следующий вид:

``c struct input_event { struct timeval time; // Метка времени события (секунды и микросекунды) __u16 type; // Тип события (EV_KEY, EV_REL, EV_ABS и др.) __u16 code; // Код события (конкретная клавиша, ось, кнопка) __s32 value; // Значение события (0/1 для клавиш, смещение для относительных осей, абсолютное значение для абсолютных осей) }; ``

Поля структуры

  • time: Метка времени, когда событие было сгенерировано ядром, с точностью до микросекунд. Позволяет синхронизировать события во времени.
  • type: Определяет категорию события. Основные типы:
  • EV_KEY (0x01): События клавиш и кнопок (клавиатуры, мыши, джойстики). Значение value равно 0 (отпускание), 1 (нажатие) или 2 (автоповтор).
  • EV_REL (0x02): События относительного перемещения (мышь, трекбол). value — смещение относительно предыдущего положения.
  • EV_ABS (0x03): События абсолютного позиционирования (тачпад, сенсорный экран, джойстик). value — абсолютное значение по оси.
  • EV_SYN (0x00): Синхронизирующие события. Используются для разделения групп событий, произошедших одновременно. EV_SYN с кодом SYN_REPORT (0) сигнализирует о завершении пакета событий.
  • code: Уточняет тип события. Для EV_KEY это код клавиши (например, KEY_A, KEY_ENTER). Для EV_REL — код оси (REL_X, REL_Y, REL_WHEEL). Для EV_ABS — код оси (ABS_X, ABS_Y, ABS_MT_POSITION_X).
  • value: Значение события. Для EV_KEY — 0 или 1. Для EV_REL — целое число со знаком. Для EV_ABS — целое число без знака в пределах диапазона оси.

Чтение и использование

Доступ к файлам

Файлы /dev/input/event* по умолчанию доступны для чтения только пользователю root или членам группы input. Для предоставления доступа обычным пользователям необходимо добавить их в группу input или изменить права доступа через udev-правила.

Чтение в программе

Чтение из файла /dev/input/event* осуществляется стандартными системными вызовами (open, read, close). Приложение считывает данные блоками размером sizeof(struct input_event) (обычно 16 байт на 32-битных системах и 24 байта на 64-битных). Пример на языке C:

```c

include <stdio.h>

include <stdlib.h>

include <fcntl.h>

include <unistd.h>

include <linux/input.h>

int main() { int fd = open("/dev/input/event0", O_RDONLY); if (fd == -1) { perror("open"); return 1; }

struct input_event ev; while (1) { if (read(fd, &ev, sizeof(ev)) < sizeof(ev)) { perror("read"); break; } if (ev.type == EV_KEY && ev.value == 1) { printf("Key %d pressed\n", ev.code); } } close(fd); return 0; } ```

Инструменты командной строки

  • evtest: Основной инструмент для отладки и тестирования устройств ввода. Выводит список доступных устройств и отображает все события в удобочитаемом формате.
  • input-utils: Набор утилит, включающий input-evt (аналог evtest), input-kbd (для эмуляции нажатий) и другие.
  • cat /dev/input/event0 | od -t x1: Позволяет просматривать сырые шестнадцатеричные данные.

Идентификация устройств

Для определения, какому физическому устройству соответствует конкретный файл /dev/input/event*, используются следующие методы:

  • Символические ссылки в /dev/input/by-id/ и /dev/input/by-path/: Эти каталоги содержат символические ссылки, указывающие на файлы /dev/input/event*. Названия ссылок основаны на идентификаторах устройства (например, usb-Logitech_USB_Receiver-event-mouse) или на пути подключения (например, pci-0000:00:14.0-usb-0:1:1.0-event-mouse). Это позволяет однозначно идентифицировать устройство независимо от динамической нумерации.
  • Файловая система sysfs: Каждое устройство ввода имеет запись в /sys/class/input/. Например, /sys/class/input/event0/device/ содержит информацию о производителе, продукте, версии и возможностях устройства.
  • Утилита evtest: При запуске без аргументов выводит список всех доступных устройств с их описанием.

Применение

Графические серверы и оконные менеджеры

X.Org Server и Wayland Compositor (например, Weston, GNOME Shell, KWin) используют файлы /dev/input/event* для получения событий от устройств ввода. Они читают события напрямую или через библиотеку libinput, которая предоставляет более высокоуровневый API и обрабатывает сложные случаи (например, мультитач, настройки тачпада).

Промышленные и встраиваемые системы

В системах с ограниченными ресурсами (например, на базе Raspberry Pi, BeagleBone) файлы /dev/input/event* используются для реализации пользовательских интерфейсов, обработки нажатий кнопок, считывания данных с энкодеров и других устройств.

Игровые приложения

Многие игры и игровые движки (например, SDL, Unity) используют evdev для поддержки джойстиков, рулей и других игровых контроллеров.

Специализированное программное обеспечение

  • Системы автоматизации: Программы, управляющие роботами или станками, могут считывать данные с датчиков через evdev.
  • Программное обеспечение для людей с ограниченными возможностями: Утилиты для эмуляции ввода или переназначения клавиш.
  • Инструменты для тестирования: Автоматические системы тестирования, имитирующие действия пользователя.

Ограничения и альтернативы

Ограничения

  • Прямой доступ к оборудованию: Не все устройства ввода предоставляют полный набор событий через evdev. Некоторые функции (например, управление светодиодами клавиатуры, настройка DPI мыши) могут быть доступны только через специальные интерфейсы (например, hidraw).
  • Производительность: Для высоконагруженных приложений (например, обработка мультитач с высокой частотой опроса) может потребоваться оптимизация чтения (неблокирующий режим, epoll).
  • Безопасность: Предоставление доступа к /dev/input/event* обычным пользователям может быть рискованным, так как позволяет перехватывать все события ввода (включая пароли).

Альтернативы

  • libinput: Библиотека, предоставляющая более высокоуровневый API для работы с устройствами ввода. Она абстрагирует работу с evdev, обрабатывает мультитач, настройки тачпада, калибровку и другие сложные функции.
  • /dev/input/mice: Устаревший интерфейс, предоставляющий события только от мышей в упрощенном формате.
  • /dev/input/js*: Устаревший интерфейс для джойстиков.
  • hidraw: Интерфейс для прямого доступа к HID-устройствам (Human Interface Device). Позволяет отправлять и получать необработанные HID-отчеты, что дает более полный контроль над устройством, но требует большего объема работы по разбору данных.

Источники

  • Документация ядра Linux: Documentation/input/input.rst, Documentation/input/event-codes.rst.
  • Исходный код ядра Linux: drivers/input/input.c, include/uapi/linux/input.h.
  • Man-страницы: evtest(1), input(4), libinput(3).
  • Спецификация Linux Input Subsystem.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →