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

В нашем полифункциональном заряднике есть небольшой графический дисплей. Разберём что тут можно подобрать.  

На слуху теперь четыре движка для малых встраиваемых систем:

С этой четверкой разом или по отдельности можно встретиться на многих отладочных платах известных производителей микроконтроллеров: STMicroelectronics, NXP, Infineon, Renesas  и прочих. Безусловно есть и другие движки. Но они не так ярко представлены на рынке популярных отладочных плат. 

Первые два движка  не совсем открыты, но имеют версии для свободного использования. В состав ПО всех движков входят приложения для визуального дизайна форм и конфигурирования интерактивного взаимодействия экранных элементов. И все визуальные редакторы умеют генерировать исходные тексты на С или С++ для целевых платформ.  

Исходные предпочтения

В нашем полифункциональном заряднике применяется дисплей 240x240 пикселей с собственной экранной памятью на чипе Sitronix ST7789VW с SPI интерфейсом. Снаружи память дисплея доступна только на запись. В таких случая требуется собственный экранный буфер внутри микроконтроллера для создания сколько-нибудь привлекательного дизайна. Но в  микроконтроллере не так много RAM. Весь экранный буфер занимает целых 115200 байт (если использовать кодирование цвета RGB565)  или 172800 байт (если использовать кодирование цвета RGB888).

Отсюда проистекает ряд пожеланий к GUI. 

Во-первых, нужна концепция фрагментированного фреймбуфера, как на рисунке ниже. Единого названия этой концепции нет, в каждой GUI это называют по разному. В Embedded Wizard это назвали Scratch-pad buffer. В Segger emWin это называется Banding. В TouchGFX это назвали partial framebuffer. В Azure RTOS GUIX такой концепции нет, её должен реализовать драйвер дисплея. 

Суть проста. Экран во внутренней RAM микроконтроллера формируется частями или полосами, а не целиком, как обычно это делается. Полностью прорисован полосу экрана  GUI пересылает её  в дисплей по нужному адресу и начинает рисовать следующую полосу. Весь экран прорисовывается и пересылается на дисплей за несколько итераций. Так в несколько раз экономится память микроконтроллера. При быстрой анимации такой способ приводит к некоторому мерцанию экрана, но, например, динамическая смена цифр с частотой 10 и менее Герц смотрится удовлетворительно. 

Во-вторых, желательно иметь растровые шрифты малого размера: 10x8, 8x6, 6x4 пикселей. Хочется как можно больше информации выводить на дисплей.  Все же зарядник - это не потребительский гаджет, тут чем больше диагностики на экране тем лучше.  Движок GUI должен иметь механизм интеграции сторонних растровых шрифтов без необходимости конвертации их из векторных форматов.  

Сравнение движков.

Segger emWin

Приложение для создания экранов называется AppWizard. Есть более старый инструмент GUI Builder.

Ниже дан обзор бесплатной версии AppWizard и библиотек. В коммерческой версии некоторых перечисленных недостатков нет.

Вид экрана графического дизайнера
Вид экрана графического дизайнера

Плюсы:

  • Богатый набор виджетов. Включает QR код, таблицы, экранную клавиатуру и т.д. 

  • Конвертер шрифтов TrueType (.ttf),OpenType (.otf) выполняют управляемый антиалиасинг на 2 или 4 пиксела.

  • Не требуется RTOS, нужен только сервис тактов времени.  

  • Широкий набор кодировок цвета. От монохромного однобитного и до 32-битного. 

  • Встроенный симулятор и возможность генерации проекта для симуляции в MS Visual Studio. 

  • Наличие специального отладчика для GUI под названием AppWizard SPY. Отладчик позволяет наблюдать характеристики всех графических объектов в системе, событий и потребляемых GUI ресурсов в реальном времени. 

  • Поддержка мультиязычности, реализуемая менеджером наборов строк на разных языках.  

  • Много встроенных сценариев анимации графических объектов

  • Есть шрифты малого размера, вплоть до 4x6, но они доступны только через более старый инструмент GUIBuilder в составе STemWin Library.  

  • Кодогенерация производится в язык С.

  • Есть бинарные библиотеки GUI для  сред разработки IAR Embedded Workbench, Keil MDK-ARM, GCC в составе STemWin Library

  • Есть драйвер GUIDRV_FlexColor для серии контроллеров дисплея Sitronix ST77xx в составе STemWin Library (но конкретно для ST7789VW драйвера нет).

