Дескриптор usb

Интерфейс USB. Часть 4. Дескрипторы и классы

Дескриптор usb

В зависимости от назначения, все usb устройства разделены по классам. Это деление довольно широкое и объединяет довольно большие группы устройств. Например, класс HID (human interface device) включает все устройства человеко-машинного взаимодействия (мышки, клавиатуры и тому подобное), класс Printer — все печатающие устройства и так далее. Зачем это деление нужно?

Дело в том, что для каждого класса устройств написаны свои спецификации, которые позволяют унифицировать общение с устройствами.

Это удобно и разработчикам устройств (не надо каждый раз изобретать новые интерфейсы и протоколы) и производителям операционок (можно организовать поддержку всяких стандартных устройств на уровне операционок).

Да и для простых пользователей навигация в менеджере устройств становится приятнее.

Наряду с классом, определить для чего предназначен девайс, как с ним общаться и какие дрова при этом использовать, помогает пара идентификаторов VID/PID, а также номер версии устройства.

VID — это уникальный идентификатор производителя (Vendor ID), а PID — это уникальный идентификатор продукта (Product ID). Каждый VID стоит денег и покупать его надо у некоммерческой международной организации, занимающейся разработкой USB, которая называется USB Implementers Forum или просто USB-IF.

Покупая VID, производитель получает в своё распоряжение пачку PID-ов от 0x0000 до 0xFFFF и гарантии того, что серьёзные производители не будут делать свои продукты с такими же VID/PID (и писать под них свои дрова).

То есть его оборудование будет идентифицироваться операционкой одназначно и она будет однозначно выбирать для работы с этим оборудованием нужные дрова.

Всю информацию о себе и отдельных своих частях (классы, VID/PID, интерфейсы, конечные точки …) устройства хранят в специальных структурах данных, называемых дескрипторами (от англ. description — описание).

Дескрипторы бывают стандартные и специфические. Стандартные дескрипторы для всех USB-устойств одинаковы, они обязательно есть в любом USB-устройстве и содержат общее описание устройства и его отдельных частей. Специфические дескрипторы содержат всякую специфическую для различных классов устройств информацию, соответственно, такие дескрипторы для каждого класса устройств свои.

Ниже описаны структуры и назначения различных стандартных дескрипторов:

Standard Device Descriptor (стандартный дескриптор устройства) — содержит информацию об устройстве вцелом и о количестве его возможных конфигураций. Такой дескриптор может быть в устройстве только один.

Структура стандартного дескриптора устройства
Смещение(байт)Название поляРазмер(байт)Описание
0bLength1Размер дескриптора в байтах (всегда 18)
1bDescriptorType1Тип дескриптора (всегда 1)
2bcdUSB2Номер версии USB в формате BCD
4bDeviceClass1Код класса
5bDeviceSubClass1Код подкласса (всегда 0)
6bDeviceProtocol1Код протокола (всегда 0)
7bMaxPacketSize01Максимальный размер пакета для нулевой конечной точки (64 для HS, 8 — для FS и LS)
8idVendor2Идентификатор производителя
10idProduct2Идентификатор продукта
12bcdDevice2Номер версии устройства в формате BCD
14iManufacturer1Индекс дескриптора строки, описывающей производителя
15iProduct1Индекс дескриптора строки, описывающей продукт
16iSerialNumber1Индекс дескриптора строки, содержащей серийный номер устройства
17bNumConfigurations1Количество возможных конфигураций устройства

Номер версии USB может принимать следующие значения:

  1. 0x0100 — USB1.0
  2. 0x0110 — USB1.1
  3. 0x0200 — USB2.0

Коды классов бывают следующими:

  1. 0x00 — интерфейсы функционируют независимо друг от друга и каждый из них имеет собственный код класса.
  2. 0x01-0xFE — стандартные классы, поддерживающие различные спецификации для интерфейсов. Интерфейсы не могут функционировать независимо.
  3. 0xFF — класс устройства определяется изготовителем.

Если устройство поддерживает режимы HS и FS, то у него должно быть два разных дескриптора для этих режимов, один из которых — это стандартный дескриптор устройства, а другой — уточняющий дескриптор устройства.

Device Qualifier Descriptor (уточняющий дескриптор устройства) — содержит дополнительную информацию об устройстве, для его работы на другой скорости.

Структура уточняющего дескриптора устройства
Смещение(байт)Название поляРазмер(байт)Описание
0bLength1Размер дескриптора в байтах
1bDescriptorType1Тип дескриптора
2bcdUSB2Номер версии USB в формате BCD
4bDeviceClass1Код класса
5bDeviceSubClass1Код подкласса
6bDeviceProtocol1Код протокола
7bMaxPacketSize01Максимальный размер пакета для нулевой конечной точки (64 для HS, 8 — для FS и LS)
8bNumConfigurations1Количество дополнительных конфигураций устройства
9bReserved1Зарезервировано (всегда 0)

Standard Configuration Descriptor (стандартный дескриптор конфигурации) — содержит информацию об одной из возможных конфигураций устройства.

