Эта статья создавалась как перевод поста (который почему-то больше не доступен) из блога The Qt Company для публикации на Хабре. Но НЛО сказало, что статья рекламная, и опубликовать не дало.

Qt on MCU

Я бы не сказал, что это рекламная статья, хотя в ней действительно есть ссылки вида “свяжитесь с нашими консультантами” и там и сям упоминается коммерческая лицензия. Как бы то ни было, на Хабре статья так и не вышла, но вот теперь спустя четыре года (лучше поздно, чем никогда) выходит здесь.

This article in english 🇺🇸.

Нас часто спрашивают, можно ли использовать Qt для разработки ПО (в основном, GUI) для микроконтроллеров, и может ли Qt вообще работать без операционной системы (так называемый, bare metal). Сегодня мы ответим на эти вопросы и посмотрим конкретные примеры.

Зачем нужны микроконтроллеры

Микроконтроллер - это миниатюрный компьютер, построенный на одной микросхеме (кристалле), которая содержит на себе все основные элементы “больших” компьютеров: процессор, память, устройства ввода-вывода и другие периферийные устройства. Предназначение микроконтроллеров - выполнение простых задач, не требующих больших вычислительных мощностей.

Из определения уже видны отличительные особенности микроконтроллеров: малые габаритные размеры, низкое энергопотребление и очевидно невысокая стоимость.

Так что основной причиной использования микроконтроллеров можно назвать вполне понятное желание сэкономить на себестоимости продукта.

Зачем использовать Qt на микроконтроллерах

Малые вычислительные мощности микроконтроллеров накладывают ограничения на выбор инструментов разработки, особенно если речь идёт о GUI: размер прошивки, объём оперативной памяти, требуемой для выполнения программы, а также насколько “привлекательным” может быть GUI.

В процессе поиска таковых инструментов довольно быстро выясняется, что не существует какой-то одной универсальной графической библиотеки. Вместо этого есть большое количество разрозненных простеньких библиотек, которые зачастую “заточены” под определённую модель микроконтроллера. Компании-разработчики таких библиотек редко задумываются о кроссплатформенности, а в итоге страдает сначала разработчик ПО, а затем и заказчик этого ПО.

Некоторые фреймворки действительно неплохо справляются с задачей, но зачастую они имеют собственный рантайм с закрытым исходным кодом, то есть вы приобретаете чёрный ящик с неизвестным содержимым, в результате чего оказываетесь завязаны на этого поставщика.

Как бы было хорошо, если бы на микроконтроллерах можно было использовать такой фреймворк как Qt - кросcплатформенный, с обширной библиотекой классов, включая GUI, с отличной документацией и массой примеров, с большим сообществом разработчиков и открытым исходным кодом.

Однако в силу упомянутых ограниченных аппаратных ресурсов микроконтроллеров, до сегодняшнего дня Qt, если говорить о разработке для embedded платформ (Qt for Device Creation), официально поддерживал только железо уровня Cortex-A, в основном под управлением Linux и некоторых коммерческих RTOS (INTEGRITY, QNX и VxWorks).

Но сегодня ситуация несколько изменилась.

Исследование

Исходные данные

Итак, была поставлена задача исследовать возможности портирования Qt на аппаратную платформу уровня микроконтроллеров.

Сразу же определим, о каких именно микроконтроллерах пойдёт речь, потому что некоторые возможно уже размечтались о моделях с 12 MHz CPU и 128 bytes RAM.

В настоящий момент “официальными” системными требованиями для работы Qt на том или ином устройстве являются следующие:

  • 256 MB of RAM;
  • 500 MHz CPU (желательно 1 GHz);
  • поддержка OpenGL ES 2.0.

…что совсем не похоже на уровень возможностей микроконтроллеров.

Однако, благодаря новой системе конфигурации Qt (больше известной как Qt Lite) и ряду оптимизаций в кодовой базе, системные требования удалось понизить. Настоящее исследование проводилось на следующих моделях:

STM32F469
STM32F469 - ARM Cortex-M4, FPU unit single precision.
STM32F746
STM32F746 - ARM Cortex-M7, FPU unit single precision, L1 Cache (Data/Instruction).
STM32F769
STM32F769 - ARM Cortex-M7, FPU unit double precision, L1 Cache (Data/Instruction).

Что касается требования поддержки OpenGL, то благодаря Qt Quick 2D Renderer это требование не является обязательным.

В число первых модулей Qt для портирования вошли:

Портирование

Как вообще осуществляется портирование Qt на ту или иную платформу? Для начала нужно понять, что именно Qt требует для работы. И в основном, это две вещи:

  • POSIX-совместимая операционная система;
  • наличие C++11-совместимого компилятора.

Начнём с требования наличия C++11 совместимого компилятора. Оно относится к версиям Qt старше 5.6, так как для поддержи новых возможностей C++ с версии Qt 5.7 требует поддержки стандарта C++11. Но если по тем или иным причинам ваша платформа поддерживает только C++98, то вы можете взять Qt 5.6 (или младше). Однако в этом случае, вы не сможете воспользоваться возможностями Qt Lite, так как он появился только в Qt 5.8, то есть вам будет труднее втиснуть Qt в микроконтроллерную среду.

