Cludo Qt i STM32

Cludo Qt i STM32Prynhawn Da Rydym yn y prosiect Embox lansio Qt ar STM32F7-Discovery a hoffai siarad amdano. Yn gynharach, dywedasom eisoes sut y gwnaethom lwyddo i lansio OpenCV.

Mae Qt yn fframwaith traws-lwyfan sy'n cynnwys nid yn unig cydrannau graffigol, ond hefyd pethau fel QtNetwork, set o ddosbarthiadau ar gyfer gweithio gyda chronfeydd data, Qt for Automation (gan gynnwys ar gyfer gweithredu IoT) a llawer mwy. Mae tîm Qt wedi bod yn rhagweithiol ynglŷn â defnyddio Qt mewn systemau wedi'u mewnosod, felly mae'r llyfrgelloedd yn eithaf ffurfweddadwy. Fodd bynnag, tan yn ddiweddar, ychydig o bobl a feddyliodd am borthi Qt i ficroreolyddion, yn ôl pob tebyg oherwydd bod tasg o'r fath yn ymddangos yn anodd - mae Qt yn fawr, mae MCUs yn fach.

Ar y llaw arall, ar hyn o bryd mae microreolyddion wedi'u cynllunio i weithio gydag amlgyfrwng ac yn well na'r Pentiums cyntaf. Tua blwyddyn yn ôl, ymddangosodd blog Qt post. Gwnaeth y datblygwyr borthladd o Qt ar gyfer yr RTEMS OS, a lansiodd enghreifftiau gyda widgets ar sawl bwrdd yn rhedeg stm32f7. Roedd hyn o ddiddordeb i ni. Roedd yn amlwg, ac mae'r datblygwyr eu hunain yn ysgrifennu amdano, bod Qt yn araf ar y STM32F7-Discovery. Roeddem yn meddwl tybed a allem redeg Qt o dan Embox, ac nid tynnu teclyn yn unig, ond rhedeg animeiddiad.

Mae Qt 4.8 wedi cael ei gludo i Embox ers amser maith, felly fe benderfynon ni roi cynnig arni. Fe wnaethom ddewis y cymhwysiad moveblocks - enghraifft o animeiddiad springy.

Symud blociau Qt ar QEMUCludo Qt i STM32

I ddechrau, rydym yn ffurfweddu Qt, os yn bosibl, gyda'r set leiaf o gydrannau sydd eu hangen i gefnogi animeiddio. Ar gyfer hyn mae opsiwn "-qconfig minimal, bach, canolig ...". Mae'n cysylltu ffeil ffurfweddu o Qt gyda llawer o macros - beth i'w alluogi / beth i'w analluogi. Ar ôl yr opsiwn hwn, rydym yn ychwanegu baneri eraill at y ffurfweddiad os ydym am analluogi rhywbeth arall. Dyma enghraifft o'n cyfluniad.

Er mwyn i Qt weithio, mae angen ichi ychwanegu haen gydnawsedd OS. Un ffordd yw gweithredu QPA (Qt Platform Abstraction). Cymerasom fel sail yr ategyn fb_base parod sydd wedi'i gynnwys yn Qt, y mae QPA ar gyfer Linux yn gweithio ar ei sail. Y canlyniad yw ategyn bach o'r enw emboxfb, sy'n darparu'r Embox framebuffer i Qt, ac yna mae'n tynnu yno heb unrhyw gymorth allanol.

Dyma sut olwg sydd ar greu ategyn

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

A dyma sut olwg fydd ar yr ail-lunio

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

O ganlyniad, gyda'r optimeiddio casglwr ar gyfer maint cof -Os wedi'i alluogi, trodd delwedd y llyfrgell i fod yn 3.5 MB, nad yw wrth gwrs yn ffitio i brif gof y STM32F746. Fel yr ydym eisoes wedi ysgrifennu yn ein herthygl arall am OpenCV, mae gan y bwrdd hwn:

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

Gan fod cefnogaeth ar gyfer gweithredu cod gan QSPI eisoes wedi'i ychwanegu at OpenCV, fe benderfynon ni ddechrau trwy lwytho'r ddelwedd Embox c Qt gyfan i QSPI. A hurray, dechreuodd popeth bron yn syth o QSPI! Ond fel yn achos OpenCV, daeth yn amlwg ei fod yn gweithio'n rhy araf.

