Portování Qt na STM32

Portování Qt na STM32Dobrý den! Jsme v projektu Embox spustili Qt na STM32F7-Discovery a rádi bychom o tom pohovořili. Dříve jsme již popisovali, jak se nám podařilo spustit OpenCV.

Qt je multiplatformní framework, který zahrnuje nejen grafické komponenty, ale také věci jako QtNetwork, sadu tříd pro práci s databázemi, Qt for Automation (včetně implementace IoT) a mnoho dalšího. Vývojáři týmu Qt se předem připravili na použití Qt v embedded systémech, proto jsou knihovny velmi dobře konfigurovatelné. Avšak do nedávna se málo kdo zamýšlel nad portováním Qt na mikrokontroléry, pravděpodobně proto, že tato úloha vypadá složitě — Qt je velké, MCU malé.

Na druhé straně v současné době existují mikrokontroléry určené pro multimediální práci, které překonávají první Pentia. Před asi rokem se na blogu Qt objevil příspěvek. Vývojáři provedli port Qt pro OS RTEMS a spustili příklady s widgety na několika deskách pod správou stm32f7. To nás zaujalo. Bylo zřejmé, a sami vývojáři o tom píší, že Qt má na STM32F7-Discovery určité zpoždění. Zajímalo nás, zda dokážeme spustit Qt pod Embox, a to nejen nakreslit widget, ale spustit animaci.

V Emboxu už dlouho portovali Qt 4.8, takže jsme se rozhodli to zkusit. Vybrali jsme aplikaci moveblocks — příklad pružné animace.

Qt moveblocks na QEMUPortování Qt na STM32

Nejprve konfigurováme Qt co nejvíce s minimálním souborem komponent, potřebných pro podporu animace. K tomu existuje volba “-qconfig minimal,small,medium …”. Ta připojuje konfigurační soubor ze složení Qt s množstvím maker — co zapnout / co vypnout. Po této volbě přidáváme do konfigurace další vlajky, pokud nechceme něco vypnout navíc. Tady je příklad naší konfigurace.

Aby Qt fungovalo, je třeba přidat vrstvu kompatibility s OS. Jeden z způsobů — implementovat QPA (Qt Platform Abstraction). Jako základ byl použit již hotový plugin fb_base ze složení Qt, na jehož základě funguje QPA pro Linux. Výsledkem je malý plugin emboxfb, který poskytuje Qt framebuffer Emboxu, a dále už to kreslí bez cizí pomoci.

Takto vypadá vytvoření pluginu

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 (fbFd setPhysicalSize(QSize(fbWidth, fbHeight));
    mScreens.append(mPrimaryScreen);

    this->printFbInfo();
}

Takto bude vypadat překreslení

QRegion QEmboxFbScreen::doRedraw()
{
    QVector rects;
    QRegion touched = QFbScreen::doRedraw();

    DPRINTF("QEmboxFbScreen::doRedrawn");

    if (!compositePainter) {
        compositePainter = new QPainter(mFbScreenImage);
    }

    rects = touched.rects();
    for (int i = 0; i drawImage(rects[i], *mScreenImage, rects[i]);
    }
    return touched;
}

V důsledku aktivace optimalizace kompilátoru pro paměť -Os se obraz knihovny ukázal jako 3.5 MB, což rozhodně nepobírá hlavní paměť STM32F746. Jak jsme již psali v našem jiném článku o OpenCV, na této desce je:

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

Protože byla do OpenCV již přidána podpora vykonávání kódu ze QSPI, rozhodli jsme se začít tím, že jsme natáhli obraz Embox s Qt do QSPI vcelku. A hurá, vše se téměř okamžitě spustilo z QSPI! Ale stejně jako v případě OpenCV se ukázalo, že to funguje příliš pomalu.

Portování Qt na STM32

Proto jsme se rozhodli dělat to takto — nejprve kopírujeme obraz do QSPI, pak ho nahráváme do SDRAM a odtud se vykonáváme. Z SDRAM bylo trochu rychlejší, ale stále daleko od QEMU.

Portování Qt na STM32

Dále byl nápad zapnout plovoucí desetinnou čárku — protože Qt provádí některé výpočty souřadnic čtverců při animaci. Zkoušeli jsme to, ale nedosáhli jsme viditelného zrychlení, ačkoliv v článku vývojáři Qt tvrdili, že FPU přináší významný nárůst rychlosti pro "animaci táhnutí" na dotykové obrazovce. Možná, že v moveblocks je výrazně méně výpočtů s plovoucí desetinnou čárkou, a to závisí na konkrétním příkladu.

Nejúčinnějším řešením se ukázalo být přesunutí framebufferu z SDRAM do interní paměti. Pro tento účel jsme změnili rozměry obrazovky z 480×272 na 272×272. Dále jsme snížili hloubku barev z A8R8G8B8 na R5G6B5, čímž jsme zmenšili velikost jednoho pixelu ze 4 na 2 bajty. Výsledný velikost framebufferu byla 272 * 272 * 2 = 147968 bajtů. Tímto došlo k významnému zrychlení, které bylo asi nejvíce patrné, animace se stala téměř plynulou.

Posledním zlepšením bylo spuštění kódu Embox z RAM a Qt ze SDRAM. Nejprve, jak je obvyklé, staticky linkujeme Embox spolu s Qt, ale segmenty text, rodata, data a bss knihovny umísťujeme do QSPI, abychom je následně mohli zkopírovat do 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))

Spuštěním kódu Embox z ROM jsme také dosáhli znatelného zrychlení. Výsledkem je, že animace je dostatečně plynulá:

Přehrát video

Na samém konci, při přípravě článku a zkoušení různých konfigurací Emboxu, se ukázalo, že Qt moveblocks funguje skvěle i z QSPI s framebufferem v SDRAM, přičemž užším místem byl právě velikost framebufferu! Zdá se, že pro překonání počátečního "slideshow" stačilo zrychlení 2x jednoduchým snížením velikosti framebufferu. A dosáhnout takového výsledku přesunutím pouze kódu Embox do různých rychlých pamětí se nepodařilo (zrychlení bylo ne 2x, ale přibližně 1,5x).

Jak to vyzkoušet sám

Pokud máte STM32F7-Discovery, můžete spustit Qt pod Embox sami. Přečíst si, jak na to, můžete na našich wiki.

Závěr

Nakonec se nám podařilo spustit Qt! Obtížnost úkolu se nám na náš názor jeví jako poněkud přehnaná. Je samozřejmě třeba vzít v úvahu specifika mikrokontrolérů a vůbec rozumět architektuře výpočetních systémů. Výsledky optimalizace ukazují na známý fakt, že nejslabším článkem ve výpočetním systému není procesor, ale paměť.

Tento rok se zúčastníme festivalu TechTrain. Na něm podrobněji přiblížíme a ukážeme Qt, OpenCV na mikrokontrolérech a další naše úspěchy.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster