又一次移植最新lvgl8到esp32的踩坑记录

上一次移植了lvgl8到esp32后,发现用别人的仓库里面的lvgl并不是最新的版本,没有集成gif组件,为了使用gif播放,同时也自己尝试走一遍从0开始的移植过程。
之前移植的记录看这里

一、创建工程

1、在vscode新建esp32工程

在vscode中,按ctrl+shift+p键打开命令面板,输入搜索“show examples projects”,点击ESP-IDF:展示示例项目,选择你所用的esp-idf版本后,将打开esp-idf的例程创建界面。我这里esp-idf的版本是4.3.2。然后随便选个最简单的hello_world作为创建模板就可以了

2、添加lvgl最新版本的相关仓库代码

打开上一步创建的hello_world目录,新建一个“components”目录
然后将lvgl和lvgl_esp32_drivers两个仓库的最新代码clone到components目录内
https://github.com/lvgl/lvgl
https://github.com/lvgl/lvgl_esp32_drivers
现在的工程目录结构应该是这样的
在这里插入图片描述

3、创建lv_conf.h

在lvgl的目录下,有一个lv_conf_template.h的模板头文件,将其复制到同目录内,重命名为lv_conf.h。然后将里面最开始的“#if 0”改为“#if 1”使其生效,其它的都不用动了。在后面的menucofig后,相关的配置会作用里面的各种宏定义。

4、修改main.c

这里直接贴代码

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"

#include "esp_log.h"
#include "esp_system.h"
#include "esp_freertos_hooks.h"

#include "../components/lvgl/lvgl.h"
#include "lvgl_helpers.h"

/*-----------------函数声明-----------------------------------*/
void lvgl_test(void);
/*-----------------------------------------------------------*/

/* LVGL 移植部分 */
static void lv_tick_task(void *arg)
{
    (void)arg;
    lv_tick_inc(portTICK_PERIOD_MS);
}
SemaphoreHandle_t xGuiSemaphore;

/* UI 任务 */
static void gui_task(void *arg)
{
    xGuiSemaphore = xSemaphoreCreateMutex();
    lv_init();          //lvgl内核初始化
    lvgl_driver_init(); //lvgl显示接口初始化

 	static lv_disp_draw_buf_t draw_buf;
    lv_color_t *buf1 = heap_caps_malloc(LV_HOR_RES_MAX * LV_VER_RES_MAX * sizeof(lv_color_t), MALLOC_CAP_DMA);
    lv_color_t *buf2 = heap_caps_malloc(LV_HOR_RES_MAX * LV_VER_RES_MAX * sizeof(lv_color_t), MALLOC_CAP_DMA);
    lv_disp_draw_buf_init(&draw_buf, buf1, buf2, LV_HOR_RES_MAX * LV_VER_RES_MAX); /*Initialize the display buffer*/

    static lv_disp_drv_t disp_drv;         /*A variable to hold the drivers. Must be static or global.*/
    lv_disp_drv_init(&disp_drv);           /*Basic initialization*/
    disp_drv.draw_buf = &draw_buf;         /*Set an initialized buffer*/
    disp_drv.flush_cb = disp_driver_flush; /*Set a flush callback to draw to the display*/
    disp_drv.hor_res = 128;                /*Set the horizontal resolution in pixels*/
    disp_drv.ver_res = 160;                /*Set the vertical resolution in pixels*/
    lv_disp_drv_register(&disp_drv);       /*Register the driver and save the created display objects*/
    esp_register_freertos_tick_hook(lv_tick_task);

    lvgl_test();

    while (1)
    {
        /* Delay 1 tick (assumes FreeRTOS tick is 10ms */
        vTaskDelay(pdMS_TO_TICKS(10));

        /* Try to take the semaphore, call lvgl related function on success */
        if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY))
        {
            lv_timer_handler();
            xSemaphoreGive(xGuiSemaphore);
        }
    }
}

// lvgl测试
void lvgl_test(void)
{
    lv_obj_t *label1 = lv_label_create(lv_scr_act());
    lv_label_set_long_mode(label1, LV_LABEL_LONG_WRAP); /*Break the long lines*/
    lv_label_set_recolor(label1, true);                 /*Enable re-coloring by commands in the text*/
    lv_label_set_text(label1, "#0000ff Re-color# #ff00ff words# #ff0000 of a# label, align the lines to the center"
                              "and  wrap long text automatically.");
    lv_obj_set_width(label1, 120); /*Set smaller width to make the lines wrap*/
    lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_CENTER, 0);
    lv_obj_align(label1, LV_ALIGN_CENTER, 0, -40);

    lv_obj_t *label2 = lv_label_create(lv_scr_act());
    lv_label_set_long_mode(label2, LV_LABEL_LONG_SCROLL_CIRCULAR); /*Circular scroll*/
    lv_obj_set_width(label2, 120);
    lv_label_set_text(label2, "It is a circularly scrolling text. ");
    lv_obj_align(label2, LV_ALIGN_CENTER, 0, 40);
}