Структура стандартного дескриптора конфигурации
Смещение(байт)Название поляРазмер(байт)Описание
0bLength1Размер дескриптора в байтах
1bDescriptorType1Тип дескриптора
2wTotalLength2Общий объём данных (в байтах), возвращаемых для данной конфигурации
4bNumInterfaces1Количество интерфейсов для данной конфигурации
5bConfigurationValue1Идентификатор конфигурации (используется при запросе SetConfiguration для установки данной конфигурации)
6iConfiguration1Индекс дескриптора строки, описывающей данную конфигурацию
7bmAttributes1Характеристики конфигурации
8MaxPower1Максимальный потребляемый ток, делённый на 2

Битовая маска атрибутов содержит следующую информацию:

  1. [7] — зарезервирован (должен равняться нулю)
  2. [6] — признак наличия у устройства собственного питания (0 — девайс питается от шины USB, 1 — девайс имеет собственный источник питания)
  3. [5] — возможность пробуждения по внешнему сигналу (0 — нет возможности, 1 — есть возможность)
  4. [4:0] — зарезервированы (должны равняться нулю)

Standard Interface Descriptor (стандартный дескриптор интерфейса) — содержит информацию об одном из доступных в какой-либо конфигурации интерфейсов.

Структура стандартного дескриптора интерфейса
Смещение(байт)Название поляРазмер(байт)Описание
0bLength1Размер дескриптора в байтах
1bDescriptorType1Тип дескриптора
2bInterfaceNumber1Номер интерфейса в наборе, поддерживаемом в данной конфигурации (нумерация начинается с нуля)
3bAlternateSetting1Альтернативный номер интерфейса
4bNumEndpoints1Количество конечных точек данного интерфейса (нулевая конечная точка не учитывается, поскольку она общая для всех)
5bInterfaceClass1Код класса интерфейса
6bInterfaceSubClass1Код подкласса интерфейса
7bInterfaceProtocol1Код протокола
8iInterface1Индекс дескриптора строки, содержащей описание данного интерфейса

Standard Endpoint Descriptor (стандартный дескриптор конечной точки) — содержит информацию об одной из доступных для какого-либо интерфейса конечных точек.

Структура стандартного дескриптора конечной точки
Смещение(байт)Название поляРазмер(байт)Описание
0bLength1Размер дескриптора в байтах
1bDescriptorType1Тип дескриптора
2bEndpointAddress1Адрес конечной точки
3bmAttributes1Атрибуты конечной точки
4wMaxPacketSize2Максимальный размер пакета для конечной точки
6bInterval1Интервал опроса конечной точки в миллисекундах (используется при передаче данных по прерываниям, для остальных, кроме изохронных, — игнорируется, для изохронных всегда равен 1)

Битовая маска атрибутов содержит следующую информацию:

  1. [7:6] — зарезервированы (должны равняться нулю)
  2. [5:4] — тип использования конечной точки (00 — обычная, 01 — для явной обратной связи, 10 — для неявной обратной связи, 11 — зарезервировано)
  3. [3:2] — тип синхронизации (00 — нет синхронизации, 01 — асинхронная, 10 — адаптивная, 11 — синхронная), используется только для изохронных каналов
  4. [1:0] — тип конечной точки (00 — канал сообщений, 01 — изохронный канал, 10 — канал передачи данных, 11 — канал прерываний)

Unicode String Descriptor (дескриптор строки) — текст в формате Unicode. Строка не содержит нуль-терминатора, а её размер вычисляется как размер дескриптора минус два.

Структура стандартного дескриптора конечной точки
Смещение(байт)Название поляРазмер(байт)Описание
0bLength1Размер дескриптора в байтах
1bDescriptorType1Тип дескриптора
2bStringNСтрока в формате Unicode

Дескрипторы строк являются необязательными. Если девайс не поддерживает дескрипторы строк, то во всех остальных дескрипторах индексы дескрипторов строк, содержащих текстовое описание, должны быть равны нулю.

При подключении USB-устройства, хост с помощью управляющих передач запрашивает у устройства список дескрипторов в следующем порядке:

  1. стандартный дескриптор устройства
  2. дескрипторы конфигураций

Причём при запросе дескриптора конфигурации хост получает сразу все дескрипторы (дескрипторы интерфейсов, конечных точек), относящиеся к этой конфигурации.

Общий объём этих дескрипторов хосту заранее неизвестен, он хранится в поле wTotalLength дескриптора конфигурации, поэтому хост сначала запрашивает первые 8 байт этого дескриптора, запоминает из прочитанных данных значение поля wTotalLength, а потом снова запрашивает этот же дескриптор конфигурации, но размер запрашиваемых данных уже указывает равным wTotalLength. В результате такого трюка устройство присылает хосту все дескрипторы, относящиеся к данной конфигурации, в следующем виде:

  1. дескриптор конфигурации
    1. дескриптор интерфейса 1
      1. дескриптор конечной точки 1 для интерфейса 1
      2. дескриптор конечной точки 2 для интерфейса 1
    2. дескриптор интерфейса 2
      1. дескриптор конечной точки 1 для интерфейса 2
      2. дескриптор конечной точки 2 для интерфейса 2

