Лабораторная работа №1 Программирование горячего подключения USB Цель работы: Получение навыка работы с горячим подключением устройств USB с использованием универсального кроссплатформенного интерфейса libusb. План: 1. Создать функцию обратного вызова (callback) с кодом реакции на подключение нового устройства 2. Выполнить инициализацию библиотеки libusb 3. Зарегистрировать функцию обратного вызова 4. Ожидать возникновение события на USB шине 5. Отменить регистрацию функции обратного вызова 6. Выполнить деинициализацию библиотеки libusb 1. Функция обратного вызова - это функция, которая будет вызвана подсистемой libusb при детектировании определенных событий на шине USB. Функция обратного вызова имеет следующий вид: int имя_функции (libusb_context *ctx, libusb_device *device, libusb_hotplug_event event, void *user_data){ //действия, выполняемые по событию на шине USB } Параметры функции: ctx - ссылка на контекст библиотеки (для общего контекста - NULL) device - ссылка на USB устройства, с которым произошло событие event - тип произошедшего события (значения: LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED - устройство подключено LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT - устройство отключено ) user_data - произвольные пользовательские данные, которые можно передать в функцию-обработчик. Определяются на этапе регистрации callback функции. Возвращаемое значение - 0 - обработка продолжается, 1 - для дерегистрации функции обработчика в системе libusb. Функцию определить выше функции main. В функции необходимо реализовать код реакции на подключение устройства, а именно получить дескриптор устройства при помощи функции libusb_get_device_descriptor и вывести параметры дескриптора bDeviceClass, bDeviceSubClass и bDeviceProtocol. Для работы с библиотекой libusb необходимо: - подключить заголовочный файл библиотеки #include - выполнять компиляцию с ключем: -lusb-1.0 2. Выполнить инициализацию библиотеки libusb Инициализация выполняется функцией libusb_init. int libusb_init (libusb_context ** context) Вместо context передать в функцию NULL. Функция возвратит 0 при успешной инициализации, иначе код ошибки. 3. Зарегистрировать функцию обратного вызова Регистрация функции обработчика событий USB выполняется при помощи следующий функции: int libusb_hotplug_register_callback ( libusb_context * ctx, int events, int flags, int vendor_id, int product_id, int dev_class, libusb_hotplug_callback_fn cb_fn, void * user_data, libusb_hotplug_callback_handle * callback_handle); Параметры: ctx - ссылка на контекст библиотеки (для общего контекста - NULL) events - битовая маска событий, для которых будет вызвана функция обработки (значения: LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) flags - битовая маска метода обработки события на шине (значения: LIBUSB_HOTPLUG_ENUMERATE - запускать функцию обработки для всех устройств на шине, удовлетворяющих условиям) vendor_id - VID устройства, для которого требуется обработка события, или LIBUSB_HOTPLUG_MATCH_ANY (для отключения фильтрации по VID) product_id - PID устройства, для которого требуется обработка события, или LIBUSB_HOTPLUG_MATCH_ANY (для отключения фильтрации по PID) dev_class - Класс устройства, для которого требуется обработка события, или LIBUSB_HOTPLUG_MATCH_ANY (для отключения фильтрации по классу) cb_fn - имя функции обработчика user_data - ссылка на пользовательские данные (или NULL в случае их отсутствия) callback_handle - ссылка на метку функции обработчика, по которой производится дерегистрация Фунция возвращает LIBUSB_SUCCESS (успех) или LIBUSB_ERROR (ошибка) 4. Ожидать возникновение события на USB шине libusb предоставляет множество функций для ожидания возникновения событий. В простейшем случае - это функция ожидания с блокированием libusb_handle_events, которая приостанавливает работу программы до тех пор, пока не появиться любое событие на шине USB, фильтрует события по условиям (VID, PID, devClass, тип события) и осуществляет вызов соответствующих зарегистрированных функций обратного вызова. Обычно функция детектирования вызывается в отдельном потоке, чтобы не блокировать выполнение основной программы, однако в данной работе детектирование является самой целью, поэтому предлагается осуществлять вызов из main. Функция ожидания событий на шине USB с блокированием выполнения имеет вид: int libusb_handle_events( libusb_context * ctx ) Параметры: ctx - ссылка на контекст библиотеки (для общего контекста - NULL) Функция возвращает 0 - при удачном детектировании или LIBUSB_ERROR - при таймауте (60 сек) или иной ошибке. В рамках работы предлагается вызывать ее по циклу. Цикл выполнять до тех пор, пока не будет вызвана функция обработки. 5. Отменить регистрацию функции обратного вызова Для отмены регистрации обратного вызова используется функция: void libusb_hotplug_deregister_callback(libusb_context * ctx, libusb_hotplug_callback_handle callback_handle) Параметры: ctx - ссылка на контекст библиотеки (для общего контекста - NULL) callback_handle - ссылка на метку функции обработчика, которая сформирована функцией регистрации libusb_hotplug_register_callback() Фунция возвращает LIBUSB_SUCCESS (успех) или LIBUSB_ERROR (ошибка) 6. Выполнить деинициализацию библиотеки libusb Функция libusb_exit(NULL); Полная справочная информация по libusb доступна по адресу: http://libusb.sourceforge.net/api-1.0/modules.html