Intégration dans le projet LVGL d'une bibliothèque graphique pour microcontrôleurs

LVGL - Bibliothèque graphique légère et polyvalente également connue sous le nom de LittleVGL.





La bibliothèque prend en charge un grand nombre de microcontrôleurs tels que STM32, ESP32 et autres. Jusqu'à présent, j'ai réussi à exécuter un programme de démonstration à part entière sur ESP32 et STM32f429 Discovery. La bibliothèque est open source, prend en charge un grand nombre d'éléments graphiques avec des thèmes Dark et Light. Distribué sous la licence MIT. Peut être utilisé librement même dans les produits commerciaux. Vous pouvez regarder une démo en ligne interactive sans installer sur l'appareil



La bibliothèque prend en charge la connexion de deux types d'affichage



  1. Directement via l'interface RVB où le tampon sera du côté MCU dans la RAM interne ou la SDRAM externe
  2. Via un contrôleur d'affichage externe. Dans ce cas, la MCU peut communiquer avec le contrôleur d'affichage via le bus SPI ou I2C. Pour améliorer les performances, des tampons de rendu intermédiaires à l'intérieur du MCU peuvent également être utilisés dans ce cas.


Deux configurations matérielles typiques
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.





Tout est très flexible à cet égard. Si vous avez un pilote, mais que la bibliothèque n'a pas encore de port pour ce pilote, vous pouvez facilement intégrer vous-même la bibliothèque dans votre



projet.Le moyen le plus simple, mais aussi le plus lent, est de réécrire le rappel de dessin - 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 - Ceci est le rendu des pixels de votre pilote. En raison du fait que le rendu est pixel par pixel, cela est lent. La documentation de la bibliothèque détaille d'autres méthodes d'intégration plus efficaces:



Intégrer LVGL dans le projet. La première consiste à initialiser la bibliothèque, l'affichage et le système d'entrée.




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

   lv_demo_widgets();  //     


Puisque la bibliothèque a un gestionnaire de tâches à l'intérieur d'elle-même. Oui, c'est un système multi-thread, corrigez-moi si ce n'est pas le cas, alors il faut augmenter le compteur interne du dispatcher en appelant lv_tick_inc



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*/
    }
}


De plus, il faut transférer à la fonction les millisecondes qui se sont écoulées depuis le moment de son dernier appel, ou en d'autres termes, le temps depuis le moment de l'itération précédente.



Afin de ne pas gaspiller de ressources sur un thread supplémentaire, vous pouvez appeler cette fonction sur une interruption de minuterie. STM32 a une minuterie SysTick à ces fins:




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
 }


Minuterie SysTick
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.




Il est également nécessaire d'appeler lv_task_handler dans la boucle. Il est recommandé de le secouer toutes les 5 ms pour assurer une bonne réponse. J'ai essayé d'augmenter à 20 ms et le système était toujours assez réactif et fluide. Peut être laissé comme une boucle éternelle ou utiliser Thread



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


Les boucles doivent être à des endroits différents. J'ai fait une erreur et j'ai bourré lv_tick_inc et lv_task_handler dans une boucle. Voici ce qui en est arrivé - Freins



Lorsque les deux méthodes ont été divisées en différents flux aux intervalles corrects, tout fonctionnait correctement et rapidement:





La bibliothèque a la possibilité de personnaliser le nombre de tampons internes:



  1. Un tampon lorsque LVGL dessine le contenu de l'écran vers un tampon et l'envoie à l'écran
  2. Deux tampons d'écran partiel, lors du rendu dans un tampon, le contenu de l'autre tampon est envoyé pour être affiché en arrière-plan
  3. Deux tampons plein écran


Le site dispose d'un convertisseur de polices et d' images . Vous pouvez ajouter en toute sécurité votre police au projet ou votre icône dans le menu. De plus, vous pouvez éventuellement charger des images à partir d'un stockage externe, tel qu'un CD-CARD, ou à partir d'un tableau d'octets situés dans la mémoire Flash interne.



Comment utiliser le fichier généré dans 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»);



Une autre caractéristique importante et intéressante de cette bibliothèque est que vous pouvez utiliser l'EDI Eclipse sous Linux et Windows pour le déboguer.







C'est bien qu'il soit bien documenté pour la bibliothèque OpenSource. Il existe de nombreux exemples et ports. La bibliothèque est devenue une communauté assez nombreuse ,



j'ai lancé un portage pour ESP32. Même lors de l'utilisation du mappage pour les broches SPI, c'est-à-dire pas ceux par défaut, auxquels la meilleure vitesse de transmission est obtenue, tout a fonctionné sans ralentissements:



ESP32 ST7789 LVGL

ESP32 ILI9341 LVGL



Matériaux associés
docs.lvgl.io/latest/en/html/porting/sys.html

Basic systick configuration on the STM32




All Articles