Минусы:

  • Нет исходников библиотек GUI.

  • Не выполняется сборка симулятора в Visual Studio 2022. Требуется более старые версии не новее VS2017. 

  • Встроенный симулятор для некоторых примеров с динамическим поведением некорректно работает.

  • В AppWizard очень маленький набор встроенных фонтов. Нет встроенных растровых шрифтов малого размера. Нет виджета для построения графиков. Нет поддержки проигрывания видеофайлов. Нет готовых драйверов для  различных типов интерфейсов дисплеев. В частности с интерфейсом SPI.

  • Нет поддержки аппаратных ускорителей специфичных для платформы STM32

  • Требует сервисы файловой системы emFile для больших по объёму ресурсов 

  • Реализация интерактивности вынуждает применять пользовательский код на C  в среде AppWizard. Такой код находящийся не в контексте общей кодовой базы приложения запутывает и затрудняет отладку. 

  • Хотя RTOS и не требует, но вставляет артефакты embOS при кодогенерации под наличествующие BSP для платформы STM32. 

  • Посредственное качество дизайна демо примеров. 

  • Нет возможности сгенерировать проект под заданную среду разработки (IAR Embedded Workbench, Keil MDK-ARM, GCC …). Надо вручную собирать файлы и создавать воркспейс для сред разработки.   

Embedded Wizard

Приложение для создания экранов называется - Embedded Wizard, текущая версия - 11. 

Вид экрана графического дизайнера
Вид экрана графического дизайнера

В наборе демо примеров нашёлся даже проект близкий по теме, а именно экран блока питания. Правда он выполнен почему-то в винтажном стиле старых SCADA, что вызывает лёгкие подозрения в юзабельности такого GUI. Но на самом деле там есть и более модные виджеты.

Демонстрационный проект
Демонстрационный проект

Пользователя в Embedded Wizard подстерегает некая инновационная компонентная модель пользовательского интерфейса выражаемая в непропорционально больших панелях настроек с размещёнными на них компонентами. Что-то здесь напоминает старый добрый RAD Studio. 

Вид окна компонентов в графическом дизайнере
Вид окна компонентов в графическом дизайнере

Ниже дан обзор бесплатной версии. В коммерческой версии некоторых перечисленных недостатков нет. 

Плюсы:

  • Набор виджетов разнообразный. Включает графики и диаграммы. (QR кода нет)

  • Реализация иерархической компонентной модели, которая упрощает реюзинг созданных фрагментов графического интерфейса.  

  • Встроенные эффекты анимации.

  • Автогенерация симулятора под Windows 11. Без проблем компилируется в Visual Studio 2022 и выполняется. 

  • Есть встроенный быстрый симулятор запускаемый сразу в среде Embedded Wizard

  • Наличие специального отладчика для GUI. Отладчик позволяет наблюдать характеристики всех графических объектов в системе, событий и потребляемых GUI ресурсов в реальном времени. 

  • Не требует RTOS.

  • Наличие библиотеки открытых графические ресурсов: пиктограмм, рамок, кнопок…

  • Поддержка мультиязычности реализуемая менеджером наборов строк на разных языках. Поддержка UNICODE и BIDI.

  • Поддержка мультитач и жестов на сенсорных экранах. Правда тут не ясно с драйверами. 

  • Есть некоторая поддержка графических акселераторов на аппаратных платформах. В частности STM DMA2D.

  • Есть диагностические функции для наблюдения за расходом памяти

  • Кодогенерация производится в язык С и JavaScript (для приложений работающих в браузере). Да, можно создавать интерфейсы для страниц встраиваемых WEB серверов.

Минусы:

  • Нет исходников библиотек GUI.

  • Мало вариантов кодирования цвета, нет монохрома с одним битом на пиксел.

  • Нет встроенных растровых шрифтов малого размера. Интеграция своих растровых шрифтов невозможна.  

  • Интерактивность виджетов и связь между виджетами программируется на специфическом языке Chora, который придётся дополнительно изучать.  

  • Не умеет генерировать воркспейс для IAR Embedded Workbench, Keil MDK-ARM и др. Создаёт только make файл.

  • Готовые воркспейсы и драйвера под дисплеи поставляются с определенными отладочными платами. Для тестов использовалась плата STM32H747I-DISCO.

  • Нет описания процедуры создания собственных драйверов для дисплеев.

  • Нет драйверов для Sitronix ST7789VW. 

TouchGFX

Приложение для создания экранов называется TouchGFX Designer. Это GUI позиционируется как исключительно заточенное под микроконтроллеры семейства STM32. Может быть скачано отдельно, а можно скачать и из среды STM32CubeMX. В любом случае придётся покопаться по директориям чтобы найти инсталлятор  TouchGFX-4.19.1.msi 

Далее, уже в дизайнере можем увидеть такое окно для одного из демо-проектов:  

Вид экрана графического дизайнера
Вид экрана графического дизайнера