Теперь о POSIX. Вот это, собственно, и есть ответ на вопрос, может ли Qt работать без операционной системы на голом железе прямо из коробки. Внутри Qt используется много POSIX функционала (pthreads, mmap, fopen, open и т.д.), поэтому если мы хотим запуститься на голом железе, то придётся реализовывать эти функции самостоятельно, то есть фактически написать собственную операционную систему. К счастью, в нашем исследовании такой задачи не стояло.

Так как из операционных систем реального времени официально Qt поддерживает только коммерческие, то для поддержания баланса мы решили взять какую-нибудь из Open Source. И выбор пал на RTEMS, к достоинствам которой можно отнести следующее:

  • простота;
  • поддержка POSIX;
  • поддержка различных файловых систем, включая NFS и FAT;
  • уже есть порт TCP/IP стека из FreeBSD;
  • поддержка C++11;
  • Open Source лицензия (модифицированная GPL);
  • активное сообщество.

Процесс портирования включает в себя следующие шаги:

  1. “Запустить” плату: настроить тактовую частоту, инициализировать память, периферию и т.д;
  2. Портировать операционную систему RTEMS на STM32F4/F7 (подготовить BSP);
  3. Портировать Qt под RTEMS:
    • Добавить поддержку в Qt Core;
    • Написать новый QPA плагин.

Схематично портирование самого Qt можно представить так:

Porting Qt

Подробное описание всего процесса, начиная с “запуска” платы и заканчивая реализацией нового QPA, мы оставим за кадром. Понимаем ваше разочарование, но целью статьи было лишь рассказать об исследовании.

Теперь давайте посмотрим на результаты.

Результаты

Для демонстрации результатов были подготовлены три прошивки с разными приложения для запуска на каждой из трёх плат.

If video doesn't play in your browser, you can download it here.

Qt Widgets demo

  • размер прошивки: 6.6 MB
  • потребление памяти: 3.4 MB

Видео (изначально было опубликовано в YouTube, но The Qt Company убрала его в приватные, хорошо что остался оригинал):

If video doesn't play in your browser, you can download it here.

Как видим, виджеты работают без проблем (если не обращать внимание на плохенькую отзывчивость/чувствительность тачскрина).

Qt Quick demo

  • размер прошивки: 9 MB
  • потребление памяти: 5 MB

Видео (изначально было опубликовано в YouTube, но The Qt Company убрала его в приватные, хорошо что остался оригинал):

If video doesn't play in your browser, you can download it here.

Можно заметить, что на STM32F4/F746 эффект перетаскивания в Qt Quick подтормаживает. Такое поведение является наглядным примером отсутствия JIT компиляции, так как на этих MCU нет поддержки операций double-precision floating-point. А вот на STM32F769 поддержка таких операций присутствует, и потому анимация эффекта отрабатывает гораздо лучше.

Далее мы попробуем задействовать Qt Quick Compiler (как “старый”, так и “новый”, и сравним результаты), потому что в теории он должен помочь с производительностью в условиях отсутствия JIT на платформе.

E-bike demo

Мы решили не останавливаться на простых примерах и попробовать запустить в третьей прошивке что-то более интересное, например недавнее демо E-bike.

  • размер прошивки: 13 MB
  • потребление памяти: 10 MB

Видео (изначально было опубликовано в YouTube, но The Qt Company убрала его в приватные, хорошо что остался оригинал):

If video doesn't play in your browser, you can download it here.

Демо завелось и вполне себе работает. Кстати говоря, без единой модификации в исходниках (оригинальный проект был под Linux) - спасибо кроссплатформенности Qt.

Заключение

Исследование можно считать успешным. Конечно, до готового решения “из коробки” ему ещё далеко, но работа будет продолжаться.

Из текущих задач:

  • портирование большего количества модулей Qt, в первую очередь - библиотеки из состава Qt for Automation;
  • оптимизация порта и улучшение производительности. К примеру, на каждой из плат есть некое подобие графического ускорителя, который мы ещё не задействовали;
  • доработка конфигурационной системы (Qt Lite);
  • добавление поддержки в Qt Creator.

Что данное исследование означает для вас, как вы можете использовать его в своих проектах:

  1. Исходники QPA и другие модификации кодовой базы Qt будут опубликованы в Open Source (скорее всего, под GPLv3), и разумеется будут доступны в коммерческой лицензии тоже;
  2. Мы планируем предоставлять сервисные услуги по подготовке готового образа системы и портированию Qt для вашей платформы на основе MCU.

Следите за нашими новостями и публикациями в блоге.

Кстати, скоро будет вебинар как раз на эту тему. Вебинар по этой ссылке тоже больше не доступен, но зато есть его запись (~24 MB):

If video doesn't play in your browser, you can download it here.