Специфические дескрипторы мы рассмотрим подробнее когда будем разрабатывать какой-нибудь конкретный девайс, какого-нибудь определённого класса, а пока на этом всё.

Источник: https://radiohlam.ru/usb4/

Как исправить: Сбой запроса дескриптора устройства

Дескриптор usb

Ежедневно обладатели ноутбуков и персональных компьютеров подключают к USB портам множество различного оборудования — от флешек до телефонов и планшетов через кабели. От этого никуда не деться, ведь интерфейс USB остаётся самым распространённым методом подключения между устройствами, а в особенности между ПК и другим оборудованием.

Рисунок 1. Руководство по устранению ошибки сбоя дескриптора

Поэтому необходимо поддерживать стабильную работу устройств и заботиться о том, чтобы ко всем были подходящие драйвера, а порты USB при этом были исправны. Иначе, могут возникать ошибки, к примеру, «Сбой запроса дескриптора устройства». Она малоприятная, но решаемая, о чём и пойдёт речь в это материале.

Решение проблемы сбой запроса дескриптора устройства

Определить, что делать в ситуации, когда появляется ошибка о сбое запроса дескриптора устройства, довольно непросто.

Потому что не каждому пользователю понятно, что значит, дескриптор и почему из-за него они не могут подключить устройство.

Но так как дело в том, что система не может распознать неизвестное устройство, обращаются прежде к драйверам и проверке исправности USB портов, а потом уже переходят к остальному.

Стоит обратить внимание, что эта проблема касается не только подключения флешек, но и вообще всех устройств. Но только при использовании USB портов, через Bluetooth, к примеру, такого не будет (Рисунок 2). Ошибка может возникать и при подключении:

  1. Мышки.
  2. Клавиатуры.
  3. Джойстика.
  4. Принтера.
  5. Телефона и т. д.

Полный список предлагаемых решений и рекомендации по их достижению будет предложен в материале далее. Ошибка «Сбой запроса дескриптора устройства» появляется на актуальных версиях Виндовс, включая Windows 8. Поэтому способы, описанные здесь, не сработают на Windows XP и устаревших сборках операционки.

Рисунок 2. Список подключенных устройств

Сбой запроса дескриптора устройства usb

Ошибка о сбое дескриптора имеет код 43 (Рисунок 3). В спецификации говорится, что это означает физические нарушения подсоединения к компьютеру USB устройства, однако, это не всегда так. Конечно, если порты подвержены загрязнению и повреждениям, а также если с ними происходили какие-то ремонтные работы, то ошибка, вполне возможно, возникла из-за этого.

Поэтому необходимо провести визуальный анализ и, желательно, залезть в системный блок, чтобы проверить качество подключения и чистоту внутри.

Но целостность пусть и проверяется, то скорее для профилактики. А вот положение дел можно будет узнать, только пробуя разные способы решения, связанные с причинами, описанными в следующем разделе. В какой-то момент устройство перестанет быть неизвестным для ПК.

Рисунок 3. Внешний вид окна с ошибкой 43

Причина возникновения

Причин, из-за которых пользователь ПК имеет риск встретиться с кодом 43, может быть несколько:

  1. Драйверы. Они могли устареть, повредиться, быть удалены или вступить в конфликт друг с другом.
  2. Вредоносное ПО или вирусы привели к сбою системных файлов.
  3. Неисправность самого разъёма, или подключаемого к юсб порту устройства. Любого, будь то флешка или клавиатура. Поэтому проверять важно не только порты, но и подсоединяемое оборудование и в особенности кабели USB, используемые для телефонов, планшетов и плееров.
  4. Повреждения реестра — такое иногда возникает при обновлениях или полной переустановке программного обеспечения.
  5. Проблемы в блоке питания.

Сбой запроса дескриптора usb устройства на Windows 10 имеет схожие причины. Установить, какая из них подходит в конкретной ситуации, можно только методично пробуя разные методы решения ошибки дескриптора. Начинать стоит с тех, что были предложены ранее, а потом переходить к более сложным, пошагово описанным далее.

Обновление драйвера usb

После того как порты были проверены на целостность, а система — на вредоносное ПО, можно переходить к методу, который срабатывает в подавляющем большинстве случаев возникновения ошибки с дескриптором устройства. Это обновление драйверов на компьютере. Они могут или сами работать неправильно, или не срабатывать правильно из-за каких-либо настроек.

Для устройств, имеющих USB 3.0, обычная, но поправимая, история:

  1. Отсутствие нужных драйверов.
  2. Замена дров на универсальные Windows.