Плюсы:

  • Интеграция со кодогенератором STM32CubeMX, в котором есть возможность сконфигурировать всю среду исполнения GUI на платформе любого микроконтроллера семейства STM32, включая инициализацию периферии, RTOS и промежуточное ПО  

  • Полная поддержка средств ускорения построения и вывода графики семейства STM32 таких как: Chrom-ART, JPEG Hardware Codec, Chrom-GRC, MDMA и т.д.

  • Реализация иерархической компонентной модели, которая упрощает реюзинг созданных фрагментов графического интерфейса.  

  • Автогенерация симулятора под Windows 11. Без проблем компилируется в Visual Studio 2022 и выполняется. 

  • Не требует RTOS.

  • Возможность декодирования и вывода на дисплей до 4 видеопотоков MJPEG одновременно. MJPEG поток читается из .avi файлов. В качестве конвертера обычного видео в MJPEG можно использовать пакет FFMPEG.

  • Несколько анимационных эффектов без необходимости написания скриптов.

  • Многоязычность GUI. Предусмотрен удобный механизм выполнения перевода текстов на другие языки с помощью внешних инструментов.  

  • Встроенный конвертер шрифтов TrueType (.ttf),OpenType (.otf), Glyph Bitmap Distribution Format (.bdf) 

  • Есть бинарные библиотеки GUI для  сред разработки IAR Embedded Workbench, Keil MDK-ARM, TrueSTUDIO, STM32CubeIDE и возможность генерации ворспейсов для этих IDE из STM32CubeMX 

  • Большое разнообразие демонстрационных проектов.

  • Присутствует драйвер контроллера дисплея ST7789  в некоторых проектах с TouchGFX. 

Минусы

  • Нет исходников библиотек GUI. 

  • Набор виджетов весьма ограничен. Нет QR кодов, нет представления таблиц,  нет экранных клавиатур, многие виджеты не масштабируются и не помещаются на экран 240x240.  

  • Встроенных растровых шрифтов малого размера нет. Интеграция своих растровых шрифтов невозможна.  

  • Нет средств отладки и просмотра объектов и ресурсов GUI в реальном времени.

  • Видеофайлы линкуются в прямо-адресуемую память, проигрывать видео с SD  карты не предусматривается.

  • Интерфейс дизайнера неудобен. Некорректно работает Undo. Работа со шрифтами реализована плохо.

  • В дизайнере нельзя создать эффекты размытия, тени, свечения и проч. Можно только лишь изменить прозрачность графических элементов. Для простейших примитивов типа линий, окружностей  и многоугольников доступно изменение размеров.   

  • Жёсткая привязка к семейству STM32 с помощью проверки аутентичности по наличию аппаратных особенностей чипов.     

Практика использования TouchGFX

Поскольку TouchGFX обещает быстрый и бесшовный процесс создания готового приложения с GUI, то сразу попробуем это сделать. 

Запускаем STM32CubeMX. Там конфигурируем порты микроконтроллера и активируем нужную периферию. Уже сейчас начинают появляться ошибки. Некоторые опции периферии в  STM32CubeMX остаются непонятными (никто же не предупредил, что даташит все равно надо читать от корки до корки), часть периферии явно остается не до конца инициализированной. Пока можно это игнорировать, главное запустить картинку на дисплее.

Выбираем в меню Software Packs нужные компоненты. Это будут TouchGFX Generator  и RTOS ThreadX, поскольку без RTOS  в полифункциональном заряднике делать нечего.   

Далее конфигурируем генератор TouchGFX в диалоговой панели STM32CubeMX. 

Здесь, как и было обещано, находим возможность использования частичного фреймбуфера. Разбиваем его на 3 блока по 5000 байт. В итоге на весь фреймбуфер уйдет только 15000 байт вместо 115200.  

Однако назначить в качестве интерфейса SPI  и выбрать драйвер для ST7789 тут не получится. Таких опций нет.

Что же, генерируем код из того что есть.  Указываем в качестве Toolchain/IDE нашу среду разработка EWARM. Нажимаем GENERATE CODE. Получаем файл воркспейса под EWARM  с названием Project.eww и все остальные файлы и директории, включающие код инициализации, HAL, код RTOS и прочее.   Файлы TouchGFX здесь ещё отсутствуют. Скомпилировать проект не получится. 

Закрываем Project.eww. Находим среди сгенерированного дерева исходников  директорию TouchGFX, а в ней файл ApplicationTemplate.touchgfx.part. Щёлкнув на этом файле откроется TouchGFX designer (если эта программа перед этим была правильно инсталлирована) . Выбираем для начала шаблон пустого экрана и больше ничего не конфигурируем.  Нажимаем F4 для генерации кода. 

Снова открываем Project.eww и видим, что он дополнился исходниками сгенерированными в TouchGFX designer.

Компилируем и снова получаем ошибки. Вспоминаем, что драйвер для вывода на дисплей через SPI мы ещё не имеем, и такой опции в STM32CubeMX  не было, а программа в нём нуждается. Процесс перестаёт казаться быстрым. 

Замечаем, что одновременно была создана директория симулятора.  Запускаем проект симулятора в среде Visual Studio 2022. Все отлично компилируется и показывает нам, как и предполагалось, пустой экран. К сожалению проект симулятора включает только файлы GUI, ни RTOS ни другое промежуточное программное обеспечение в проект симулятора не попало. Это уже как бы не та симуляция, которую хотелось бы видеть, но лучше чем ничего.    

