Построение практикумов по изучению архитектуры и периферийных устройств на основе шины USB (Дмитрий Костюк, OSEDUCONF-2019) — различия между версиями
Материал из 0x1.tv
StasFomin (обсуждение | вклад) |
StasFomin (обсуждение | вклад) (Batch edit: replace PCRE (\n\n)+(\n) with \2) |
||
=== Особенности изучаемого материала ===
По сложности USB очень отличается от классических интерфейсов, представляя собой сеть с собственным стеком протоколов:
[[File:2019-kostiuk1a.svg|center|640px]]
[[File:2019-kostiuk1b.svg|center|640px]]
В логическом плане USB-устройство всегда является ''хабом'' либо ''функцией''. Функции реализуют функционал устройства, хабы — дополнительные точки подключения, а композитные устройства сочетают несколько функций через внутренние хабы. Каждая функция имеет как минимум одну ''конфигурацию'', каждая конфигурация — как минимум один ''интерфейс'', а уже интерфейс может иметь ''оконечные точки'' (endpoints) (рис. [[#fig:kostiuk1|2]]-b). Оконечные точки различают по номеру, а также по направлению передачи данных в соответствующем ''канале'' (pipe). Каждая функция реализует минимум две оконечных точки с номером 0, доступные сразу по включению устройства; остальные оконечные точки становятся доступны после конфигурирования. Виртуальная файловая система ConfigFS позволяет создавать и изменять из пространства пользователя объекты ядра. В нашем случае она используется в качестве интерфейса для описания функций и конфигураций, составляющих композитное USB-устройство (в частности, аналогичный подход используется Android-смартфонами). При этом создание сложной иерархической структуры, схематично показанной на рис. 1-b, выполняется на уровне файловой абстракции, созданием/изменением соответствующих файлов и каталогов. Для создания типовых функций устройства в пространстве пользователя ConfigFS используется совместно с виртуальной файловой системой FunctionFS: [[File:2019-kostiuk2.svg|center|640px]] === Программный инструментарий и выбор аппаратной платформы === Кроме соответствующих модулей ядра, библиотеки libusb и стандартного тулчейна GNU/Linux, в лабораторном практикуме используется утилита lsusb для получения информации о подключённых устройствах, а также анализатор сетевых пакетов Wireshark для исследования обмена информации хоста с устройством (с помощью модуля ядра usbmon). Выбор аппаратного обеспечения для проведения практикума предопределён тем, что в часть функционала, отвечающая за поведение USB-устройства, требует наличия контроллера, способного работать в режиме USB-device, отсутствующего на стандартных ПК. Таким контроллером обычно оснащены одноплатные компьютеры на базе процессора ARM, поэтому разумным выбором оказываются компьютеры Raspberry Pi либо им подобные; в нашем случае в этой роли выступал комплект отладочных плат на процессоре Exynos для практикума по программированию встраиваемых систем . Заметим, что при необходимости упростить требования за счёт отказа от взаимодействия с реальным USB-устройством в пользу его эмуляции, выбор эмулятора и эмулируемой платформы не является тривиальным. Очевидный вариант с запуском USB-устройства в виртуальной машине и подключение эмулируемого USB-контроллера к контроллеру хост-системы представляет собой задачу, прямо противоположную той, которую решают системы виртуализации, включая QEMU (проброс реального USB-устройства в виртуализованное окружение). Однако запуск учебных программ в режиме эмуляции легко решается с помощью модуля ядра dummy_hcd, который перенаправляет трафик USB-устройства обратно в систему на виртуальный USB-хаб, создавая закольцованное устройство. Благодаря этому драйвер USB-хоста и драйвер USB-устройства могут работать на одной и той же хост-системе: [[File:2019-kostiuk3.svg|center|640px]] === Структура практикума === Структура разработанного практикума включает 5 лабораторных работ. В первой работе наглядно демонстрируется, как происходит обмен информацией, студенты знакомятся утилитой lsusb и библиотекой libusb для получения информации об устройстве, а также используют анализатор пакетов Wireshark для отслеживания простейшего взаимодействия с устройством (нажатия клавиши). Во второй работе рассматриваются особенности передачи данных по шине USB и соответствующий функционал libusb. В третьей работе рассматривается конфигурирование устройства с помощью файловой системы ConfigFS. Четвёртая работа позволяет реализовать стандартную функцию с помощью файловой системы FunctionFS. Наконец, целью завершающей пятой работы является реверс-инжиниринг разработанного проприетарного драйвера с помощью Wireshark. {{----}} [[File:{{#setmainimage:Построение практикумов по изучению архитектуры и периферийных устройств на основе шины USB (Дмитрий Костюк, OSEDUCONF-2019)!.jpg}}|center|640px]] {{LinksSection}} <!-- <blockquote>[©]</blockquote> --> * [1] ''Костюк Д.А.'' Изучение низкоуровневого программирования и вычислительной архитектуры на базе платформы GNU/Linux //Свободное программное обеспечение в высшей школе: тезисы докладов V конференции. Переславль, 30–31 января 2010 г. / Москва, Институт логики, 2010. — С. |
Текущая версия на 12:22, 4 сентября 2021
- Докладчик
- Дмитрий Костюк
Рассматриваются особенности применения Linux-устройства в роли конфигурируемого USB-гаджета для практического изучения студентами архитектуры и протоколов шины USB. Подход нацелен на абстрагирование от низкоуровневой реализации в рамках ОС для максимальной фокусировки на особенностях обмена данными и стандартных классах устройств, применении средств отладки и мониторинга USB-трафика. За счёт работы в пространстве пользователя и использования виртуальных файловых систем ConfigFS и FunctionFS достигается упрощение учебных задач, благодаря чему изучение USB-протоколов, несмотря на их значительно большую сложность, требует времени, сравнимого с изучением legacy-интерфейсов.
Содержание
Видео
Презентация
Thesis
Введение
Классический подход в изучении низкоуровневого программирования и архитектуры предполагает поэтапное изучение процессора и соответствующего ему языка машинных команд, архитектуры вычислительной системы и периферийных устройств (их принципов действия, интерфейсов подключения и протоколов обмена данными). Взаимодействие с классическими (т. н. legacy) интерфейсами (COM, PS/2, LPT/IEEE 1284) позволяет изучить работу с портами ввода-вывода и прерываниями, но в многозадачных ОС данную задачу осложняет необходимость написания драйверов, работающих полностью или частично в привилегированном режиме, и взаимодействующих с другими частями ОС.
В своё время успешное решение данной задачи с использованием модулей ядра GNU/Linux позволило авторам сохранить прежнюю схему курса в условиях современной и более чем актуальной платформы . Однако изучаемые студентами классические интерфейсы начинают создавать проблему при выполнении учебных задач из-за их постепенного вытеснения интерфейсом USB, полностью завершившегося на ноутбуках и почти полностью — на настольных компьютерах.
Особенности изучаемого материала
По сложности USB очень отличается от классических интерфейсов, представляя собой сеть с собственным стеком протоколов:
В логическом плане USB-устройство всегда является хабом либо функцией. Функции реализуют функционал устройства, хабы — дополнительные точки подключения, а композитные устройства сочетают несколько функций через внутренние хабы. Каждая функция имеет как минимум одну конфигурацию, каждая конфигурация — как минимум один интерфейс, а уже интерфейс может иметь оконечные точки (endpoints) (рис. 2-b). Оконечные точки различают по номеру, а также по направлению передачи данных в соответствующем канале (pipe). Каждая функция реализует минимум две оконечных точки с номером 0, доступные сразу по включению устройства; остальные оконечные точки становятся доступны после конфигурирования.
Взаимодействие с этой иерархией осуществляется с помощью структур данных определённого формата — дескрипторов. Каждое устройство имеет как минимум один дескриптор конфигурации, каждый дескриптор конфигурации — минимум один дескриптор интерфейса, а каждый дескриптор интерфейса — до 15 дескрипторов оконечных точек (плюс строковые дескрипторы на разных языках). Обмен данными с устройством всегда инициируется хостом и осуществляется в виде транзакций приёма и передачи данных. Передаваемые наборы служебных пакетов и пакетов данных зависят от типа передачи. По типу передачи каналы (и, соответственно, оконечные точки) подразделяются на поточные (bulk), управляющие (control), изохронные (isochronous) и прерывания (interrupt).
Взаимодействие с устройством всегда начинается с управляющего канала 0, который позволяет прочитать краткую информацию об устройстве, включая коды производителя и модели (Vendor ID и Product ID), а также список других оконечных точек, после чего драйвер выполняет конфигурирование устройства и далее — информационный обмен со сконфигурированными оконечными точками по одному из четырёх протоколов передачи. При этом устройство может принадлежать к одному из стандартных классов (например USB-HID), либо представлять собой некоторую проприетарную реализацию.
Специфика разработанного практикума
Из приведённого краткого описания очевидно, что разработка драйвера USB-устройства оказывается очень сложной задачей даже для студентов, уже умеющих создавать простые модули ядра. Осложняет задачу также то, что многоуровневой логической организации соответствует не самый простой API, а также существенная разница в реализации программного обеспечения для хоста и устройства. Поэтому учебные курсы архитектуры ЭВМ зачастую ограничиваются теоретическим изучением особенностей шины USB без практических заданий, касающихся создания какой-либо законченной реализации.
Представляемый лабораторный практикум решает данную проблему за счёт абстрагирования от реализации драйвера в рамках ОС и максимального переноса логики работы в пространство пользователя для концентрации на изучении логической структуры и принципов взаимодействия с USB.
Заметим, что работа с USB-устройствами в пространстве пользователя достаточно распространена, в частности, на этапе прототипирования и отладки драйвера устройства, а также в случаях, когда производительность не является проблемой. В GNU/Linux данный уровень абстракции обеспечивает популярная библиотека libusb, однако её API также требует времени на изучение, что создаёт дополнительную когнитивную нагрузку, а следовательно увеличивает время, необходимое на освоение материала. Поэтому в разработанном курсе ей отведена не самая большая роль, а взамен упор делается на взаимодействие с USB на уровне виртуальных файловых систем ConfigFS и FunctionFS.
Виртуальная файловая система ConfigFS позволяет создавать и изменять из пространства пользователя объекты ядра. В нашем случае она используется в качестве интерфейса для описания функций и конфигураций, составляющих композитное USB-устройство (в частности, аналогичный подход используется Android-смартфонами). При этом создание сложной иерархической структуры, схематично показанной на рис. 1-b, выполняется на уровне файловой абстракции, созданием/изменением соответствующих файлов и каталогов. Для создания типовых функций устройства в пространстве пользователя ConfigFS используется совместно с виртуальной файловой системой FunctionFS:
Программный инструментарий и выбор аппаратной платформы
Кроме соответствующих модулей ядра, библиотеки libusb и стандартного тулчейна GNU/Linux, в лабораторном практикуме используется утилита lsusb для получения информации о подключённых устройствах, а также анализатор сетевых пакетов Wireshark для исследования обмена информации хоста с устройством (с помощью модуля ядра usbmon).
Выбор аппаратного обеспечения для проведения практикума предопределён тем, что в часть функционала, отвечающая за поведение USB-устройства, требует наличия контроллера, способного работать в режиме USB-device, отсутствующего на стандартных ПК. Таким контроллером обычно оснащены одноплатные компьютеры на базе процессора ARM, поэтому разумным выбором оказываются компьютеры Raspberry Pi либо им подобные; в нашем случае в этой роли выступал комплект отладочных плат на процессоре Exynos для практикума по программированию встраиваемых систем .
Заметим, что при необходимости упростить требования за счёт отказа от взаимодействия с реальным USB-устройством в пользу его эмуляции, выбор эмулятора и эмулируемой платформы не является тривиальным. Очевидный вариант с запуском USB-устройства в виртуальной машине и подключение эмулируемого USB-контроллера к контроллеру хост-системы представляет собой задачу, прямо противоположную той, которую решают системы виртуализации, включая QEMU (проброс реального USB-устройства в виртуализованное окружение). Однако запуск учебных программ в режиме эмуляции легко решается с помощью модуля ядра dummy_hcd, который перенаправляет трафик USB-устройства обратно в систему на виртуальный USB-хаб, создавая закольцованное устройство. Благодаря этому драйвер USB-хоста и драйвер USB-устройства могут работать на одной и той же хост-системе:
Структура практикума
Структура разработанного практикума включает 5 лабораторных работ. В первой работе наглядно демонстрируется, как происходит обмен информацией, студенты знакомятся утилитой lsusb и библиотекой libusb для получения информации об устройстве, а также используют анализатор пакетов Wireshark для отслеживания простейшего взаимодействия с устройством (нажатия клавиши). Во второй работе рассматриваются особенности передачи данных по шине USB и соответствующий функционал libusb. В третьей работе рассматривается конфигурирование устройства с помощью файловой системы ConfigFS. Четвёртая работа позволяет реализовать стандартную функцию с помощью файловой системы FunctionFS. Наконец, целью завершающей пятой работы является реверс-инжиниринг разработанного проприетарного драйвера с помощью Wireshark.
Примечания и ссылки
- [1] Костюк Д.А. Изучение низкоуровневого программирования и вычислительной архитектуры на базе платформы GNU/Linux //Свободное программное обеспечение в высшей школе: тезисы докладов V конференции. Переславль, 30–31 января 2010 г. / Москва, Институт логики, 2010. — С.
32–35.
- [2] Костюк Д.А., Жук А.М. Построение практикумов по программированию периферийных устройств и архитектуре ЭВМ на базе GNU/Linux // Тези мiжнародної науково-практичної конференцiї FOSS LVIV–2011, Львiв, 1–6 лютого 2011 р. – Львiв: Вид. ЛНУ iм. I. Франка, 2011. — С. 73–75.
- [3] Make your own USB gadget (Andrzej Pietrasiewicz, LVEE-2017)
- [4] Построение практикумов по программированию встраиваемых систем (Дмитрий Костюк, OSEDUCONF-2015)
Plays:65 Comments:0