Usb provisioning что это

Помогаем компьютеру, если он не смог опознать USB устройство

Бывает, что при подключении USB 3.0 устройства, оно работает в режиме USB 2.0. Этим грешат, в частности, некоторые WiFi адаптеры с интерфейсом USB. Как решить данную проблему и заставить коварный гаджет перейти в скоростной режим USB 3.0, путем внесения изменений системный в реестр, я подробно написал здесь, поэтому повторяться не буду. Единственное, что могу добавить, если в роли «тормоза» выступает не сетевой адаптер, а внешний USB 3.0 диск, идентифицируемый как скази (SCSI) накопитель, попробуйте поковырять его настройки в этой ветке реестра: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class<4d36e97b-e325-11ce-bfc1-08002be10318>\00xx.

реклама

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

Самое удивительное, что на самом деле, это вовсе не страшно. Я как раз на днях столкнулся с подобным случаем, поэтому поделюсь впечатлениями…

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

реклама

Это сообщение свидетельствует о неработоспособности подключенного USB-устройства.

Вынув это устройство, и вставив в тот же USB-порт другое, заведомо исправное USB-устройство (мышь там, или флэшку) – пользователь получает на экран точно такое же сообщение об ошибке, а исправное устройство на порту также не работает.

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

реклама

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

Справедливости ради уточню, что в очень редких случаях подключаемый USВ девайс действительно может оказаться неисправен. Но вероятность этого крайне низка.

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

Причина появления данной ошибки в том, что при быстром последовательном подключении/отключении USB устройства несколько раз подряд в системе происходит сбой USB контроллера. Причина череды подключений/отключений гаджета может быть разной: вы намеренно подключили/отключили устройство несколько раз подряд; у вас просто «дрогнула рука» и при подключении в «расшатанный» порт устройство само быстро переподключилось непроизвольно; наконец вы могли совать штекер USB-кабеля в сильно запыленный USB-порт и скопившаяся в порту грязь (а также возможная коррозия на контактах разъема) привела к быстрому повторному переподключению USB-устройства. В любом случае USB контроллер воспринял этот процесс неадекватно и произошел сбой в его функционировании. Только и всего. Чтобы устранить возникшую проблему зачастую (хотя не всегда) достаточно реинициализировать (отключить и снова включить) соответствующий контроллер в диспетчере задач Windows.

реклама

Но! Обычный пользователь не всегда знает, какой именно контролер нужно реинициализировать. Скажу больше, многие даже не знают, где этот контроллер искать вообще. Поэтому побороть данную проблему лучше универсальным и наиболее надежным методом: нужно перезагрузить компьютер, чтобы произошла аппаратная реинициализация USB контроллера. А лучше выключите компьютер, выньте устройство/шнур из USB порта, очистите штекер и сам разъем USB от грязи, снова плотно вставьте USB устройство или шнур от него в порт на материнской плате и затем включите компьютер.

Источник

Приобщение к миру USB-устройств на примере микроконтроллеров от Silicon Laboratories

Устройства от Silicon Laboratories не пользуются широкой популярностью в любительских кругах, им далеко до таких флагманов, как Atmel. Однако у них есть и вполне доступные простому смертному микроконтроллеры основных линеек в корпусе TQFP, и стартовые комплекты USB ToolStick (о чем совсем недавно упоминалось на хабре). Я сам начал свое знакомство с микропроцессорной техникой, работая с «силабсами», и вполне успешно.
В данной статье я расскажу, каким образом можно организовать связь компьютера с МК, используя USB-интерфейс, и как Silabs попытались сделать это простым для разработчика.
В качестве испытуемого будем использовать плату С8051F320DK, с микроконтроллером соответственно F32x серии, поддерживающей USB аппаратно, и Keil’овскую среду разработки uVision4.

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

Создание USB совместимого HID-устройства типа джойстик

Начинаем с дескриптора устройства