Далее тупик. Признаюсь честно, на “бесшовность”  я и не надеялся. 

Пробуем вариант B. 

У меня уже был создан проект для платы зарядника с RTOS ThreadX и рабочими драйверами. И тогда файлы GUI можно просто перенести в него. Осталось только найти какие это файлы.  TouchGFX designer совместно с STM32CubeMX нагенерили достаточно ветвистое дерево исходников и прочих файлов.

Я обнаружил что переносить надо вот эти директории вместе с их поддиректориями:

  • Middlewares/ST/touchgfx

  • TouchGFX/App

  • TouchGFX/generated

  • TouchGFX/gui

  • TouchGFX/target

Из директории TouchGFX/generated удаляем поддиректорию simulator. Из директории Middlewares/ST/touchgfx удаляем директорию os.

Очищаем также отовсюду файлы связанные с симуляцией. 

Несколько важных технических особенностей требующих внимания:

  • Библиотека TouchGFX обращается к модулю CRC чипов для проверки аутентичности аппаратной платформы. Поэтому тактирование модуля CRC надо  обязательно включать. Иначе библиотека зависнет на старте. 

  • Исходники сгенерированные TouchGFX  не совсем корректны. В них не вызывается функция MX_TouchGFX_PreOSInit. Её вызов придётся вставить вручную.

  • Также исходники не предполагают размещение фреймбуфера в некэшируемой области памяти. Это вызывает некорректную работу DMA, если оно используется при пересылке на дисплей. 

  • Формат RGB565 двух-байтовых  пикселей дисплея на ST7789 не совпадает с форматом  TouchGFX, нужно переставлять байты местами. Но возможность переставлять на лету есть только у модуля MDMA чипов STM32.

  • Каждый раз после редактирования в TouchGFX designer требуется перестраивать состав файлов в воркспейсе сторонней IDE, применяющейся для компиляции. 

  • По непонятной причине не компилируется файл GraphElements.cpp. Компилятор выкидывает исключение без описания ошибки. Приходится этот файл убирать из проекта.  

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

Выше показан пример как отображаются некоторые шрифты на дисплее в результате работы GUI TouchGFX.

А здесь показано, как этот же экран представляется в TouchGFX Designer. Очевидны расхождения в визуализации. Программа TouchGFX Designer не отображает результаты антиалиасинга шрифтов.  

Azure RTOS GUIX

Приложение для создания экранов называется - Azure RTOS GUIX Studio, текущая версия - 6.1.11.0. 

 Особенностью этого GUI является тесная привязка к Azure RTOS. Т.е. GUI работает полагаясь на сервисы этой операционной системы. Есть инструкция как портировать движок на другую RTOS, но совсем без RTOS нельзя. И мне кажется это правильно. У всех движков описанных выше реальные практичные примеры используют ту или иную RTOS. 

Демонстрационный проект
Демонстрационный проект
Вид экрана графического дизайнера
Вид экрана графического дизайнера

Плюсы:

  • Полностью открыты исходные тексты.

  • Многопоточность. API движка можно вызывать из разных задач. 

  • Поддержка кодирования цвета от монохрома до 32-битного цвета.

  • Поддержка работы и вывода на экран курсора.

  • Предоставляются файлы проектов симулятора для Visual Studio. Проекты совместимы с Visual Studio 2022. Помимо GUI симулируется и Azure RTOS. Экран симулятора точно повторяет экран на устройстве включая антиалиасинг.  

  • Есть поддержка графических ускорителей семейства STM32 и Renesas Synergy

  • Предусмотрено API для переключения в рантайме языка надписей, цветовой темы и обоев. 

  • Поддержка мультиязычности реализуемая менеджером наборов строк на разных языках.

  • Встроенный конвертер шрифтов TrueType (.ttf). В дистрибутив входит свободный для использования шрифт со всеми языками включая кириллицу.

  • Есть программные JPG и PNG декодеры.

  • Есть поддержка нескольких независимых дисплеев. 

  • Большое разнообразие демонстрационных проектов.

  • Удобный интерфейс дизайнера

Минусы

  • Набор виджетов довольно ограничен. Нет QR кодов и графиков.

  • Нет встроенных растровых шрифтов малого размера. 

  • Нет нативного способа вывода видео.

  • Нет средств отладки и просмотра объектов и ресурсов GUI в реальном времени.

  • Нет драйверов различных типов дисплеев в частности с шиной SPI.

  • Нет поддержки частичного фреймбуфера. Фреймбуфер должен быть такого же размера как экранное пространство. 

  • Не генерируются воркспейсы для каких либо сред разработки.

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

Практика использования Azure RTOS GUIX