Это распространённая проблема на ноутбуках. Так, чтобы исправить проблему с драйверами, действовать нужно следующим образом:

  1. Нажать Win+R для вызова окна «Выполнить».
  2. Ввести devmgmt.msc и нажать запуск.
  3. В открывшемся окне найти строчку с Контроллерами USB.
  4. Проверить, не висит ли где-нибудь на открывшихся строчках жёлтый значок ошибки. Если да, выделить одну из них.
  5. Нажать правой кнопкой мыши.
  6. Выбрать пункт про обновление драйверов.
  7. Кликнуть на «Выполнить поиск».
  8. Нажать на вариант «о выборе из списка существующих» (Рисунок 4).
  9. Подобрать нужный файл из полученного результата.
  10. Подтвердить выбор.

Рисунок 4. Обновление драйверов для устройства

Если в окне с Контроллерами нет строчек с ошибками, то обновление драйверов по описанному в пунктах 5–9 алгоритму нужно провести для строчек:

  1. Generic USB Hub. Это дополнительная микросхема, чтобы разъёмов для USB было больше
  2. USB концентратор (корневой). Он может неправильно срабатывать из-за нестабильного переключения между одновременно установленными устройствами.
  3. Составное устройство USB.

После процедуры компьютер перезагружается.

Приведённый алгоритм можно и упростить. Это не самый лучший способ, но он срабатывает, потому и стоит рассказать о нём. Для этого нужно вновь дойти до сервиса диспетчера устройств, а потом удалить из списка подключённые ранее устройства. При их повторном подключении драйверы установятся заново.

Отключение режима энергосбережения

Конфигурация операционной системы иногда ограничивает количество напряжения, которое отправляется на USB-порт. Эта функция есть и в ноутбуках, и используется для сохранения уровня заряда у батареи. Для проверки её работы нужно:

  1. Перейти в диспетчер устройств.
  2. Найти поле про контроллеры USB.
  3. Вызвать свойства через нажатие правой кнопкой мыши на любой строчке.
  4. Перейти в «Управление».
  5. На строчке с разрешением отключения нужно снять галочку (Рисунок 5).
  6. Сохраниться и нажать ОК.

Для устранения ошибки «Сбой запроса дескриптора usb устройства код 43» потребуется повторить действия пунктов 3–6 на доступных в списке устройствах — от флешек до планшетов.

Рисунок 5. Окно настроек режимов электропитания портов

Обновление драйвера материнской платы

Сбой запроса дескриптора устройства не означает, что дело в драйверах для USB. Помимо всего, можно попробовать обновить дрова и у материнской платы, возможно, она не может правильно распознавать флешку или геймпад. Для этого потребуется узнать её модель, так как по ней можно будет найти необходимые программы на сайте производителя в пункте «Обновить» (Рисунок 6).

Не самый часто используемый способ, когда дело касается не Windows 10, но попробовать можно. Подробнее об этом рассказывается в разделе про Windows 10 далее. Так же отлично поможет справиться с данной задачей приложение DriverMax.

Рисунок 6. Обновление драйверов материнской платы

Статическое электричество и обесточивание компьютера

Сбросить лишнее статическое напряжение можно следующим способом:

  1. Извлечь из usb-разъёмов установленные устройства, включая мышь.
  2. Отключить ПК или ноутбук через Пуск.
  3. Отсоединить от сети и вытащить батарею из ноутбука, если это возможно. Если ноутбук на гарантии, то лучше ничего не вытаскивать.
  4. Зажать кнопку включения на 10 секунд.

После можно подключить всё заново и включить устройство. Ошибка должна исчезнуть, однако, этот способ является скорее дополнением к уже предложенным, а не отдельным. На некоторых интернет-сервисах процесс избавления от статического электричества имеет больше пунктов, однако, в данном случае хватит и алгоритма из четырёх шагов. Риска получить удар током, конечно же, нет.

Windows 10

Сбой запроса дескриптора устройства на Windows 10 возникает только в том случае, когда происходит подключение к USB 3.0. Это нормальная ситуация, поэтому и решается она легко — нужно найти подходящие драйвера:

  1. Для ноутбуков есть на сайте производителя (важно учитывать модель устройства).
  2. Для ПК — по материнской плате.

После установки драйверов обычно всё срабатывает. Однако, если нет, и если никакой из описанных методов не сработал, значит, случай уникальный и помочь могут только радикальные способы — сброс настроек BIOS или переустановка ОС, так как дело может быть в том, что она пиратская и ошибки были изначально.

Но к этим способам лучше не прибегать, да и до них вряд ли дойдёт, потому что, какой-то из предложенных ранее, сработает. Ведь в 99% случаев причина возникновения проблем с дескриптором USB лежит в неправильной конфигурации ОС, а в этих случаях эффективна проверка драйверов и настроек. О чём и рассказывается в материале выше.

Источник: https://soft-ok.net/5136-sboy-zaprosa-deskriptora-ustroystva.html

Ошибка «Сбой запроса дескриптора USB-устройства» в Windows 10 – решения

Дескриптор usb

Устройства с интерфейсом подключения USB в последнее время совсем вытеснили другие стандарты соединения девайсов с компьютером. Однако и с таким популярным видом подключения иногда возникают проблемы. В нашей статье мы подробно расскажем об ошибке «Сбой запроса дескриптора USB-устройства», опишем, из-за чего она возникает и что можно предпринять для её устранения.

