USB HID прием данных

Модератор: Модераторы разделов

Аватара пользователя
COKPOWEHEU
Сообщения: 47
ОС: Debian (ядро 4.4.2) / Win7

USB HID прием данных

Сообщение COKPOWEHEU »

Собрал устройство, аналогичное этому. Оно должно управляться с компьютера посылками по 2 байта (в оригинальном устройстве по 3, но какая разница). Управляющая программа, также слегка видоизмененная, с устройством работает прекрасно, но она расчитана под windows (в том числе работает в виртуальной машине). Пытаюсь написать подобную программу для linux. Устройство находится и даже принимает данные, но вот отдавать их не желает ни в какую.
Вывод lsusb -v -d (VID,PID)

user

$ lsusb -v -d 16c0:05df Bus 002 Device 115: ID 16c0:05df VOTI Couldn't open device, some information will be missing Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x16c0 VOTI idProduct 0x05df bcdDevice 1.00 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 34 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 No Subclass bInterfaceProtocol 0 None iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.01 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 22 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 100


Код, которым пытаюсь заставить его работать

Код:

#include <libusb-1.0/libusb.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #define DEV_VID 0x16c0 //0x5824 #define DEV_PID 0x05df //0x1503 #define DEV_CONFIG 1 #define DEV_INTF 0 int main(int argc, char * argv[]){ libusb_device_handle * handle; int i, ret; unsigned int level; unsigned char command[1], buf[8], channel; char param; libusb_init(NULL); libusb_set_debug(NULL, 3); handle = libusb_open_device_with_vid_pid(NULL, DEV_VID, DEV_PID); if (handle == NULL) { printf("Не удалось найти устройство\n"); libusb_exit(NULL); return 0; } if (libusb_kernel_driver_active(handle,DEV_INTF)) libusb_detach_kernel_driver(handle, DEV_INTF); if ((ret = libusb_set_configuration(handle, DEV_CONFIG)) < 0){ printf("Ошибка конфигурации\n"); libusb_close(handle); libusb_exit(NULL); return 0; } if (libusb_claim_interface(handle, DEV_INTF) < 0){ printf("Ошибка интерфейса\n"); libusb_close(handle); libusb_exit(NULL); return 0; } int tr; unsigned char data[10]; data[0]=0x0D; data[1]=0x0D; ret = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 0x9, 0x300, 0, data, 2, 500); printf("received %i bytes\n",ret); ret=libusb_interrupt_transfer(handle,0x81/*EP_1_IN*/,data,2/*len*/,&tr,1000); printf("ret=%i\ndata[0]=0x%x\ndata[1]=0x%x\n",ret,data[0],data[1]); libusb_release_interface(handle,0); libusb_attach_kernel_driver(handle, DEV_INTF); libusb_close(handle); libusb_exit(NULL); return 0; }
Проверка:

root

# gcc -o prog test.c -lusb-1.0 && ./prog received 2 bytes ret=-7 data[0]=0xd data[1]=0xd


От рута, поскольку libusb этого требует. Сколько я понимаю, возвращаемое значение -7 означает TIMEOUT, доступное время на это не влияет (до 10 сек по крайней мере), данные 0xd это ранее записанное, должно было вернуть 0x0.
Спасибо сказали:
FatZer
Сообщения: 33
ОС: Gentoo

Re: USB HID прием данных

Сообщение FatZer »

COKPOWEHEU писал(а):
07.03.2014 19:24
От рута, поскольку libusb этого требует. Сколько я понимаю, возвращаемое значение -7 означает TIMEOUT, доступное время на это не влияет (до 10 сек по крайней мере), данные 0xd это ранее записанное, должно было вернуть 0x0.

Чтобы делать это от пользователя нужно права на чтение запись в /dev/bus/usb/<bus>/<device>

По сабжу: как я понимаю, у hid'а есть свой протокол надстроенный над usb. Стоит глянуть в сторону библиотек hidapi и libhid.
Ещё можно убедиться, что именно происходит на usb, проснифав wireshark'ом (оффтопик запускается в виртуалке, usb устройство пробрасывается туда, а wireshark'ом на хосте смотрим, что там происходит).
Спасибо сказали:
Аватара пользователя
COKPOWEHEU
Сообщения: 47
ОС: Debian (ядро 4.4.2) / Win7

Re: USB HID прием данных

Сообщение COKPOWEHEU »

Сейчас требование рута меня не пугает а потом, конечно, буду решать.
По использованию libhid и hidapi не нашел вообще ничего.
wireshark попробую
Спасибо сказали:
FatZer
Сообщения: 33
ОС: Gentoo

Re: USB HID прием данных

Сообщение FatZer »

COKPOWEHEU писал(а):
08.03.2014 13:03
По использованию libhid и hidapi не нашел вообще ничего.

для hidapi прямо на официальной страничке доходчивый пример: http://www.signal11.us/oss/hidapi/
судя по названию, функции прямо аналогичны оффтопиковым в статье...
про libhid ничего не скажу...
Спасибо сказали:
Аватара пользователя
COKPOWEHEU
Сообщения: 47
ОС: Debian (ядро 4.4.2) / Win7

Re: USB HID прием данных

Сообщение COKPOWEHEU »

