1
1
hid/README.md

164 строки
8.9 KiB
Markdown
Исходник Обычный вид История

## Общая структура подсистемы ввода
```
┌───────────────────────────┐
│ │
│ Устройство ввода ◂───────────────────────┐
│ │ │
└─────────────▴─────────────┘ │
│ │
┌─────────────┴─────────────┐ │ Не HID-совместимое
│ │ │ устройство
│ HID-драйвер (devh-*) │ │
│ │ │
└─────────────▴─────────────┘ │
│ │
┌─────────────┴─────────────┐ ┌─────────────┴─────────────┐
│ │ │ │
│ HID-менеджер (io-hid) ◂─── * ───┤ Драйвер ввода (devi-*) ◂───▸ /dev/??? (standalone-режим)
│ │ │ │
└───────────────────────────┘ ▲ └─────────────▴─────────────┘
│ │
│ ┌─────────────▾─────────────┐
Интерфейс libhiddi ─────┘ │ │
│ Оконная оболочка Photon │
│ │
└───────────────────────────┘
```
## Дерево исходных кодов
```
|- devh/
| |- egalax/ - Исходный код HID-драйвера поддержки тачскринов egalax, подключаемых по USB
| |- Makefile - Правила сборки дерева исходников
| `- common.mk - Параметры сборки драйверов
|
`- Makefile - Правила сборки дерева исходников
```
## Сборка драйвера
- Установить и настроить [комплект разработчика](https://help.kpda.ru/help/topic/ru.kpda.doc.dev_tools_ru/html/devkit/devkit.html) для [ЗОСРВ "Нейтрино" редакции 2020](https://help.kpda.ru/help/index.jsp).
- Выполнить команду:
```
make
```
## Запуск драйвера
Вместе с менеджером [io-hid](https://help.kpda.ru/help/topic/ru.kpda.doc.os_ru/html/services/io-hid.html):
```
io-hid -d <имя_драйвера|путь к библиотеке> [параметры]
```
С помощью утилиты [mount](https://help.kpda.ru/help/topic/ru.kpda.doc.os_ru/html/utils/utils/mount.html):
```
mount -T io-hid <путь к библиотеке> [параметры]
```
## Разработка драйвера
**Дескриптор драйвера:**
```
struct io_hid_dll_entry {
char *name;
int nfuncs;
int (*init)( void *dll_hdl, dispatch_t *dpp, io_hid_self_t *ioh, char *options );
int (*shutdown)( void *dll_hdl );
}
```
**Дескриптор [io-hid](https://help.kpda.ru/help/topic/ru.kpda.doc.os_ru/html/services/io-hid.html):**
```
struct io_hid_self_t {
_Uint32t nfuncs;
int (*reg)( void *dll_hdl, io_hid_registrant_t *registrant, int *reg_hdlp );
int (*dereg)( void *dll_hdl );
int (*get_buffer)( int reg_hdlp, void **buffer );
int (*send_report)( int registrant_hdl, void *data, _Uint32t dlen );
}
```
**Инициализация драйвера:**
- Заполнить дескриптор устройства (`io_hid_registrant`)
- Установить обработчики прерываний и инициализировать ресурсы драйвера
- Зарегистрировать драйвер, вызвав функцию `reg()` менеджера [io-hid](https://help.kpda.ru/help/topic/ru.kpda.doc.os_ru/html/services/io-hid.html) (содержится в структуре `io_hid_self_t`)
**При получении данных от устройства:**
- Заполнить HID-report
- Передать HID-report менеджеру [io-hid](https://help.kpda.ru/help/topic/ru.kpda.doc.os_ru/html/services/io-hid.html), вызвав функцию `send_report()`
**Дескриптор HID-устройства:**
```
struct io_hid_registrant_t {
_Uint32t flags;
hidd_device_ident_t *device_ident; /* vid, pid */
void *desc; /* binary descriptor */
_Uint16t dlen; /* binary descriptor length */
_Uint8t reserved[2];
void *user_hdl;
io_hid_registrant_funcs_t *funcs; /* callbacks */
_Uint8t reserved2[4];
}
```
**Дескриптор функций драйвера:**
Дескриптор функций драйвера определяет структура `io_hid_registrant_funcs`:
- Подключение/отключение клиента (`client_attach()` / `client_detach()`)
- Управление памятью (`rbuffer_alloc()` / `rbuffer_free()`)
- Чтение/Запись HID пакетов (`report_read()` / `report_write()`)
- Управление частотой обмена (`get_idle()` / `set_idle()`)
- Управление режимом работы (`get_protocol()` / `set_protocol()`)
- Получение дополнительных данных от устройства (`string`, `indexed_string`)
- Перезагрузка устройства (`reset()`)
## Общий принцип работы HID-драйвера
```
┌────────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐
│ Hardware │ │ devh-* │ │ io-hid │ │ devi-hid │ │ Клиент │
└─────┬──────┘ └─────┬────┘ └─────┬────┘ └──────┬─────┘ └─────┬────┘
│ │ │ │ │
│ │ Регистрация │ │ │
│ ├────────────────────────────▸│ │ │
│ │ │ │ │
│ ├──┐ │ │ │
│ │ │ Регистрация │ │ │
│ │ │ обработчиков прерываний │ │ │
│ │◂─┘ │ │ │
│ Прерывание │ │ │ │
├──────────────▸│ Отправка HID-report │ │ │
│ │ с помощью send_report() │ Передача │ │
│ ├────────────────────────────▸│ HID-report │ │
│ │ ├─────────────▸│ enqueue_packet() │
│ │ │ ├───────────────────▸│
│ │ │ │ │
```