Добър ден! Ние сме в проекта започнахме с Qt на STM32F7-Discovery и искаме да споделим за него. По-рано разказахме как успяхме да стартираме .
Qt е кросплатформен фреймворк, който включва не само графични компоненти, но и такива неща като QtNetwork, набор от класове за работа с бази данни, Qt for Automation (включително за реализация на IoT) и много други. Разработчиците от екипа на Qt предварително предвидиха използването на Qt в вградени системи, затова библиотеките са доста добре конфигурируеми. Въпреки това, до наскоро, малко хора се замисляха за портирование на Qt на микроконтролери, вероятно защото задачата изглежда сложна — Qt е голям, MCU са малки.
От друга страна, в момента съществуват микроконтролери, предназначени за работа с мултимедия и надхвърлящи първите Pentium процесори. Около година назад в блога на Qt се появи . Разработчиците направиха порт на Qt под ОС RTEMS и стартираха примери с виджети на няколко платформи под управление на stm32f7. Това ни заинтересува. Забеляза се, и самите разработчици пишат за това, че Qt забавя на STM32F7-Discovery. Нас ни заинтригува, можем ли да стартираме Qt под Embox, като не просто нарисуваме виджет, а стартираме анимация.
В Embox отдавна е портировано Qt 4.8, затова решихме да опитаме с него. Избрахме приложението moveblocks — пример за пружиниста анимация.
Qt moveblocks на QEMU
Първо конфигурираме Qt с минимален набор от компоненти, необходими за поддръжка на анимацията. За това съществува опция “-qconfig minimal,small,medium …”. Тя свързва конфигурационен файл от състава на Qt с множество макроси — какво да включим/какво да изключим. След тази опция добавяме в конфигурацията други флагове, ако искаме да изключим нещо допълнително. Ето пример на нашата .
За да заработи Qt, трябва да добавим слой на съвместимост с ОС. Един от начините е да се реализира QPA (Qt Platform Abstraction). За основа взехме готовия плагин fb_base от състава на Qt, на базата на който работи QPA за Linux. В резултат се получи малък плагин emboxfb, който предоставя на Qt framebuffer на Embox, а след това рисува без допълнителна помощ.
Ето как изглежда създаването на плъгин
QEmboxFbIntegration::QEmboxFbIntegration()
: fontDb(new QGenericUnixFontDatabase())
{
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
const char *fbPath = "/dev/fb0";
fbFd = open(fbPath, O_RDWR);
if (fbFd setPhysicalSize(QSize(fbWidth, fbHeight));
mScreens.append(mPrimaryScreen);
this->printFbInfo();
}
Така ще изглежда прерисуването
QRegion QEmboxFbScreen::doRedraw()
{
QVector rects;
QRegion touched = QFbScreen::doRedraw();
DPRINTF("QEmboxFbScreen::doRedrawn");
if (!compositePainter) {
compositePainter = new QPainter(mFbScreenImage);
}
rects = touched.rects();
for (int i = 0; i drawImage(rects[i], *mScreenImage, rects[i]);
}
return touched;
}
В крайна сметка, с включена оптимизация на компилатора по размер на паметта -Os, образът на библиотеката стана 3.5 Мб, което, разбира се, не се побира в основната памет на STM32F746. Както вече споменахме в друга наша статия за OpenCV, на тази платка има:
- 1 Мб ROM
- 320 Кб RAM
- 8 Мб SDRAM
- 16 Мб QSPI
Тъй като за OpenCV вече беше добавена поддръжка за изпълнение на код от QSPI, решихме да започнем като заредим образа на Embox с Qt изцяло в QSPI. И ура, всичко почти веднага се стартира от QSPI! Но, както и при OpenCV, се оказа, че работи прекалено бавно.

Следователно решихме да направим така — първо копираме образа в QSPI, след това го зареждаме в SDRAM и изпълняваме оттам. От SDRAM стана малко по-бързо, но все пак далеч от QEMU.

След това имаше идея да включим плаваща запетая — защото Qt прави някои изчисления на координатите на квадратите в анимацията. Опитахме, но не получихме видимо ускорение, въпреки че разработчиците на Qt твърдяха, че FPU дава значителен прираст в скоростта за "dragging animation" на тъчскрийн. Може би в moveblocks изчисленията с плаваща запетая са много по-малко и това зависи от конкретния пример.
Най-ефективната идея се оказа прехвърлянето на фреймбуфера от SDRAM в вътрешната памет. За целта направихме размерите на екрана не 480×272, а 272×272. Освен това намалихме дълбочината на цвета от A8R8G8B8 на R5G6B5, като по този начин намалихме размера на един пиксел от 4 на 2 байта. Получихме размер на фреймбуфера 272 * 272 * 2 = 147968 байта. Това доведе до значително увеличаване на скоростта, вероятно най-забележимо, анимацията стана почти плавна.
Последната оптимизация се състоеше в изпълнението на кода на Embox от RAM, а на Qt от SDRAM. За целта първо свързахме статично Embox заедно с Qt, но сегментите text, rodata, data и bss на библиотеката поставихме в QSPI, за да можем след това да копираме в SDRAM.
section (qt_text, SDRAM, QSPI)
phdr (qt_text, PT_LOAD, FLAGS(5))
section (qt_rodata, SDRAM, QSPI)
phdr (qt_rodata, PT_LOAD, FLAGS(5))
section (qt_data, SDRAM, QSPI)
phdr (qt_data, PT_LOAD, FLAGS(6))
section (qt_bss, SDRAM, QSPI)
phdr (qt_bss, PT_LOAD, FLAGS(6))
Чрез изпълнението на кода на Embox от ROM също получихме забележимо увеличаване на скоростта. В резултат анимацията стана доста плавна:

В края, подготвяйки статията и опитвайки различни конфигурации на Embox, се установи, че Qt moveblocks работи чудесно и от QSPI с фреймбуфер в SDRAM, а тясното място всъщност беше размерът на фреймбуфера! Очевидно, за да се преодолее началното "слайдшо" е било достатъчно ускорение от 2 пъти просто чрез намаляване на размера на фреймбуфера. А да се постигне такъв резултат чрез прехвърляне само на кода на Embox в различни бързи памети не се оказа удачно (ускорението беше не 2, а около 1.5 пъти).
Как да опитате сами
Ако имате STM32F7-Discovery, можете сами да стартирате Qt под Embox. Можете да прочетете как става това на нашия .
Заключение
В крайна сметка успяхме да стартираме Qt! Трудността на задачата, според нас, е малко преувеличена. Разбира се, трябва да се вземат предвид спецификите на микроконтролерите и наистина да се разбере архитектурата на изчислителните системи. Резултатите от оптимизацията показват известния факт, че най-тясното място в изчислителната система не е процесорът, а паметта.
Тази година ще участваме на фестивала . Там ще разкажем по-подробно и ще покажем Qt, OpenCV на микроконтролери и други наши постижения.
Източник: habr.com
