Veguheztina Qt bo STM32

Veguheztina Qt bo STM32Paş nîvro Em di projeyê de ne Embox Qt li ser STM32F7-Discovery da destpêkirin û dixwazim li ser wê biaxivim. Berê, me berê jî got ku me çawa dest pê kir OpenCV.

Qt çarçoveyek cross-platformê ye ku ne tenê hêmanên grafîkî, lê di heman demê de tiştên wekî QtNetwork, komek çînên ji bo xebata bi databasan, Qt ji bo Otomasyonê (di nav de ji bo pêkanîna IoT) û hêj bêtir vedihewîne. Tîma Qt di derbarê karanîna Qt-ê de di pergalên pêvekirî de çalak e, ji ber vê yekê pirtûkxane pir têne mîheng kirin. Lêbelê, heya van demên dawî, hindik kes difikirîn ku Qt bi mîkrokontrolkeran veguhezînin, dibe ku ji ber ku karekî wusa dijwar xuya dike - Qt mezin e, MCU piçûk in.

Ji hêla din ve, di vê gavê de mîkrokontrolker hene ku ji bo ku bi multimedia re bixebitin û ji Pentiumên yekem bilindtir in hatine çêkirin. Nêzîkî salek berê, bloga Qt xuya bû post. Pêşdebiran ji bo RTEMS OS-ê portek Qt çêkirin, û nimûneyên bi widgetan li ser gelek tabloyên ku stm32f7 dixebitin dan destpêkirin. Ev me eleqedar kir. Balkêş bû, û pêşdebiran bixwe li ser wê dinivîsin, ku Qt li ser STM32F7-Discovery hêdî ye. Me meraq dikir gelo em dikarin Qt-ê di binê Embox-ê de bimeşînin, û ne tenê widgetek xêz bikin, lê anîmasyonek bimeşînin.

Qt 4.8 ji bo demek dirêj ve li Embox-ê hatî veguheztin, ji ber vê yekê me biryar da ku em wê li ser biceribînin. Me serîlêdana moveblocks hilbijart - mînakek anîmasyonek biharî.

Qt li ser QEMU bar dikeVeguheztina Qt bo STM32

Ji bo destpêkê, em Qt-ê, heke gengaz be, bi mînîmal komek pêkhateyên ku ji bo piştgirîkirina anîmasyonê hewce ne mîheng dikin. Ji bo vê vebijarkek "-qconfig mînîmal, piçûk, navîn ..." heye. Ew pelek mîhengê ji Qt-ê bi gelek makroyan ve girêdide - çi çalak bike / çi were neçalak kirin. Piştî vê vebijarkê, heke em dixwazin tiştek din neçalak bikin, em alayên din li veavakirinê zêde dikin. Li vir mînakek me ye veavakirina.

Ji bo ku Qt bixebite, divê hûn qatek lihevhatina OS-ê lê zêde bikin. Yek rê pêkanîna QPA (Qt Platforma Abstraction) ye. Me pêveka fb_base ya amadekirî ya ku di Qt-ê de tê de tête bingeh girt, li ser bingeha ku QPA ji bo Linux dixebite. Encam pêvekek piçûk e ku jê re emboxfb tê gotin, ku Qt bi çarçoweya Embox-ê re peyda dike, û dûv re ew bêyî arîkariya derveyî li wir dikişîne.

Ya ku afirandina pêvekek xuya dike ev e

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

Û ev e ya ku ji nû ve xêzkirin dê xuya bike

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

Wekî encamek, digel ku xweşbîniya berhevkerê ji bo mezinahiya bîranînê -Os çalak e, wêneya pirtûkxaneyê derket 3.5 MB, ku bê guman di bîra sereke ya STM32F746 de cih nagire. Wekî ku me berê di gotara xweya din de di derbarê OpenCV de nivîsand, vê panelê heye:

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

Ji ber ku piştgirî ji bo cîbicîkirina kodê ji QSPI jixwe li OpenCV-ê hatiye zêdekirin, me biryar da ku em dest bi barkirina tevahiya wêneya Embox c Qt li QSPI bikin. Û hurray, her tişt hema yekser ji QSPI dest pê kir! Lê wekî di doza OpenCV de, derket holê ku ew pir hêdî dixebite.

Veguheztina Qt bo STM32

Ji ber vê yekê, me biryar da ku em bi vî rengî bikin - pêşî em wêneyê li QSPI-yê kopî dikin, dûv re wê li SDRAM-ê bar dikin û ji wir bicîh dikin. Ji SDRAM ew hinekî zûtir bû, lê hîn jî ji QEMU dûr.

Veguheztina Qt bo STM32

Dûv re, ramanek hebû ku meriv xalek herikbar bihewîne - her tiştî, Qt di anîmasyonê de hin hesabên koordînatên çargoşeyan dike. Me hewl da, lê li vir me tu lezbûnek xuya negirt, her çend di nav de gotara Pêşdebirên Qt îdîa kirin ku FPU ji bo "kişandina anîmasyonê" li ser ekrana destikê lezek girîng dide. Dibe ku di blokên tevgerê de hejmartinên xala herikandinê pir hindiktir hebin, û ev bi mînaka taybetî ve girêdayî ye.

Ramana herî bi bandor ew bû ku framebuffer ji SDRAM-ê berbi bîra navxweyî veguhezîne. Ji bo vê yekê, me pîvanên ekranê ne 480x272, lê 272x272 kir. Me her weha kûrahiya rengan ji A8R8G8B8 daxist R5G6B5, bi vî rengî mezinahiya yek pixel ji 4 ber 2 bayt kêm kir. Mezinahiya framebuffera encam 272 * 272 * 2 = 147968 byte ye. Vê yekê lezek girîng da, dibe ku ya herî berbiçav, anîmasyon hema hema nerm bû.

Optimîzasyona herî paşîn ev bû ku koda Embox ji RAM û koda Qt ji SDRAM-ê were xebitandin. Ji bo kirina vê yekê, em pêşî, wekî her car, Embox bi Qt re bi statîkî ve girêdidin, lê em beşên nivîs, roda, dane û bss yên pirtûkxaneyê li QSPI-yê bi cih dikin da ku paşê wê li SDRAM-ê kopî bikin.

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))

Bi pêkanîna koda Emboxê ya ji ROM-ê, me lezek berbiçav jî wergirt. Wekî encamek, anîmasyon pir xweş derket:


Di dawiyê de, dema amadekirina gotarê û ceribandina mîhengên cihêreng ên Embox-ê, derket holê ku Qt moveblocks ji QSPI-yê bi çarçoveyek li SDRAM-ê re pir baş dixebite, û qeçik bi rastî mezinahiya framebufferê bû! Xuya ye, ji bo têkbirina "slideshow"a destpêkê, ji ber kêmbûna banalî ya mezinahiya framebufferê lezek 2-qatî bes bû. Lê ne gengaz bû ku bi veguheztina tenê koda Embox-ê li bîranînên cihêreng ên bilez (lezkirin ne 2, lê bi qasî 1.5 carî) encamek wusa bi dest bixe.

Meriv çawa xwe biceribîne

Ger we STM32F7-Dîspêkirinek heye, hûn dikarin Qt-ê di binê Emboxê de bi xwe bimeşînin. Hûn dikarin bixwînin ka ev çawa li ser me tê kirin wiki wiki.

encamê

Di encamê de, me karî Qt bidin destpêkirin! Tevliheviya peywirê, li gorî me, hinekî zêde ye. Bi xwezayî, hûn hewce ne ku taybetmendiyên mîkrokontrolkeran bihesibînin û bi gelemperî mîmariya pergalên komputerê fam bikin. Encamên xweşbîniyê rastiya naskirî destnîşan dikin ku di pergalek hesabker de kêşa ne pêvajoker, lê bîranîn e.

Em ê îsal beşdarî festîvalê bibin TechTrain. Li wir em ê bi hûrgulî ji we re vebêjin û Qt, OpenCV li ser mîkrokontrolkeran û destkeftiyên me yên din nîşan bidin.

Source: www.habr.com

Add a comment