Cludo Qt i STM32

Felly, fe benderfynon ni ei wneud fel hyn - yn gyntaf rydyn ni'n copïo'r ddelwedd i QSPI, yna'n ei llwytho i SDRAM a'i gweithredu oddi yno. O SDRAM daeth ychydig yn gyflymach, ond yn dal i fod ymhell o QEMU.

Cludo Qt i STM32

Nesaf, roedd syniad i gynnwys pwynt arnawf - wedi'r cyfan, mae Qt yn gwneud rhai cyfrifiadau o gyfesurynnau sgwariau mewn animeiddiad. Ceisiwyd, ond yma ni chawsom unrhyw gyflymiad gweladwy, er yn Erthygl Honnodd datblygwyr Qt fod FPU yn rhoi cynnydd sylweddol mewn cyflymder ar gyfer “llusgo animeiddio” ar sgrin gyffwrdd. Efallai y bydd llawer llai o gyfrifiadau pwynt arnawf mewn blociau symud, ac mae hyn yn dibynnu ar yr enghraifft benodol.

Y syniad mwyaf effeithiol oedd symud y byffer ffrâm o SDRAM i'r cof mewnol. I wneud hyn, gwnaethom ni ddimensiynau'r sgrin 480x272, ond 272x272. Fe wnaethom hefyd ostwng y dyfnder lliw o A8R8G8B8 i R5G6B5, gan leihau maint un picsel o 4 i 2 beit. Maint y framebuffer canlyniadol yw 272 * 272 * 2 = 147968 bytes. Rhoddodd hyn gyflymiad sylweddol, efallai yn fwyaf amlwg, daeth yr animeiddiad bron yn llyfn.

Yr optimeiddio diweddaraf oedd rhedeg cod Embox o RAM a chod Qt o SDRAM. I wneud hyn, rydym yn gyntaf, fel arfer, yn cysylltu Embox yn statig â Qt, ond rydym yn gosod segmentau testun, rodata, data a bss y llyfrgell yn QSPI er mwyn ei gopïo i 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))

Trwy weithredu'r cod Embox o ROM, cawsom gyflymiad amlwg hefyd. O ganlyniad, trodd yr animeiddiad yn eithaf llyfn:


Ar y diwedd, wrth baratoi'r erthygl a rhoi cynnig ar wahanol gyfluniadau Embox, daeth i'r amlwg bod symud blociau Qt yn gweithio'n wych o QSPI gyda byffer ffrâm yn SDRAM, ac roedd y dagfa yn union faint y byffer ffrâm! Yn ôl pob tebyg, i oresgyn y “sioe sleidiau” gychwynnol, roedd cyflymiad deublyg yn ddigon oherwydd gostyngiad banal ym maint y byffer ffrâm. Ond nid oedd yn bosibl cyflawni canlyniad o'r fath trwy drosglwyddo'r cod Embox yn unig i wahanol atgofion cyflym (nid oedd y cyflymiad yn 2, ond tua 2 gwaith).

Sut i roi cynnig arni eich hun

Os oes gennych STM32F7-Discovery, gallwch redeg Qt o dan Embox eich hun. Gallwch ddarllen sut mae hyn yn cael ei wneud ar ein wiki.

Casgliad

O ganlyniad, rydym wedi llwyddo i lansio Qt! Mae cymhlethdod y dasg, yn ein barn ni, wedi'i orliwio braidd. Yn naturiol, mae angen i chi ystyried manylion microreolyddion a deall pensaernïaeth systemau cyfrifiadurol yn gyffredinol. Mae'r canlyniadau optimeiddio yn tynnu sylw at y ffaith adnabyddus nad y brosesydd yw'r dagfa mewn system gyfrifiadurol, ond y cof.

Eleni byddwn yn cymryd rhan yn yr ŵyl TechTrain. Yno byddwn yn dweud wrthych yn fwy manwl ac yn dangos Qt, OpenCV ar ficroreolyddion a'n cyflawniadau eraill.

Ffynhonnell: hab.com

Ychwanegu sylw