Integration einer Grafikbibliothek für Mikrocontroller in das LVGL-Projekt

LVGL - Light and Versatile Graphics Library, auch bekannt als LittleVGL.





Die Bibliothek unterstützt eine große Anzahl von Mikrocontrollern wie STM32, ESP32 und andere. Bisher habe ich es geschafft, ein vollständiges Demo-Programm auf ESP32 und STM32f429 Discovery auszuführen. Die Bibliothek ist Open Source und unterstützt eine große Anzahl grafischer Elemente mit dunklen und hellen Themen. Unter der MIT-Lizenz vertrieben. Kann auch in kommerziellen Produkten frei verwendet werden. Sie können eine interaktive Online-Demo ansehen, ohne sie auf dem Gerät zu installieren



Die Bibliothek unterstützt die Verbindung zweier Anzeigetypen



  1. Direkt über die RGB-Schnittstelle, wo sich der Puffer auf der MCU-Seite im internen RAM oder im externen SDRAM befindet
  2. Über einen externen Display-Controller. In diesem Fall kann die MCU über den SPI- oder I2C-Bus mit dem Display-Controller kommunizieren. Um die Leistung zu verbessern, können in diesem Fall auch Zwischen-Renderpuffer innerhalb der MCU verwendet werden.


Zwei typische Hardware-Setups
MCU with TFT/LCD driver If your MCU has a TFT/LCD driver periphery then you can connect a display directly via RGB interface. In this case, the frame buffer can be in the internal RAM (if the MCU has enough RAM) or in the external RAM (if the MCU has a memory interface).



External display controller If the MCU doesn't have TFT/LCD driver interface then an external display controller (E.g. SSD1963, SSD1306, ILI9341) has to be used. In this case, the MCU can communicate with the display controller via Parallel port, SPI or sometimes I2C. The frame buffer is usually located in the display controller which saves a lot of RAM for the MCU.





In dieser Hinsicht ist alles sehr flexibel. Wenn Sie einen Treiber haben, die Bibliothek jedoch noch keinen Port für diesen Treiber hat, können Sie die Bibliothek problemlos selbst in Ihr Projekt integrieren. Der



einfachste, aber auch langsamste Weg besteht darin, den Zeichnungsrückruf neu zu schreiben - my_flush_cb



void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
    int32_t x, y;
    for(y = area->y1; y <= area->y2; y++) {
        for(x = area->x1; x <= area->x2; x++) {
            put_px(x, y, *color_p)
            color_p++;
        }
    }

    /* IMPORTANT!!!
     * Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp);
}


put_px - Dies ist das Pixel-Rendering Ihres Treibers. Aufgrund der Tatsache, dass das Rendern Pixel für Pixel erfolgt, ist dies langsam. In der Bibliotheksdokumentation werden weitere effizientere Integrationsmethoden beschrieben.



Integration von LVGL in das Projekt. Die erste besteht darin, die Bibliothek, das Anzeige- und das Eingabesystem zu initialisieren.




   lv_init();
   tft_init();
   touchpad_init();

   lv_demo_widgets();  //     


Da die Bibliothek einen Task-Manager in sich hat. Ja, dies ist ein Multithread-System. Wenn dies nicht der Fall ist, müssen wir den internen Zähler des Dispatchers erhöhen, indem wir lv_tick_inc aufrufen



void * tick_thread (void *args)
{
      while(1) {
        usleep(5*1000);   /*Sleep for 5 millisecond*/
        lv_tick_inc(5);      /*Tell LVGL that 5 milliseconds were elapsed*/
    }
}


Darüber hinaus ist es notwendig, auf die Funktion Millisekunden zu übertragen, die seit dem Moment ihres letzten Aufrufs oder mit anderen Worten der Zeit seit dem Moment der vorherigen Iteration vergangen sind.



Um keine Ressourcen für einen zusätzlichen Thread zu verschwenden, können Sie diese Funktion bei einem Timer-Interrupt aufrufen. STM32 verfügt über einen SysTick-Timer für folgende Zwecke:




void systickInit (uint16_t frequency)
{
   RCC_ClocksTypeDef RCC_Clocks;
   RCC_GetClocksFreq (&RCC_Clocks);
   (void) SysTick_Config (RCC_Clocks.HCLK_Frequency / frequency);
}

extern "C" void SysTick_Handler (void)
 {
      lv_tick_inc(1);    // 1 ms
 }


SysTick-Timer
This timer is dedicated to real-time operating systems, but could also be used as a standard

downcounter. It features:



  • A 24-bit downcounter
  • Autoreload capability
  • Maskable system interrupt generation when the counter reaches 0
  • Programmable clock source.




Es ist auch notwendig, lv_task_handler in der Schleife aufzurufen. Es wird empfohlen, alle 5 ms zu ruckeln, um eine gute Reaktion zu gewährleisten. Ich habe versucht, auf 20 ms zu erhöhen, und das System war immer noch sehr reaktionsschnell und flüssig. Kann als ewige Schleife belassen werden oder Thread verwenden



while(1) {
  lv_task_handler();
  my_delay_ms(5);
}


Die Schleifen sollten sich an verschiedenen Stellen befinden. Ich habe einen Fehler gemacht und lv_tick_inc und lv_task_handler in eine Schleife gestopft. Folgendes kam dabei heraus: Bremsen



Als beide Methoden in den richtigen Intervallen in verschiedene Streams aufgeteilt wurden, funktionierte alles korrekt und schnell:





Die Bibliothek kann die Anzahl der internen Puffer anpassen:



  1. Ein Puffer, wenn LVGL den Inhalt des Bildschirms in einen Puffer zeichnet und an die Anzeige sendet
  2. Zwei Teilbildschirmpuffer werden beim Rendern in einem Puffer gesendet, um den Inhalt des anderen Puffers im Hintergrund anzuzeigen
  3. Zwei Vollbildpuffer


Die Site verfügt über einen Konverter für Schriftarten und Bilder . Sie können Ihre Schriftart sicher zum Projekt oder zu Ihrem Symbol im Menü hinzufügen. Darüber hinaus können Sie Bilder optional von einem externen Speicher wie einer CD-CARD oder von einem Array von Bytes im internen Flash-Speicher laden.



Wie verwende ich die generierte Datei in LittlevGL?
For C arrays

Copy the result C file into your LittlevGL project

In a C file of your application declare the image as: LV_IMG_DECLARE(my_image_name);

Set the image for an lv_img object: lv_img_set_src(img1, &my_image_name);

For external binary files (e.g. SD card)

Set up a new driver. To learn more read the Tutorial.

Set the image for an lv_img object: lv_img_set_src(img1, «S:/path/to/image»);



Eine weitere wichtige und nette Funktion dieser Bibliothek ist, dass Sie die Eclipse-IDE unter Linux und Windows zum Debuggen verwenden können.







Es ist schön, dass es für die OpenSource-Bibliothek gut dokumentiert ist. Es gibt viele Beispiele und Ports. Die Bibliothek hat sich zu einer ziemlich großen Community entwickelt.



Ich habe einen Port für ESP32 gestartet. Selbst wenn die Zuordnung für SPI-Pins verwendet wird, d.h. Nicht Standard, bei denen die beste Baudrate erzielt wird, alles funktionierte ohne Verlangsamung:



ESP32 ST7789 LVGL

ESP32 ILI9341 LVGL



Verwandte Materialien
docs.lvgl.io/latest/en/html/porting/sys.html

Basic systick configuration on the STM32




All Articles