Porting di Qt su STM32

Porting di Qt su STM32Buongiorno! Siamo nel progetto Embox abbiamo avviato Qt su STM32F7-Discovery e vorremmo parlarne. In precedenza, abbiamo già raccontato come siamo riusciti a far partire OpenCV.

Qt è un framework multipiattaforma che include non solo componenti grafici, ma anche cose come QtNetwork, un insieme di classi per lavorare con i database, Qt for Automation (incluso per l'implementazione dell'IoT) e molto altro. I sviluppatori del team Qt hanno anticipato l'uso di Qt nei sistemi embedded, quindi le librerie sono abbastanza ben configurabili. Tuttavia, fino a poco tempo fa, pochi avevano considerato il porting di Qt su microcontrollori, probabilmente perché un compito del genere sembra difficile — Qt è grande, i MCU sono piccoli.

D'altra parte, attualmente ci sono microcontrollori progettati per lavorare con la multimedialità e che superano i primi Pentium. Circa un anno fa, nel blog di Qt è apparso un post. Gli sviluppatori hanno creato una portazione di Qt per il sistema operativo RTEMS e hanno eseguito esempi con widget su diverse schede basate su stm32f7. Questo ci ha intrigato. Era evidente, e gli stessi sviluppatori ne hanno parlato, che Qt rallentava sulla STM32F7-Discovery. Ci siamo chiesti se fossimo in grado di eseguire Qt su Embox, non limitandoci a disegnare un widget, ma avviando anche un'animazione.

Su Embox è già stata portata da tempo la versione Qt 4.8, quindi abbiamo deciso di provare a usarla. Abbiamo scelto l'applicazione moveblocks — un esempio di animazione a molla.

Qt moveblocks su QEMUPorting di Qt su STM32

Per iniziare, configuriamo Qt con il più piccolo insieme possibile di componenti necessari per supportare l'animazione. Per questo esiste l'opzione “-qconfig minimal,small,medium …”. Questa opzione collega un file di configurazione di Qt che contiene molti macro — cosa attivare / cosa disattivare. Dopo questa opzione, aggiungiamo alla configurazione altri flag se vogliamo disabilitare ulteriormente qualcosa. Ecco un esempio della nostra configurazione.

Per far funzionare Qt, è necessario aggiungere uno strato di compatibilità con il sistema operativo. Uno dei modi è implementare il QPA (Qt Platform Abstraction). Si è preso come base un plugin già esistente, fb_base, che fa parte di Qt e su cui si basa il QPA per Linux. Alla fine è stato creato un piccolo plugin emboxfb, che fornisce a Qt il framebuffer di Embox, e poi disegna su di esso senza ulteriore assistenza.

Ecco come appare la creazione di un 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 (fbFd setPhysicalSize(QSize(fbWidth, fbHeight));
    mScreens.append(mPrimaryScreen);

    this->printFbInfo();
}

Ecco come apparirà il ridisegno

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

Di conseguenza, con l'ottimizzazione del compilatore abilitata per la memoria -Os, l'immagine della libreria è risultata di 3.5 MB, che naturalmente non entra nella memoria principale STM32F746. Come abbiamo già scritto nel nostro altro articolo su OpenCV, su questa scheda ci sono:

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

Poiché per OpenCV è già stata aggiunta la supporto per l'esecuzione del codice da QSPI, abbiamo deciso di iniziare caricando completamente l'immagine di Embox con Qt in QSPI. E, finalmente, tutto è partito quasi immediatamente da QSPI! Ma, come nel caso di OpenCV, si è rivelato funzionare troppo lentamente.

Porting di Qt su STM32

Quindi abbiamo deciso di procedere in questo modo: prima copiamo l'immagine in QSPI, poi la carichiamo in SDRAM ed eseguiamo da lì. Da SDRAM è stato leggermente più veloce, ma comunque lontano da QEMU.

Porting di Qt su STM32

In seguito, l'idea era di attivare la virgola mobile — dal momento che Qt esegue alcuni calcoli delle coordinate dei quadrati nell'animazione. Ci abbiamo provato, ma non abbiamo ottenuto un miglioramento visibile, anche se in articolo Gli sviluppatori di Qt hanno affermato che l'FPU offre un notevole aumento della velocità per l'animazione di trascinamento su touchscreen. È possibile che nel movimento dei blocchi ci siano molte meno operazioni in virgola mobile, e ciò dipende dal caso specifico.

L'idea più efficace si è rivelata essere il trasferimento del framebuffer dalla SDRAM alla memoria interna. Per fare questo, abbiamo impostato le dimensioni dello schermo non a 480×272, ma a 272×272. Abbiamo anche ridotto la profondità del colore da A8R8G8B8 a R5G6B5, riducendo così la dimensione di un pixel da 4 a 2 byte. Abbiamo ottenuto una dimensione del framebuffer di 272 * 272 * 2 = 147968 byte. Questo ha dato un notevole aumento di velocità, probabilmente il più evidente, e l'animazione è diventata quasi fluida.

L'ultima ottimizzazione è stata l'esecuzione del codice Embox dalla RAM e di Qt dalla SDRAM. Per questo, prima come al solito, colleghiamo staticamente Embox insieme a Qt, ma posizioniamo i segmenti text, rodata, data e bss della libreria nel QSPI, in modo da poterli poi copiare nella 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))

L'esecuzione del codice Embox dalla ROM ha anche portato a un sensibile aumento di velocità. Alla fine, l'animazione è risultata sufficientemente fluida:

Riproduci video

Giunti ormai alla fine della preparazione dell'articolo e provando diverse configurazioni di Embox, è emerso che Qt moveblocks funziona splendidamente anche da QSPI con framebuffer in SDRAM; il collo di bottiglia era proprio nelle dimensioni del framebuffer! A quanto pare, per superare il primo "slideshow" bastava un'accelerazione di 2 volte grazie alla semplice riduzione delle dimensioni del framebuffer. Non siamo riusciti a ottenere lo stesso risultato semplicemente trasferendo il codice di Embox in diverse memorie veloci (l'accelerazione si attestava su circa 1,5 volte).

Come provare da soli

Se avete un STM32F7-Discovery, potete avviare Qt sotto Embox da soli. Potete leggere come farlo nel nostro wiki.

Conclusione

Alla fine siamo riusciti a far partire Qt! La difficoltà del compito, a nostro avviso, è stata leggermente esagerata. È ovvio che è necessario tenere conto della specificità dei microcontrollori e comprendere l'architettura dei sistemi computazionali. I risultati dell'ottimizzazione evidenziano il fatto noto che il vero collo di bottiglia di un sistema computazionale non è la CPU, ma la memoria.

Quest'anno parteciperemo al festival TechTrain. Lì parleremo in dettaglio e mostreremo Qt, OpenCV sui microcontrollori e altri nostri successi.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster