Есть такие устройства – USB Трекеры (USB Analyzer). Они позволяют перехватить трафик между USB устройством и компьютером, записать его и проанализировать. Трекеры обычно используются разработчиками USB устройств и программистами для отладки оборудования и драйверов. Очень полезная штука, если нужно заниматься проектами связанными с шиной USB.
У нас в офисе сейчас есть два таких USB трекера. Первый трекер (беленький), компании Ellisys позволяет работать только с устройствами USB1.1. Когда-то давным давно мы приобретали его за большие деньги, кажется около 600 евро. Уже потом цены на них сильно упали.
Второй трекер Beagle (синенький), компании Total Phase, попал к нам почти случайно. Он уже посовременней, можно прослушивать трафик устройств USB2.0. Понятно, сейчас мы больше пользуемся им.
Несмотря на то, что у нас есть целых 2 фирменных анализатора протокола USB иногда встречаются странные устройства и странные ошибки на шине USB, которые не удается просто диагностировать.
Я предлагаю сделать свой USB анализатор на базе платы Марсоход2. Врядли получится сделать анализатор USB2.0, но уж трекер для USB1.1 сделать точно можно. Это, конечно, серьезное ограничение, но, тем не менее, наш анализатор будет обладать и своими собственными полезными и уникальными свойствами.
Как известно (
- Земля (4, обычно черный провод в кабеле);
- DP (3, обычно зеленый провод в кабеле);
- DM (2, обычно белый провод в кабеле);
- +5V (1, обычно красный провод в кабеле).
Трекер-анализатор является «шпионом», прослушивающим линию связи, то есть сигналы DP и DM. Трекер никак не модифицирует передаваемые по шине данные, а только слушает их. Схема прослушки очень простая:
Собственно нужно изготовить специальный кабель USB, который бы имел отвод трех сигналов DP, DM и GND для подключения к плате Марсоход2.
Мы сделали вот такой несколько странный переходничек из какой-то старой платки от какого-то старого устройства. На этой платке разъемы audio конечно не нужны, просто не стали их отпаивать. Нам вообще ничего не нужно от этой платки кроме одного разъема USB.
Платка подключается к плате Марсоход2 к сигналам IO[9] и IO[11] на гребеночке. Это будут DP и DM соответственно.
В ПЛИС платы Марсоход2 мы загрузим (через встроенный на плату USB JTAG программатор MBFTDI) наш проект, который будет принимать на шине USB все ходящие там пакеты. Встроенный программатор MBFTDI создан на микросхеме FTDI и имеет два канала передачи. Второй канал мы используем как высокоскоростной последовательный порт. Принятые USB данные ПЛИС тут же будет отправлять в текстовом виде через последовательный порт в компьютер для просмотра в обычной программе терминала.
Я собираюсь передавать перехваченные USB данные в компьютер в текстовом виде, чтобы на компьютере не писать программу отображения данных. Упрощаю себе задачу. Принятые данные будут отображаться в обычной программе текстового терминала, например, Putty или TeraTerm.
Перевод двоичных данных в текстовый вид вообще-то делает поток через последовательный порт чрезмерным: вместо одного байта будет отправляться 3 байта.
Например, двоичный байт 0х45 надо отправить как 3 байта текста:
- 0x34 (код ASCII символа «4»)
- 0x35 (код ASCII символа «5»)
- 0x20 (это код пробела)
FullSpeed устройства (такие как USB наушники или колонки) передают данные в USB на частоте 12Мгц.
С другой стороны 12Мгц – это предельная частота приемопередатчика последовательного порта в микросхеме FTDI на плате Марсоход2. Таким образом, вообще-то переводить байты USB трафика в текстовый вид увеличивая поток в три раза – это не очень здоровая идея.. Последовательный порт может не успеть все передать. Буду надеяться, что исследуемые USB устройства не будут занимать всю пропускную способность шины. Поставлю в проекте большое FIFO между USB приемником и передатчиком последовательного порта – оно должно сгладить разницу в скоростях передачи этих модулей.
Вот топ модуль проекта ПЛИС (можно кликнуть по изображению, чтобы увеличить):
- Модуль usb_recv принимает прослушиваемые на шине данные.
- Модуль txtgen переводит байт данных в 3 байта текста. Еще каждый сигнал EOP на штне USB будет транслироваться в 2 байта перевод строки 0x0D 0x0A. Сигнал EOP (End Of Packet) на шине USB завершает каждый пакет передаваемых данных. Так же в случае низкоскоростного устройства EOP посылается в начале каждого фрейма каждую 1 миллисикунду.
- Модуль myfifo – это буфер между приемником USB и передатчиком передатчиком последовательного порта.
- Модуль serial читает данные из FIFO и передает их в последовательный порт на скорости 12Мбит/сек.
Весь проект USB трекера для среды Altera Quartus II можно взять вот здесь:
Попробуем испытать трекер в работе: нужно подсоединить плату Марсоход2 к ноутбуку, кабель от платки USB разъема так же к ноутбуку или к другому компьютеру. Исследуемую компьютерную USB мышь будем подключать к USB разъему. Главное не запутаться в проводах:
Теперь проект для ПЛИС в среде Altera Quartus II нужно откомпилировать и загрузить в плату Марсоход2.
Еще на ноутбуке запускаем программу терминала Putty. Настраиваем ее на последовательный порт со скоростью 12000000 (12Мбит/сек).
Подключаем USB мышь и видим, как в терминале побежали строки с шестнадцатеричными данными, вот демонстрационное видео:
Посмотрим, например, фрагмент лога инициализации подключенной USB мыши:
RST
80 2D 00 10
80 C3 00 05 01 00 00 00 00 00 EB 25
80 D2
80 69 00 10
80 4B 00 00
80 D2
80 2D 01 E8
80 C3 80 06 00 01 00 00 12 00 E0 F4
80 D2
80 69 01 E8
80 4B 12 01 00 02 00 00 00 08 57 E7
80 D2
80 69 01 E8
80 C3 6D 04 5B C0 00 54 01 02 F1 3E
80 D2
80 69 01 E8
80 4B 00 01 3F 8F
80 D2
80 E1 01 E8
80 4B 00 00
80 D2
Все пакеты начинаются с байта 0x80 - это код SYNC. Следующий байт - это так называемый PID - идентификатор команды. Основные команды - это ox2D Setup, 0x69 In, 0xE8 Out, 0x4B или 0хС3 - это данные. PID подтверждения передачи 0xD2 Ack, отсутствие данных у устройства - PID 0x5A NACK.
Протокол довольно сложный и запутанный, но разобраться можно.
Если бы мы использовали для отображения не текстовый терминал, а сами писали бы программу для этого, то можно было бы как-то интеллектуально сгруппировывать пакеты и расшифровывать их. Так делают все произовдители USB трекеров. Их программное обеспечение показывает и расшифровывает USB дескрипторы устройств, используемую конфигурацию, количество edpoints и прочую полезную информацию.
Написание такого ПО - это отдельная и большая задача, не реализованная в рамках этого простого проекта.
Что еще можно увидеть в логе нашего трекера? Ну вот например происходит опрос мыши ноутбуком:
80 69 81 58
80 5A
80 69 81 58
80 5A
80 69 81 58
80 C3 00 01 00 00 00 00 C2 24
80 D2
Между пакетами не случайно накие отступы. Каждый USB фрейм каждую 1 миллисекунду для низкоскоростного устройства начинается с EOP, а он у нас передается как перевод строки 0x0D 0x)A. В основном пакеты идут парами: пакет от хоста 0x69 - IN чтение. И обычно устройство отвечает пакетом 0x5A NACK -нет данных. Так происходит всегда, пока мышь находится в покое. Если же ее сдвинуть, то в ответ на запрос 0x69 мышь ответит пакетом данных 0xC3 или 0x4B. Теперь уже хост должен подтвердить своим 0xD2 ACK, что пакет успешно принят.
Этот USB трекер был испытан с разными USB устройствами: мышью, клавиатурой, джойстиком (это низкоскоростные устройства) и с USB наушниками (высокоскоростное устройство).
Конечно, у нашего USB трекера есть недостатки. Главным образом они связаны с тем, что у нас нет собственно анализирующего программного обеспечения на стороне ноутбука. Его можно написать и наверное это сможет сделать тот, кому это действительно будет нужно.
Несомненным плюсом нашего анализатора является то, что мы можем посмотреть вживую на проходящие в шине USB пакеты средствами Altera SignalTap. Модуль SignalTap позволяет посмотреть некоторые сигналы проекта внутри ПЛИС.
Вот,, например, так выглядят пакеты USB в шине (можно кликнуть по изображению, чтобы увеличить):
Такой возможности, посмотреть сигнал USB нет в обычных USB трекерах. Вот вам наш плюсик нашего проекта.
Подробнее...