Flytja Qt til STM32

Flytja Qt til STM32Góðan daginn Við erum í verkefninu Embox setti Qt á STM32F7-Discovery og langar að tala um það. Áður sögðum við þegar hvernig okkur tókst að koma af stað OpenCV.

Qt er þvert á vettvang ramma sem inniheldur ekki aðeins grafíska hluti, heldur einnig hluti eins og QtNetwork, hóp flokka til að vinna með gagnagrunna, Qt fyrir sjálfvirkni (þar á meðal fyrir IoT útfærslu) og margt fleira. Qt teymið hefur verið fyrirbyggjandi varðandi notkun Qt í innbyggðum kerfum, þannig að bókasöfnin eru frekar stillanleg. Hins vegar, þar til nýlega, hafa fáir hugsað um að flytja Qt til örstýringa, líklega vegna þess að slíkt verkefni virðist erfitt - Qt er stórt, MCU eru lítil.

Á hinn bóginn, í augnablikinu eru örstýringar hannaðir til að vinna með margmiðlun og betri en fyrstu Pentiums. Fyrir um ári síðan birtist Qt bloggið staða. Hönnuðir gerðu Qt höfn fyrir RTEMS OS og settu af stað dæmi með búnaði á nokkrum borðum sem keyra stm32f7. Þetta vakti áhuga okkar. Það var áberandi, og verktaki sjálfir skrifa um það, að Qt er hægt á STM32F7-Discovery. Við vorum að velta því fyrir okkur hvort við gætum keyrt Qt undir Embox, og ekki bara teiknað búnað, heldur keyrt hreyfimynd.

Qt 4.8 hefur verið flutt í Embox í langan tíma, svo við ákváðum að prófa það á það. Við völdum moveblocks forritið - dæmi um fjaðrandi hreyfimyndir.

Qt moveblocks á QEMUFlytja Qt til STM32

Til að byrja með stillum við Qt, ef mögulegt er, með lágmarks sett af íhlutum sem þarf til að styðja við hreyfimyndir. Fyrir þetta er möguleiki “-qconfig minimal,small, medium...”. Það tengir stillingarskrá frá Qt með mörgum fjölvi - hvað á að virkja / hvað á að slökkva á. Eftir þennan valkost bætum við öðrum fánum við uppsetninguna ef við viljum slökkva á einhverju öðru. Hér er dæmi um okkar stillingar.

Til þess að Qt virki þarftu að bæta við stýrikerfissamhæfislagi. Ein leið er að innleiða QPA (Qt Platform Abstraction). Við lögðum til grundvallar tilbúnu fb_base viðbótinni sem fylgir Qt, á grundvelli þess virkar QPA fyrir Linux. Niðurstaðan er lítil viðbót sem heitir emboxfb, sem gefur Qt framebuffer frá Embox og svo dregur það þangað án utanaðkomandi aðstoðar.

Svona lítur út fyrir að búa til viðbót

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();
}

Og svona mun endurteikningin líta út

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;
}

Fyrir vikið, með þýðanda fínstillingu fyrir minnisstærð -Os virkjuð, reyndist bókasafnsmyndin vera 3.5 MB, sem passar auðvitað ekki inn í aðalminni STM32F746. Eins og við skrifuðum þegar í annarri grein okkar um OpenCV, hefur þetta borð:

  • 1 MB ROM
  • 320 KB vinnsluminni
  • 8 MB SDRAM
  • 16 MB QSPI

Þar sem stuðningi við að keyra kóða frá QSPI hefur þegar verið bætt við OpenCV ákváðum við að byrja á því að hlaða allri Embox c Qt myndinni inn í QSPI. Og húrra, allt byrjaði nánast strax frá QSPI! En eins og í tilfelli OpenCV, þá kom í ljós að það virkar of hægt.

Flytja Qt til STM32

Þess vegna ákváðum við að gera þetta á þennan hátt - fyrst afritum við myndina í QSPI, hleðum henni svo inn í SDRAM og keyrum þaðan. Frá SDRAM varð það aðeins hraðari, en samt langt frá QEMU.

Flytja Qt til STM32

Næst var hugmynd um að taka með fljótandi punkt - þegar allt kemur til alls þá gerir Qt nokkra útreikninga á hnitum ferninga í hreyfimyndum. Við reyndum, en hér fengum við enga sjáanlega hröðun, þó inn grein Qt forritarar fullyrtu að FPU gefi verulega aukningu á hraða fyrir að „draga hreyfimyndir“ á snertiskjá. Það kann að vera umtalsvert færri útreikningar á flotpunkti í hreyfiblokkum og það fer eftir tilteknu dæmi.

Áhrifaríkasta hugmyndin var að færa framebuffer frá SDRAM yfir í innra minni. Til að gera þetta gerðum við skjámálin ekki 480x272, heldur 272x272. Við lækkuðum líka litadýptina úr A8R8G8B8 í R5G6B5 og minnkuðum þannig stærð eins pixla úr 4 í 2 bæti. Framebuffer stærðin sem myndast er 272 * 272 * 2 = 147968 bæti. Þetta gaf verulega hröðun, kannski mest áberandi, hreyfimyndin varð næstum slétt.

Nýjasta fínstillingin var að keyra Embox kóða úr vinnsluminni og Qt kóða frá SDRAM. Til að gera þetta, tengjum við fyrst, eins og venjulega, Embox saman við Qt, en við setjum texta, rodata, gögn og bss hluta bókasafnsins í QSPI til að afrita það síðan í 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))

Með því að keyra Embox kóðann frá ROM fengum við líka áberandi hröðun. Fyrir vikið reyndist hreyfimyndin nokkuð slétt:


Í lokin, þegar verið var að undirbúa greinina og prófa mismunandi Embox stillingar, kom í ljós að Qt moveblocks virka frábærlega frá QSPI með framebuffer í SDRAM og flöskuhálsinn var einmitt á stærð við framebuffer! Svo virðist sem til að sigrast á upphaflegu „skyggnusýningunni“ var 2-föld hröðun nóg vegna banal minnkunar á stærð rammabuffarans. En það var ekki hægt að ná slíkum árangri með því að flytja aðeins Embox kóðann yfir í ýmis hröð minningar (hröðunin var ekki 2, heldur um 1.5 sinnum).

Hvernig á að prófa það sjálfur

Ef þú ert með STM32F7-Discovery geturðu keyrt Qt undir Embox sjálfur. Þú getur lesið hvernig þetta er gert á okkar wiki.

Ályktun

Fyrir vikið tókst okkur að setja Qt! Flækjustig verkefnisins er að okkar mati nokkuð ýkt. Auðvitað þarftu að taka tillit til sérstöðu örstýringa og skilja almennt arkitektúr tölvukerfa. Hagræðingarniðurstöðurnar benda til þeirrar alkunnu staðreyndar að flöskuhálsinn í tölvukerfi er ekki örgjörvinn, heldur minnið.

Í ár munum við taka þátt í hátíðinni TechTrain. Þar munum við segja þér nánar og sýna Qt, OpenCV á örstýringum og önnur afrek okkar.

Heimild: www.habr.com

Bæta við athugasemd