Для упрощения задачи составления дескриптора можно воспользоваться программой, лежащей на www.usb.org (HID Descriptor Tool). В комплекте с программой предоставляются примеры конфигураций некоторых HID-устройств, которые можно корректировать под свою задачу или создавать собственное HID-устройство.
На этом описание джойстика заканчивается и нужно подготовить данные для передачи в PC.

Процедуры передачи данных

Находим в примере следующий код:
void IN_Report(void)<

IN_PACKET[0] = VECTOR;
IN_PACKET[1] = BUTTONS;

// point IN_BUFFER pointer to data packet and set
// IN_BUFFER length to transmit correct report size
IN_BUFFER.Ptr = IN_PACKET;
IN_BUFFER.Length = 2;
>

В этой процедуре идет составление отправляемого пакета, который после через хитрый указатель (на самом деле это просто структура из указателя и его длины) и передается нашим устройством. Главное аккуратно составить пакет, о чем нам и намекает комментарий, а дальше уже с ним сделают все без нашего участия.
Теперь расскажу о том, как и откуда мы берем переменные VECTOR и BUTTONS (обе, к слову, имеют тип unsigned char размером в байт).
Глобальной переменной VECTOR присваиваются значения с АЦП во время возникновения прерывания от него:
void ADC_Conver_ISR(void) interrupt 10
<
AD0INT = 0;

VECTOR = ADC0H;
>

Глобальная переменная BUTTONS аналогично изменяет значение в зависимости от нажатия кнопок. Кнопки опрашиваются по прерыванию от таймера. Таймер настраивайте в соответствии с личными предпочтениями.
void Timer2_ISR (void) interrupt 5
<
P2 &=

