Goeiemiddei Wy binne yn it projekt
Qt is in cross-platfoarm ramt dat omfiemet net allinnich grafyske komponinten, mar ek sokke dingen as QtNetwork, in set fan klassen foar in wurk mei databases, Qt foar automatisearring (ynklusyf foar IoT ymplemintaasje) en folle mear. It Qt-team hat proaktyf west oer it brûken fan Qt yn ynbêde systemen, sadat de biblioteken frij konfigurearber binne. Lykwols, oant koartlyn tochten in pear minsken oer it portearjen fan Qt nei mikrocontrollers, wierskynlik om't sa'n taak lestich liket - Qt is grut, MCU's binne lyts.
Oan 'e oare kant binne d'r op it stuit mikrocontrollers ûntworpen om te wurkjen mei multimedia en superieur oan' e earste Pentiums. Sawat in jier lyn ferskynde it Qt-blog
Qt 4.8 is in lange tiid nei Embox porteare, dus wy besletten it derop te besykjen. Wy keas de moveblocks-applikaasje - in foarbyld fan springende animaasje.
Qt moveblocks op QEMU
Om te begjinnen, wy konfigurearje Qt, as it mooglik is, mei de minimale set fan komponinten nedich foar in stipe animation. Hjirfoar is d'r in opsje "-qconfig minimaal, lyts, medium ...". It ferbynt in konfiguraasjetriem út Qt mei in protte makro - wat te skeakeljen / wat te skeakeljen. Nei dizze opsje foegje wy oare flaggen ta oan 'e konfiguraasje as wy wat oars wolle útskeakelje. Hjir is in foarbyld fan ús
Om Qt te wurkjen, moatte jo in OS-kompatibiliteitslaach tafoegje. Ien manier is in útfiere QPA (Qt Platform Abstraksje). Wy namen as basis de klearmakke fb_base-plugin opnommen yn Qt, op basis wêrfan QPA foar Linux wurket. It resultaat is in lyts plugin neamd emboxfb, dy't Qt foarsjocht mei de framebuffer fan Embox, en dan tekenet it dêr sûnder help fan bûten.
Dit is wat it meitsjen fan in plugin liket
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 (fbPath < 0) {
qFatal("QEmboxFbIntegration: Error open framebuffer %s", fbPath);
}
if (ioctl(fbFd, FBIOGET_FSCREENINFO, &finfo) == -1) {
qFatal("QEmboxFbIntegration: Error ioctl framebuffer %s", fbPath);
}
if (ioctl(fbFd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
qFatal("QEmboxFbIntegration: Error ioctl framebuffer %s", fbPath);
}
fbWidth = vinfo.xres;
fbHeight = vinfo.yres;
fbBytesPerLine = finfo.line_length;
fbSize = fbBytesPerLine * fbHeight;
fbFormat = vinfo.fmt;
fbData = (uint8_t *)mmap(0, fbSize, PROT_READ | PROT_WRITE,
MAP_SHARED, fbFd, 0);
if (fbData == MAP_FAILED) {
qFatal("QEmboxFbIntegration: Error mmap framebuffer %s", fbPath);
}
if (!fbData || !fbSize) {
qFatal("QEmboxFbIntegration: Wrong framebuffer: base = %p,"
"size=%d", fbData, fbSize);
}
mPrimaryScreen = new QEmboxFbScreen(fbData, fbWidth,
fbHeight, fbBytesPerLine,
emboxFbFormatToQImageFormat(fbFormat));
mPrimaryScreen->setPhysicalSize(QSize(fbWidth, fbHeight));
mScreens.append(mPrimaryScreen);
this->printFbInfo();
}
En sa sil de wertekening der útsjen
QRegion QEmboxFbScreen::doRedraw()
{
QVector<QRect> rects;
QRegion touched = QFbScreen::doRedraw();
DPRINTF("QEmboxFbScreen::doRedrawn");
if (!compositePainter) {
compositePainter = new QPainter(mFbScreenImage);
}
rects = touched.rects();
for (int i = 0; i < rects.size(); i++) {
compositePainter->drawImage(rects[i], *mScreenImage, rects[i]);
}
return touched;
}
As gefolch, mei de gearstaller-optimalisaasje foar ûnthâldgrutte -Os ynskeakele, die bliken dat de biblioteekôfbylding 3.5 MB wie, wat fansels net past yn it haadûnthâld fan 'e STM32F746. Lykas wy al skreaun hawwe yn ús oare artikel oer OpenCV, hat dit boerd:
- 1 MB ROM
- 320 KB RAM
- 8 MB SDRAM
- 16 MB QSPI
Sûnt stipe foar it útfieren fan koade fan QSPI is al tafoege oan OpenCV, hawwe wy besletten om te begjinnen mei it laden fan de hiele Embox c Qt-ôfbylding yn QSPI. En hoera, alles begon hast fuortendaliks fan QSPI! Mar lykas yn it gefal fan OpenCV, die bliken dat it te stadich wurket.
Dêrom besleaten wy it op dizze manier te dwaan - earst kopiearje wy de ôfbylding nei QSPI, laden it dan yn SDRAM en útfiere dêrwei. Fan SDRAM waard it in bytsje flugger, mar noch fier fan QEMU.
Folgjende, der wie in idee om in driuwend punt - na docht Qt guon berekkeningen fan de koördinaten fan pleinen yn animaasje. Wy besochten, mar hjir krigen wy gjin sichtbere fersnelling, hoewol yn
It meast effektive idee wie om de framebuffer fan SDRAM nei ynterne ûnthâld te ferpleatsen. Om dit te dwaan, makken wy de skermôfmjittings net 480x272, mar 272x272. Wy hawwe ek de kleurdjipte ferlege fan A8R8G8B8 nei R5G6B5, sadat de grutte fan ien piksel fan 4 nei 2 bytes fermindere. De resultearjende framebuffergrutte is 272 * 272 * 2 = 147968 bytes. Dit joech in wichtige fersnelling, miskien it meast opfallend, de animaasje waard hast glêd.
De lêste optimalisaasje wie in útfiere Embox koade út RAM en Qt koade út SDRAM. Om dit te dwaan, wy earst, lykas gewoanlik, statysk keppele Embox tegearre mei Qt, mar wy pleatse de tekst, rodata, gegevens en bss segminten fan de bibleteek yn QSPI om dan kopiearje it nei 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))
Troch de Embox-koade út te fieren fan ROM, krigen wy ek in merkbere fersnelling. As gefolch, de animaasje draaide frij glêd:
Oan 'e ein, wylst it tarieden fan it artikel en besykje ferskillende Embox konfiguraasjes, die bliken dat Qt moveblocks wurket great út QSPI mei in framebuffer yn SDRAM, en de knelpunt wie krekt de grutte fan 'e framebuffer! Blykber, om de earste "slideshow" te oerwinnen, wie in 2-fâldige fersnelling genôch troch in banale reduksje fan 'e framebuffergrutte. Mar it wie net mooglik om sa'n resultaat te berikken troch allinich de Embox-koade oer te setten nei ferskate rappe oantinkens (de fersnelling wie net 2, mar sawat 1.5 kear).
Hoe kinne jo it sels besykje
As jo in STM32F7-Discovery, kinne jo rinne Qt ûnder Embox sels. Jo kinne lêze hoe't dit dien wurdt op ús
konklúzje
As gefolch, wy slagge in lansearring Qt! De kompleksiteit fan de taak is neffens ús wat oerdreaun. Fansels moatte jo rekken hâlde mei de spesifikaasjes fan mikrocontrollers en yn 't algemien de arsjitektuer fan kompjûtersystemen begripe. De optimalisaasjeresultaten wize op it bekende feit dat de knelpunt yn in komputersysteem net de prosessor is, mar it ûnthâld.
Dit jier dogge wy mei oan it festival
Boarne: www.habr.com