Russian Qt Forum
Ноябрь 25, 2024, 12:05
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Программирование
>
Общий
>
libusb, обёртка
Страниц: [
1
]
2
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: libusb, обёртка (Прочитано 11984 раз)
juvf
Программист
Offline
Сообщений: 570
libusb, обёртка
«
:
Апрель 11, 2016, 11:30 »
Пишу обмен с девайсом с использованием libusb. Сделал в девайсе EP_IN и EP_OUT. Обе точки bulk. В хосте осуществляется обмен с девайсом по алгоритму запрос-ответ. В нужно месте вызываю usb_bulk_write() и следом usb_bulk_read() в ожидании ответа.
возникла необходимость получать от девайса спорадические сообщения. Как это сделать с libusb? Хотелось бы, чтоб девайс в лбюбое время послал сообщение, а в хосте возник бы эвент или сигнал "Пришло сообщение от usb девайса", и к этому эвенту или сигналу прикрутить обработчик или слот.
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: libusb, обёртка
«
Ответ #1 :
Апрель 11, 2016, 11:43 »
http://libusb.sourceforge.net/api-1.0/group__asyncio.html
Записан
juvf
Программист
Offline
Сообщений: 570
Re: libusb, обёртка
«
Ответ #2 :
Апрель 11, 2016, 12:41 »
это я видел, но не понятно... как это можно использовать в моём случае?
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: libusb, обёртка
«
Ответ #3 :
Апрель 11, 2016, 13:02 »
Цитата: juvf от Апрель 11, 2016, 12:41
это я видел, но не понятно... как это можно использовать в моём случае?
Стоп, вы хотите чтобы устройство спонтанно отправляло данные? Насколько я помню, все USB-транзакции выполняются по инициативе хоста.
Записан
juvf
Программист
Offline
Сообщений: 570
Re: libusb, обёртка
«
Ответ #4 :
Апрель 11, 2016, 13:11 »
Цитата: Old от Апрель 11, 2016, 13:02
Цитата: juvf от Апрель 11, 2016, 12:41
это я видел, но не понятно... как это можно использовать в моём случае?
Стоп, вы хотите чтобы устройство спонтанно отправляло данные? Насколько я помню, все USB-транзакции выполняются по инициативе хоста.
Да, вот именно, мне нужно чтоб устройство само инициализировало передачу. Пока вижу такой сценарий: в устройстве сделать отдельную точку bulk, в хосте в отдельном потоке
1) открыть усб
2) при успешном открытии пробовать прочитать заведомо много байт usb_bulk_read(handlerDev, EP_IN, bufferUsb, 6000, 100);
3)закрыть усб
4)если прочитал что-то, то оработать (послать сигнал с сообщением)
5)уснуть на 100 мс.
6) goto 1
будут задержки до 200 мс, но в моём случае это приемлемо.
Записан
juvf
Программист
Offline
Сообщений: 570
Re: libusb, обёртка
«
Ответ #5 :
Апрель 11, 2016, 13:13 »
а как HID работают? Например клавиатура? Хост постоянно опрашивает HID на предмет наличия данных? Или клавиатура сама шлёт данные, когда её вздумается?
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: libusb, обёртка
«
Ответ #6 :
Апрель 11, 2016, 13:35 »
Цитата: juvf от Апрель 11, 2016, 13:13
а как HID работают? Например клавиатура? Хост постоянно опрашивает HID на предмет наличия данных?
Да. Вы можете задавать частоту, с которой хаб будет опрашивать устройство.
Записан
juvf
Программист
Offline
Сообщений: 570
Re: libusb, обёртка
«
Ответ #7 :
Апрель 11, 2016, 13:41 »
хорошо, а как с libusb можно hid поднять? Придется всё руками делать, т.е. в отдельном треде опрашивать hid? Или можно проинить как нить libusb и обрабатывать эвенты?
Записан
Old
Джедай : наставник для всех
Offline
Сообщений: 4350
Re: libusb, обёртка
«
Ответ #8 :
Апрель 11, 2016, 13:51 »
Цитата: juvf от Апрель 11, 2016, 13:41
хорошо, а как с libusb можно hid поднять? Придется всё руками делать, т.е. в отдельном треде опрашивать hid? Или можно проинить как нить libusb и обрабатывать эвенты?
Это хороший вопрос.
Думаю, что все придется делать самому. Но не думаю, что это будет сильно проблемно.
Можно обойтись без отдельного потока, все будет зависеть от необходимой вам частоты опроса. Если она будет не максимальная (1кГц), а скажем раз в 300 мс, то можно использовать таймер. Пришло время, опросили железку, если что-то пришло, послали сигнал с данными.
Записан
kuzulis
Джедай : наставник для всех
Offline
Сообщений: 2812
Re: libusb, обёртка
«
Ответ #9 :
Апрель 11, 2016, 18:14 »
Бррр... Не знаю как там в libusb все "закручено", но нет никаких проблем если использовать нативное API.
Например, если используется Windows то:
= Если принято решение использовать HID девайс, то для этого надо =
1. Реализовать HID класс у-ва (дескрипторы и прочие плюшки) в прошивке железки.
2. Используем Win32 API для работы с HID девайсом:
- ищем DevicePath
- открываем с помощью CreateFile
- конфигурим девайс
- пишем/читаем в ендпойнты девайса (используя WriteFile/ReadFile или DeviceIoControl, в зависимости от того, какая ендпойнт используется).
Прелесть здесь в том, что WriteFile/ReadFile асинхронные для bulk (если открывать девайс в OVERLAPPED режиме)... Например, если хотим прочитать что-то из девайса, то алгоритм такой:
- при открытии девайса передаем его хендл в QWinOverlappedIoNotifier, и коннектим его сигнал notified() к нашему слоту. Этот сигнал будет сигнализировать нам о том, что какая-то I/O операция на хендле девайса завершена.
- делаем ReadFile c OVERLAPEPD структурой и все....
- когда в устройстве появятся данные, то сработает QWinOverlappedIoNotifier с нашей OVERLAPPED структурой, по которой можно сравнить, какая из операций завершена (в нашем случае только одна read).
- И все.. в буфере, который передавался как параметр ReadFile будут лежать прочитанные данные...
- После того как обработаем данные, можно снова вызвать ReadFile c OVERLAPEPD структурой и т.п. все заново.
Тут не нужны потоки и прочий треш
.
Минус в том, что для контрол-эндпойнтов это не будет работать, используя HID функции, т.к. они не используют OVERLAPPED (емнип). т.е. QWinOverlappedIoNotifier будет постоянно срабатывать и грузить event-loop... Хотя, у меня работало и с загрузкой..
= Если принято решение использовать девайс как "Стандартное" USB у-во, то для этого надо =
1. Задать USB дескриптору девайса (в его прошивке) класс как "Стандартное ЮСБ" (MSDN в помощь). Это надо чтобы виндовс подгрузил стандартные дрова и определил девайс как "Стандартное ЮСБ у-во".
2. А далее, также как и с HID, ищем devicepath, открываем его, делаем I/O в экдпойнты, используя или ReadFile/WriteFile или WinUSB API, в зависимости от эндпойнтов..
По аналогии такое можно сделать и для Linux, только использовать QSocketNotifier... но я не пробовал.
ЗЫ: Возможно, что асинхонная работа также поддерживается и в LibUSB (как выше приведено в ссылке), т.е. делаем транзакцию, и каллбек вызовется только тогда, когда данные были прочитаны из у-ва... Но я ХЗ. я не работал с LibUSB..
«
Последнее редактирование: Апрель 12, 2016, 08:41 от kuzulis
»
Записан
ArchLinux x86_64 / Win10 64 bit
juvf
Программист
Offline
Сообщений: 570
Re: libusb, обёртка
«
Ответ #10 :
Апрель 12, 2016, 07:29 »
Цитата: kuzulis от Апрель 11, 2016, 18:14
2. Используем Win32 API для работы с HID девайсом:
- ищем DevicePath
- открываем с помощью CreateFile
- конфигурим девайс
- пишем/читаем в ендпойнты девайса (используя WriteFile/ReadFile или DeviceIoControl, в зависимости от того, какая ендпойнт используется).
Как найти DevicePath у USB? Есть рабочий пример?
Цитировать
передаем его хендл в QWinOverlappedIoNotifier
Нет такого класса в Qt 5.4. Есть QWinEventNotifier? Наверно это тоже самое?
Записан
kuzulis
Джедай : наставник для всех
Offline
Сообщений: 2812
Re: libusb, обёртка
«
Ответ #11 :
Апрель 12, 2016, 08:35 »
Цитировать
Как найти DevicePath у USB? Есть рабочий пример?
В Windows - использовать SetupAPI, где перечислять нужные девайсы по их GUID, где искомое будет то, у которого совпадают VID/PID. В принципе, гугл в помощь, например:
http://stackoverflow.com/questions/13927475/windows-how-to-enumerate-all-connected-usb-devices-device-path
и много других ресурсов.
Рабочих примеров - полно.
Цитировать
Нет такого класса в Qt 5.4. Есть QWinEventNotifier?
Начиная с 5.5, оно есть но приватное, чтобы использовать достаточно прописать QT += core-private.
Qt 5.4 - ну уж очень древнемамонт..
Цитировать
Наверно это тоже самое?
Нет, не то-же, но использовать тоже можно. Тут нужно просто в OVERLAPPED структуре создавать ovl.hHandle и его передавать в QWinEventNotifier, вместо хендла девайса.
Как это используется - можно посмотреть в том-же QSerialPort до 5.5 и после 5.5 (также там можно посмотреть как SetupApi используется - разницы в принципе нет).
«
Последнее редактирование: Апрель 12, 2016, 08:38 от kuzulis
»
Записан
ArchLinux x86_64 / Win10 64 bit
juvf
Программист
Offline
Сообщений: 570
Re: libusb, обёртка
«
Ответ #12 :
Апрель 12, 2016, 08:38 »
Ещё нюанс.... вот вызвали ReadFile и занимаемся своими делами..... но сообщений нет..... внезапно юзер отключает разъем усб, что тогда? ReadFile корректно отработает такую ситуацию?
Записан
kuzulis
Джедай : наставник для всех
Offline
Сообщений: 2812
Re: libusb, обёртка
«
Ответ #13 :
Апрель 12, 2016, 08:46 »
Цитировать
ReadFile корректно отработает такую ситуацию?
да, там Notifier сработает, но с кодом ошибки (GetLastError)... обычно это будет что-то типа OPERATION_ABORTED (или как-то так, не помню)... но, в общем, с ошибкой все вернется.
если такое не устраивает, то можно подписаться на события ATTACH/DETACH (на WM_MESSAGE), для конкретного класса у-в по их GUID. Тогда конкретно уже можно получать нотификации о том что у-во выло всунуто-высунуто и закрывать его хендл если надо.. (гугл в помощь).
Записан
ArchLinux x86_64 / Win10 64 bit
juvf
Программист
Offline
Сообщений: 570
Re: libusb, обёртка
«
Ответ #14 :
Апрель 12, 2016, 09:28 »
Я ещё не подымал в железке хид.... смотрю в Деспетчер устройств в винде... там все HID-устройства безымянные. Это свойство HID? Я не смогу увидеть что-то типа "HID совместимое устройство MyDevice"?
Цитата: Old от Апрель 11, 2016, 11:43
http://libusb.sourceforge.net/api-1.0/group__asyncio.html
в принцепе похожий алгоритм, предложенный kuzulis, можно бы и на либусб сделать, есть там всякие
libusb_fill_bulk_transfer()
, но в текущей версии(1.2.5) libusb нет такой функции.
Записан
Страниц: [
1
]
2
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...