Энумерация – часть вторая
Событийно-ориентированное программирование (event driven programming) – это то, что нужно, что бы лучше понимать работу программ микроконтроллера с аппаратной поддержкой USB. Иначе такие программы называют – программы управляемые событиями. Логика программы реализуется, как максимально изолированные обработчики спонтанных событий. Во многих объектно-ориентированных средах разработки – эта парадигма реализована. При программировании микроконтроллеров, такими обработчиками событий могут быть обработчики прерываний, а основная программа может выродиться в загрузчик пробелов, выполнять пустой цикл. Кончено обработчики прерываний общаются между собой через доступную всем обработчикам область памяти. Особенно эффективно решаются задачи, алгоритм работы которых описывается конечным автоматом. Часто такие задачи возникают при описании коммуникационных протоколов и работы технологических механизмов.
Иногда события, после первичной обработки направляют в единственный обработчик событий, который занимается их разделением и обработкой. График переходов между состояниями USB устройства, в процессе функционирования, напрашивается сам собой на анализ, с точки зрения парадигмы событийно-управляемого программирования.
Рисунок 20 |
Выше говорилось о процессе энумерации, но процесс энумерации только часть жизненного цикла устройства на шине, события могут возникать спонтанно в любое время, и USB устройство должно корректно на них реагировать.
Необходима глобальная переменная, в которой будет храниться текущее состояние USB устройства. При возникновении события, обработчик определит текущее состояние, по значению глобальной переменной, сделает необходимые действия и установит новое значение этой переменной в соответствии с новым состоянием USB устройства.
Выполнять мониторинг событий можно различными методами. Организовать как обработчик прерываний, или опрашивать состояние регистров, или по прерыванию таймера вызывать монитор и опрашивать регистры.
Событие |
Реакция |
USB устройство обнаруживает напряжение на линии VBUS |
USB устройство подключает резистор к D+ |
Хост посылает команду «Сброс шины» (Bus Reset) |
USB устройство, настраивается на прием управляющих запросов на точку управления по нулевому адресу |
Хост посылает команду, выдать первые 8 байт дескриптора устройства |
USB устройство посылает 8 байт дескриптора |
Хост назначает адрес |
USB устройство адрес устанавливает |
Хост запрашивает все дескрипторы |
USB устройство эти дескрипторы выда.т |
Хост назначает конфигурацию. |
USB устройство активизирует конфигурацию и готово к работе. |
Перечислим события шины, которые должны вызывать переход USB устройства из одного состояния в другое.
Переход напряжения из «0» в «1» на шине VBUS. При подключении USB устройства к хосту. Переходит из состояния «подключено» в состояние «запитано».
Переход напряжения из «1» в «0» на шине VBUS. Из любого состояния переходит в состояние «подключено».
Команда «сброс шины» (Bus Reset). Из любого состояния, кроме «подключено», переходит в состояние «дежурное».
Хост перевел сегмент шины c USB устройством в состояние «приостановлено» (Suspended state), состояние шины Bus Idle более 3 миллисекунд. Переход в состояние «приостановлено» возможен из любого состояния, кроме «подключено».
Хост выводит USB устройство из состояния «приостановлено». Хост посылает специальную команду «пробуждение» (Resume). Суть команды, из состояния J шина переводится в состояние K на 20 миллисекунд, и затем в состояние SE0 на 1,33 микросекунд и опять в состояние J на 0,66 мксек. На рисунке 21 представлена временная диаграмма. После этой команды USB устройство должно быть готово к приему пакетов SOF. По этой команде происходит возврат в активное состояние, из которого USB устройство перешло в состояние «приостановлено».
Нужно вспомнить, что USB устройство может по своей инициативе сообщить хосту о необходимости пробуждения. Устройство USB выводит хост из спящего состояния командой «удаленное пробуждение» (Upstream Resume), переводит шину на интервал от 1 до 15 миллисекунд в состояние K (K-state), перед этим шина должна быть в состоянии J как минимум 5 миллисекунд.
Команда достигает хоста и он в свою очередь отвечает командой «пробуждение» направленной к USB устройству. Команда «пробуждение» от хоста описана выше.
Стандартные управляющие запросы, должны корректно обрабатываться USB устройством. Некоторые из них выполняют функцию событий, приводящих к изменению состояния USB устройства.
На управляющий запрос Get_Device_Descriptor по нулевому адресу, в состоянии «дежурное», USB устройство остается в дежурном состоянии, выполнив посылку первых 8 байт дескриптора устройства хосту.
Управляющий запрос Set_Address назначает адрес, эффективен только в состоянии «дежурное», в остальных состояниях, должен рассматриваться как некорректный. Событие переводит USB устройство в состояние «адресовано» и присваивает адрес.
На управляющий запрос Get_Device_Descriptor , USB устройство посылает дескриптор устройства целиком, оставаясь в состоянии «адресовано». Затем хост по меньшей мере еще два раза посылается этот управляющий запрос, для получения дескриптора конфигурации и дескрипторов конечных точек. После приема дескрипторов USB устройство остается в состоянии «адресовано».
На управляющий запрос Set_Configuration, с ненулевым номером конфигурации, USB устройство переходит из состояния «адресовано» в состояние «сконфигурировано».
На управляющий запрос Set_Configuration , с нулевым номером конфигурации, если USB устройство в состоянии «сконфигурировано», переходит в состояние «адресовано».
Программное обеспечение контроллера, должно так же распознавать события по каналам передачи данных. Когда по инициативе хоста, USB устройство обработает транзакцию, то генерируется событие, которое можно условно назвать «транзакция данных обработана». Организовать обработку события можно либо опросом флагов, либо обработкой прерывания. Транзакции по каналам данных обрабатываются аппаратурой SIE. Да и по каналам управления транзакции обрабатываются аппаратурой SIE.
Твердое знание протокола рабочего режима и процесса энумерации очень важно для понимания назначения регистров SIE микроконтроллера и построения программы микроконтроллера.
Рисунок 21 |
Огромную помощь в изучении шины USB может оказать анализатор протокола USB. Аппаратура такого анализатора подключается к шине, захватывает пакеты и демонстрирует на мониторе. Но такая аппаратура дорого стоит и не всегда доступна.
Другое подспорье – это программный анализатор, по своим возможностям он не сравним с аппаратным анализатором, но может оказаться очень полезным. Существует множество программных анализаторов. Мной использовалась свободная программа Wireshark (www.wireshark.org). Это программный анализатор широкого применения, чаще он применяется для анализа сетевого трафика, но можно использовать и для анализа активности USB устройств. Существуют порты как для Windows так и для Linux. Для Windows XP необходимо устанавливать версию не старше 1.10. Для Windows нужно дополнительно установить программу USBPcap, не путать с WinPcap. С Windows порядок работы следующий. После установки Wireshark, распаковываем архив с USBPcap и запускаем консольную программу USBPCapCMD.exe. Программа выводит список корневых хабов и устройств, подключенных к хабам в системе, и спрашивает, какой номер хаба выбираете, иначе говоря, какой слот будем прослушивать. Введите номер соответственный USB устройству. Затем просит ввести название файла, куда программа сбросит все захваченные данные. По Ctrl+C прерывается процесс прослушивания. Запускаем Wireshark и открываем полученный файл дампа. Можно вести мониторинг с помощью Wireshark и в реальном режиме, на родном сайте http://desowin.org/usbpcap/, привед.н образец командной строки.
Для Linux нужно ядро не моложе 2.6.21 и загруженный модуль usbmon. Только начиная с версии 1.1.0 библиотеки libpcap, правильно работает Wireshark для Linux, поэтому проверьте версию библиотеки на вашей системе. Средства перехвата даннх встроены в ядро Linux и никаких дополнительных программ устанавливать не надо.
Чтобы захватить процесс энумерации, запускаем прослушивание нужного слота, а затем в этот слот вставляем штекер исследуемого USB устройства. Экран Wireshark с запросами процесса энумерации показан на рисунке 22.
Для Windows, захватом данных занимается USBPcap, а Wireshark используется для понятного представления данных. В свою очередь USBPcap состоит из 2-х частей. Одна часть – это драйвер, работающий в пространстве ядра операционной системы, и вторая часть – это консольная программа, работающая в пространстве пользователя. В стек USB ядра операционной системы, данные поступают от драйвера в виде пакетов URB (USB request blocks). Это особые структуры, которые в себе содержат данные запросов от хоста к USB устройству. Проще говоря, URB– это некий контейнер, содержащий запрос или транзакцию ввода-вывода. Программа USBPcap перехватывает URB и передает программе пользовательского уровня. Важно понимать, что Wireshark показывает URB и содержащиеся в них данные. Без труда можно разобраться, где запросы, а где транзакции ввода-вывода.
Рисунок 22 |
Выводимые на экран данные можно фильтровать по различным признакам. Например фильтровать по адресу USB устройства. Из меню «Analyze -> Display filters». Создать новый фильтр «new», затем жмем кнопку «Expression». Появляется окно конструктора фильтров, выбираем секцию «USB» и необходимый атрибут, и в конце «Apply». На рисунке 23 показаны снимки экрана. Программа анализатора дает наглядное представление о процессе энумерации. Важно на начальных этапах изучения шины USB, брать простые устройства. В качестве простейшего устройства для изучения шины, можно взять загрузчик DFU микроконтроллера AT90USB162. Об этом загрузчике сказано ниже.
Рисунок 23 |
.
|