![](https://habrastorage.org/getpro/habr/upload_files/272/72c/afe/27272cafe6fcfb907ae8532cd506bd99.jpg)
Здесь представлено продолжение проекта на платформе S7V30 с использованием микроконтроллеров семейства Synergy. В прошлой статье был разработан bootloader с функциями криптозащиты прошивки и SD карты. В данном проекте мы расширяем функциональность нашего бутлодера добавляя в него криптозащищенные каналы связи по Wi-Fi и Bluetooth. Стараемся не делать компромиссов между скоростью и функциональностью. Нам нужно устройство которое могло бы предоставлять услуги точки доступа по Wi-Fi, станции Wi-Fi, периферии Bluetooth LE и централи Bluetooth LE и все это одновременно. Кроме этого мы сделаем резервное подключение к интернету через USB и реализуем виртуальный COM порт через Bluetooth Classic. Сетевой стек должен работать в мульти интерфейсном режиме, то есть каждый из внутренних серверов (FTP, HTTP, Telnet и т.д.) доступен со всех подключенных IP интерфейсов. Управлять будем через минималистичный веб интерфейс с шифрованием TLS 1.3, через него же и апгрейдить прошивку.
Предыдущие статьи по теме
Открытый проект Wi-Fi логгера по USB, CAN, RS-485, RS-232 - здесь первая публикация по модулю предшественнику нашего
Открытый проект встраиваемого модуля для IoT - схема и конструкция первой версии модуля. В текущей версии добавился только чип SPI Flash
Разработка универсального ПЛК для домашних агрегатов - здесь про то, где наш модуль применяется
Как сделать быстрый Wi-Fi для ПЛК - здесь о том, как мы разогнали Wi-Fi в нашем модуле
Архитектура, планирование и реализация DMA в микроконтроллерах Synergy - тут мы погружаемся в технологию быстрой пересылки данных внутри микроконтроллеров.
Делаем начальный загрузчик с криптографической защитой для Synergy на базе Azure RTOS - здесь описана первая версия нашего универсального и защищёного загрузчика.
Установка пароля на SD карту с помощью веб-приложения на jQuery, веб-сервера Azure RTOS и Synergy - а здесь мы нашли нетривиальное приложение для нашего модуля. С помощью него можно залочивать sd-карты. Почти хакерский инструмент.
Упаковка данных
В малых embedded системах всегда является проблемой ограниченный объем внутренней флэш памяти. В нашем устройстве требуется несколько сравнительно больших блоков данных для загрузки в Wi-Fi Bluetooth модуль. Чтобы не использовать внешние чипы памяти или SD карту эти блоки надо помещать во внутреннюю флеш. Чтобы данные занимали меньше места мы применили алгоритм компрессии Sixpack. Этот алгоритм не намного уступает лучшим архиваторам на персональных компьютерах. Благодаря ему мы смогли сжать бинарные загружаемые в модуль файлы в полтора раза.
Чтобы процесс переноса образов загружаемых файлов в исходники проекта на языке си был более простым я создал скрипт на языке Python - Pack_BLOBs.py. Он находится в директории Tools/BLOBs_packer. Результатом работы скрипта являются файлы Infineon_BLOBs.c и Infineon_BLOBs.h, где бинарные данные представлены массивами данных сжатыми алгоритмом Sixpack. Размещение массивов в памяти микроконтроллера фиксированное, и ими может воспользоваться рабочее приложение после того как оно будет прошито загрузчиком. Префикс Infineon файлы имеют потому что все бинарники предназначены для модуля выполненного на чипсете фирмы Infineon.
Модификация веб интерфейса
![Вид экрана с подключённой станцией wi-fi и точкой доступа wi-fi Вид экрана с подключённой станцией wi-fi и точкой доступа wi-fi](https://habrastorage.org/getpro/habr/upload_files/f80/4bb/ce9/f804bbce96d9003bce1e1fe864cb83a0.png)
Появление ChatGPT все изменило. Больше не нужны фреймворки прокладки для работы JScript и DOM моделью HTML страниц. По сути эти фреймворки навязывают нам свой дизайн предлагая якобы упрощённый API. ChatGPT позволяет легко разобраться в дебрях любого API. Теперь мы можем генерировать исходные тексты не опираясь ни на какие вспомогательные библиотеки скриптов и библиотеки стилей. Поэтому от JQuery мы отказываемся. Переходим на чистый JScript. От этого веб сайт нашего устройства становится предельно компактным. Нам больше не нужен внешний носитель для файлов веб интерфейса. Все помещается во внутреннюю флеш память микроконтроллера. Общий объём памяти занимаемый сжатыми файлами страниц, скриптами и стилями составляет всего 14 КБ. Скрипт сжатия всех файлов и генерирования исходника на си для встроенного веб-сервера находится здесь -Tools/WEB_compressor_to_C/Compres_web_files.py
Однако для встроенного сервера по-прежнему доступны файлы и на SD карте. В случае необходимости можно дополнительные страницы, стили, скрипты записать на sd-карту в директорию www.
Небольшой размер HTML страниц обусловлен еще и тем что используется динамическое создание панели настроек. Т.е. панель настроек по началу представляет собой пустой HTML файл. Во время работы браузер получает от дивайса этот файл и JSON файл с полным описанием настроек и на основе этого строит динамическую панель с формами ввода и редактирования.
![](https://habrastorage.org/getpro/habr/upload_files/141/c55/ca3/141c55ca399f405a2f7d2c2e834e80f6.gif)
Для удобства рефакторинга и модификации все страницы созданы как отдельные файлы с использованием техники шаблонизации в среде Adobe Dreamweaver. Исходные материалы можно найти в директории \SDcard_content\www .
Параметризация
Во встроенной EEPROM модуля содержится база данных параметров. База данных создаётся традиционно для наших изделий утилитой EMBPMAN.exe.Она находится в директории /Tools/Parameters_generator. В этой утилите создаются и редактируются параметры, задаются их характеристики и иерархия. Утилита как результат генерирует файл на cи с базой данных встраиваемой в проект. Также утилита может генерировать JSON файл для апгрейда параметров модуля online. Непосредственно файл базы данных на PC находится в файле ParamsDB.mdb Это нативный формат баз данных MS Office. Т.е. параметрами можно манипулировать напрямую в среде MS Access.
![Вид утилиты для создания базы данных с параметрами устройства Вид утилиты для создания базы данных с параметрами устройства](https://habrastorage.org/getpro/habr/upload_files/155/6bf/58e/1556bf58e139271219a5f0f1a7cad839.png)
Как восстановить параметры бутлодера
Бывает приходится экспериментировать с параметрами устройства и нужно откатиться на предыдущий шаг. Чтобы это сделать надо восстановить предыдущую конфигурацию параметров. Для этого следует записать на sd карту JSON файл с желаемый конфигурацией. Файл JSON можно подготовить с помощью программной утилиты EMBPMAN.exe. Это та же утилита с помощью которой создаются сами параметры. Файл должен иметь название BSettins.JSON и быть записанным в корневую директорию SD карты. После запуска бутлодера он считывает данные из этого файла и в случае успеха парсинга и записи во флеш стирает файл. Параметры устройства хранятся во внутренней eeprom микроконтроллера в 2 дублирующих друг друга областях защищенных CRC32 кодом для детекции случайных искажений.
Кроме того файл настроек можно создать из меню терминала бутлодера. Файл будет иметь название PSettins.json. Чтобы он вступил в действие его надо переименовать в BSettins.JSON.
Создание сертификатов для TLS 1.3
Применение современного стандарта шифрования cетевого трафика TLS 1.3 требует использование сертификатов на основе эллиптических кривых. Прежде применявшийся в загрузчике алгоритм RSA для TLS 1.2 здесь не подходит.
В пакете программного обеспечения Synergy поддерживается аппаратный алгоритм шифрования на основе эллиптических кривых. Но только для одного типа кривой - secp256r1. Чтобы не возникло проблем в сертификате для веб сервера устройства я создал командный скрипт - Tools/WEB_Сertificate_generation_with_EC_key/Certificates_generator.cmd. Там же находится конфигурационный файл для этого скрипта. Результатом работы скрипта являются секретные ключи и сертификаты для клиента и сервера. Клиентом в данном случае будет выступать браузер пользователя PC. Сертификат сервера записывается во флеш память устройства. Для облегчения задачи конвертации сертификатов в массивы на языке си был создан скрипт на языке Python - Converter_to_C.py. В результате работы скрипта появляются файлы: WEB_server_certificate.c, WEB_server_certificate.h. Их нужно добавить в директорию веб сервера. Эти файлы компилируются вместе с проектом.
Чтобы браузеры на компьютере пользователя не выдавали предупреждения о некорректном сертификате веб сервера нужно импортировать сгенерированный сертификат клиента CA.crt в перечень корневых сертификатов компьютера. Благодаря корневому сертификату клиента браузеры могут устанавливать зашифрованную защищенную связь с устройством. Обычно для каждого устройства генерируется уникальный сертификат сервера на базе единого корневого сертификата. Поэтому браузеры способны идентифицировать каждого клиента отдельно и компрометация сертификата сервера не ведет к компрометации всех аналогичных устройств.
Важное обстоятельство. В конфигурации для генерации сертификата сервера должны присутствовать правильные DNS и IP адреса, по которым будут обращаться к устройству.
Например такие:
[ alternate_names ]
DNS.1 = localhost
DNS.2 = S7V30
IP.1 = 192.168.137.1
IP.2 = 192.168.1.1
Иначе даже если корневой самоподписанный сертификат буде импортирован в систему броузера веб сайт устройства все равно будет обозначен как небезопасный.
Например, допустим в настройках дивайса имя хоста будет установлено как S7V3 и сервис mDNS после подключения распространит его по сети. Тогда браузер обратившись по имени S7V3 сможет открыть страницу на устройстве, но она будет отмечена как небезопасная. Чтобы она принималась как безопасная имя хоста должно быть S7V30, т.е. соответствовать прописаному в примере выше в конфигурации сертификата.
Ну и конечно, корневой сертификат CA.crt является секретом и должен передаваться через надёжные защищенные каналы.
Маршрутизация
Стек интернет-протоколов NetX Duo в составе операционной системы реального времени Azure RTOS имеет два механизмов маршрутизации.
Первый механизм заключается в установке прямых маршрутов от одного интерфейса к другому с помощью функции API nx_ip_static_route_add и nx_ip_static_route_delete.
Во втором случае используется NAT (Network Address Translation) сервер. NAT сервер позволяет по одному внешнему IP адресу обращаться к множеству узлов внутренней сети. С помощью NATсервера мы можем организовать прямой доступ из интернета к каждому индивидуальному узлу во внутренней сети обслуживаемой нашим устройством. Внутренняя сеть может быть организована либо через USB CDC ECM Host интерфейс, либо через интерфейс WiFi точки доступа. При этом каждое устройство должно иметь уникальный номер порта в пределах внутренней сети, по которому к нему будет осуществляться обращение.
Важным условием работы NAT сервера в NetX Duo является необходимость размещения всех интерфейсов в рамках одной IP структуры имеющий тип NX_IP. Сколько разных интерфейсов может поддерживать структура NX_IP конфигурируется при компиляции стека.
Если создавать интерфейсы на разных IP структурах, то тогда между ними не будет работать прямая маршрутизация и NAT сервер. Эти подсети будут абсолютно изолированы друг от друга. Что тоже бывает полезно.
Портирование Bluetooth стека
Поскольку мы применяем модуль на чипе фирмы Infineon то для организации Bluetooth стека мы взяти библиотеку BTSTACK Library. Библиотека выложена в виде заранее скомпилированных библиотечных файлов. Их много для разных платформ. Наш вариант лежит здесь. Это библиотека для компилятора IAR под микропроцессорное ядро ARM Cortex M4 с аппаратным float-point сопроцессором. Dual Mode здесь означает, что библиотека поддерживает и старый Bluetooth Classic и новый Bluetooth LE
Но одной библиотеки недостаточно, кроме неё нужны патчи для конкретного модуля и чипа. Патчи берём отсюда. Наш модуль серии LWB5+ с идентификатором 453-00045R. Это модуль с одной встроенной антенной без диверсификации антенн. Значит нам подходит архив с названием laird-lwb5plus-sdio-sa-firmware-11.171.0.24.tar.bz2 . Модули также могут быть реализованы с диверсификацией двух внешних антенн или с реализацией протокола m2m или USB. Поэтому надо проявлять внимательность при выборе прошивки.
Библиотека от Infineon требует портирования на операционную систему реального времени. Портирование предполагает реализацию около десятка функций использующих сервисы операционной системы включая мьютиксы, флаги, операции выделения динамической памяти. Infineon предоставляет отдельную библиотеку облегчающую портирование - btstack-integration.
Большинство примеров портирования реализованы для операционной системы FreeRTOS. Можно найти редкие примеры портирования на RTOS ThreadX. RTOS ThreadX - прямой предок Azure RTOS. Всё крайне сомнительного качества.
В рамках интеграции WiFi и Bluetooth стеков от Infineon мне пришлось полностью переписать слой портирования на Azure RTOS. Драйвера были значительно модифицированы и ускоренна их работа. Для связи по UART с модулем используются механизм DMA. Скорость связи равна 4 мб/с. Bluetooth и Wi-Fi работают в модуле одновременно и в нём есть специальный механизм предотвращающий конфликты этих двух протоколов. Слой портирования снабжён отладочным выводом в канал RTT через адаптер SWD интерфейса. Включение или отключение отладочного вывода управляется макросом во время компиляции. Так же и есть вывод диагностических сообщений в лог файл сохраняемый на sd-карту. Он также управляется макросом.
![](https://habrastorage.org/getpro/habr/upload_files/d5e/2a6/5de/d5e2a65defe611809651b0d401f716e5.png)
Так как у нас библиотека Dual mode, то компьютеры при сканировании эфира будут видеть наш модуль как два разных устройства. Для коммуникации с модулем достаточно выполнить связывание с одним из них. Чтобы связывание прошло успешно надо нажать перед его выполнением кнопку BT3 на модуле. Модуль запоминает связанных клиентов и при последующих подключениях связывания повторять не надо.
![Расположение кнопки BT3 Расположение кнопки BT3](https://habrastorage.org/getpro/habr/upload_files/2de/50f/85b/2de50f85b247cd6edc8da2f4566d9c7c.png)
Конфигурирование Bluetooth стека
После того как стек портирован и начал свою работу на нашем микроконтроллере ему нужно придать полезные функции. Полезные функции задаются базой данных специального формата. В современном Bluetooth стеке не принято просто брать и передавать данные в эфир. Так было принято в ранних версиях в частности в виртуальном COM порте. Теперь любые данные пересылаемые по bluetooth имеют заранее определённые смысл, тип, особенности доступа к себе и уникальный длинный идентификатор. Зато не надо беспокоиться об упаковке и валидности данных, оформлять их в пакеты или прочие артефакты. Но надо беспокоиться об идентификаторах переменных, номерах каналов, кодах операций и аутентификации данных. Кроме того все операции становятся асинхронными. Словом всё усложнилось во имя интероперабельности. Поэтому просто так вручную организовать данные для обмена по Bluetooth не удастся. Для этого применяются специальные инструменты - генераторы баз данных. Печальнее всего что формат этих баз для Bluetooth стеков разных производителей серьёзно отличается.
В нашем случае мы используем инструменты от Infineon. Отдельно генератор базы данных Bluetooth не поставляется. Нужно скачивать весь пакет ModusToolbox. В его составе будет утилита bt-configurator.exe. Путь к ней будет выглядеть приблизительно так: C:\Users\<user name>\ModusToolbox\tools_3.2\bt-configurator\bt-configurator.exe
Утилита поддерживает генерацию для нескольких типов чипов с разными возможностями. Тут надо не ошибиться с выбором типа. Для облегчения задачи мной создан уже готовый файл конфигурации для этой утилиты - Infineon_BLE_config.cybt. Если его открыть в утилите, то нужный тип чипа будет выбран автоматически. Чтобы было ещё легче я создал ссылку bt-configurator.lnk
![Открывая утилиту по ссылке bt-configurator.lnk увидим такое окно Открывая утилиту по ссылке bt-configurator.lnk увидим такое окно](https://habrastorage.org/getpro/habr/upload_files/c83/82e/7a1/c8382e7a179fd324782874f9fa15366b.png)
Для создания профилей к современному Bluetooth 5 используем вкладку GATT Settings
![](https://habrastorage.org/getpro/habr/upload_files/a5f/d64/d47/a5fd64d47c4e178b36f608698a5bde8a.png)
Для создания виртуального COM порта под Bluetooth Classic используем вкладку Service Discovery Settings:
![](https://habrastorage.org/getpro/habr/upload_files/619/22b/44d/61922b44de2ecae5919f59f5e55ee1f0.png)
Не забываем настраивать служебные протоколы L2CAP, PSM, BR/EDR ERTM:
![](https://habrastorage.org/getpro/habr/upload_files/944/ee2/2a7/944ee22a7ac4db8a50afca826ecc815c.png)
Результатом работы утилиты будет создание директории GeneratedSource с файлами базы данных. Эти файлы будут перезаписываться всякий раз при закрытии утилиты и их редактироватьне стоит.
В данном случае я создал кастомный сервис для управления реквизитами подключения Wi-Fi станции к точке доступа.
Приложения для работы через Bluetooth
Infineon предлагает приложение для Android и iOS - AIROC™ Bluetooth® Connect App. Исходники для Android лежат тут. Приложение интересно прежде всего открытостью своих исходников. Легко модифицируются и без проблем компилируется в Android Studio. Но ему не хватает некоторых отладочных свойств.
Поскольку современные стандарт Bluetooth LE отличается своей уникальной интер-операбельностью, то для работы с нашим модулем подходят приложения любых производителей. Для более тонкой отладки взаимодействия по Bluetooth я бы рекомендовал программу nRF Connect, которая есть в исполнении как для десктопов, так и для мобильных устройств. Там можно смотреть подробные логи обмена данными и битовые поля важных структур.
Теперь попробуем со всем этим взлететь. Настройка приоритетов задач.
Немаловажным делом является настройка приоритетов задач. От того насколько правильно выставлены приоритеты задач может зависеть производительность всей системы и даже риск её зависания. Дело усложняет то что во многих сторонних библиотеках организуются задачи с приоритетами установленными по своим внутренним соображениям. Они не согласуются с порядком принятым в целом в приложении. Такая ситуация часто вынуждает прибегать к редактированию исходников сторонних библиотек.
Что касается операционной системы Azure RTOS, то в ней приоритеты задач задаются в .h файлах пользовательских конфигураций. Там их можно просто стереть чтобы не мешали.
В библиотеках от Infineon придётся тоже кое-что подправить чтобы убрать объявление приоритетов в неподходящих местах.
Я организовал централизованное объявление всех приоритетов в одном заголовочном файле thread_priorities.h. Центральной идеей является то, что задачи основного приложения должны иметь приоритет выше всех остальных вспомогательных и коммуникационных задач. Каким образом соблюдается требование жёсткого реального времени для критических задач модуля.
Вот что получается в результате:
![Список активных задач с их приоритетами в отладчике IAR Список активных задач с их приоритетами в отладчике IAR](https://habrastorage.org/getpro/habr/upload_files/0f7/4ae/bfb/0f74aebfb94a4efdcff6172ea4170384.png)
Весь проект здесь
Комментарии (5)
ColdPhoenix
12.08.2024 12:51+4Больше не нужны фреймворки прокладки для работы JScript и DOM моделью HTML страниц.
<ЗанудаMode>
JScript и JavaScript это разные вещи. Если лень писать полностью все же пишут JS.
</ЗанудаMode>
viordash
Скажите пжлст, а есть ли повторяемость кода и дизайна страниц при повторных запросах chatGPT? Т.е. если вам нужно расширить или изменить функционал, то как я понял вам придется весь код сайта заново генерировать, наврятли чистый html+js легко поддерживать, раз нет библиотек и\или фреймворков.
gsaw
Да программисты-человеки тоже два раза подряд одинаковый код не пишут. Искусство же.
Если надо расширить функционал, выбираешь нужный участок кода и говоришь, что тут надо добавить функционал и Chat GPT генерирует дельту. Так даже лучше выходит, чем заново объяснять все человеческим языком + новые изменения. Все эти модели редко сразу генерируют рабочий код. Либо править самому приходится, либо уточнять.
Все как и с кожаными мешками. Сначала пишут код, потом месяцами правят понаписанное.
viordash
фреймворки и библиотеки как раз таки позволяют не править месяцами.
Также интересно, подход с чатГПТ позволит ли поддерживать продукт в долгую? Мне кажется на второй-третьей добавляемой фиче возникнет мысль переписать на чтото стандартное.
devprodest
Наврядли там чистый js и HTML, скорее куча плохопонимаемого кода, который если написать руками будет сильно меньше.