Porting Qt mun STM32

Porting Qt mun STM32Wilujeng sonten Kami dina proyék Embox dibuka Qt on STM32F7-Papanggihan tur hoyong ngobrol ngeunaan eta. Sateuacanna, kami parantos nyarios kumaha urang tiasa ngaluncurkeun OpenCV.

Qt mangrupakeun kerangka cross-platform nu ngawengku teu ukur komponén grafis, tapi ogé hal kayaning QtNetwork, susunan kelas pikeun gawé bareng database, Qt pikeun Automation (kaasup pikeun palaksanaan IoT) jeung loba deui. Tim Qt geus proaktif ngeunaan ngagunakeun Qt dina sistem embedded, jadi perpustakaan rada configurable. Sanajan kitu, nepi ka ayeuna, sababaraha urang mikir ngeunaan porting Qt ka microcontrollers, meureun kusabab tugas sapertos sigana hese - Qt badag, MCUs leutik.

Di sisi anu sanés, ayeuna aya mikrokontroler anu dirancang pikeun damel sareng multimédia sareng punjul ti Pentium munggaran. Ngeunaan sataun katukang, blog Qt mucunghul pasang. Pamekar dijieun port of Qt pikeun RTEMS OS, sarta dibuka conto kalawan widget dina sababaraha dewan ngajalankeun stm32f7. Ieu museurkeun kami. Ieu noticeable, sarta pamekar sorangan nulis ngeunaan eta, yén Qt slow on STM32F7-Papanggihan. Kami wondering lamun urang bisa ngajalankeun Qt handapeun Embox, na teu ngan ngagambar widget, tapi ngajalankeun hiji animasi.

Qt 4.8 parantos lami dialihkeun ka Embox, ku kituna kami mutuskeun pikeun nyobian éta. Kami milih aplikasi moveblocks - conto animasi springy.

Qt moveblocks on QEMUPorting Qt mun STM32

Pikeun mimitian, urang ngonpigurasikeun Qt, lamun mungkin, jeung set minimum komponén diperlukeun pikeun ngarojong animasi. Pikeun ieu aya pilihan "-qconfig minimal, leutik, sedeng ...". Ieu nyambungkeun file konfigurasi ti Qt kalawan loba macros - naon ngaktipkeun / naon nganonaktipkeun. Saatos pilihan ieu, urang tambahkeun umbul séjén kana konfigurasi upami urang hoyong nganonaktipkeun anu sanés. Ieu conto urang konfigurasi.

Supaya Qt tiasa dianggo, anjeun kedah nambihan lapisan kasaluyuan OS. Salah sahiji cara nyaéta ngalaksanakeun QPA (Qt Platform Abstraction). Simkuring nyandak salaku dadasar plugin fb_base siap-dijieun kaasup dina Qt, dina dasar nu QPA pikeun Linux Ubuntu jalan. hasilna mangrupakeun plugin leutik disebut emboxfb, nu nyadiakeun Qt kalawan framebuffer Embox urang, lajeng draws aya tanpa pitulung luar.

Ieu naon nyieun plugin a Sigana mah

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

Sareng ieu anu bakal katingali ku ngagambar ulang

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

Hasilna, ku optimasi kompiler pikeun ukuran memori -Os diaktipkeun, gambar perpustakaan tétéla 3.5 MB, nu tangtu teu cocog kana mémori utama STM32F746. Sakumaha urang parantos nyerat dina tulisan kami anu sanés ngeunaan OpenCV, papan ieu ngagaduhan:

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

Kusabab rojongan pikeun executing kode ti QSPI geus ditambahkeun kana OpenCV, urang mutuskeun pikeun ngamimitian ku ngamuat sakabéh gambar Embox c Qt kana QSPI. Jeung hurray, sagalana dimimitian ampir langsung ti QSPI! Tapi sakumaha dina kasus OpenCV, tétéla éta jalan teuing lalaunan.

Porting Qt mun STM32

Ku alatan éta, urang mutuskeun pikeun ngalakukeunana ku cara kieu - mimiti urang nyalin gambar ka QSPI, lajeng muka kana SDRAM tur ngajalankeun ti dinya. Ti SDRAM janten sakedik gancang, tapi masih jauh ti QEMU.

Porting Qt mun STM32

Salajengna, aya hiji gagasan pikeun ngawengku hiji titik floating - sanggeus kabeh, Qt ngalakukeun sababaraha itungan koordinat kuadrat dina animasi. Urang diusahakeun, tapi di dieu urang teu meunang sagala akselerasi katempo, sanajan dina artikel pamekar Qt ngaku yén FPU méré kanaékan signifikan dina speed pikeun "nyeret animasi" dina layar rampa. Meureun aya itungan titik floating nyata kirang dina moveblocks, sarta ieu gumantung kana conto husus.

Gagasan paling éféktif éta mindahkeun framebuffer ti SDRAM ka memori internal. Jang ngalampahkeun ieu, urang nyieun dimensi layar teu 480x272, tapi 272x272. Urang ogé lowered jero warna ti A8R8G8B8 mun R5G6B5, sahingga ngurangan ukuran hiji piksel ti 4 ka 2 bait. Ukuran framebuffer hasilna nyaeta 272 * 272 * 2 = 147968 bait. Ieu masihan hiji akselerasi signifikan, sugan paling noticeably, animasi jadi ampir lemes.

Optimasi panganyarna éta ngajalankeun kode Embox tina RAM jeung kode Qt ti SDRAM. Jang ngalampahkeun ieu, urang mimitina, sakumaha biasa, statically link Embox bareng jeung Qt, tapi urang nempatkeun téks, rodata, data jeung bagéan bss perpustakaan di QSPI guna lajeng nyalin ka 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))

Ku ngalaksanakeun kode Embox tina ROM, kami ogé nampi akselerasi anu nyata. Hasilna, animasi tétéla rada lancar:


Dina tungtungna, bari Nyiapkeun artikel na nyobian konfigurasi Embox béda, tétéla yén Qt moveblocks jalan hébat ti QSPI kalawan framebuffer di SDRAM, sarta bottleneck éta persis ukuran framebuffer nu! Tétéla, pikeun nungkulan awal "slideshow", a 2-melu akselerasi cukup alatan réduksi banal dina ukuran framebuffer nu. Tapi ieu teu mungkin pikeun ngahontal hasil misalna ku mindahkeun ngan kode Embox ka sagala rupa kenangan gancang (akselerasi teu 2, tapi ngeunaan 1.5 kali).

Kumaha coba sorangan

Upami Anjeun gaduh STM32F7-Papanggihan, anjeun tiasa ngajalankeun Qt handapeun Embox diri. Anjeun tiasa maca kumaha ieu dilakukeun dina kami wiki.

kacindekan

Hasilna, urang junun ngajalankeun Qt! Pajeulitna tugas, dina pamadegan urang, rada exaggerated. Alami, anjeun kedah tumut kana akun spésifik mikrokontroler sareng umumna ngartos arsitektur sistem komputer. Hasil optimasi nunjuk ka kanyataan well-dipikawanoh yén bottleneck dina sistem komputasi sanes processor, tapi mémori.

Taun ieu urang bakal ilubiung dina festival TechTrain. Di dinya kami bakal nyarioskeun ka anjeun langkung rinci sareng nunjukkeun Qt, OpenCV dina mikrokontroler sareng prestasi kami anu sanés.

sumber: www.habr.com

Tambahkeun komentar