Общие сведения

Вышеупомянутая ошибка сообщает пользователю о том, что устройство, подключенное через USB-порт, отключено системой из-за неизвестной ошибки. При этом в диспетчере устройств оно не опознается и имеет статус «Неизвестное».

Неизвестное устройство в диспетчере

Причин, по которым возникает данная неполадка, может быть достаточно много – это недостаток питания, неисправность порта, конфликт драйверов или выход из строя самого девайса. Рассмотрим далее всевозможные ошибки и расскажем, как можно их устранить в каждом конкретном случае.

Вариант №1: Неисправность USB порта или подключаемого устройства

Прежде чем приступить к устранению неполадки, нужно убедиться в исправности подключаемого устройства и USB разъема на компьютере. Сделать это достаточно легко — нужно будет просто подключить девайс к другому порту.

Если он работает, и в диспетчере не появляются ошибки, то по всей видимости гнездо USB порта вышло из строя.

Для большей уверенности можно взять заведомо исправную флэшку или другое USB устройство и подключить его в тот же разъем.

Порты USB

Вариант №2: Недостаточная мощность питания

Для нормальной работы устройств, подключаемых через USB-порт, требуется определенное количество электроэнергии. Для каждого порта системой выделяется определенный размер потребления тока. Если устройство для своего функционирования требует большее количество энергии, то это также может привести к различным ошибкам, в том числе и сбою запроса к дескриптору.

Чаще всего такое случается, когда пользователь использует разветвители (USB хабы) без дополнительного питания. Проверить потребляемое устройством количество электроэнергии, а также посмотреть, сколько на него выделено мощности системой, можно следующим образом:

  1. В контекстном меню кнопки «Пуск» выбираем вариант «Диспетчер устройств».

Открываем «Диспетчер устройств» из меню пуска

2. Далее в появившемся окне открываем раздел с контроллерами USB.

Папка с USB устройствами

3. После этого потребуется просмотреть настройки всех имеющихся устройств по очереди и проверить, не превышен ли лимит питания.

4. Кликаем по каждому пункту дважды и в новом окне переходим на вкладку «Питание».

5. Изучаем цифры в параметрах «Доступная мощность» и «Требует питание».

Сравниваем показатели питания

Если значение в графе «Требует питания» больше чем «Доступная мощность», то следует отключить лишние устройства или подключить их к другому разъему. Также такую проблему можно решить путем использования хаба с собственным питанием.

Вариант №3: Энергосберегающие технологии

Проблемы из-за энергосберегающих функций системы в большинстве случаев возникают при использовании ноутбуков, но иногда появляются и на обычных компьютерах.

Функция энергосбережения Windows работает так, что при недостатке питания некоторые подключённые устройства автоматически деактивируются. Исправить ситуацию можно, изменив настройки электропитания.

Для этого нам понадобится выполнить следующие операции:

  1. Открываем диспетчер устройств, как это было описано в предыдущем способе.
  2. Далее опять раскрываем каталог с USB устройствами.
  3. Теперь, переходя в настройки каждого устройства, открываем вкладку «Управление электропитанием».
  4. Далее снимаем птичку в пункте «Разрешить отключение этого устройства».
  5. После проделанных операций кликаем по кнопке «ОК».

Запрещаем отключение устройства

6. Закончив установку требуемых настроек на всех устройствах USB, открываем контекстное меню кнопки «Пуск» и выбираем пункт «Управление электропитанием».

Открываем настройки электропитания из меню Пуск

7. Далее кликаем по ссылке «Дополнительные параметры питания».

Переходим в раздел дополнительных настроек

8. После этого напротив активной схемы переходим в её настройки.

Открываем настройки активной схемы

9. В новом окне нажимаем «Изменить дополнительные параметры питания».

Переходим в окно дополнительных параметров

10. В появившемся списке ищем пункт «Параметры USB», открываем его и выставляем значение «Запрещено».

11. Нажимаем на кнопку «OK».

Запрещаем отключение USB порта

12. Перезагружаем компьютер.

Вариант №4: Сброс статического заряда

Если пользователь долго работает на компьютере, то на его комплектующих может скопиться статическое электричество, что может привести к появлению проблем, в том числе и с портами USB. Сбросить статический заряд можно следующим способом:

  1. Отключаем компьютер полностью, вынув розетку из штепселя. В случае с ноутбуками вынимаем батарею.
  2. После этого нажимаем на кнопку включения и держим её в таком состоянии в течение примерно десяти секунд.
  3. Затем запускаем компьютер как обычно.

Для отвода статического электричества также рекомендуется заземлять корпус системного блока.

BIOS – это программное обеспечение на материнской плате компьютера, которое содержит в себе настройки подключенных к ней устройств.

Если по каким-либо причинам они изменились, то можно сбросить их до заводских.

Для этого нам нужно будет открыть BIOS, нажимая на кнопку «Del» перед запуском системы, и найти параметр «Load Bios или Setup Defaults», а затем активировать его.

Установка настроек по умолчанию в БИОСе

Вариант №6: Обновление драйверов

