Доброго времени суток, дорогие друзья! Прежде всего, хотел бы поздравить всех с прошедшими новогодними праздниками и пожелать всего наилучшего.
Ранее в статье Анонсирована разработка USB-драйвера RNDIS для контроллеров серии STM32F4. С тех пор библиотека постепенно развивалась и сейчас достигла своей первой релизной версии.
Библиотека под названием LRNDIS (LWIP+RNDIS) позволяет создавать на базе контроллера STM32F4 как USB-устройства класса «модем», так и любые другие устройства, управляемые через веб-интерфейс.
Пример управления платой stm32f4-discovery из веб-браузера на планшете Android показан на видео:
На странице видео представлена ссылка на исходные коды и HEX-файл прошивки платы Discovery, с помощью которого можно повторить этот эксперимент. В статье рассказывается о том, как и когда полезна технология доступа через WEB-интерфейс, а также о том, как работает библиотека LRNDIS для контроллеров STM32F4. Также есть обучающие материалы по работе USB и проектированию сетей Ethernet. Предыстория создания библиотеки
Предыстория проекта весьма типична.
Это был теплый летний день.
Хммм.
Задача заказчика была разработать устройство с сервисным интерфейсом управления.
Подробности По мере развития прошивки было введено несколько команд управления через интерфейс VCP. Это значит, что после подключения USB-устройства в ОС был создан виртуальный COM-порт. С его помощью с пользовательского терминала передавались команды управления и диагностики.
В ответ устройство получало статус выполнения и свое текущее состояние.
С сервисной точки зрения система вполне типична: имеется последовательный порт и набор команд управления и диагностики.
Все изменилось за короткое время.
По объективным причинам требуемый набор команд вырос.
Нам также была необходима интерактивность вывода: некоторые параметры нужно было отображать динамически.
Как, например, показания магнитного датчика, когда мимо него проносят ферромагнетик.
Для этого были введены дополнительные команды, которые, управляя escape-последовательности , печатает информацию на пользовательском терминале с высокой частотой.
Это создавало необходимое ощущение наблюдения в реальном времени.
Интерактивные команды оказались настолько удобными для инженеров, что некоторые команды позже были добавлены в соответствии с концепцией.
А потом случился крах.
Необходимо было поддерживать сразу несколько групп команд: интерактивные, диагностические, команды управления.
При этом периодический рефакторинг кода был связан с трудоемким редактированием большого количества обрабатываемых команд. Стало понятно, что все же нужна пользовательская группа команд — для менее квалифицированного персонала, который будет просто следовать инструкциям по эксплуатации.
Пришла в голову идея написать клиентский терминал с кнопками и флажками.
И тут возникли сомнения: стало понятно, что мы имеем дело с сервисной частью, уделяя функционалу всё меньше внимания! Но к пользовательской программе, запускаемой на клиентской ВМ, тоже должны быть свои требования: кроссплатформенность и LTS (длительность поддержки).
Допустим, мы закончили устройство, и нам предстоит портировать и протестировать пользовательское ПО с каждой выпущенной версией операционной системы! Сколько? Вот и родился вопрос – как избавиться от дополнительных трудозатрат? Было решено использовать гарантированные стандарты долгосрочной поддержки.
Те стандарты, которые позволят нам создать программу управления клиентскими устройствами, которая будет поддерживаться наиболее полным набором операционных систем в настоящем и будущем.
В первые несколько дней были обнаружены недостатки популярных кроссплатформенных фреймворков: - Java: должна присутствовать в ОС JVM , а необходимость распространения виртуальных машин вытекает из противоположного предположения - qt: периодическая необходимость версионное портирование И нюансы запуск для Android. Нет, эти трудности не должны вас пугать.
Вопрос, пожалуй, только в трудочасах, которые мы иногда занижаем, учитывая фактор долгосрочной поддержки.
Так родилась идея сделать WEB-интерфейс для управления устройством.
Не требует разработки стороннего программного обеспечения; браузеры для отображения страницы управления доступны во всех необходимых операционных системах.
Потенциал дизайна интерфейсов огромен.
Продолжительность поддержки стандартов http/html/js также не вызывает сомнений.
По плану управление должно было работать следующим образом.
1. Устройство, подключенное через USB, похоже на сетевую карту.
2. Клиентская ВМ (ПК или гаджет) получает IP-адрес для работы в сети нашего устройства.
3. По запросу веб-браузера на клиентской ВМ наше устройство отправляет страницу 4. Страница содержит информацию о текущем состоянии и доступных элементах управления.
5. Когда клиент активирует элементы управления, из браузера отправляются соответствующие HTTP-запросы.
По сути, между браузером и устройством проходят одни и те же текстовые команды, но только в формате протокола HTTP. Вы должны понимать, что это лишь один вариант из большого множества возможных решений.
У этого есть свои плюсы и минусы.
Так получилось, что сейчас производители прибегают к использованию веб-интерфейсов в основном для чисто сетевых устройств: настройки модемов и роутеров.
Посыл этой статьи – давайте использовать то, что действительно удобно.
И не будем бояться трудностей на пути: преодоление их сейчас сэкономит нам гораздо больше времени в будущем! Объем библиотеки
К сожалению, первый анонс не был полностью успешным, потому что.
история с размахом была упущена.
Попробуем немного подтянуться и расширить эту тему.
Если мы находимся на этапе системного проектирования устройства, то в сторону использования веб-интерфейсов (независимо от физического канала, Ethernet или USB) нас могут склонить следующие соображения: 1. Устройство должно иметь интерфейс управления и/или диагностики.
2. Элементы управления могут использоваться не только на этапе разработки, но и на этапе эксплуатации (пользовательское ПО) 3. Квалификация пользователя может быть недостаточно высокой, что требует удобного интерфейса управления.
4. «Дружественный» метод управления должен быть доступен для разных платформ и операционных систем.
5. Соответствующие средства должны поддерживаться в рабочем состоянии в течение длительного времени.
Дополнительным критерием может быть то, проектируем ли мы сетевое устройство с самого начала.
А также: не будет ли (иначе) добавление в прошивку сетевого стека и веб-сервера лишним на фоне гораздо менее богатого функционала устройства.
Другими словами, добавление веб-интерфейса к контроллеру управления лампочками — заведомо избыточное решение.
Если мы верим в веб-интерфейс, то следующие соображения могут помочь нам в выборе физического канала связи (с точки зрения Ethernet и USB).
Тип | Внутрисхемное соединение | Типичное применение |
Ethernet | PHY-контроллер Ethernet | — Промышленные устройства
— Бытовые устройства с функцией сети и доп.
еда |
USB | Контроллер ULPI или прямое подключение к МК | Бытовые и некоторые промышленные устройства.
Особенно если: - устройства не имеют гарантированного источника питания (аккумулятора, например) — устройства, потенциально подключаемые к хосту только через USB-интерфейс (например, планшет) - миниатюрный класс устройств |
Исходя из вышеизложенного, становится понятной сфера применения библиотеки: бытовые и некоторые промышленные устройства, которые: — работа на базе МК STM32F4 - должен иметь удобный интерфейс управления - должно управляться из другого аппаратно-программного комплекса - может не иметь гарантированного источника питания - должен иметь длительный период поддержки программного обеспечения управления Существует множество возможных примеров использования этой технологии, даже за пределами чисто сетевых устройств.
Например, в настоящее время планируется превратить stm32f4-discovery в инструмент разработки для хобби с функциями портативного генератора/анализатора сигналов и осциллографа.
Подключите такого помощника к телефону и посмотрите в динамике, что происходит в интересующей вас схеме.
В бесплатные преимущества входит отсутствие необходимости собирать или устанавливать программное обеспечение; Просто прошейте HEX-файл и откройте браузер — в нем будут все прелести графического интерфейса.
На мой привередливый вкус - как раз то, что нужно.
Конечно, инструмент не для повышения квалификации, но определенный интерес к нему есть.
Итак, я надеюсь, что мы поняли.
А теперь о том, как работает библиотека.
Как это работает
Мы не будем спешить с ответом на этот вопрос.
Человек с небольшим опытом взаимодействия с сетями вполне справедливо может растеряться.
Поэтому, что касается того или иного протокола взаимодействия, я также дам его краткое техническое описание на том уровне.
которого мне самому когда-то не хватало.
Шаг 1. Подключите USB-устройство.
Как говорилось ранее, на этом этапе наше устройство сообщает хосту «Я — сетевая карта!» Хост (т. е.
клиентская ВМ), после подключения к ней нашей поделки, начинает отправлять запросы.
Хозяину необходима следующая информация - как называется продукт? — что такое VID и PID продукта (идентификаторы производителя и продукта, см.
список ) - которому класс и подкласс относится к устройству — на каких конечных точках и в каких блоках следует обмениваться данными? Ну и еще немного информации.
Пакеты конфигурации передаются через конечную точку 0. Ответные пакеты от устройства с информацией о себе обычно называются «дескрипторами USB-устройства».
Подробнее о процессе опроса (переписи) можно узнать Здесь .
В целом протокол USB довольно богатый.
иногда даже кажется избыточным.
Однако это богатство уже много лет позволяет подключать совершенно разные устройства, делая возможным передачу изохронных потоков, блоков данных и прерываний.
В общем, все необходимое, что может потребоваться широкому кругу современных устройств.
Другая сторона медали — высокий барьер входа в разработку USB-устройств.
После получения информации об устройстве операционная система хоста ищет подходящий драйвер для связи.
В типичном случае, например флэш-носителе (класс USB MSC) или клавиатуре и мыши (класс HID), загружается стандартный драйвер для этого класса.
В более «тяжелом» случае, как у нашей сетевой карты USB (класс CDC с подклассом RNDIS), операционная система действует по своему усмотрению: — Linux/android/mac OS, как правило, успешно пытается установить стандартный обмен — ОС Windows просит установить внешний драйвер В первом случае наше устройство работает сразу.
В случае ОС Windows (более поздних версий XP) вы можете установить стандартный драйвер Microsoft .
Для Windows XP вам необходимо установить inf-файл, доступный в Репозитории библиотек LRNDIS .
Шаг 2. Драйвер инициализирует устройство RNDIS. На этом рисунке показан принцип связи с устройством RNDIS (ОС Windows).
Вы можете прочитать об этом больше здесь И там .
Короче говоря, протокол RNDIS — это расширение NDIS для внешних устройств.
Роль протокола заключается в обеспечении поддержки PnP и обмена сетевыми пакетами.
По своей сути RNDIS представляет собой независимый сетевой интерфейс, информационной нагрузкой которого являются кадры канального/сетевого уровня (кадры Ethernet или IP, опционально).
На схеме выше это реализовано кубом «Remote NDIS Miniport», который отвечает за: — услуга связи (запросить у сетевого устройства его MAC-адрес, размер пакета, скорость работы и т. д.) — оборачивает сетевые пакеты, отправленные хостом, в заголовок RNDIS — транслирует пакеты, полученные от устройства, отбрасывая заголовок RNDIS Куб «Remote NDIS USB Miniport» отвечает за транзит посылок RNDIS, работая с драйвером шины USB. На стороне контроллера STM32 файл отвечает за поддержку протокола RNDIS и работу с USB. usbd_rndis_core.c .
Он делает то же самое, что и «куб» хоста «Remote NDIS Miniport» — вклеивает/отклеивает заголовки, а также отвечает на вопросы драйверов.
Он принимает ответы, такие как MAC-адрес и скорость, из файла.
После успешной инициализации RNDIS драйвер Windows создает сетевой интерфейс, который в дальнейшем отображается в «Сетевом центре» и в области индикатора в трее.
Шаг 3. Получение IP-адреса Итак, зачем нам нужен сервис получения динамического адреса? Ээтот сервис называется DHCP (Протокол динамической конфигурации узла).
После того как хост инициализирует наше устройство, он создает сетевой интерфейс.
Сетевой интерфейс (если кто не знает) Сетевой интерфейс — это программный объект, который обеспечивает доступ к ресурсам в физической или виртуальной сети.
Чаще всего каждый сетевой интерфейс хоста соответствует определенному сетевому адаптеру.
Но существует множество других интерфейсов, например, локального шлейфа или интерфейсов, которые взаимодействуют с виртуальной машиной.
В их случае в виде сигнала «от хоста ничего не выходит» — обмен происходит программно.
Каждый сетевой интерфейс хоста должен быть связан хотя бы с одним IP-адресом.
С его помощью «резиденты сети» могут связаться с хостом.
Если несколько сетей адресованы «по проводу» (например, устройства с IP-адресами 10.4.1.хх и 192.168.1.хх), то интерфейсу можно назначить два «персональных» IP-адреса.
Они могут выглядеть так: 10.4.1.151 и 192.168.1.200. Узнать набор сетевых интерфейсов и связанные с ними IP-адреса в ОС Windows можно с помощью команды ipconfig и с помощью ifconfig в ОС Linux. Маска используется для описания сетей/подсетей.
Например, правильное описание сети 10.4.1.xx: сеть 10.4.1.0, маска 255.255.255.0. Или, если 4-байтовый номер маски представить в двоичном виде и посчитать количество ведущих, значение будет равно 24. Тогда сеть можно описать следующим образом: 10.4.1.0/24. Подробнее об этом можно прочитать в соответствующей теме.
Существует две основные стратегии назначения IP-адреса интерфейсу: статический метод (когда пользователь сам назначает адрес интерфейсу) и динамический метод (с использованием службы DHCP).
Последнее заключается в том, что при создании интерфейса на хосте активируется служба DHCP-клиента.
Он начинает отправлять широковещательные пакеты в сеть (конфигурация которой пока не известна) по протоколу UDP , в надежде, что в сети есть DHCP-сервер.
Функция DHCP-сервера вообще и на нашем контроллере в частности — отвечать клиенту.
В ответ контроллер «говорит»: клиент, ты находишься в такой-то сети, держи такой-то IP-адрес, а еще у нас есть DNS-сервер с таким-то адресом.
После этого хост «чувствует себя» гораздо лучше: он присваивает интерфейсу выданный IP-адрес и запоминает IP-адрес DNS-сервера.
Инициализация завершена, теперь вы можете ввести имя страницы (run.stm) в хост-браузере.
Надо сказать, что поведение библиотеки LRNDIS настраиваемо.
Службу DHCP-сервера можно исключить из сборки.
Тогда на хосте вам нужно будет прописать любой адрес, принадлежащий диапазону 192.168.7.(2-254).
Эта сеть создается по умолчанию.
Его параметры (192.168.7.0/24) также настраиваются.
В примере клиенту предоставлены адреса в диапазоне 192.168.7.2… 192.168.7.4 со сроком аренды 24 часа.
Более подробную информацию о настройке библиотеки можно найти в предыдущая статья .
Шаг 4. Загрузка страницы Для загрузки страницы пользователь может ввести адрес нашего устройства 192.168.7.1 напрямую.
Однако запоминать цифры нет необходимости, потому что… Помимо DHCP-сервера, можно собрать библиотеку с поддержкой DNS-сервера, функция которого — разрешение сетевых имен.
В опубликованном примере DNS-сервер обучен разрешать имя ресурса «run.stm».
Поэтому, если вы пишете в браузере run.stm , служба хост-сети отправит запрос на наш (и не только) DNS-сервер, в ответ на который сервер услужливо сообщит: доменное имя «run.stm» соответствует IP-адресу 192.168.7.1 .
Далее хост-браузер по известному адресу выполнит TCP соединение для отправки HTTP запрос на получение корневой страницы.
Запрос и ответ между браузером Firefox и контроллером:
История запросов при загрузке страницы:
Из истории мы видим, что после загрузки корневого HTML-документа браузер также загружает с контроллера еще два файла: Discover.svg и zepto.min.js. Первое — это изображение доски открытий.
Формат SVG был выбран потому, что, являясь векторным графическим изображением, он занимает мало места в ПЗУ микроконтроллера.
Файл сценария zepto.min.js включен, потому что.
является урезанным аналогом известного JQUERY .
Следует отметить, что щепетильной экономии места в ПЗУ не было, т.к.
несмотря на жертвование 35 КБ на все статические ресурсы, памяти контроллера все равно вполне достаточно.
Кроме того, этот размер обещает расти заметно медленнее при дальнейшем усложнении интерфейса.
Если интерфейс значительно разросся, всегда есть способ хранить и обслуживать статические ресурсы в сжатом виде — все известные браузеры в настоящее время поддерживают распаковку «на лету».
Другой запрос, который отправляет браузер, — это запрос /state.cgi. Он генерируется скриптом из корневого HTML-документа с интервалом 5 раз в секунду.
Запрос нужен для получения текущего состояния устройства в динамике.
При получении этого запроса контроллер генерирует и отвечает следующей строкой в JSON формат:
Он содержит все данные о текущем состоянии устройства, которые впоследствии отображаются на странице с помощью кода JavaScript. Ну и, пожалуй, последний момент общения с браузером – это способ управления.{ "systick": 9528746, "button": 0, "acc": [54, -288, 936], "leds": { "g": 0, "o": 0, "r": 0 } }
В примере управляются три светодиода.
Например, когда вы нажимаете на красный светодиодный флаг с помощью JavaScript, отправляется запрос HTTP GET, передавая параметр «r» и значение 0 или 1. Полный запрос выглядит следующим образом: /ctl.cgiЭr=1 Этим или альтернативными способами можно передать любой набор данных, будь то логическое состояние 0/1, или значение текстового поля, или уведомление о нажатии кнопки.
Прелесть подхода в том, что логика программы может вообще не знать об элементах управления, поскольку получает строго формализованные управляющие сообщения.
Также можно изменить и отладить интерфейсную часть (HTML+JS) локально со всеми удобствами, а затем один раз загрузить ее в составе прошивки в контроллер.
Локальную веб-разработку, что также немаловажно, может осуществлять соответствующий специалист. О стеке LWIP Никакой сетевой обмен организовать было бы невозможно, если бы не этот сетевой стек, встроенный в библиотеку.
Поскольку библиотека работает на «голом железе» (без ОС и динамического выделения памяти), надстройка в виде сокетов недоступна для использования.
Поэтому сетевые приложения пишутся с использованием необработанного стека API. К счастью, в Интернете есть много этой темы.
Также в пакет вкладов входит множество готовых решений.
Именно оттуда использовался HTTP-сервер.
В прошлой статье я дал краткое описание стека и его настройки.
На данный момент уточнен набор важных для стека определений в файле: lwipopts.h #define NO_SYS 1
#define MEM_ALIGNMENT 4
#define LWIP_RAW 1
#define LWIP_NETCONN 0
#define LWIP_SOCKET 0
#define LWIP_DHCP 0
#define LWIP_ICMP 1
#define LWIP_UDP 1
#define LWIP_TCP 1
#define ETH_PAD_SIZE 0
#define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67))
#define MEM_SIZE 10000
#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/)
#define TCP_SND_BUF (2 * TCP_MSS)
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
#define LWIP_HTTPD_CGI 1
#define LWIP_HTTPD_SSI 1
#define LWIP_HTTPD_SSI_INCLUDE_TAG 0
Проблема с mem_malloc также решена.
Хотя текущая версия прошивки не использует динамическое размещение, аппаратный сбой при вызове mem_malloc заставил меня насторожиться.
Решено путем добавления определения MEM_ALIGNMENT, которое ранее игнорировалось.
По этой же причине поддерживаемый сообществом HTTP-сервер работал стабильно, что побудило нас отказаться от планов по созданию собственного.
Нерешенные проблемы 1. Нюансы перелицензирования lwip стека, который может иметь свои условия для включения в другой софт; 2. Улучшение DNS-сервера для обработки пакетов «много вопросов»; Вместо заключения Благодарю читателя за терпение и надеюсь, что эта статья окажется ему полезной.
Опубликовано в исходных кодах библиотека ЛРНДИС доступен для использования по лицензии MIT. Я думаю, это замечательно, если работа, на которую вы потратили много времени и сил, оказывается полезной кому-то другому.
В худшем случае без использования открытых библиотек это было бы невозможно.
В настоящее время мы планируем поддержку библиотеки, поэтому по вопросам вы можете обращаться по адресу [email protected]. В опросе могут участвовать только зарегистрированные пользователи.
Войти , Пожалуйста.
Использовали бы вы в своей разработке веб-интерфейс 59,48% Определенно 91 32,68% Возможно 50 1,96% Нет необходимости и возможности 3 5,23% Предпочли бы другую альтернативу 8 0,65% Что это? Проголосовало 1 153 пользователя.
22 пользователя воздержались.
Теги: #rndis #stm32f4 #stm32f4discovery #модем #http-сервер #dns #dhcp #интерфейс #веб-программирование #стандарты #гаджеты и устройства #ethernet #usb #lwip #клиент-сервер #контроллер #встроенные системы #разработка веб-сайтов #C++ #Программирование микроконтроллеров
-
Аутсорсинг Разработки Java В Индии
19 Oct, 24 -
Как Ускорить Работу Windows Vista?
19 Oct, 24 -
Как Поделиться Видео С Другими?
19 Oct, 24 -
Начался Прием Заявок На Домены В Зоне Tel
19 Oct, 24 -
Выпущен Linux Mint 13 «Maya»
19 Oct, 24 -
Youtube Создает Локальные Версии
19 Oct, 24 -
Откуда Берутся Корпоративные Паразиты – 2
19 Oct, 24