Драйверы HID-устройств (devh-*)
devh | ||
Makefile | ||
README.md |
Общая структура подсистемы ввода
┌───────────────────────────┐
│ │
│ Устройство ввода ◂───────────────────────┐
│ │ │
└─────────────▴─────────────┘ │
│ │
┌─────────────┴─────────────┐ │ Не HID-совместимое
│ │ │ устройство
│ HID-драйвер (devh-*) │ │
│ │ │
└─────────────▴─────────────┘ │
│ │
┌─────────────┴─────────────┐ ┌─────────────┴─────────────┐
│ │ │ │
│ HID-менеджер (io-hid) ◂─── * ───┤ Драйвер ввода (devi-*) ◂───▸ /dev/??? (standalone-режим)
│ │ │ │
└───────────────────────────┘ ▲ └─────────────▴─────────────┘
│ │
│ ┌─────────────▾─────────────┐
Интерфейс libhiddi ─────┘ │ │
│ Оконная оболочка Photon │
│ │
└───────────────────────────┘
Дерево исходных кодов
|- devh/
| |- egalax/ - Исходный код HID-драйвера поддержки тачскринов egalax, подключаемых по USB
| |- Makefile - Правила сборки дерева исходников
| `- common.mk - Параметры сборки драйверов
|
`- Makefile - Правила сборки дерева исходников
Сборка драйвера
- Установить и настроить комплект разработчика для ЗОСРВ "Нейтрино" редакции 2020.
- Выполнить команду:
make
Запуск драйвера
Вместе с менеджером io-hid:
io-hid -d <имя_драйвера|путь к библиотеке> [параметры]
С помощью утилиты mount:
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:
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 (содержится в структуреio_hid_self_t
)
При получении данных от устройства:
- Заполнить HID-report
- Передать HID-report менеджеру io-hid, вызвав функцию
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() │
│ │ │ ├───────────────────▸│
│ │ │ │ │