В некоторых случаях устранить проблему с ошибкой «Сбой запроса дескриптора USB-устройства» можно путем установки обновлённых драйверов. Для этого вам может пригодиться программа DriverPack Solution, которая умеет автоматически устанавливать драйвера для всех комплектующих компьютера.

Интерфейс программы DriverPack Solution

На этом все. В нашей статье мы перечислили самые распространённые методы устранения ошибки «Сбой запроса дескриптора USB-устройства». Надеемся, что при помощи данной инструкции вам удастся устранить проблему без особых затруднений.

Автор материала: Виктор Зверев

Подписывайтесь на наш канал и ставьте лайки! А еще можете посетить наш официальный сайт.

Источник: https://zen.yandex.ru/media/tehnichka/oshibka-sboi-zaprosa-deskriptora-usbustroistva-v-windows-10--resheniia-5fe47f46b28ab778a72775c9

Интерфейс USB. Завершение реализации

Дескриптор usb
Итак, нам осталось разобраться с процессом обработки стандартных запросов USB и с дескрипторами. Давайте сначала разберемся с теорией, а потом подробно разберем пример обработки конкретного запроса.

Обработка запросов.

Процесс обработки запроса состоит из трех фаз (SETUP, DATA, STATUS), причем фаза DATA является опциональной. Как мы помним из предыдущей статьи, для передачи запросов хост использует специальный TOKEN пакет — TOKEN SETUP. Собственно говоря, первая фаза состоит из того, что хост посылает TOKEN SETUP, затем посылает пакет данных (8 байт) который содержит запрос. Устройство подтверждает получение запроса ACK пакетом. Структуру запроса мы рассмотрим ниже, пока перейдем к следующей фазе – фазе обмена данными. Дело в том, что некоторые типы запросов предполагают передачу дополнительных данных, как от хоста к устройству (передача дополнительных параметров запроса) так и от устройства к хосту (получение хостом ответа на запрос). Этот обмен и составляет фазу обмена данными. Хост, отравив запрос в SETUP фазе, знает тип запроса и, соответственно, знает: нужна ли для данного типа запроса фаза обмена данными и в какую сторону будет происходить обмен. Если запрос предполагает передачу дополнительных параметров — хост отправляет TOKEN OUT и пакет данных содержащий дополнительные параметры запроса. Устройство подтверждает получение пакета данных, после чего хост может послать следующий пакет данных и т. д. Соответственно, если запрос предполагает получение ответа от устройства, хост посылает TOKEN IN и ожидает пакет данных от устройства. Последняя (STATUS) фаза нужна для подтверждения корректности обработки всего запроса. На данной фазе устройство или хост просто посылает пакет данных нулевой длины, что свидетельствует об успешной обработке запроса на логическом уровне. Если запрос предполагал получение ответа от устройства – то данный пакет посылает хост, подтверждая, что ответ получен/обработан. В другом случае – пакет нулевой длины шлет устройство, подтверждая, что запрос (запрос и дополнительные параметры) получены и обработаны. Если что-то пошло не так (например, мы получили запрос который не умеем обрабатывать), устройство может послать STALL пакет, что свидетельствует об ошибке на логическом уровне. Но хост расценит это как фатальную ошибку т. к. стандартные запросы должны всегда корректно обрабатывается всеми USB устройствами. Теперь заглянем «внутрь» запроса (8 байт данных полученных устройством в SETUP фазе). Запрос состоит из следующих полей: bmRequestType — 1 байт bRequest – 1 байт wValue – 2 байта, WORD wIndex – 2 байта, WORD wLength – 2 байта, WORD Теперь подробно:

bmRequestType – битовое поле, которое содержит характеристики запроса:

Бит 7: Направление передачи данных в DATA фазе: 0 = от хоста к устройству 1 = от устройства к хосту Биты 6…5: Тип запроса 0 = стандартный запрос USB 1 = стандартный запрос для определенного класса устройств USB 2 = пользовательский запрос 3 = зарезервировано Биты 4…0: Кому адресован запрос 0 = устройству 1 = интерфейсу 2 = конечной точке 3 = другое 4…31 = зарезервировано

bRequest – уникальный код запроса (например, 0 = GET_STATUS, 5 = SET_ADDRESS, 6 = GET_DESCRIPTOR и т. д.)

Здесь следует пояснить, зачем нужны биты 4..0 поля bmRequestType. Например, для получения статуса хост посылает запрос GET_STATUS (bRequest = 0). Значение бит 4…0 поля bmRequestType определяет, статус чего именно хочет получить хост: 0 – статус устройства, 1 – статус интерфейса, 2 – статус контрольной точки и т. д.). Таким образом, «тип запроса» определяется битами 4..0 поля bmRequestType и полем bRequest.

wValue – данное поле может использоваться для передачи параметров запроса. Например, для запроса SET_ADDRESS данное поле содержит адрес, который нужно присвоить устройству. Если параметры запроса не помещаются в 2 байта wValue, то хост их передает в DATA фазе.