if ((P2 & Sw1)==0) // Проверка нажатия кнопки #1
<
// pressed
BUTTONS = BUTTONS | (1

Дескриптор имени HID-устройства

Напоследок можем скорректировать строковые данные, чтобы устройство имело то название, какое мы хотим (в моем примере «JOYSTICK-HABR»).
Ищем строковый дескриптор String2Desc, переписываем
#define STR2LEN sizeof («JOYSTICK-HABR») * 2

Идентификация HID-устройства

После компиляции проекта и программирования микроконтроллера можно подключить устройство к USB-порту. Хост определяет, что устройство принадлежит к HID классу и передает управление устройством соответствующему драйверу.
Usb provisioning что это. Смотреть фото Usb provisioning что это. Смотреть картинку Usb provisioning что это. Картинка про Usb provisioning что это. Фото Usb provisioning что это
Теперь в Windows идем в Панель управления->Игровые устройства и видим там нашего пассажира. Смотрим свойства и проверяем функциональность.
Usb provisioning что это. Смотреть фото Usb provisioning что это. Смотреть картинку Usb provisioning что это. Картинка про Usb provisioning что это. Фото Usb provisioning что это
Низкая скорость передачи является главным ограничением HID-варианта построения устройства. Максимально возможная скорость передачи данных при такой организации обмена составляет 64 Кбит/сек. Такой показатель в сравнении с 12 Мбит/сек полной скорости USB-шины выглядит минусом HID-технологии в вопросе выбора конкретной USB-реализации. Однако для многих задач коммуникации указанной скорости вполне хватает и HID-архитектура как специализированный инструмент занимает достойное место среди способов организации обмена данными.

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

Создание полноценного USB-устройства с использованием инструментария Silabs USBXpress

Но вот наступает момент, когда вам необходимо использовать свой протокол работы с устройством на МК. При этом хотелось бы передавать много данных на большой скорости, и делать все это с помощью своего ноутбука, в котором много USB и ни одного COM, да еще и ваше устройство должно быть не больше спичечного коробка, и лепить на плату USB-UART на микросхеме FT232RL нет никакой возможности.
Тут-то ребята из Silabs и решили облегчить всем жизнь и показать “дорогу в будущее”, без тяжелого ломанья зубов об написание собственных дров и прошивок.
USBXpress Development Kit – это законченное решение для МК и хоста (PC), обеспечивающее простую работу с протоколом USB с помощью высокоуровневого API для обоих сторон. Не требуется особых знаний ни самого протокола USB, ни написания драйверов. Так пишут силабовцы в своем гайде.
Usb provisioning что это. Смотреть фото Usb provisioning что это. Смотреть картинку Usb provisioning что это. Картинка про Usb provisioning что это. Фото Usb provisioning что это
Кстати о Programmer’s Guid: занимая всего 30 страниц, он крайне прост и доходчив. Примеры же лично мне не нравятся, часто встречаются очень кривые места, программы же под PC вообще лучше не смотреть, крайне нечитабельны.
USBXpress DK предоставляется к микроконтроллерам линеек C8051F32x, C8051F34x и для CP210x (USB-to-UART Bridge Controller). Библиотека USBXpress включает в свой состав библиотеку нижнего уровня, драйверы USB для ПК и DLL-библиотеку для разработки приложений на верхнем уровне. Ну и, конечно же, набор документации и примеров.
В библиотеке реализована передача данных только в режиме BULK. При использовании всех функций библиотеки, их реализация займет всего 3 Кбайта Flash-памяти микроконтроллера.

Firmware
Написание USB-дескриптора

В отличие от HID с его хитро формализованной структурой тут все просто
code const UINT USB_VID = 0x10C4;
code const UINT USB_PID = 0xEA61;
code const BYTE USB_MfrStr[] = <0x1A,0x03,'S',0,'i',0,'l',0,'a,0,'b,0,'s,0>;
code const BYTE USB_ProductStr[] = <0x10,0x03,'U',0,'S',0,'B',0,'X',0,'_',0,'A',0,'P',0>;
code const BYTE USB_SerialStr[] = <0x0A,0x03,'H',0,'A',0,'B',0,'R',0>;
code const BYTE USB_MaxPower = 15;
code const BYTE USB_PwAttributes = 0x80;
code const UINT USB_bcdDevice = 0x0100;

С VID, PID и именами думаю все понятно, плюс еще можно задавать максимальный ток параметром MaxPower (макс.ток = _MaxPower*2), PwAttributes — параметр отвечающий за удаленный wake-up хоста, и bcdDevice — номер релиза устройства.

Нюанс инициализации устройства и USB на борту

0x40; // Disable Watchdog timer
USB_Clock_Start(); // Init USB clock *before* calling USB_Init
USB_Init(USB_VID,USB_PID,USB_MfrStr,USB_ProductStr,USB_SerialStr,USB_MaxPower,USB_PwAttributes,USB_bcdDevice);

Initialize();
USB_Int_Enable();
.

Здесь, как требует комментарий, в первую очередь необходимо инициализировать тактовый генератор для USB перед самой его инициализацией, только потом провести остальные стартовые операции для МК — Initialize(); — который настраивает порты, таймер и АЦП; затем разрешаем прерывания от USB.

Обработка входящих данных и формирование исходящего пакета

Вот подобрались к самому главному
//. продолжение main
while (1)
<
if (Out_Packet[0] == 1) Led1 = 1;
else Led1 = 0;
if (Out_Packet[1] == 1) Led2 = 1;
else Led2 = 0;

In_Packet[0] = Switch1State;
In_Packet[1] = Switch2State;
In_Packet[2] = Potentiometer;
In_Packet[3] = Temperature;
>
// конец main
>

Out_Packet – пакет, принятый от хоста;
In_Packet — пакет, отправляемый хосту;
Суть ясна, МК постоянно обновляет отправляемый пакет и считывает статус полученного.

Обработка прерываний

Теперь в 2-х словах о том, откуда получаем значения в отправляемый пакет. Как и в примере с HID, состояния кнопок получаем по прерываниям от таймера, а значения АЦП и термометра — по прерываниям от АЦП.
Вот здесь один тонкий момент — при инициализации АЦП настраиваем его так, чтобы конвертирование значений происходило по переполнению таймера (того же, который мы используем для кнопок), а само же прерывание от АЦП возникает по завершению конвертирования. И тут кроме получения значений преобразователя в конце процедуры вызываем API функцию
Block_Write(In_Packet, 8)
которая и отправляет собранные данные на компьютер.
Получение команд от компьютера происходит в процедуре обработки прерываний от USB:
void USB_API_TEST_ISR(void) interrupt 16
<
BYTE INTVAL = Get_Interrupt_Source();

if (INTVAL & DEV_CONFIGURED)
<
Initialize();
>
>

Этот момент подробно расписан в Programmer’s Guid. Суть в том, что вызывается API-функция Get_Interrupt_Source(), возвращающая код причины возникновения API прерывания. Далее код анализируется и выполняется необходимое действие.

Программ на PC

Разбирать программу для компьютера я не буду. Силабовцы предоставили примеры на Visual Basic и на C, но, даже не заглядывая в исходники, подключить библиотеку в используемой вами среде разработки и прочитать пару страниц о функциях сложности вызвать не должно.
Поэтому я воспользуюсь уже скомпилированной программой из примера.

Итак, компилируем проект для МК, зашиваем, устанавливаем универсальные драйвера для USBXpress и подключаем отладочную плату. Система определит новое устройство и установит для него драйвера.
Посмотрим после установки, что творится в диспетчере устройств Винды:
Usb provisioning что это. Смотреть фото Usb provisioning что это. Смотреть картинку Usb provisioning что это. Картинка про Usb provisioning что это. Фото Usb provisioning что это
Теперь запускаем программу:
Usb provisioning что это. Смотреть фото Usb provisioning что это. Смотреть картинку Usb provisioning что это. Картинка про Usb provisioning что это. Фото Usb provisioning что это
Видим, что она правильно нашла устройство.
Usb provisioning что это. Смотреть фото Usb provisioning что это. Смотреть картинку Usb provisioning что это. Картинка про Usb provisioning что это. Фото Usb provisioning что это
Все, теперь можно тут потыкать кнопки, поморгать диодами, погреть МК руками, увидеть как растет температура.

Заключение

В целом создание USB устройства с помощью библиотек USBXpress оказалось более быстрым и прозрачным процессом, нежели используя HID-архитектуру. Да и скорость будет однозначно выше. Наиболее тонким местом является то, что библиотека закрыта, и узнать насколько надежным является это решение невозможно, к тому же доступен только BULK режим передачи данных.

Источник

Поддержка USB в KolibriOS: что внутри? Часть 3: код поддержки хост-контроллеров

Usb provisioning что это. Смотреть фото Usb provisioning что это. Смотреть картинку Usb provisioning что это. Картинка про Usb provisioning что это. Фото Usb provisioning что этоУровень поддержки хост-контроллеров, как я писала в общем обзоре, должен вызывать вышележащие уровни при наступлении некоторых событий и предоставлять функции, необходимые вышележащим уровням для работы.
Для удобства восприятия я буду рассказывать о различных элементах кода поддержки в том порядке, в котором они получают управление.

Запуск подсистемы USB

Подготовка: USB-контроллеры в списке PCI-устройств

Подсистема USB запускается вызовом usb_init из init.inc в ходе загрузки системы.

Отключение контроля BIOS

Некоторые BIOS умеют обрабатывать USB-мыши, USB-клавиатуры и USB-флешки, предоставляя данные для операционных систем, не знающих про USB. Данные от мышей и клавиатур преобразуются в формат PS/2 и тем или иным способом доводятся до операционной системы так же, как если бы в системе существовала настоящая PS/2-мышь и/или клавиатура. USB-флешка представляется жёстким диском с точки зрения int 13h — такая поддержка встречается куда чаще поддержки мышей, ибо необходима для загрузки с флешек.
Операционная система может использовать любой режим процессора и самостоятельно обрабатывать любые прерывания. Чтобы BIOS в таких условиях всё же могла получать управление с предсказуемым окружением, ещё в районе 486-х (начиная со специальной версии i386SL, если точно) Intel придумала специальный режим процессора System Management Mode (SMM), в котором и работает BIOS, прерывая операционную систему. В SMM невозможно попасть средствами самого процессора; процессор попадает в этот режим, когда железо материнской платы подаёт специальный сигнал System Management Interrupt (SMI). USB-контроллеры, встроенные в чипсет, как правило, могут генерировать SMI вместо прерывания в зависимости от настроек.

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

Инициализация контроллеров

Связи между каналами: UHCI

Очевидный плюс такой схемы — простота железа при полном соблюдении требований спецификации USB на приоритеты обработки. Минусы: при большой нагрузке, когда контроллер не успевает обработать все передачи до конца фрейма, каналы одного типа неравноправны — те, кому посчастливилось оказаться в начале списка, получают существенное преимущество, — а при малой нагрузке контроллер постоянно занят чтением из памяти только для того, чтобы убедиться, что новой работы нет. Разработчики следующих контроллеров учли минусы UHCI.

Связи между каналами: OHCI

Usb provisioning что это. Смотреть фото Usb provisioning что это. Смотреть картинку Usb provisioning что это. Картинка про Usb provisioning что это. Фото Usb provisioning что это
В OHCI регистров-указателей целых семь, шесть из которых связаны с каналами. Один из регистров OhciHCCAReg указывает на таблицу периодических каналов, аналогичную остальным контроллерам (с поправками на изохронные передачи), второй OhciPeriodCurrentEDReg указывает на текущий периодический канал и неинтересен настолько, что даже не показан на схеме.

Связи между каналами: EHCI

Работа с USB-устройством

Картинка из спецификации USB, описывающая различные состояния устройства и переходы между ними:
Usb provisioning что это. Смотреть фото Usb provisioning что это. Смотреть картинку Usb provisioning что это. Картинка про Usb provisioning что это. Фото Usb provisioning что это

Подключение устройства

В ходе инициализации контроллеры OHCI и EHCI настраиваются так, чтобы генерировать прерывание при подключении и отключении устройства. В UHCI такой возможности, увы, нет, поэтому при наличии контроллера UHCI поток USB периодически просыпается сам по себе и опрашивает порты контроллера, проверяя изменения статуса подключённости. Интервал опроса составляет UHCI_POLL_INTERVAL тиков таймера, что при текущем значении составляет 1 секунду.

Подключённое USB-устройство начинает взаимодействие с хост-контроллером в состоянии Powered.

В USB2 в процессе сброса выясняется скорость устройства. Я напомню из предыдущей части, что EHCI умеет работать только с HighSpeed-устройствами, а все устройства, работающие на одной из скоростей USB1, должны быть направлены к USB1-компаньону или хабу. С программной точки зрения после окончания сброса EHCI либо разрешает передачу данных к порту, либо нет. Если после сброса порт остаётся запрещённым, значит, подключённое устройство не работает на скорости USB2. В таком случае остаётся только сообщить логике выбора владельца о перенаправлении порта компаньону; после этого компаньон увидит обычное событие подключения и будет его обрабатывать.

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

После сброса и последующей паузы устройство переходит из состояния Powered в состояние Default — одно из двух «полурабочих» состояний, когда устройство уже готово получать и отсылать данные для нулевой конечной точки, но ещё не полностью инициализировано. В состоянии Default устройство отзывается на нулевой адрес на шине USB. Это и есть причина, по которой нельзя проводить сброс для двух устройств параллельно: иначе получились бы два устройства, каждое из которых думало бы, что последующая настройка относится именно к нему.

Открытие канала и передачи по каналу

Usb provisioning что это. Смотреть фото Usb provisioning что это. Смотреть картинку Usb provisioning что это. Картинка про Usb provisioning что это. Фото Usb provisioning что это
С точки зрения контроллера очередь дескрипторов передач (один дескриптор может описывать целую передачу, а может какую-то часть, в зависимости от контроллера) организована как односвязный список, физический адрес первого дескриптора находится в структуре канала, физический адрес следующего дескриптора находится в предыдущем дескрипторе. Когда контроллер заканчивает обрабатывать один дескриптор, он обновляет структуру канала, записывая туда адрес следующего дескриптора. Отсюда следует, что при работающей очереди передач код поддержки хост-контроллера не может сам обновлять адрес следующего дескриптора во избежание состояния гонки с железом. Чтобы организовать работу, нужен дополнительный пустой дескриптор в конце очереди. Пустой дескриптор помечен для контроллера как неактивный. Когда код хочет добавить дескриптор, он заполняет текущий пустой дескриптор, выделяет следующий пустой дескриптор, проставляет в старом дескрипторе ссылку на новый, последним действием активирует старый дескриптор — и всё это без пересечений по записи с контроллером. Когда контроллер доходит до неактивного дескриптора, он останавливает обработку очереди, оставляя в структуре канала ссылку на неактивный дескриптор.

Изменение характеристик канала

Иногда необходимо поменять характеристики канала. Есть три таких случая, два из них возникают в процессе настройки уровнем логического устройства, третий — при закрытии канала (в этом случае меняется поле «следующий канал» у предыдущего канала). Первый, обрабатываемый usb_hardware_func.SetDeviceAddress : после назначения адреса устройству нужно обновить адрес устройства в структуре канала. Второй, обрабатываемый usb_hardware_func.SetEndpointPacketSize : уровень логического устройства может поменять максимальный размер транзакции в ходе инициализации. В UHCI оба этих поля в структуре канала — исключительно программные, контроллер на них даже не смотрит, поэтому с обновлением проблем нет. Первая версия кода просто обновляла параметры в памяти для всех контроллеров, и это даже работало на некоторых конфигурациях. Но в ходе тестов выяснилось, что не на всех. В EHCI контроллер имеет право кэшировать структуру канала, и некоторые контроллеры этим правом активно пользуются, в результате чего могут увидеть обновление в дескрипторе передачи, но проигнорировать обновление в структуре канала. Строго говоря, расхождение возможно даже без кэша: если контроллер только что прочёл структуру канала, потом надолго задумался, в ходе чего код успел обновить структуру канала и поставить в очередь следующую передачу, после чего контроллер оставил размышления и прочитал дескриптор передачи, получится такая же ситуация.

Для корректного обновления в OHCI и EHCI нужно, чтобы контроллер гарантированно не приступал к обработке дескриптора передачи, пока не прочтёт обновлённые данные структуры канала. Для периодического канала достаточно подождать, пока не сменится номер фрейма. Для обновления непериодического канала в OHCI приходится временно останавливать обработку соответствующего списка каналов и сбрасывать указатель на текущий канал в списке. В EHCI предусмотрен специальный механизм Interrupt on Async Advance Doorbell: код устанавливает в одном из регистров бит «продвинься в кольце непериодических каналов и сообщи, когда сделаешь» и ждёт сигнала. Как правило, прерывание приходит. Иногда не приходит, поэтому не помешает подстраховка в виде таймаута.

Отключение устройства

Здесь всё просто: событие приходит аналогично событию подключения устройства — прерыванием на OHCI и EHCI, периодическим опросом на UHCI — и код вызывает функцию usb_device_disconnected уровня работы с каналами, чтобы тот корректно закрыл все каналы и освободил все ресурсы. Кроме того, если устройство на этом порту было подключено менее 100 миллисекунд назад и ждало следующего этапа обработки, код вычёркивает устройство из списка ожидающих.

Источник

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *