- Драйверы устройств ввода
- Serio
- Клавиатуры
- Клавиатуры ПК
- USB и Bluetooth клавиатуры
- PS/2 мышь
- Пример драйвера: Мышь-колёсико
- Русские Блоги
- 21.Linux-Write USB-драйвер клавиатуры (подробное объяснение)
- Интеллектуальная рекомендация
- Пошаговая загрузка файла Spring MVC-09 (на основе файла загрузки клиента Servlet3.0 + Html5)
- Создайте многоканальное окно в приложениях Win32
- Путь к рефакторингу IOS-APP (3) Введение в модульное тестирование
- Tree——No.617 Merge Two Binary Trees
Драйверы устройств ввода
Давайте обратим наше внимание на драйверы для распространённых устройств ввода, таких как клавиатуры, мыши и сенсорные экраны. Но сначала давайте кратко рассмотрим готовый сервис для доступа к оборудованию, доступный для драйверов ввода.
Serio
Уровень serio предлагает библиотечные подпрограммы для доступа к устаревшему оборудованию ввода, такому как i8042-совместимые контроллеры клавиатуры и последовательный порт. Клавиатуры PS/2 и мыши подключаются к первому, а сенсорные контроллеры с последовательным интерфейсом подключаются к последнему. Для взаимодействия с оборудованием, обслуживаемым serio, например, для передачи команды для PS/2 мыши, предписанные процедуры обратного вызова serio регистрируются с помощью serio_register_driver() .
Чтобы добавить новый драйвер как часть serio, с помощью serio_register_port() регистрируются точки входа open() / close() / start() / stop() / write() . Для примера посмотрите drivers/input/serio/serport.c .
Как можно увидеть на Рисунке 7.1, serio — это только один из маршрутов доступа к низкоуровневому оборудованию. Некоторые драйверы устройств ввода вместо него полагаются на низкоуровневую поддержку от шинных уровней, таких как USB или SPI.
Клавиатуры
Клавиатуры бывают на любой вкус — устаревшие PS/2, USB, Bluetooth, ИК, и так далее. Каждый тип имеет специальный драйвер устройства ввода, но все используют один и тот же драйвер событий клавиатуры, обеспечивая тем самым единый интерфейс для пользователей. Драйвер событий клавиатуры, однако, имеет отличительную особенность по сравнению с другими драйверами событий: он передаёт данные другой подсистеме ядра (уровню tty), а не в пользовательское пространстве с помощью узлов /dev .
Клавиатуры ПК
Клавиатуры ПК (также называемые клавиатурами PS/2 или AT клавиатурами) взаимодействует с процессором через i8042-совместимый контроллер клавиатуры. ПК обычно имеют специальный контроллер клавиатуры, но на ноутбуках взаимодействие с клавиатурой является одной из обязанностей встроенного контроллера общего назначения (смотрите раздел «Встроенные контроллеры» в Главе 20, «Дополнительные устройства и драйверы»). Когда вы нажимаете клавишу на клавиатуре компьютера, это происходит по такому пути:
1. Контроллер клавиатуры (или встроенный контроллер) сканирует и декодирует клавиатурную матрицу и заботится о нюансах, таких как устранение дребезга контактов.
2. Клавиатурный драйвер устройства с помощью serio для каждого нажатия и отпускания клавиши читает с контроллера клавиатуры сырые коды сканирования . Разницей между нажатием и отпусканием является самый старший бит, который для последнего случая установлен. Например, нажатие на кнопку «a» даёт пару скан-кодов, 0x1e и 0x9e . Специальные кнопки экранируются с помощью 0xE0 , так что нажатие кнопки со стрелкой вправо производит последовательность ( 0xE0 0x4D 0xE0 0xCD ). Для наблюдения выходящих из контроллера скан-кодов вы можете использовать утилиту showkey (после символа → идут пояснения):
bash> showkey -s
кл-ра была в режиме UNICODE
[ если вы пробуете это под X, это может не работать, так как
X сервер также читает /dev/console ]
нажмите любую кнопку (программа завершится спустя 10с после
последнего нажатия на кнопку).
.
0x1e 0x9e → Нажатие кнопки «a»
3. Клавиатурный драйвер устройства преобразует полученные скан-коды в коды клавиш, основываясь на режиме ввода. Чтобы увидеть код клавиши, соответствующий кнопке «a»:
bash> showkey
.
код кнопки 30 нажатие → Нажатие на кнопку «a»
код кнопки 30 отпускание → Отпускание кнопки «a»
Чтобы сообщить эти коды клавиш дальше вверх, драйвер генерирует событие ввода, которое передаёт управление драйверу событий клавиатуры.
4. Драйвер событий клавиатуры берёт на себя работу по преобразованию кода клавиши в зависимости от загруженной карты кодов клавиш. (Смотрите страницы справки loadkeys и map-файлы в /lib/kbd/keymaps .) Он проверяет, является ли преобразованный код клавиш такими действиями, как переключение виртуальной консоли или перезагрузка системы. Чтобы вместо перезагрузки системы в ответ на нажатие Ctrl+Alt+Del зажглись светодиоды CAPSLOCK и NUMLOCK , добавьте в обработчик Ctrl+Alt+Del драйвера событий клавиатуры, drivers/char/keyboard.c , следующее:
static void fn_boot_it(struct vc_data *vc, struct pt_regs *regs)
<
+ set_vc_kbd_led(kbd, VC_CAPSLOCK);
+ set_vc_kbd_led(kbd, VC_NUMLOCK);
— ctrl_alt_del();
>
5. Для обычных клавиш преобразованный код нажатия отправляется ассоциированному виртуальному терминалу и дисциплине линии N_TTY . (Мы обсуждали виртуальные терминалы и дисциплины линий в Главе 6, «Драйверы последовательных портов.») drivers/char/keyboard.c делает это следующим образом:
/* Добавляем код клавиши в переключаемый буфер */
tty_insert_flip_char(tty, keycode, 0);
/* Планируем */
con_schedule_flip(tty);
Дисциплина линии N_TTY обрабатывает ввод таким образом, что полученные с помощью клавиатуры данные отображаются на виртуальной консоли и позволяет приложениям пользовательского пространства читать символы из узла /dev/ttyX , подключённого к виртуальному терминалу.
На Рисунке 7.3 показано движение данных от момента нажатия клавиши на клавиатуре, до момента его появления на виртуальной консоли. Левая половина рисунка является зависимой от оборудования, а правая половина носит общий характер. В соответствии с целью разработки подсистемы ввода, нижележащий аппаратный интерфейс является прозрачным для драйвера событий клавиатуры и уровня tty. Таким образом, ядро ввода и чётко определённые интерфейсы событий ограждают пользователей ввода от нюансов оборудования.
Рисунок 7.3. Поток данных от PS/2-совместимой клавиатуры.
USB и Bluetooth клавиатуры
Спецификациями USB, связанными с устройствами взаимодействия с человеком (HID), предусмотрен протокол, по которому для взаимодействия используются USB клавиатуры, мыши, наборы кнопок и другие периферийные устройства ввода. На Linux это осуществляется через клиентский драйвер USB usbhid , который отвечает за класс USB HID ( 0x03 ). Usbhid регистрирует себя в качестве драйвера устройства ввода. Он соответствует API ввода и сообщает о соответствующих событиях ввода подключенных HID.
Для того, чтобы понять путь кода для USB клавиатуры, вернёмся к Рисунку 7.3 и изменим аппаратно-зависимую левую половину. Заменим контроллер клавиатуры в квадратике «Оборудование ввода» на контроллер USB, serio на уровень ядра USB и квадратик «Драйвер устройства ввода» на драйвер usbhid.
Для Bluetooth клавиатуры заменим на Рисунке 7.3 контроллер клавиатуры на набор микросхем Bluetooth, serio на уровень ядра Bluetooth и квадратик «Драйвер устройства ввода» на драйвер Bluetooth hidp.
USB и Bluetooth подробно рассматриваются в Главе 11, «Универсальная последовательная шина» и в Главе 16, «Linux без проводов», соответственно.
Мыши, как и клавиатуры, бывают с разными возможностями и имеют различные варианты взаимодействия. Давайте посмотрим на обычно использующиеся.
PS/2 мышь
Мыши генерируют относительные передвижения по осям X и Y. Кроме того, они имеют одну или несколько кнопок. Некоторые из них также имеют колёсико прокрутки. Драйвер устройства ввода для устаревшей PS/2-совместимой мыши для взаимодействия с контроллером основывается на уровне serio. Драйвер событий ввода для мышей, называемый mousedev , сообщает события мыши пользовательским приложениям с помощью /dev/input/mice .
Пример драйвера: Мышь-колёсико
Чтобы получить настоящий драйвер устройства мыши, давайте преобразуем вращающееся колёсико, рассматриваемое в Главе 4, «Создание основы», в вариант обычной PS/2 мыши. «Мышь-колёсико» создаёт одномерное движение по оси Y. Повороты колёсика по часовой стрелке и против часовой стрелки создают положительные и отрицательные относительные Y координаты соответственно (как колесо прокрутки на мыши), а нажатие на колёсико приводит к событию нажатия на левую кнопку мыши. Мышь-колёсико идеально подходит для навигации по меню в таких устройствах, как смартфоны, КПК и музыкальные плееры.
Драйвер устройства мыши-колёсика, реализованный в Распечатке 7.3, работает с оконными системами, такими как X Windows. Чтобы увидеть, как драйвер заявляет о своих похожих на мышь возможностях, посмотрите на roller_mouse_init() . В отличие от драйвера вращающегося колёсика в Распечатке 4.1 Главы 4, драйверу мыши-колёсика не нужны методы read() или poll() , так как о событиях сообщается с использованием API ввода. Обработчик прерывания от колёсика roller_isr() также соответственно изменяется. Убираем служебные действия, выполняемые в обработчике прерывания, использующие очередь ожидания, спин-блокировку и процедуру store_movement() для поддержки read() и poll() .
В Распечатке 7.3, + и — в начале строк обозначают отличия от драйвера вращающего колёсика, реализованного в Распечатке 4.1 Главы 4.
Источник
Русские Блоги
21.Linux-Write USB-драйвер клавиатуры (подробное объяснение)
1. Во-первых, мы модифицируем код из предыдущего раздела для печати данных с клавиатуры.
Позвольте мне сначала напомнить, что управляемая мышью id_table, которую мы написали ранее, выглядит так:
Поэтому нам нужно изменить id_table, чтобы сделать этот драйвер драйвером клавиатуры, как показано на следующем рисунке:
Затем измените функцию прерывания, чтобы распечатать данные через printk ():
В качестве примера нажмите кнопку A и распечатайте 0x04, как показано ниже:
Мы нажимаем кнопки A и S одновременно, чтобы распечатать 0x04, 0X16, как показано ниже:
Очевидно, что эти обычные ключи начинаются с buf [2], так какое же значение хранится в первом массиве?
После нажатия всех клавиш клавиатуры мы обнаружили, что только 8 клавиш будут напечатаны в buf [0], как показано ниже:
Таким образом, buf [0] — это клавиша, используемая для сохранения определенной функции клавиатуры, а buf [1] может быть зарезервированной клавишей, которая не используется, buf [2]
buf [7] — обычные клавиши, такие как ABCD, 1234, F1. , F2 и т. Д. Могут поддерживать до 6 кнопок одновременно.
2. Так как же определяются данные каждой кнопки?
2.1 Например, когда мы нажимаем кнопку A, зачем печатать 0X04?
Мы находим значение, определенное кнопкой A во входной подсистеме (input.h), но оно соответствует 30, которое, похоже, не вызывается напрямую, как показано ниже:
Обратимся к драйверу USB-клавиатуры, который поставляется с ядром (/drivers/hid/usbhid/usbkbd.c)
Обнаружено, что в его функции прерывания есть таблица кодов описания клавиатуры (где 0 означает зарезервировано):
Оказывается, что 0X04 массива — 0X30. Похоже, что для написания драйвера клавиатуры также необходим указанный выше массив.
Затем проблема возникает снова. Если мы нажмем левую клавишу alt, 0x04 появится в buf [0]. Если он также будет подставлен в таблицу кодов описания клавиатуры, он, очевидно, будет использоваться как кнопка клавиатуры A.
2.2 Давайте проанализируем, как обрабатывается функция прерывания клавиатуры в ядре:
Я нашел это предложение:
Среди них kbd-> new представляет массив данных клавиатуры, который выгружает каждый бит buf [0] в событие нажатия клавиши в форме usb_kbd_keycode [i + 224]
Очевидно, 0X04 нашего buf [0] — это загруженный usb_kbd_keycode [4+ 224]
2.3 Посмотрим, соответствуют ли данные в usb_kbd_keycode [226] левой клавише ALT
Найдите usb_kbd_keycode [226] = 56:
Затем введите input.h и найдите определение 56, которое оказывается KEY_LEFTALT (клавиша alt слева)
3. Затем давайте внимательно проанализируем функцию прерывания в драйвере USB-клавиатуры usbkbd.c, который поставляется с ядром:
код показан ниже:
3.1 При получении нормальных ключей, указанных выше, почему бы не судить напрямую, что это не 0, а судить о ключевых данных> 3?
Мы анализировали ранее, когда ключевые данные = 0X01, 0X02, они представляют собой ключ определенной функции (crtl, shift), которая принадлежит buf [0].
Среди них memscan () используется для сопоставления данных последнего нажатия клавиши и текущего нажатия клавиши. Причина этого в том, что он опасается, что данные последнего buf [] и текущего buf [] не совпадают, поэтому я не буду проводить здесь подробный анализ.
Все решено, нам нужно только добавить свой код ко всем событиям нажатия клавиш через эту кодовую таблицу, а затем загрузить события в соответствии с данными в функции прерывания клавиатуры.
4. Коды клавиатуры в этом разделе следующие:
5.Тестовый забег
5.1 Сбросить скомпилированное ядро(Удалить значение по умолчаниюhid_USBводить машину)
сделайте menuconfig, войдите в меню, чтобы сбросить параметры ядра:
Войдите -> Драйверы устройств -> Устройства HID
<> Поддержка USB Human Interface Device (полная HID) // hid: драйвер USB для взаимодействия человека с компьютером, такого как мышь, клавиатура и т. Д.
Затем заставьте uImage скомпилировать ядро
Поместите новый модуль драйвера клавиатуры в каталог файловой системы nfs.
5.2Затем сжечь ядро,Загрузите модуль драйвера сенсорного экрана
Как показано на рисунке ниже, когда мы подключаем клавиатуру USB, мы видим, что VID и PID такие же, как параметры клавиатуры на компьютере.
5.3использованиеcat tty1Тест процесса
5.4 использованиеexec 0
Интеллектуальная рекомендация
Пошаговая загрузка файла Spring MVC-09 (на основе файла загрузки клиента Servlet3.0 + Html5)
пример тестовое задание Исходный код Несмотря на загрузку файлов в Servlet3.0 +, мы можем очень легко программировать на стороне сервера, но пользовательский интерфейс не очень дружелюбен. Одна HTML-ф.
Создайте многоканальное окно в приложениях Win32
Создайте многоканальное окно в приложениях Win32, создайте несколько оконных объектов одного и того же класса Windows, а окна объектов разных классов окон. .
Путь к рефакторингу IOS-APP (3) Введение в модульное тестирование
IOS-APP реконструкция дороги (1) структура сетевых запросов IOS-APP реконструкция дороги (два) Модельный дизайн При рефакторинге нам нужна форма, позволяющая вносить смелые изменения, обеспечивая при .
Tree——No.617 Merge Two Binary Trees
Problem: Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. You need to merge them into a new bin.
Источник