wIndex – значение данного поля зависит от типа запроса. Например, для запроса GET_STATUS к конечной точке, данное поле содержит индекс конечной точки, статус которой хост хочет получить.

wLength – данное поле содержит размер данных, которые будут переданы хостом в DATA фазе либо которые хост ожидает получить в DATA фазе.

Для примера, рассмотрим алгоритм обработки запроса GET_DESCRIPTOR. 1. Хост посылает устройству запрос: bmRequestType = 0x80 bRequest = 6 (GET_DESCRIPTOR) wValue = 0x100 (тип дескриптора, который хост хочет получить, в данном случае дескриптор устройства) wIndex = 0 (в данном случае параметр не используется) wLength = 18 (в ответ хост хочет получить 18 байт) Из запроса видно, что хост хочет получить дескриптор нашего устройства и что за SETUP фазой предполагается DATA фаза «от устройства к хосту». 2. Устройство посылает хосту 18 байт дескриптора (DATA фаза). 3. Хост подтверждает успешное завершение обработки запроса, отправив устройству пакет данных нулевой длины (STATUS фаза). Будем считать, что с обработкой запросов мы разобрались. Все запросы подробно разбирать мы не будем, т. к. это очень объемный материал. Детально все типы стандартных запросов описаны в разделе 9.3 официальной спецификации. Касательно нашего CDC устройства — помимо стандартных запросов USB, для нашего класса устройств предусмотрено несколько дополнительных запросов (SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE). Эти запросы предназначены для установки параметров (Baudrate, Stop Bits, Parity, Data bits) нашего виртуального COM-порта. В нашей реализации эти параметры нам не нужны, но обрабатывать эти запросы мы обязаны, поэтому реализуем обработку в виде «заглушек».

Дескрипторы

