LibUsb — библиотека для языка C, которая позволяет обмениваться данными с устройствами по протоколу usb.
У меня есть устройсво на базе STM32F407VGT6 микроконтроллера.
Давайте рассмотрим механизм посылки и принятия данных.
Прежде всего стоит отметить, что данные можно слать разными способами. Мы рассмотрим асинхронную передачу прерывания ( interrapt transfer )
Этот тип передачи позволяет передавать небольшие объёмы данных без получения подтверждения о получении. Тобеш послали и забыли))
При работе с libusb следует помнить, что его нужно инициализировать:
libusb_init(NULL); // инициализация libusb_set_debug(NULL, USB_DEBUG_LEVEL); // уровень вывода отладочных сообщений
Теперь получим handle устройства:
libusb_device_handle *handle = libusb_open_device_with_vid_pid(NULL, VID, PID);
Я считаю, что вы знаете Vendor ID и Product ID вашего устройства. Эти данные редко меняются, поэтому я задал их define`ом.
Если устройство не обнаружено handle = NULL :
if (handle == NULL) { printf("Устройство не подключено\n"); }
Кроме того, если система уже захватила контроль над устройством его нужно у неё забрать! Ато малоли чего она туда нашлёт…
if (libusb_kernel_driver_active(handle,DEV_INTF)) libusb_detach_kernel_driver(handle, DEV_INTF);
DEV_INTF — интерфейс устройства. Он тоже статичен, а указывать нужно из-за того, что он может быть не один.
Такие параметры удобно узнавать при помощи команды
lsusb -v -d VID:PID
Теперь захватываем интерфейс:
if (libusb_claim_interface(handle, DEV_INTF) < 0){ printf("Ошибка интерфейса\n"); }
Теперь можно читать данные. У меня «реализация usb мышки» такчто читаем по 4 байта:
int returned = libusb_interrupt_transfer(handle, EP_IN, buf, DATA_SIZE, &ret, 1000); if (returned >= 0) { cout << "buf[0] = " << (int)buf[0] << endl; cout << "buf[1] = " << (int)buf[1] << endl; cout << "buf[2] = " << (int)buf[2] << endl; cout << "buf[3] = " << (int)buf[3] << endl; }
Всё это можно делать в бесконечном цикле. Для наглядности.
В первой строке мы читаем данные в буфер buf из устройства handle, через точку EP_IN (для мыши это 0x81).
Читаем DATA_SIZE байт. Причём int ret получит число реально считанных байт. А ждать данные мы будем не больше 1000мс.
Буфер я объявлял так:
unsigned char buf[DATA_SIZE];
Самое забавное, что для посылки данные делается всё точно также, за исключением выбора конечной точки EP_OUT (у мыши 0x01 но смысла туда чтот слать я не вижу). Ну и конечно буфер перед этим нужно заполнить.
Для компиляции в linux нужно прилинковать библиотеку usb-1.0.
забыл. В конце отдаём девайс системе и вырубаем libusb:
libusb_attach_kernel_driver(handle, DEV_INTF);
libusb_close(handle);
libusb_exit(NULL);
Можно посмотреть полный код программы?
У меня, как у новичка, возникает куча ошибок при компиляции.
Вот пример
https://www.dropbox.com/s/mkuu2f3z5k4bapb/usb_testing.cpp?dl=0
DEV_INTF — интерфейс устройства. Как его определить?
при выполнении lsusb -v -d VID:PID, среди прочего всякого есть такие строки:
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 2
я верно понял, что iInterface это и есть DEV_INTF?
А если нужно это же скомпилировать на винде? это вообще реально?? а то у меня пишет что нет половины функции
Да, нужно добавить к проекту dll.
Вот только когда то я пробовал добавить libusb к проекту Qt и она у меня отказалась работать. Точно уже не помню в чем дело.
Печальный код, платформо зависеммые функции даже в ifdef не обернуты