Bonan posttagmezon Ni estas en la projekto
Qt estas transplatforma kadro, kiu inkluzivas ne nur grafikajn komponentojn, sed ankaŭ tiajn aferojn kiel QtNetwork, aron da klasoj por labori kun datumbazoj, Qt por Aŭtomatigo (inkluzive por IoT-efektivigo) kaj multe pli. La Qt-teamo estis iniciatema pri uzado de Qt en enigitaj sistemoj, do la bibliotekoj estas sufiĉe agordeblaj. Tamen, ĝis antaŭ nelonge, malmultaj homoj pensis pri porti Qt al mikroregiloj, verŝajne ĉar tia tasko ŝajnas malfacila - Qt estas granda, MCUoj estas malgrandaj.
Aliflanke, nuntempe ekzistas mikrokontroliloj destinitaj por labori kun plurmediaj kaj superaj ol la unuaj Pentiums. Antaŭ ĉirkaŭ unu jaro aperis la blogo Qt
Qt 4.8 estis portita al Embox dum longa tempo, do ni decidis provi ĝin sur ĝi. Ni elektis la aplikaĵon moveblocks - ekzemplo de printempa animacio.
Qt moveblocks sur QEMU
Komence, ni agordas Qt, se eble, kun la minimuma aro de komponantoj necesaj por subteni animacion. Por tio ekzistas opcio "-qconfig minimuma, malgranda, meza...". Ĝi ligas agordan dosieron de Qt kun multaj makrooj - kion ebligi / kion malŝalti. Post ĉi tiu opcio, ni aldonas aliajn flagojn al la agordo se ni volas malŝalti ion alian. Jen ekzemplo de nia
Por ke Qt funkciu, vi devas aldoni OS-kongruan tavolon. Unu maniero estas efektivigi QPA (Qt Platform Abstraction). Ni prenis kiel bazon la pretan fb_base kromaĵon inkluzivita en Qt, surbaze de kiu QPA por Linukso funkcias. La rezulto estas malgranda kromaĵo nomata emboxfb, kiu provizas Qt per la framebuffer de Embox, kaj poste ĝi desegnas tie sen ia ekstera helpo.
Jen kiel aspektas krei kromprogramon
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();
}
Kaj jen kiel aspektos la redesegnaĵo
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;
}
Kiel rezulto, kun la kompililo optimumigo por memorgrandeco -Os ebligita, la biblioteko bildo montriĝis esti 3.5 MB, kiu kompreneble ne konvenas en la ĉefa memoro de la STM32F746. Kiel ni jam skribis en nia alia artikolo pri OpenCV, ĉi tiu tabulo havas:
- 1 MB ROM
- 320 KB RAM
- 8 MB SDRAM
- 16 MB QSPI
Ĉar subteno por ekzekuti kodon de QSPI jam estis aldonita al OpenCV, ni decidis komenci ŝarĝante la tutan bildon de Embox c Qt en QSPI. Kaj hure, ĉio komenciĝis preskaŭ tuj de QSPI! Sed kiel en la kazo de OpenCV, montriĝis, ke ĝi funkcias tro malrapide.
Tial ni decidis fari ĝin tiel - unue ni kopias la bildon al QSPI, poste ŝarĝas ĝin en SDRAM kaj ekzekutas de tie. De SDRAM ĝi fariĝis iom pli rapida, sed ankoraŭ malproksime de QEMU.
Poste, estis ideo inkluzivi glitkomon - finfine, Qt faras kelkajn kalkulojn de la koordinatoj de kvadratoj en animacio. Ni provis, sed ĉi tie ni ne ricevis ajnan videblan akcelon, kvankam en
La plej efika ideo estis movi la framebuffer de SDRAM al interna memoro. Por fari tion, ni faris la ekranajn dimensiojn ne 480x272, sed 272x272. Ni ankaŭ malaltigis la kolorprofundon de A8R8G8B8 al R5G6B5, tiel reduktante la grandecon de unu pikselo de 4 ĝis 2 bajtoj. La rezulta frambuffer grandeco estas 272 * 272 * 2 = 147968 bajtoj. Ĉi tio donis gravan akcelon, eble plej rimarkinde, la animacio fariĝis preskaŭ glata.
La plej nova optimumigo estis ruli Embox-kodon de RAM kaj Qt-kodon de SDRAM. Por fari tion, ni unue, kiel kutime, statike ligas Embox kune kun Qt, sed ni metas la tekstojn, rodatajn, datumojn kaj bss-segmentojn de la biblioteko en QSPI por tiam kopii ĝin al 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))
Ekzekutante la Embox-kodon el ROM, ni ankaŭ ricevis rimarkindan akcelon. Kiel rezulto, la animacio rezultis sufiĉe glata:
Ĉe la fino, dum preparante la artikolon kaj provante malsamajn Embox-agordojn, montriĝis, ke Qt moveblocks funkcias bonege de QSPI kun framebuffer en SDRAM, kaj la botelkolo estis ĝuste la grandeco de la framebuffer! Ŝajne, por venki la komencan "diagramon", 2-obla akcelo sufiĉis pro banala redukto de la grandeco de la kadrobufro. Sed ne eblis atingi tian rezulton transdonante nur la Embox-kodon al diversaj rapidaj memoroj (la akcelo ne estis 2, sed ĉirkaŭ 1.5 fojojn).
Kiel provi ĝin mem
Se vi havas STM32F7-Discovery, vi mem povas ruli Qt sub Embox. Vi povas legi kiel ĉi tio estas farita sur nia
konkludo
Kiel rezulto, ni sukcesis lanĉi Qt! La komplekseco de la tasko, laŭ nia opinio, estas iom troigita. Kompreneble, vi devas konsideri la specifaĵojn de mikroregiloj kaj ĝenerale kompreni la arkitekturon de komputilaj sistemoj. La optimumigo-rezultoj montras al la konata fakto, ke la botelkolo en komputika sistemo ne estas la procesoro, sed la memoro.
Ĉi-jare ni partoprenos en la festivalo
fonto: www.habr.com