Есть несколько вещей которые сильно упрощают портирование GUIX. 

  • Во-первых, если есть место в RAM микроконтроллера для всего фреймбуфера, то написание своего драйвера превращается в реализацию всего одной простой функции. Эта функция должна переслать содержимое фреймбуфера в дисплей. 

  • Во-вторых, какой бы сложный графический интерфейс ни был, он всегда будет сконвертирован в 4 файла. Таким образом не возникает проблема перестройки воркспейса в сторонней IDE, когда он один раз уже был создан. Это сильно отличается от поведения  TouchGFX.

Эти два фактора привели к тому, что движок GUIX на наш полифункциональный зарядник был перенесён легко и быстро. 

Правда пришлось свои предпочтения забыть и пожертвовать 230400 байтами памяти в RAM на два фреймбуфера (второй просто от того чтобы не возиться с аппаратной конвертацией little- в big-endian для дисплея). Однако осталась надежда на интеграцию своих растровых шрифтов благодаря открытым исходникам.

Шаг 1. Скачиваем Azure RTOS GUIX Studio И в этой программе создаём нужный нам дизайн. Стилизованный под семи-сегментный индикатор шрифт был скачан из стороннего источника.

Шаг 2. Генерируем исходники нашего дизайна в выбранную директорию проекта

Будут созданы 2-е файла с исходниками и два файла с объявлениями. Один файл будет содержать все ресурсы кодированные в массивы и структуры на языке С. Другой файл будет содержать функции конфигурирования прорисовки окон нашего дизайна.

Шаг 3. Копируем исходники самой GUIX в дерево нашего проекта . Копируем только содержимое директории common. Из директории guix\ports\cortex_m7\iar\inc копируем к исходникам файл gx_port.h

Шаг 4. В директории guix\common\inc находим файл gx_user_sample.h, переименовываем его в gx_user.h и также копируем к исходникам. В настройка препроцессора среды разработки записываем макроопределение GX_INCLUDE_USER_DEFINE_FILE. Это означает что при компиляции GUIX будут учитываться настройки из файла gx_user.h

Шаг 5. В файле gx_user.h объявляем такие макроопределения:

#define GX_SYSTEM_TIMER_MS             20
#define GX_EXTENDED_UNICODE_SUPPORT
#define GX_SYSTEM_THREAD_PRIORITY      20
#define GX_THREAD_STACK_SIZE           4096

Эти определения специфичны для конкретного приложения. За подробностями надо обращаться к документации GUIX.

Шаг 6. Предполагаем что функция вывода на дисплей содержимого фреймбуфера у нас уже есть. Тогда надо создать функции инициализации драйвера (у нас называется _565rgb_driver_setup), ввода на дисплей (у нас называется _565rgb_buffer_toggle) и вызвать пару функций для запуска прорисовки нашего экрана:

  TFT_init(); // Инициализация дисплея. Эту функцию пишем сами

  // Далее идут вызовы API GUIX

  gx_system_initialize();

  // Кофигурируем и назначаем callback функцию иницализации драйвера _565rgb_driver_setup
  gx_studio_display_configure(DISPLAY_1, _565rgb_driver_setup, LANGUAGE_RUSSIAN, DISPLAY_1_THEME_1,&root);

  //  Назначаем адрес фреймбуфера. Фреймбуфер объявлен в некэшируемой памяти   
  root->gx_window_root_canvas->gx_canvas_memory = (ULONG*)frame_buffer;
  gx_studio_named_widget_create("window", (GX_WIDGET *) root, (GX_WIDGET **)&first_screen);
  gx_widget_show(root);
  gx_system_start(); // Последняя функция запускающая работу GUI

Функция инициализации драйвера выглядит вот так:

static UINT _565rgb_driver_setup(GX_DISPLAY *display)
{
  // Вызываем установку штатного драйвера для кодировки цвета RGB-565
  // и назанчаем callback функцию вывода на дисплей - _565rgb_buffer_toggle
  _gx_display_driver_565rgb_setup(display, (VOID *)SCREEN_HANDLE, _565rgb_buffer_toggle);

  // Наши функции передачи команд дисплею по интерфейсу SPI
  TFT_wr__cmd(0x29); // display ON
  // Задаем размер области экрана 
  TFT_Set_rect(0, 0, DISPLAY_1_X_RESOLUTION-1, DISPLAY_1_Y_RESOLUTION-1);
  TFT_wr__cmd(0x2C); // Команда указавающая дисплею непрерывно принимать и отобразать принятые данные 

  return (GX_SUCCESS);
}

Функция непосредственного вывода на дисплей выглядит так:

