Bonjour ! Nous avons dans notre projet lancé Qt sur STM32F7-Discovery et aimerions en parler. Auparavant, nous avons déjà expliqué comment nous avons réussi à lancer .
Qt est un framework multiplateforme qui inclut non seulement des composants graphiques, mais aussi des Ă©lĂ©ments tels que QtNetwork, un ensemble de classes pour travailler avec des bases de donnĂ©es, Qt for Automation (y compris pour la mise en Ćuvre de l'IoT) et bien d'autres. Les dĂ©veloppeurs de l'Ă©quipe Qt ont prĂ©vu l'utilisation de Qt dans des systĂšmes embarquĂ©s, ce qui rend les bibliothĂšques assez configurables. Cependant, jusqu'Ă rĂ©cemment, peu de gens pensaient Ă porter Qt sur des microcontrĂŽleurs, probablement parce que cela semblait compliquĂ© : Qt est vaste, les MCU sont petits.
D'un autre cĂŽtĂ©, il existe actuellement des microcontrĂŽleurs conçus pour des applications multimĂ©dia et qui surpassent les premiers Pentium. Il y a environ un an sur le blog de Qt est apparu . Les dĂ©veloppeurs ont portĂ© Qt sur le systĂšme d'exploitation RTEMS et ont exĂ©cutĂ© des exemples avec des widgets sur plusieurs cartes fonctionnant sous stm32f7. Cela nous a interpellĂ©s. Il Ă©tait Ă©vident, comme le notent les dĂ©veloppeurs eux-mĂȘmes, que Qt ralentit sur STM32F7-Discovery. Nous nous sommes demandĂ© si nous pourrions faire fonctionner Qt sous Embox, et non seulement dessiner un widget, mais aussi lancer une animation.
Qt 4.8 a été porté sur Embox depuis longtemps, donc nous avons décidé d'essayer avec celui-ci. Nous avons choisi l'application moveblocks - un exemple d'animation en ressort.
Qt moveblocks sur QEMU
Pour commencer, nous configurons Qt avec le minimum de composants nĂ©cessaires pour prendre en charge l'animation. Pour cela, il existe l'option â-qconfig minimal,small,medium âŠâ. Cette option charge un fichier de configuration de Qt avec de nombreux macros - ce qu'il faut inclure / ce qu'il faut dĂ©sactiver. AprĂšs cette option, nous ajoutons d'autres drapeaux Ă la configuration si nous voulons dĂ©sactiver encore quelque chose. Voici un exemple de notre .
Pour que Qt fonctionne, il faut ajouter une couche de compatibilitĂ© avec le systĂšme d'exploitation. L'un des moyens - mettre en Ćuvre QPA (Qt Platform Abstraction). Nous avons basĂ© notre travail sur le plugin fb_base dĂ©jĂ prĂȘt dans Qt, sur lequel repose le QPA pour Linux. Au final, nous avons obtenu un petit plugin emboxfb, qui fournit Ă Qt le framebuffer d'Embox, et ensuite il dessine sans aide extĂ©rieure.
Voici à quoi ressemble la création d'un plugin
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();
}
Voici Ă quoi ressemblera le rafraĂźchissement
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;
}
Avec l'optimisation du compilateur pour la taille de la mémoire -Os, l'image de la bibliothÚque s'est révélée faire 3,5 Mo, ce qui évidemment ne rentre pas dans la mémoire principale du STM32F746. Comme nous l'avons déjà écrit dans notre autre article sur OpenCV, cette carte dispose de :
- 1 Mo de ROM
- 320 Ko de RAM
- 8 Mo de SDRAM
- 16 Mo de QSPI
Ătant donnĂ© que la prise en charge de l'exĂ©cution du code depuis QSPI a dĂ©jĂ Ă©tĂ© ajoutĂ©e pour OpenCV, nous avons dĂ©cidĂ© de commencer par charger l'image d'Embox avec Qt dans le QSPI dans son intĂ©gralitĂ©. Et oui, tout a presque immĂ©diatement dĂ©marrĂ© depuis le QSPI ! Mais comme dans le cas d'OpenCV, il s'est avĂ©rĂ© que cela fonctionne trop lentement.

Nous avons donc décidé de procéder ainsi : d'abord nous copions l'image dans le QSPI, puis nous la chargeons dans la SDRAM et nous exécutons à partir de là . C'était un peu plus rapide depuis la SDRAM, mais c'était encore loin de QEMU.

Ensuite, l'idĂ©e Ă©tait d'activer le point flottant - car Qt effectue certains calculs de coordonnĂ©es des carrĂ©s dans l'animation. Nous avons essayĂ©, mais ici nous n'avons pas obtenu d'accĂ©lĂ©ration visible, bien que les dĂ©veloppeurs de Qt aient affirmĂ© que le FPU offre un gain de vitesse significatif pour l'animation de "dragging" sur l'Ă©cran tactile. Peut-ĂȘtre que dans moveblocks, il y a considĂ©rablement moins de calculs avec des nombres flottants, et cela dĂ©pend de l'exemple spĂ©cifique.
L'idĂ©e la plus efficace a Ă©tĂ© de transfĂ©rer le framebuffer de la SDRAM vers la mĂ©moire interne. Pour cela, nous avons dĂ©fini les dimensions de l'Ă©cran non pas Ă 480Ă272, mais Ă 272Ă272. Nous avons Ă©galement rĂ©duit la profondeur de couleur de A8R8G8B8 Ă R5G6B5, diminuant ainsi la taille d'un pixel de 4 Ă 2 octets. Cela nous a donnĂ© une taille de framebuffer de 272 * 272 * 2 = 147968 octets. Cela a entraĂźnĂ© un gain de performance significatif, sans doute le plus notable, rendant l'animation presque fluide.
La derniÚre optimisation consistait à exécuter le code Embox depuis la RAM et Qt depuis la SDRAM. Pour cela, nous avons d'abord lier statiquement Embox avec Qt comme d'habitude, mais nous plaçons les segments text, rodata, data et bss de la bibliothÚque dans le QSPI, afin de les copier ensuite dans la 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))
En exécutant le code Embox depuis la ROM, nous avons également obtenu un gain de performance perceptible. Au final, l'animation est devenue suffisamment fluide :

Déjà à la fin, en préparant l'article et en essayant différentes configurations d'Embox, il est apparu que Qt moveblocks fonctionne merveilleusement bien depuis le QSPI avec le framebuffer en SDRAM, et le goulet d'étranglement était justement la taille du framebuffer ! Apparemment, pour surmonter le stade initial de "diaporama", une accélération de 2 fois était suffisante en réduisant simplement la taille du framebuffer. Le simple transfert du code Embox vers différentes mémoires rapides n'a pas permis d'obtenir un tel résultat (l'accélération était de 1,5 fois environ).
Comment essayer par soi-mĂȘme
Si vous avez un STM32F7-Discovery, vous pouvez exĂ©cuter Qt sous Embox vous-mĂȘme. Vous pouvez lire comment cela se fait sur notre .
Conclusion
Finalement, nous avons réussi à lancer Qt ! La difficulté de la tùche, selon nous, a été quelque peu exagérée. Bien sûr, il faut tenir compte des spécificités des microcontrÎleurs et comprendre l'architecture des systÚmes de calcul. Les résultats de l'optimisation indiquent un fait bien connu : le point le plus étroit d'un systÚme de calcul, ce n'est pas le processeur, mais la mémoire.
Cette année, nous participerons au festival . Là , nous expliquerons plus en détail et montrerons Qt, OpenCV sur microcontrÎleurs et d'autres de nos réalisations.
Source : habr.com