// 主函数
void app_main(void)
{
    xTaskCreatePinnedToCore(gui_task, "gui task", 1024 * 3, NULL, 1, NULL, 0);
}

5、配置和编译

然后menuconfig,根据自己需要配置(可参考之前的移植blog)
这里有点要注意,因为我没有导入lvgl的examples工程,所以“Enable the examples to be built”这个就不要勾选了。
最后点击编译。
理所当然是肯定会报错的。这些开源该死的频繁更新。。。
在这里插入图片描述

二、出现的问题以及解决过程

1、‘SPI_HOST_MAX’ undeclared (first use in this function); did you mean ‘GPIO_PORT_MAX’?"

位于lvgl_esp32_drivers内的lvgl_helpers.c,直接粗暴将这句“assert((0 <= host) && (SPI_HOST_MAX > host))”注释掉就行了

bool lvgl_spi_driver_init(int host,
    int miso_pin, int mosi_pin, int sclk_pin,
    int max_transfer_sz,
    int dma_channel,
    int quadwp_pin, int quadhd_pin)
{
    // assert((0 <= host) && (SPI_HOST_MAX > host));
    const char *spi_names[] = {
        "SPI1_HOST", "SPI2_HOST", "SPI3_HOST"
    };

2、‘DLV_HOR_RES_MAX’ undeclared (first use in this function); did you mean ‘LV_HOR_RES’?
‘DLV_VER_RES_MAX’ undeclared (first use in this function); did you mean ‘LV_VER_RES’?

lvgl_helpers.h缺少这两个宏定义,加上

 * When using RGB displays the display buffer size will also depends on the
 * color format being used, for RGB565 each pixel needs 2 bytes.
 * When using the mono theme, the display pixels can be represented in one bit,
 * so the buffer size can be divided by 8, e.g. see SSD1306 display size. */
#define LV_HOR_RES_MAX 240
#define LV_VER_RES_MAX 240

#if defined (CONFIG_CUSTOM_DISPLAY_BUFFER_SIZE)
#define DISP_BUF_SIZE   CONFIG_CUSTOM_DISPLAY_BUFFER_BYTES

3、好了,编译通过了,是不是这就完了?不,Too young too simple。
程序启动时报错,然后不断重启。。。
在这里插入图片描述
又是一番爬之后,改这里吧:
还是lvgl_helpers.h这个文件。不知到为社么,显示缓存大小的计算定义在新版本中被改成了水平宽度x40了。我的是ST7735S,这里改成水平x垂直
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX)

#define LV_HOR_RES_MAX 240
#define LV_VER_RES_MAX 240

#if defined (CONFIG_CUSTOM_DISPLAY_BUFFER_SIZE)
#define DISP_BUF_SIZE   CONFIG_CUSTOM_DISPLAY_BUFFER_BYTES
#else
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789)
#define DISP_BUF_SIZE  (LV_HOR_RES_MAX * 40)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S
#define DISP_BUF_SIZE  (LV_HOR_RES_MAX * LV_VER_RES_MAX)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S
#define DISP_BUF_SIZE  (LV_HOR_RES_MAX * 40)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357
#define DISP_BUF_SIZE  (LV_HOR_RES_MAX * 40)

然后,就终于完成了
在这里插入图片描述

版权声明:本文为CSDN博主「flamebox」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/flamebox/article/details/122357337

生成海报
点赞 0

flamebox

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

【STM32】串口接收任意字符串

前言 之前写了一篇STM32hal库串口中断接收任意字符 实际上是不完美的,他接收到换行符就完蛋了。 花了点时间深入研究了一下hal库的串口中断函数,发现他其实是不完美的,有一些BUG。 所以查了资

MDK5(keil5)编译按钮不见?

1.大部分是第一种情况 整个组件工具栏都不见了 解决办法: 2.小部分是组件工具栏没有编译按钮 解决办法: 参考: KEIL4 上面那个编译的工具栏怎么不见了 Keil工具栏详细说明