что такое usb hid
Менее распространенные HID
СОДЕРЖАНИЕ
HID стандарт
Компоненты протокола HID
Предполагается, что хост будет более сложным объектом, чем устройство. Хосту необходимо получить дескриптор HID с устройства и проанализировать его, прежде чем он сможет полностью взаимодействовать с устройством. Анализ дескриптора HID может быть сложным. Известно, что многие операционные системы содержат ошибки в драйверах устройств, ответственных за анализ дескрипторов HID, спустя годы после того, как драйверы устройств были изначально выпущены для общественности. Однако эта сложность является причиной того, что возможны быстрые инновации с HID-устройствами.
Вышеупомянутый механизм описывает так называемый «протокол отчетов» HID. Поскольку было понятно, что не все хосты могут анализировать дескрипторы HID, HID также определяет «протокол загрузки». В протоколе загрузки поддерживаются только определенные устройства с определенными функциями, поскольку используются фиксированные форматы пакетов данных. В этом режиме дескриптор HID не используется, поэтому нововведения ограничены. Однако преимущество в том, что минимальная функциональность все еще возможна на хостах, которые в противном случае не смогли бы поддерживать HID. Единственные устройства, поддерживаемые в протоколе загрузки:
Обычно режим загрузки используется в первые моменты загрузки компьютера. Непосредственная настройка BIOS компьютера часто выполняется только в режиме загрузки. Иногда появляется сообщение, информирующее пользователя о том, что на устройстве установлен правильный драйвер и теперь его можно использовать.
HID определение устройства
Согласно спецификации HID, устройство описывается в режиме отчета как набор элементов управления или группа элементов управления. Элементы управления соответствуют полю, содержащему данные, и другому полю, содержащему тег использования. Каждый тег использования описан в спецификации, поскольку конструктор предложил использовать данные, описанные в режиме отчета.
Другие протоколы с использованием HID
Что такое устройство с интерфейсом пользователя (HID)?
Есть много странных терминов, связанных с использованием компьютера. Возможно, вы видели «Устройство интерфейса человека» или «HID». Звучит как что-то из научно-фантастического фильма, но что именно это означает?
«Устройство интерфейса человека» может звучать странно чуждо, но на самом деле название очень информативное. Проще говоря, HID — это стандарт для компьютерных устройств, которыми управляет человек. Стандарт позволяет легко использовать эти устройства без какого-либо дополнительного программного обеспечения или драйверов.
Стандарт упрощения принадлежностей
«Устройства интерфейса пользователя» — это стандарт, созданный для упрощения процесса установки устройств ввода. До HID существовало несколько конкретных протоколов для каждого типа устройства ввода.
Это означало, что существует протокол для мышей, протокол для клавиатур и так далее. Устройствам необходимо использовать существующие протоколы или создавать собственные драйверы. У людей было больше работы по установке и настройке устройств.
Для сравнения, HID-совместимое устройство включает «пакеты данных», которые содержат все действия устройства. Например, на клавиатуре может быть клавиша для регулировки громкости. При нажатии этой клавиши «дескриптор HID» сообщает компьютеру, где в пакетах хранится цель этого действия, и оно выполняется.
Протокол HID значительно упрощает компаниям производство широко совместимых аксессуаров. Все современные операционные системы поддерживают протокол HID. Вы можете подключить USB-клавиатуру к ПК с Windows, Mac, Chromebook или даже к планшету Android, и она сразу заработает. Это все благодаря HID.
HID и приложения
Самым большим преимуществом HID является возможность просто подключить к вашему устройству практически любое периферийное устройство, и оно сразу же начнет работать. Но это только половина магии. А как насчет того, чтобы эти аксессуары работали с приложениями?
Вы можете подключить USB-контроллер к своему ПК, и он, как правило, будет управлять игрой должным образом. Даже если контроллер был сделан после игры, он все равно работает. Разработчикам игры не нужно было ничего делать, чтобы это произошло.
Когда вы подключаете HID-устройство, оно сообщает о своих возможностях операционной системе. Операционная система интерпретирует данные и классифицирует устройство. Это позволяет приложениям и играм ориентироваться на классы устройств, а не на конкретные модели.
Это очень важный элемент HID, и мы принимаем его как должное. Игровой контроллер будет работать с вашей библиотекой Steam. Zoom узнает, что нужно включить вашу веб-камеру. Все это происходит с очень небольшой настройкой с вашей стороны.
Типы устройств интерфейса пользователя
Как упоминалось ранее, USB-периферийные устройства являются наиболее распространенными устройствами с интерфейсом пользователя, которые вы увидите, но есть и другие типы.
USB-устройства относятся к классу «USB-HID». Это включает в себя обычные вещи, такие как клавиатуры, мыши, веб-камеры, трекпады и игровые контроллеры. Другие устройства USB-HID включают термометры, аудио инструменты, медицинское оборудование, телефоны и тренажеры.
Другой распространенный тип — Bluetooth-HID. Это тот же протокол USB-HID с небольшими изменениями для Bluetooth. Как и следовало ожидать, сюда входят устройства, аналогичные USB-HID, но они подключаются через Bluetooth. Мышь Bluetooth будет работать независимо от того, подключена ли она к ПК с Windows, Mac или Chromebook.
Устройства интерфейса пользователя — одни из наиболее распространенных устройств, которые мы используем с компьютерами. Мы не очень ценим, насколько легко ими пользоваться. Было время, когда это было не так просто.
HID не только упростил использование компьютеров, но и внес свой вклад в массовый рынок аксессуаров. Существуют тысячи клавиатур, мышей, веб-камер, контроллеров и других продуктов, о несовместимости с которыми вам просто не нужно беспокоиться.
В истории компьютеров было много достижений, но стандарт Human Interface Device имел оглушительный успех.
USB HID интерфейс для STM32 в STM32IDE
Ряд микроконтроллеров STM32 имеют на борту USB интерфейс для связи с компьютерами. Как правило, удобнее всего использовать предоставляемый компаний ST Microelectronics драйвер класса CDC (Communication Device Class ). Он позволяет использовать на стороне компьютера UART через USB и не требует установки драйверов. Со стороны STM32 при этом требуется только поменять операции вывода данных, остальное делается самостоятельно. Причём скорость такого соединения может быть практически любой, поддерживаемой компьютером.
Однако ряд разработок, особенно, когда приходишь в другую компанию, где используется HID Class (Human Interface Device), в случае разработки новой версии устройства требуется поддерживать ранее выбранный интерфейс. Что, собственно, и случилось. Примеры проектов от самой ST, которые они дают при загрузке STM32 Cube MX и IDE, как обычно, дали только минимальное понимание, но не раскрыли, что и как надо делать. Я когда-то разбирался с USB, даже писал собственный драйвер, но это было так давно… Остались только общие воспоминания. Посему пришлось искать дополнительную информацию, чтобы получить стартовую точку.
Первое найденное было видеороликом на youtube в стиле HID за 5 минут 🙂 Автор даёт доступ к своему коду на GitHub. Всё, типа круто, красиво, просто вставляйте к себе и всё будет чудесно. Судя по отзывам под роликом, некоторым этого хватило. Изучив исходники понял, что минимального прозрения не наступило, да и уровень полученной информации мал для того, чтобы решить поставленную задачу. Но закомство с этим материалом было явно полезным. Решение вопроса с использованием кубика (STM32Cube MX) мне лично импонирует больше, чем другие подходы, поскольку позволяет отвлечься от ряда низкоуровневых операций и генерация проекта всегда происходит в одном стиле. Соответственно, изучение этого примера показало, на какие файлы надо обратить внимание, где и что надо поменять или добавить, какие функции использовать для получения и отправки данных именно для нашей выбранной среды программирования.
Следующий поиск оказался весьма удачным. Хабр — известный сайт, на котором можно найти много полезного по разной электронной тематике. Нашлась там и статья STM32 и USB-HID — это просто. Я не являюсь постоянным клиентом Хабра и не знаю автора этой статьи RaJa, но на мой взгляд это очень хорошая статья, описывающая основные положения работы HID интерфейся. Без её прочтения читать дальше здесь бессмысленно, поскольку далее будут, в основном, комментарии для адаптации кода к среде разработки STM32IDE/STM32CubeMX + Atollic TrueStudio. (Далее STM32IDE). Да и столь популярный в 2014 году и реально очень неплохой проект EmBlocks, увы, умер.
Первое, что необходимо решить — как тестировать вновь создаваемое устройство. Лет… дцать назад я использовал для этого анализатор и синтезатор трафика USB — очень полезные, но дорогие игрушки 🙂 Сейчас у меня такой возможности нет, да и должен же быть более простой путь. Тем более для простого стандартного интерфейса без написания собственного драйвера. Авторы обоих рассмотренных выше проектов пошли самы простым для них путём — написание простой программы на известных им языках. Но автор статьи на Хабре сделал очень правильный шаг — он написал свой проект, совместимый с программой ST HID Demonstrator (ссылка есть в статье), позволяющей поуправлять нашим устройством, как графически, так и послать свои данные и посмотреть, что пришло от нашего устройства. Фактически программа может использоваться и в дальнейшем для отладки будущей программы на выбранном микроконтроллере.
Своё ознакомление с проектом для HID я осуществлял с платой STM32L476 Discovery. Плата, вообще говоря, может быть любой, где USB интерфейс микроконтроллера физически подключён к отдельному разъёму USB. Есть у меня и Nucleo 32 с STM32L4, но там один разъём USB тспользуется и для программирования/отладки, и для связи с хостом, что добавляет интриги в интерфейс и может служить источником дополнительных непоняток. Оно нам надо?
Итак, комментарии и дополнения к статье по привязке HID к STM32IDE примерно по тем же шагам, как и в хабровской статье.
Структура проекта
В STM32IDE структура всех проектов задаётся при генерации проекта из среды назначения функциональности пинов и пользователю о том заботиться не надо. В частности, в кубике (что отдельном STM32Cube MX, что в встроенном в STM32IDE) активируем USB, как Device, и добавляем Middleware USB Custom HID.
Заходим в Clock Configuration. Вполне вероятно, что могут быть проблемы с системными частотами, которые маркируются малиновым цветом.
Если так, нажимаем Resolve Clock Issues и, скорее всего, всё будет настроено на максимальные частоты. Главное — USB Clock будет выставлен на 48 МГц. Надо заметить, что в семействе STM32L4 генератор на 48МГц имеет автоподстройку по SOF (Start Of Frame), что позволяет создавать USB устройства без внешнего кварца/генератора. Если, конечно, остальной дизайн допускает использование некварцованных генераторов. Для других семейств не проверял, поскольку для моего текущего проекта был выбран именно L4. Только надо отметить, что при использовании USB есть некоторая минимальная частота работы микроконтроллера. Я делал прикидку для другого проекта, где надо общаться с хостом и при этом потреблять минимум тока. Задачи простые, не требуют большой скорости и я хотел запустить МК на 8МГц. Оказалось, что меньше 14МГц при подключении USB ставить не могу, RCC не позволяет. Пришлось остановиться на следующем круглом значении 16МГц.
Собственно, настройка аппаратной части USB и выбор файлов, отвечающих за базовую функциональность этого интерфейса на на этом закончены. Вся остальная периферия, находящаяся на выбранной плате настраивается автоматически при её выборе на старте проекта. Сохраняем, генерим проект и переходим к «программированию» в сравнении с описанным на Хабре проектом.
Это страшное слово Descriptor
Стандартные массивы данных для передачи информации хосту, с чем он будет иметь дело. Для интереса можно посмотреть дескрипторы устройства и конфигурации. Сейчас их можно оставить такими, как получились, но в дальнейшем они наверняка потребуют редактирования. Впрочем, не исключено, что они будут генериться по тем параметрам, что ставятся в кубике. Что не может не радовать. А вот Report Descriptor стоит изучить получше — это фактически основное, что придётся в дальнейшем править ручками. Не знаю, откуда RaJa взял его дескрипторы, в нашём случае они генерируются кубиком и располагаются в следующих файлах проекта:
Дескриптор от Raja | Дескриптор от ST | Файл в проекте |
RHID_DeviceDescriptor | USBD_FS_DeviceDesc | usbd_desc.c |
RHID_ConfigDescriptor | USBD_CUSTOM_HID_CfgFSDesc | usbd_customhid.c |
RHID_ReportDescriptor | CUSTOM_HID_ReportDesc_FS | usbd_custom_hid_if.c |
Поскольку для простоты сейчас будем работать только с ST HID Demonstrator, то не мудрствуя лукаво я просто скопировал содержимое RHID_ReportDescriptor в соответствующее место моего проекта. Только подставил свои константы на место длины. Надо отметить, что надо точно посчитать количество байтов в этом дескрипторе (в этом проекте 79) и убедиться, что именно это значение стоит в Class Parameters. Не больше и не меньше. Иначе хост не опознает подключённое устройство. Проверено 🙂
Далее заходим в файл usbd_customhid.h и меняем значения CUSTOM_HID_EPIN_SIZE и CUSTOM_HID_EPOUT_SIZE на 0x40U. Честно говоря, немного напрягает то, что ST не даёт альтернатив смене значения по умолчанию 2 на другое значение и далее в коде с использованием этих констант стоит комментарий, что не более 2х байт. Но, с другой стороны, это было рекомендовано в первом найденном описании и, вообще говоря, установка такого значения выглядит достаточно логично. Иначе в чём отличие CustomHID от обычного? Проблема в том, что при регенерации проекта из кубика, что на этапе первичного кода происходит довольно часто, это значение не сохраняется и его надо восстанавливать ручками. Для этого я себе в main вывел строку warning, чтобы не забывать проверить эти константы. Возможно я ошибаюсь, и в дальнейшем всё окажется проще. Но в такой конфигурации работает 🙂
Цикл обмена (пишем/читаем)
Для выдачи данных на хост всё достаточно аналогично описанию на Хабре. Только название функции другое: USBD_CUSTOM_HID_SendReport(). Все остальные реомендации из той статьи подходят по полной программе.
А вот чтение здесь интереснее, чем на Хабре. И на самом деле несколько проще. Обработка принятого массива происходит в usbd_custom_hid_if.c / static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state).
В этом тестовом проекте я не заморачивался с обработкой входных параметров и следуя своей обычной практике минимальности времени обработки прерываний, просто копирую полученные данные в заранее определённый массив и устанавливаю флаг готовности данных от USB
Ну, а собственно «сбор данных» (нажатие кнопок джойстика) и реакция на полученные от хоста данные в этом прото проекте делаю внутри бесконечного цикла в main.c Всё просто 🙂 В этом прото проекте нет разделения реакции на SET_FEATURE и SET_REPORT, с этим надо будет разобраться далее, в реальном проекте. Компилируем, запускаем, подключаем к хосту и там должен появиться новый CustomHID от STMicroelectronics.
Звпускаем на хосте USB HID Demonstrator. На плате, с которой я запускал этот проект, не имеет органов для работы с Variable Inputs/Outputs, поэтому в разделе Graphic customization были убраны соответствующие назначениями, оставлено 5 кнопок и назначены ID, определённые в проекте: 1, 2 для Output report (входные данные для ST) и 4 для Input Report (выход от ST).
Моей задачей для этого проекта было управлять парой светодиодов на плате, что стало работать сразу, как эта программа обнаружила подключенную плату, и включать «лампочки» этой платы при нажатии различных кнопок джойстика на плате, а вот здесь сразу не получилось. При указанных настройках все пять лампочек одновременно зажигались при нажатии на центр джойстика. Остальные кнопки не отображались. При этом, если перейти на Input/Otput transfer, то данные были вполне ожидаемы. Т.е. сам интерфейс работает, но отображение в программе на хосте не отвечает моим запросам. Слава богу ST предоставляетс исходники, а в соседнем кубике сидит программист нашей группы, пишущий в том числе и софт для компьютеров. В общем, он подправил одну функцию и сгенерил исполняемую программу. Всё стало работать, как хотелось. Конечно, можно было бы на каждую кнопку создать свой report с уникальным номером, что исходно и предусмотрено. В этом случае было бы достаточно посылать по одному байту для каждой кнопки, но мой проект предусматривает многобайтный отчёт. Исходник подправленной функции и подправленный исполняемый файл можно скачать по ссылке ниже.
На этом, пожалуй, всё. Если у Вас есть такая же плата 32L476GDISCOVERY, то для начала можно просто скачать мой прото проект, адаптированный для него демонстратор и исходник изменённой функции по этой ссылке. Исходный USB HID Demonstrator скачивается с сайта STM, инсталлируется и его исполняемый файл заменяется моим. Импортируете в STM32IDE мой проект, компилируете и должны получить работающую базу для своих проектов. Если у Вас другая плата, то адаптируете «сбор информации» и включение светодиодов под свою плату.
Для дальнейшей работы обязательно прочтите указанную статью RaJa с Хабра. Она даст понимание того, что и как должно быть сделано для других проектов с USB HID интерфейсом. А ещё лучше начать с неё 🙂
У меня изучение статей и адаптация под мои хотелки заняло три дня. Описание заняло больше 🙂 Надеюсь, что у тех, кто воспользуется этой статьёй, аналогичный процесс займёт не более одного дня. Комментируйте, спрашивайте. Что смогу — отвечу. Что не смогу, вместе поищем решение.
СОДЕРЖАНИЕ
Устройства
Класс USB HID описывает устройства, используемые практически на каждом современном компьютере. В классе USB HID существует множество предопределенных функций. Эти функции позволяют производителям оборудования разрабатывать продукт в соответствии со спецификациями класса USB HID и ожидать, что он будет работать с любым программным обеспечением, которое также соответствует этим спецификациям.
Клавиатуры
Некоторые клавиатуры реализуют профиль загрузочной USB-клавиатуры, указанный в определении класса USB-устройств для устройств с интерфейсом пользователя (HID) v1.11, и явно настроены на использование протокола загрузки. Они ограничены 6-клавишным переключением клавиш (6KRO) и будут прерывать работу ЦП каждый раз при опросе клавиатуры (даже если нет изменения состояния), если USB-контроллер не отменяет это поведение. Этот профиль предназначен для того, чтобы BIOS могла работать с USB-клавиатурой в отсутствие операционной системы, поддерживающей USB. Рекомендуемый профиль для клавиатур, которые не находятся в режиме загрузки в этой спецификации, ограничивает количество клавиатур до 6KRO и заставляет их отвечать на прерывание отчетом о состоянии не реже, чем каждые полсекунды (опять же, даже если нет изменения состояния), чтобы реализовать typematic (повторение скан-кода при достаточно долгом нажатии клавиши), если USB-контроллер не запрограммирован так, чтобы клавиатура не делала этого. Однако клавиатуры в режиме без загрузки могут использовать альтернативный профиль HID.
Вышеупомянутое поведение отличается от интерфейса PS / 2 (не путать с PlayStation 2), который поддерживает одновременное нажатие клавиш n (NKRO) для клавиатур, способных его поддерживать. Интерфейс PS / 2 вообще не прерывает работу ЦП, когда нет изменений состояния, за исключением случаев, когда клавиша удерживается достаточно долго, чтобы активировать typematic. Отсутствие необходимости отвечать на повторный опрос экономит электроэнергию, поэтому интерфейс PS / 2 часто используется во внутренних клавиатурах ноутбуков.
мышей
USB-мыши имеют меньшую задержку, чем мыши PS / 2, потому что стандартные USB-мыши часто опрашиваются с частотой по умолчанию 125 Гц, в то время как стандартные мыши PS / 2 отправляют прерывания с частотой по умолчанию 100 Гц, когда у них есть данные для отправки на компьютер. Кроме того, USB-мыши не заставляют USB-контроллер прерывать работу системы, если у них нет изменений состояния, чтобы сообщить о них в соответствии с профилем по умолчанию спецификации USB HID для устройств мыши. И PS / 2, и USB позволяют переопределить частоту дискретизации, причем PS / 2 поддерживает частоту дискретизации до 200 Гц, а USB поддерживает частоту опроса до 1 кГц, пока USB-мышь работает на полной скорости или выше. Скорость USB.
Благодаря тому, что интерфейс мыши PS / 2 управляется прерываниями и не требует периодического опроса, интерфейс PS / 2 экономит электроэнергию, что делает его популярным выбором для указывающих устройств, встроенных в ноутбуки.
Игровые контроллеры
Другие устройства
Спецификации класса USB HID позволяют использовать множество других устройств в классе USB HID. Некоторыми примерами являются контроллеры для моделирования автомобилей, тренажеры, телефонные устройства, термометры, средства управления аудиосистемой и медицинские приборы. Даже источники бесперебойного питания и программные защитные ключи заявляют о себе под этим классом, несмотря на то, что зачастую они вообще не имеют человеческого интерфейса. Любое устройство может быть устройством класса USB HID, если разработчик соответствует логическим спецификациям класса USB HID. Это не означает, что нет необходимости поставлять драйверы для этих устройств или что операционная система немедленно распознает устройство. Это означает только то, что устройство может объявить себя в классе устройства интерфейса пользователя.
Уязвимости безопасности
Интерфейс USB уязвим для уязвимостей безопасности, таких как BadUSB, которые злоупотребляют комбинацией способности USB подключать множество различных типов устройств, его неспособностью проверить, действительно ли устройства являются тем, за что они претендуют, возможностью для USB-устройств изменить свой тип или объявляет о дополнительных подустройствах, когда они подключены, и о своем поведении по умолчанию, принимающем любое подключенное к нему устройство. В качестве частичной меры противодействия вместо этого можно использовать периферийные устройства PS / 2 с отключением всех портов USB.
Драйверы
Одним из преимуществ четко определенной спецификации, такой как класс USB HID, является обилие драйверов устройств, доступных в большинстве современных операционных систем. Устройства класса USB HID и их основные функции определены в документации USB-IF без учета какого-либо специального программного обеспечения. Благодаря этим общим описаниям разработчики операционных систем могут легко включить работающие драйверы для таких устройств, как клавиатуры, мыши и другие универсальные устройства с интерфейсом пользователя. Включение этих универсальных драйверов позволяет ускорить развертывание устройств и упростить установку конечным пользователям.
Логические спецификации
Функциональные характеристики
Класс USB-устройства с интерфейсом пользователя можно использовать для описания классов устройств и интерфейсов. Класс интерфейса используется, когда устройство USB может содержать более одной функции. Следовательно, можно иметь USB-устройства с двумя разными интерфейсами одновременно (например, USB-телефон может использовать клавиатуру, относящуюся к классу HID, и динамик, относящийся к классу USB-устройств связи ).
Отчеты
Класс USB HID требует, чтобы каждое устройство описывало, как оно будет взаимодействовать с главным устройством, чтобы точно предсказать и определить все текущие и будущие устройства с интерфейсом пользователя. Во время перечисления устройство описывает, как должны быть структурированы его отчеты, чтобы хост-устройство могло должным образом подготовиться к приему этой информации.
Хост периодически опрашивает конечную точку прерывания IN устройства во время работы. Когда у устройства есть данные для отправки, оно формирует отчет и отправляет его в качестве ответа на токен опроса. Обычные устройства, такие как клавиатуры и мыши, отправляют отчеты, соответствующие стандартам, установленным Форумом разработчиков USB (USB-IF). Когда поставщик создает пользовательское устройство класса USB HID, отчеты, формируемые устройством, должны соответствовать описанию отчета, приведенному во время перечисления, и драйверу, установленному в хост-системе. Таким образом, класс USB HID может быть чрезвычайно гибким.