Теперь поговорим о дескрипторах. Стандартом определены следующие типы дескрипторов: — Дескрипторы устройства — Дескрипторы конфигурации — Дескрипторы интерфейса — Дескрипторы конечной точки — Строковые дескрипторы Дескриптор устройства всегда один, он содержит базовую информацию об устройстве (код производителя, код устройства, класс устройства и т. д.). Мы позже детально разберем данный дескриптор на примере нашего устройства. Дескрипторы конфигурации описывают конфигурации нашего устройства. Здесь остановимся немного подробнее. Дело в том, что устройство может поддерживать несколько альтернативных конфигураций. Например, в конфигурации «1» устройство питается от интерфейса USB, а в конфигурации «2» – от внешнего источника. Или в конфигурации «1» устройство для обмена данными с хостом использует дополнительные контрольные точки типа bulk, а в конфигурации «2» – весь обмен идет через «нулевую конечную точку». Для каждой из конфигураций устройство хранит свой дескриптор конфигурации. Хост получает по запросу дескрипторы всех конфигураций и выбирает одну из возможных конфигураций (логика выбора «рабочей» конфигурации из возможных заложена в драйвере устройства). После этого, хост назначает устройству номер текущей конфигурации (отправив стандартный запрос SET_CONFIGURATION) и дальнейшая работа устройства происходит в соответствии с выбранной хостом конфигурацией. Для каждой конфигурации устройства определен один или несколько «интерфейсов». Интерфейс определяет, какие контрольные точки будут использоваться для обмена данными между хостом и устройством. Эта информация и есть «дескриптор интерфейса». Информация о каждой конечной точке интерфейса называется «дескриптор конечной точки». Для каждой конечной точки дескриптор описывает тип конечной точки, ее параметры (такие как максимальный размер буфера обмена и т. д.) Каждый дескриптор конфигурации содержит в себе дескрипторы интерфейса, а каждый дескриптор интерфейса содержит дескрипторы конечных точек. Строковые дескрипторы опциональны, они позволяют получить хосту, в виде UNICODE строки, название устройства, название производителя устройства, серийный номер устройства. Для примера, рассмотрим «дескриптор устройства», пример которого уже приводился в одной из статей. static const BYTE devDescriptor[] = { /* Device descriptor */ 0x12, // длина дескриптора в байтах; 0x01, // тип дескриптора: 1-Device descriptor 0x00, // 2 байта – версия USB: 2.0 0x02, // 0x02, // класс устройства: 2-CDC class code 0x00, // подкласс: 0-CDC class sub code 0x00, // протокол: 0-CDC Device protocol 0x08, // максимальный размер пакета для “нулевой конечной точки” 0xEB, // 2 байта – код производителя VID 0x03, // 0x27, // 2 байта – код устройства PID 0x61, // 0x10, // 2 байта – версия (ревизия) устройства 0x01, // 0x01, // индекс строки с названием производителя 0x02, // индекс строки с названием устройства 0x03, // индекс строки с серийным номером устройства 0x01 // количество поддерживаемых конфигураций }; Итак, в дескрипторе содержится следующая ключевая информация: 1. Устройство поддерживает версию стандарта 2.0 2. Устройство относится к классу CDC 3. Код производителя 0x03EB (Atmel) 4. Код продукта (в рамках производителя) 0x6127 5. Код ревизии устройства 0x0110 6. Устройство поддерживает одну конфигурацию

Компания Atmel позволяет использовать свой код производителя (VID) при создании USB устройств на базе ее продукции, правда с небольшими оговорками. Остальные параметры (Код продукта, Код ревизии устройства) выбраны «с потолка» 🙂

Комбинация VID/PID используется ОС для идентификации устройства и поиска «подходящего» драйвера. В некоторых случаях, для поиска драйвера используется информация о классе устройства (например, для HID и MSD устройств). Описывать «побитно» все дескрипторы мы не будем, эта информация подробно описана в разделе 9.6 спецификации. Теперь фрагмент кода — реализации данного уровня логики USB. static void USB_Enumerate(UsbRequest * Request) { WORD wStatus; switch ((Request->bRequest bmRequestType) { //Запрос дескриптора case STD_GET_DESCRIPTOR: switch(Request->wValue) { case 0x100: //Запрос дескриптора устройства USB_CfgSend(devDescriptor, MIN(sizeof(devDescriptor), Request->wLength), NULL, NULL); break; case 0x200: //Запрос дескриптора конфигурации USB_CfgSend(cfgDescriptor, MIN(sizeof(cfgDescriptor), Request->wLength), NULL, NULL); break; case 0x300: //Запрос строкового дескриптора USB_CfgSend(strLanguage, MIN(sizeof(strLanguage), Request->wLength), NULL, NULL); break; case 0x301: //Запрос строкового дескриптора USB_CfgSend(strManufacturer, MIN(sizeof(strManufacturer), Request->wLength), NULL, NULL); break; case 0x302: //Запрос строкового дескриптора USB_CfgSend(strProduct, MIN(sizeof(strProduct), Request->wLength), NULL, NULL); break; case 0x303: //Запрос строкового дескриптора USB_CfgSend(strSerial, MIN(sizeof(strSerial), Request->wLength), NULL, NULL); break; default: //Неизвестный тип дескриптора USB_CfgSendStall(); break; } break; case STD_SET_ADDRESS: //Установка адреса устройства USB_CfgSendZlp(USB_SetAddress, (void *) (DWORD) Request->wValue); break; case STD_SET_CONFIGURATION: //Установка конфигурации устройства USB_CfgSendZlp(USB_SetConfig, (void *) (DWORD) Request->wValue); break; case STD_GET_CONFIGURATION: //Запрос номера конфигурации устройства USB_CfgSend((BYTE *) &(CurrentConfiguration), sizeof(CurrentConfiguration), NULL, NULL); break; case STD_GET_STATUS_ZERO: //Запрос статуса устройства wStatus = 0; USB_CfgSend((BYTE *) &wStatus, sizeof(wStatus), NULL, NULL); break; case STD_GET_STATUS_INTERFACE: //Запрос статуса интерфейса wStatus = 0; USB_CfgSend((BYTE *) &wStatus, sizeof(wStatus), NULL, NULL); break; case STD_GET_STATUS_ENDPOINT: //Запрос статуса конечной точки wStatus = 0; Request->wIndex &= 0x0F; if ((AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_CONFG) && (Request->wIndex UDP_CSR[Request->wIndex] & AT91C_UDP_EPEDS) ? 0 : 1; USB_CfgSend((BYTE *) &wStatus, sizeof(wStatus), NULL, NULL); } else if ((AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (Request->wIndex == 0)) { wStatus = (AT91C_BASE_UDP->UDP_CSR[Request->wIndex] & AT91C_UDP_EPEDS) ? 0 : 1; USB_CfgSend((BYTE *) &wStatus, sizeof(wStatus), NULL, NULL); } else USB_CfgSendStall(); break; //… часть кода пропущена … //Запросы специфические для CDC устройств case SET_LINE_CODING: USB_CfgRecv((BYTE *) &line, MIN(sizeof(line), Request->wLength), CDC_SetLineCodiing, NULL); break; case GET_LINE_CODING: USB_CfgSend((BYTE *) &line, MIN(sizeof(line), Request->wLength), NULL, NULL); break; case SET_CONTROL_LINE_STATE: USB_CfgSendZlp(NULL, NULL); break; default: _DBG(“[USB ENUM REQUEST %04X]”, (Request->bRequest bmRequestType); USB_CfgSendStall(); break; } } Эта статья завершает цикл. Как и обещал – выкладываю исходные коды примера реализации (не стоит забывать, что это лишь пример, реализация очень упрощена). Для демонстрации работы стека в main.c реализована простая эхо-отвечалка, все данные полученные от ПК устройство отправляет обратно 🙂 Вместе с исходниками лежит файл USBCDC.inf – этот файл нужен ОС Windows для того, чтобы связать VID/PID нашего устройства со стандартным драйвером виртуального USB COM-порта (usbser.sys)

Источник: http://we.easyelectronics.ru/electro-and-pc/interfeys-usb-zavershenie-realizacii.html

Поделиться:
Нет комментариев

    Добавить комментарий

    Ваш e-mail не будет опубликован. Все поля обязательны для заполнения.