static void _565rgb_buffer_toggle(GX_CANVAS *canvas, GX_RECTANGLE *dirty)
{
  uint16_t *ptr_fr_buf;
  uint16_t *ptr_disp_buf;

  ptr_fr_buf   = (uint16_t *)frame_buffer;
  ptr_disp_buf = (uint16_t *)display_buffer;

  // Пересылаем пиксели из одного буфера в друго с конвертацией little -> big-endian
  // Это также можно было бы делать с помощтю MDMA.
  for (uint32_t i=0; i < (DISPLAY_1_X_RESOLUTION * DISPLAY_1_Y_RESOLUTION); i++)
  {
    uint16_t v =*ptr_fr_buf;
    *ptr_disp_buf =(v >> 8) | ((v << 8) & 0xFF00);
    ptr_fr_buf++;
    ptr_disp_buf++;
  }

  // Персылка подготовленного буфера непосредственно на экран по интерфейсу SPI
  TFT_wr_data_buf((uint8_t *)display_buffer, sizeof(display_buffer));
}

И в заключении пишем код постоянно обновляющий некий текст на экране:

  do
  {
    // Конверитируем некую переменную v в строку str
    snprintf(str, VAL_STR_LEN, " %0.2f", v);
    
    // Инициализируем структуру gx_str данными о строке
    gx_str.gx_string_ptr    = str;
    gx_str.gx_string_length = strlen(str);
    
    // Записываем данные о строке в экранный виджет window.window_Val1
    gx_prompt_text_set_ext(&window.window_Val1, &gx_str);
    
    // Указываем GUI о необходимости перерисовать экран. 
    gx_system_canvas_refresh();
    
    // Делаем паузу 
    Wait_ms(100);

  }
  while (1);

Тексты представленные выше - практически все чтобы получить вот такое вид интерфейса пользователя:

Все исходники проекта можно найти здесь: сcыслка на Github.

Резюме

В результате решено было остановиться на Azure RTOS GUIX. Открытые исходные тексты сыграли решающую роль.

Не менее важным стала интеграция с Azure RTOS, которая сама по себе несёт существенную ценность. В исходниках демо проекта можно найти стек TCP/IP через USB RNDIS, файловую систему, WEB сервер и прочее ПО предоставляемое Azure RTOS.

Остаётся проблема большого фреймбуфера. Но думаю она может быть решена способом фрагментации Canvas.

И к вопросу о производительности.

В нашем демо проекте функция вывода на дисплей _565rgb_buffer_toggle длиться 17 мс
А прорисовка экрана в GUIX длиться 1.2 мс. Оптимизация по скорости в компиляторе была отключена. Частоты процессора 480 МГц, системной шины 240 МГц.