wireshark сказал что прием идет по USB_CONTROL_IN, адрес конечной точки 80 (а не 81 как мне казалось), больше мои познания ничего узнать не позволили.
hidapi наверное то что надо, если разберусь как компилировать. Я так понял что ld хочет какой-то модуль,
UDP: таки понял, надо добавить -lusb-1.0 -lhidapi-hidraw.
Процесс колдовства возобновился :-)
UDP2: оно его не видит. Показывает 3 устройства, на подключение самоделки не реагирует несмотря на lsusb, который говорит что оно hid.
Вот здесь писали что linux умеет только "Device", "Pointer", "Mouse", "Device", "Joystick", "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller". А у меня нестандартное. Пересобирать прошивку не хочется, ядро - тем более.
Спасибо сказали:
FatZer
Сообщения: 33
ОС: Gentoo

Re: USB HID прием данных

Сообщение FatZer »

COKPOWEHEU писал(а):
08.03.2014 20:17
UDP2: оно его не видит. Показывает 3 устройства, на подключение самоделки не реагирует несмотря на lsusb, который говорит что оно hid.

конкретики немного не помешало бы...

а в /sys/class/hidraw/ соответствующий симлинк для устройства появляется? и само устройство в /dev/hidraw?
Спасибо сказали:
Аватара пользователя
COKPOWEHEU
Сообщения: 47
ОС: Debian (ядро 4.4.2) / Win7

Re: USB HID прием данных

Сообщение COKPOWEHEU »

Какой конкретики, какие устройства отображаются что ли? Вроде как мышь, клава и еще что-то, особо не разбирался. Суть в том что на подключение моего устройства оно не реагирует и VID/PID другие.
В /sys/class/hidraw/ не смотрел, в /dev/hidraw не появляется, там те самые 3 штуки, /dev/hidraw0, /dev/hidraw1, /dev/hidraw2, которые смотрит тестовая программа. В /dev/bus/usb/002/ оно видно и читается, правда всегда одинаково, не реагируя на само устройство.
Спасибо сказали:
Аватара пользователя
COKPOWEHEU
Сообщения: 47
ОС: Debian (ядро 4.4.2) / Win7

Re: USB HID прием данных

Сообщение COKPOWEHEU »

Обнаружил, что на старом ядре, 2.6.32, устройство появляется в /dev/hidraw3 и опознается программой. Взаимодействие не проверял, старое ядро неудобно работает с новым окружением. То есть дело не в VID/PID.
Отдельно проверил программатор avrdoper на железе Prottoss'a (hid-версия), на старом ядре оно отображается в hidraw и работает, на новом - не отображается, но работает (как?!).
Может знаете как заставить новое ядро правильно опознавать hid'ы в /dev/hidraw*?
Спасибо сказали:
FatZer
Сообщения: 33
ОС: Gentoo

Re: USB HID прием данных

Сообщение FatZer »

COKPOWEHEU писал(а):
11.03.2014 18:24
Обнаружил, что на старом ядре, 2.6.32, устройство появляется в /dev/hidraw3 и опознается программой. Взаимодействие не проверял, старое ядро неудобно работает с новым окружением.

значит в ядре или что-то поломали, или что-то починили... что именно — хз... может всё легко и какой-то модуль не загружен... есть подозрение, что это uhid, но можно попробовать грузить все подряд из /lib/modules/$(uname -r)/kernel/drivers/hid/

COKPOWEHEU писал(а):
11.03.2014 18:24
Может знаете как заставить новое ядро правильно опознавать hid'ы в /dev/hidraw*?

если загрузка модулей не прокатит, то ИМХО это придётся спрашивать в каком-нить месте по-серьёзней, вроде маиллистов...

COKPOWEHEU писал(а):
11.03.2014 18:24
Отдельно проверил программатор avrdoper на железе Prottoss'a (hid-версия), на старом ядре оно отображается в hidraw и работает, на новом - не отображается, но работает (как?!).

скорей всего, есть реализация hid протокола в юзерспейсе (поверх libusb).
Кстати, в libhid похоже так и делает... правда доков по ней нет, и в исходниках логика работы тоже не видна... так что придётся методом тыка по названиям функций из хедера делать... +в качестве примера, можно взять тест из пакета с исходниками и мелкую утилитку...
Спасибо сказали:
Аватара пользователя
COKPOWEHEU
Сообщения: 47
ОС: Debian (ядро 4.4.2) / Win7

Re: USB HID прием данных

Сообщение COKPOWEHEU »

Обновил ядро до 3.13, устройство появилось. Буду экспериментировать дальше
Спасибо сказали:
Аватара пользователя
COKPOWEHEU
Сообщения: 47
ОС: Debian (ядро 4.4.2) / Win7

Re: USB HID прием данных

Сообщение COKPOWEHEU »

УСПЕХ

После того, как устройство определилось в /dev/hidraw*, библиотека hidapi его подцепила. Передача от компа к платке осуществляется hid_write(), прием - hid_get_feature_report(). hid_read() вылетает по таймауту, видимо, потому что в устройстве не прописаны конечные точки кроме 0, которая зарезервирована для приема-передачи фич (get/set feature report). Впрочем раз работает, не буду трогать.
Спасибо сказали: