Porting Qt għal STM32

Porting Qt għal STM32Il-waranofsinhar it-tajjeb Aħna qegħdin fil-proġett Embox nediet Qt fuq STM32F7-Discovery u tixtieq titkellem dwarha. Aktar qabel, diġà għidna kif irnexxielna nniedu OpenCV.

Qt huwa qafas bejn pjattaformi li jinkludi mhux biss komponenti grafiċi, iżda wkoll affarijiet bħal QtNetwork, sett ta 'klassijiet biex taħdem ma' databases, Qt għall-Awtomazzjoni (inkluż għall-implimentazzjoni tal-IoT) u ħafna aktar. It-tim Qt kien proattiv dwar l-użu ta 'Qt f'sistemi inkorporati, għalhekk il-libreriji huma pjuttost konfigurabbli. Madankollu, sa ftit ilu, ftit nies ħasbu dwar il-porting ta 'Qt għal mikrokontrolluri, probabbilment minħabba li kompitu bħal dan jidher diffiċli - Qt huwa kbir, MCUs huma żgħar.

Min-naħa l-oħra, bħalissa hemm mikrokontrolluri ddisinjati biex jaħdmu bil-multimedia u superjuri għall-ewwel Pentiums. Madwar sena ilu, deher il-blog Qt wara. L-iżviluppaturi għamlu port ta 'Qt għall-RTEMS OS, u nedew eżempji b'widgets fuq diversi bordijiet li jmexxu stm32f7. Dan interessatna. Kien notevoli, u l-iżviluppaturi nfushom jiktbu dwarha, li Qt huwa bil-mod fuq l-STM32F7-Discovery. Konna qed nistaqsu jekk nistgħux inħaddmu Qt taħt Embox, u mhux biss niġbdu widget, iżda nħaddmu animazzjoni.

Qt 4.8 ġie portat għal Embox għal żmien twil, għalhekk iddeċidejna li nippruvawha. Aħna għażilna l-applikazzjoni moveblocks - eżempju ta 'animazzjoni springy.

Qt moveblocks fuq QEMUPorting Qt għal STM32

Biex tibda, aħna nikkonfiguraw Qt, jekk possibbli, bis-sett minimu ta 'komponenti meħtieġa biex jappoġġjaw l-animazzjoni. Għal dan hemm għażla “-qconfig minimal,small,medium...”. Tgħaqqad fajl ta 'konfigurazzjoni minn Qt b'ħafna macros - x'għandek tippermetti / x'għandek tiddiżattiva. Wara din l-għażla, aħna nżidu bnadar oħra mal-konfigurazzjoni jekk irridu tiddiżattiva xi ħaġa oħra. Hawn eżempju ta 'tagħna konfigurazzjoni.

Sabiex Qt jaħdem, jeħtieġ li żżid saff ta 'kompatibilità OS. Mod wieħed huwa li timplimenta QPA (Qt Platform Abstraction). Ħadna bħala bażi l-plugin fb_base lest inkluż f'Qt, li fuq il-bażi tiegħu jaħdem QPA għal Linux. Ir-riżultat huwa plugin żgħir imsejjaħ emboxfb, li jipprovdi Qt mal-framebuffer ta 'Embox, u mbagħad jiġbed hemm mingħajr ebda għajnuna minn barra.

Dan huwa kif jidher li toħloq 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 (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();
}

U dan huwa kif se jidher it-tfassil mill-ġdid

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

Bħala riżultat, bl-ottimizzazzjoni tal-kompilatur għad-daqs tal-memorja -Os attivata, l-immaġni tal-librerija rriżulta li kienet ta '3.5 MB, li naturalment ma tidħolx fil-memorja ewlenija tal-STM32F746. Kif diġà ktibna fl-artiklu l-ieħor tagħna dwar OpenCV, dan il-bord għandu:

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

Peress li l-appoġġ għall-eżekuzzjoni tal-kodiċi minn QSPI diġà ġie miżjud ma 'OpenCV, iddeċidejna li nibdew billi tagħbija l-immaġni kollha ta' Embox c Qt f'QSPI. U hurra, kollox beda kważi immedjatament mill-QSPI! Iżda bħal fil-każ ta 'OpenCV, irriżulta li jaħdem bil-mod wisq.

Porting Qt għal STM32

Għalhekk, iddeċidejna li nagħmlu dan - l-ewwel nikkopjaw l-immaġini għal QSPI, imbagħad tagħbijaha f'SDRAM u tesegwixxi minn hemm. Minn SDRAM sar ftit aktar mgħaġġel, iżda għadu 'l bogħod mill-QEMU.

Porting Qt għal STM32

Sussegwentement, kien hemm idea li tinkludi punt li jvarja - wara kollox, Qt jagħmel xi kalkoli tal-koordinati tal-kwadri fl-animazzjoni. Ippruvajna, iżda hawn ma ksibna l-ebda aċċelerazzjoni viżibbli, għalkemm ġewwa artikolu L-iżviluppaturi tal-Qt sostnew li l-FPU jagħti żieda sinifikanti fil-veloċità għal "tkaxkir animazzjoni" fuq touchscreen. Jista 'jkun hemm kalkoli b'mod sinifikanti inqas floating point f'moveblocks, u dan jiddependi fuq l-eżempju speċifiku.

L-iktar idea effettiva kienet li tmexxi l-framebuffer minn SDRAM għall-memorja interna. Biex tagħmel dan, għamilna d-dimensjonijiet tal-iskrin mhux 480x272, iżda 272x272. Naqqasna wkoll il-fond tal-kulur minn A8R8G8B8 għal R5G6B5, u b'hekk naqqas id-daqs ta 'pixel wieħed minn 4 għal 2 bytes. Id-daqs tal-framebuffer li jirriżulta huwa 272 * 272 * 2 = 147968 bytes. Dan ta aċċelerazzjoni sinifikanti, forsi l-aktar notevoli, l-animazzjoni saret kważi bla xkiel.

L-aħħar ottimizzazzjoni kienet li titħaddem kodiċi Embox minn RAM u kodiċi Qt minn SDRAM. Biex nagħmlu dan, aħna l-ewwel, bħas-soltu, norbtu b'mod statiku Embox flimkien ma 'Qt, iżda npoġġu t-test, rodata, data u segmenti bss tal-librerija fil-QSPI sabiex imbagħad nikkopjah f'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))

Billi wettaq il-kodiċi Embox minn ROM, irċevejna wkoll aċċelerazzjoni notevoli. Bħala riżultat, l-animazzjoni ħarġet pjuttost bla xkiel:


Fl-aħħar nett, waqt li tħejji l-artiklu u ppruvaw konfigurazzjonijiet differenti ta 'Embox, irriżulta li Qt moveblocks jaħdem tajjeb minn QSPI b'framebuffer f'SDRAM, u l-konġestjoni kienet preċiżament id-daqs tal-framebuffer! Apparentement, biex tingħeleb il-"slideshow" inizjali, aċċelerazzjoni 2 darbiet kienet biżżejjed minħabba tnaqqis banali fid-daqs tal-framebuffer. Iżda ma kienx possibbli li jinkiseb riżultat bħal dan billi ttrasferixxi biss il-kodiċi Embox għal diversi memorji veloċi (l-aċċelerazzjoni ma kinitx 2, iżda madwar 1.5 darbiet).

Kif tipprova it yourself

Jekk għandek STM32F7-Discovery, tista 'taħdem Qt taħt Embox lilek innifsek. Tista 'taqra kif dan isir fuq tagħna wiki.

Konklużjoni

Bħala riżultat, irnexxielna nniedu Qt! Il-kumplessità tal-kompitu, fl-opinjoni tagħna, hija kemmxejn esaġerata. Naturalment, trid tqis l-ispeċifiċitajiet tal-mikrokontrolluri u ġeneralment tifhem l-arkitettura tas-sistemi tal-kompjuter. Ir-riżultati tal-ottimizzazzjoni jindikaw il-fatt magħruf li l-konġestjoni f'sistema tal-kompjuter mhix il-proċessur, iżda l-memorja.

Din is-sena ser nipparteċipaw fil-festival TechTrain. Hemmhekk ngħidulek f'aktar dettall u nuru Qt, OpenCV fuq mikrokontrolluri u kisbiet oħra tagħna.

Sors: www.habr.com

Żid kumment