Комментарии (20)


  1. ripandtear
    30.06.2022 17:12
    +8

    Как так вышло, что вы пропустили https://github.com/lvgl/lvgl ?

    Прекрасная открытая библиотека, я с ней плотно работаю, в своей "копилке" около года назад появился первый законченный коммерческий проект, с ее использованием. Честно говоря, я уже не вижу сейчас смысла использовать что-то другое.

    А Azure RTOS емнип, лицензия не открытая (в том числе и у компонентов). Только для одобренных майкрософтом линеек чипов - поправьте, если я неправ.


    1. Indemsys Автор
      30.06.2022 17:39

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


      1. iliasam
        30.06.2022 17:52
        +1

        Есть графический редактор для LVGL: squareline.io
        Однако в бесплатной версии его функциональность несколько ограничена: squareline.io
        Плюс сам он еще в процессе разработки.


        1. Indemsys Автор
          30.06.2022 18:24

          Поинтересовался этим проектом.
          В чем-то копируют TouchGFX, но нет поддержки менеджера мультиязычности. Виджетов тоже очень бедно.


      1. osmanpasha
        01.07.2022 06:37
        +3

        Тоже зашёл написать про lvgl. У него ещё требования к ресурсам гораздо ниже, можно запустить и на stm32f103.

        А точно нужен редактор для интерфейса зарядного устройства? У вас в итоговом видео 6 полей с метками, это вполне можно сделать и кодом, без редактора.

        И да, ещё хотел спросить: а зачем зарядному устройству Stm32h7?


        1. Indemsys Автор
          01.07.2022 10:53

          Я не противник lvgl, но как-то не попадаются его демки на отладочных платах от ST и NXP. Я же исследовал только то, что активно продвигают и развивают.

          Да, полей у меня в демке мало, и анимации нет и прочего. Но это не значит что я не потратил кучу времени на перебор шрифтов, цветов, позиционирование и прочие эксперименты.
          Не будь редактора я бы остановился на первом сносном варианте и не испытал бы такого эстетического удовлетворения.
          Моё мнение, что GUI без редактора - прямой путь к фрустрации, снижению производительности и низкому качеству дизайна.

          По поводу ресурсов, то основные ресурсы съедают сами элементы дизайна, картинки шрифты, анимация. Сколько Flash памяти и RAM занимает сам движок GUI имеет меньшее значение. Да и не могут движки GUI сильно отличаться по ресурсам памяти. Если какому-то движку надо меньше ресурсов, это только значит что у него меньше виджетов и фичей. Но лишние фичи не прикомпилятся если их не использовать и не займут ресурсы. У GUIX так.

          Между тем в lvgl также как и в GUIX нет концепции частичного фреймбуфера.
          Т.е. коммерческий emWin уделает обоих по компактности. Его ранние версии я на атмеге запускал с рендеренгом ttf шрифтов в реалтайме без предварительной растеризации. Но на то он и коммерческий дорогой продукт.

          По поводу stm32h7 в полифункциональном заряднике, то об этом можно почитать тут
          Простого ответа нет. Так сложилось много факторов, основной из которых - масштабируемость функциональности.


          1. mctMaks
            01.07.2022 13:35

            а рисование в отдельном редакторе, без привязки к движку не рассматривали? например, относительно недавно делали устройство с круглым дисплеем. Дизайнер создавал интерфейс в фотошопе, потом переносили на устройство в виде фиксированной картинки, чтобы понять как оно смотрится в живую. Что-то по мелочи я исправлял в обычном paint.net, полученную картинку утверждали и потом уже переносили в код (разбивка на примитивы, получение таблицы координат объектов).

            чуть позже пришла Figma на помощь. Да, внешний вид немного отличается из-за векторов, но с другой стороны показать как будут выглядеть разные экраны с переходами можно на раз-два. Получается как таковой, графический дизайнер (в смысле построитель GUI) не нужен.

            кстати, ещё один вариант Qt. Они ведь тоже рекламируют свой продукт под контроллеры, да ещё и демки красивые показывают.


            1. Indemsys Автор
              01.07.2022 13:49

              Дизайнер создавал интерфейс в фотошопе

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

              Более того, ни в каких дизайнерах под embedded в реальности дизайн не создают. Там нет таких инструментов. Все эти тени, переливы, блуры, 3D эффекты создаются как раз в фотошопах. И все демки под тот же GUIX изначально рисовались без сомнения в некоем фотошопе. Потом разбивались на битмапы, а потом битмапы импортировались в редактор GUIX.

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


              1. mctMaks
                02.07.2022 14:30

                Нужен быстрый и эффективный рефакторинг экранов.Сегодня одна информация, а завтра может быть другая

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

                Более того, ни в каких дизайнерах под embedded в реальности дизайн не создают.

                embedded linux для микрокомпьютеров с Qt смотрят на вас с недоумением. Но для микроконтроллеров возможно вы правы.

                Там нет таких инструментов. Все эти тени, переливы, блуры, 3D эффекты создаются как раз в фотошопах.

                Опять же, зависит от целей и задач.

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

                это понятно, это логично.


          1. RepoMan
            02.07.2022 11:38

            Между тем в lvgl также как и в GUIX нет концепции частичного фреймбуфера.

            Почему нет? Как раз-таки позволяет, иначе как бы цветной дисплей 800х480 влез в память обычной F4 стмки с 512К оперативкой? Двойного буфера хотя бы на 15 линий вполне достаточно для плавной работы дисплея, если, конечно, не крутить на нем видео. Прелесть lvgl в том, что она отрисовывает только изменяющиеся объекты. Сколько бы заняла отправка целого 800х480 фрейма при малейшем апдейте?

            Про редактор для lvgl узнал только сейчас, что не помешало отрисовать несколько 800х480 экранов просто кодом по дизайну в фотошопе. Хотя соглашусь, что с редактором это могло быть быстрее


            1. Indemsys Автор
              02.07.2022 11:47

              Ничего не мешает разместить буфер 800x480=384000 и палитру в 512000 байт оперативке.

              Оправить по SPI весь такой буфер тоже займет не более 70 мс с 50 МГц шиной, которая обычно есть у SPI дисплеев.

              Отправлять только измененные области может и GUIX, но если у вас движется или меняет цвет всего экрана, то такая фича не спасет. Либо вы сильно ограничиваете себя в дизайне экрана.

              Ну и наконец я не утверждал что писать программно невозможно или мучительно трудно. Сам так делаю иногда.


              1. RepoMan
                02.07.2022 12:00

                RGB565 это уже 2 байта на пиксел и 140 мс, что непозволительно долго.


                1. Indemsys Автор
                  02.07.2022 12:27

                  Я не знаю о чем вы говорите. Дайте ссылку на проект, разберемся.
                  2 байта иметь не обязательно.


  1. eps
    01.07.2022 13:29
    +2

    Весьма интересно, но похоже на рассказ из другого — параллельного, профессионального — мира.


    Пропасть между этой статьёй и нами, простыми ребятами с Platformio, Arduino IDE, Wiring / MicroPython и чипами ATMega, ESP32, RP2040.


    Как так получилось и есть ли там мостики, вот с теми же GUI библиотеками, например?


    То есть, я много раз слышал, что Wiring — неэффективная дрянь, ATMega — дилетантство, ESP чипы никто в здравом уме не потащит на продакшен и т.п., но интересно всё же поиспользовать что-то из этого кода. Пока что приходится использовать экранчики Nextion, а у них дизайнер UI только под Шindows и это очень неудобно


    1. le2
      01.07.2022 17:45

      не хочу обидеть, просто рассказываю про устройство этого мира.
      Атмега — отличный и прогрессивный чип (по сравнению с 8051) только он сдох в коммерческом плане в 2005 году после того как фирма Филипс (впоследствии NXP) первыми обрушили цены на ARM микроконтроллеры.
      Приведенные в статьи примеры с графикой также являются устаревшей экзотикой, потому что дешевле, интереснее делать большим мальчикам на Cortex-A и linux.
      Ардуино интересна в коммерческом плане только для продажи «простым ребятам» оверпрайснутых шылдов. Очень узкий сегмент. То есть пользуйтесь наздоровье, только не пытайтесь сэкономить или как-то конкурировать с профессиональными вещами.


      1. Indemsys Автор
        01.07.2022 18:44
        +1

        Однако действительность нам говорит совершенно об обратном.
        Не будем брать в расчёт игры перезрелых мальчиков с Cortex-A в качестве газоно-поливалок, а посмотрим на океан потребительской электроники.
        Если я раньше в своём пылесосе, микроволновке, духовке встречал одни атмеги и пики, то нынче я уже вижу в роботах пылесосах, духовках, стиралках, самокатах, велосипедах, коптерах ... повально STM32 и прочие 32-х битные микроконтроллеры.
        MMU-less микроконтроллеры множаться и развиваются. А с ними и всякие GUI. Этот рынок только растёт и конца росту не видно.

        Wiring, ATMega, ESP  - это не архаика, а просто другая индустрия. Индустрия образования и самообразования. Не менее мощная, кстати, индустрия чем потребительская электроника. Сложные трудоёмкие процессы освоения и разработки GUI в образовании не востребованы, вот их там и нет. А так, тот же emWin появился поначалу именно для атмег и пиков, спокойно работает на 8-разрядниках.


        1. le2
          01.07.2022 18:57

          лет 5 назад мне на работе поставили ip-телефон и я понял что не хочу уже втыкать в убогую монохромную графику. ipod, iphone и клоны его победили. С точки зрения бизнес-потребителей «интерфейс не требует обучения» это киллер фича. Это перебить никак нельзя.
          Atmel быстро сжег себе карму еще и тем что резко задрал цены в нулевых годах и увеличил лидтайм. ST — похоже идут по тому же пути.
          В абсолютных цифрах в мире на рынке микроконтроллеров рулят вообще японцы (Renesas) и немцы (Infineon) с 8051 и прочей никому не нужной экзотикой. Просто в каждом автомобиле их больше пяти десятков.
          Следующая проблема микроконтроллеров — экзотическая память, когда А-процессоры могут работать с мейнстримовой NAND/DRAM.
          Пользователи привыкают быстро к BLuetooth|WiFi/5G что также выбивает микроконтроллеры из конкурентной ниши.

          Вобщем, думаю, ниши с графикой на микроконтроллерах еще остаются, но все они будут выбиты с рынка устройствами с тачовым андроидоподобным интерфейсом.


          1. Indemsys Автор
            01.07.2022 19:11
            +2

            Все мной описанные GUI имеют поддержку жестов на тач-экранах. Жесты обрабатывает не хост процессор, а процессор ёмкостного тач-контроллера в экране, MMU-less кстати.

            Модули BLuetooth|WiFi/5G имеют внутри все тот же ARM-Cortex M.
            По сути хост контроллеру линукс уже не нужен. За него всю работу делает распределённая периферия.
            Возьмём часы наручные, там обалденные интерфейс делают без всяких линуксов.
            Линукс просто теряется в этом море, о нем потихоньку забывают.
            Мейнстримовые в embedded не NAND/DRAM, а HyperRAM и HyperFlash.
            Они идеально сочетаются с STM32H или c i.MX RT
             
            В автомобилях количество микроконтроллеров идёт не на десятки, а на сотни, и подавляющая часть там MMU-less.
            Гибкие экраны и печатаемая на поверхностях электроника только увеличит спрос на малые GUI.


      1. eps
        02.07.2022 13:44

        Но ESP-то живы и здоровы. Как производители захотели Wi-Fi в каждом чайнике, стали ставить ESP везде. А кто сообразил, что можно всю прошивку целиком в него засунуть, не только wireless modem.


        Есть куча устройств вокруг с Nordic NRF, если там Bluetooth, и ESP, если там WiFi.


        Кажется, умение собирать из них что-то и запрограммировать стало полезнее, чем раньше. И вот тут хочется экран с GUI, и желательно не Nextion...


  1. Eugeeny
    01.07.2022 15:27

    Еще бы автоматический линтер, который за эту дрянь, которую за дизайн выдают, током бы бил.