[鑫森淼焱垚] 发表于 2024-5-8 20:08

【AT-START-F405测评】移植LVGL

本帖最后由 [鑫森淼焱垚] 于 2024-5-8 20:08 编辑

#申请原创#
LVGL 简介
LVGL是最流行的免费和开源嵌入式图形库,可为任何MCU, MPU和显示类型创建漂亮的 UI。

它具有如下特性:

[*]丰富且强大的模块化图形组件:按钮 (buttons)、图表 (charts)、列表 (lists)、滑动条 (sliders)、图片 (images) 等
[*]高级的图形引擎:动画、抗锯齿、透明度、平滑滚动、图层混合等效果
[*]支持多种输入设备:触摸屏、 键盘、编码器、按键等
[*]支持多显示设备
[*]不依赖特定的硬件平台,可以在任何显示屏上运行
[*]配置可裁剪(最低资源占用:64 kB Flash,16 kB RAM)
[*]基于UTF-8的多语种支持,例如中文、日文、韩文、阿拉伯文等
[*]可以通过类CSS的方式来设计、布局图形界面(例如:Flexbox、Grid)
[*]支持操作系统、外置内存、以及硬件加速(LVGL已内建支持STM32 DMA2D、NXP PXP和VGLite)
[*]即便仅有单缓冲区(frame buffer)的情况下,也可保证渲染如丝般顺滑
[*]支持模拟器仿真,可以无硬件依托进行开发
[*]丰富详实的例程
[*]详尽的文档以及API参考手册,可线上查阅或可下载为PDF格式
[*]在 MIT 许可下免费和开源



基本上,每个能够驱动显示器的现代控制器都适合运行 LVGL。最低要求是:


[*]16/32或者64位微控制器或处理器
[*]建议使用 >16MHz 时钟速度
[*]闪存/ROM: >64KB 用于非常重要的组件 (建议使用 180KB)
[*]RAM:
[*]
[*]静态RAM使用量:~2KB,取决于使用的功能和对象类型
[*]堆:>2KB(建议使用8KB)
[*]动态数据(堆):>2KB
[*]显示缓冲区:> 水平分辨率像素
[*]MCU 或外部显示控制器中的一个帧缓冲区
[*]
C99 或更新的编译器



LVGL 源码下载

它的官网地址是 https://github.com/lvgl/lvgl

从网页选择 Tags 然后选择 v8.3.11 版本下载。



LVGL 目录组织

把下载好的 LVGL 源码拷贝到当前工程,放在 middlewares/lvgl_v8.3.11 。

LVGL 源码目录很多,文件很多,概括如下:


LVGL 移植

第一步 新建 lvgl_port 目录,拷贝文件
在 bsp 目录下新建 lvgl_port 目录,然后:


[*]拷贝 lv_conf_template.h 到 lvgl_port/ 目录下,重命名为 lv_conf.h;
[*]拷贝 lvgl_v8.3.11/examples/porting/ 目录下的 lv_port_disp_template.c 和 lv_port_disp_template.h 两个文件到 lvgl_port/ 目录下,分别重命名为 lv_port_disp.c 和 lv_port_disp.h;



第二步 修改 lv_conf.h 文件


[*]把文件中的 #if 0 改成 #if 1 使能这个文件;
[*]根据显示屏修改 LV_COLOR_DEPTH 数值,这里就使用 16 即可;
[*]设置 LVGL 使用的堆,宏定义 LV_MEM_CUSTOM 为0,由 LV_MEM_SIZE 设定堆大小,这里设置48KB;
[*]使能宏定义 LV_USE_PERF_MONITOR 和 LV_USE_MEM_MONITOR 显示帧率和内存占用率;
[*]其他根据需要设定;



第三步 修改 lv_port_disp.c 文件


[*]在文件头添加宏定义 MY_DISP_HOR_RES = 320 和 MY_DISP_VER_RES = 240 ,设定屏幕水平和垂直方向分辨率;
[*]实现 disp_init() 函数,即显示屏初始化;
[*]实现 disp_flush() 函数,调用 LCD 接口并像素显示出来;
[*]在 lv_port_disp_init() 函数中选择一种缓冲模式,这里选择单缓冲;
[*]修改头文件包含,即包含 lv_port_disp.h 头文件,而不是 lv_port_disp_template.h 头文件;



关键代码如下所示:





/*Flush the content of the internal buffer the specific area on the display
*You can use DMA or any hardware acceleration to do this operation in the background but
*'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
      if (disp_flush_enabled) {
                int32_t x;
                int32_t y;
                for (y = area->y1; y <= area->y2; y++) {
                        for (x = area->x1; x <= area->x2; x++) {
                              LCD_DrawPointColor(x, y, color_p->full);
                              color_p++;
                        }
                }
      }

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

第四步 初始化 lvgl 并添加 lvgl 应用

创建一个线程,线程代码如下:

void lvgl_ui_entry(void* arg)
{
      lv_init();
      lv_port_disp_init();

      bbs_21ic_demo();
      while (1) {
                vTaskDelay(pdMS_TO_TICKS(3));
                lv_tick_inc(3);

                lv_task_handler();
      }
}

void bbs_21ic_demo(void)
{
    lv_obj_t * label_21ic = lv_label_create(lv_scr_act());
    lv_label_set_long_mode(label_21ic, LV_LABEL_LONG_WRAP);   /*Break the long lines*/
    lv_label_set_recolor(label_21ic, true);                      /*Enable re-coloring by commands in the text*/
      lv_label_set_text(label_21ic, "21IC -- #00FF00 Best# #FF0000 Embedded World#");
      lv_obj_set_width(label_21ic, 280);/*Set smaller width to make the lines wrap*/
    lv_obj_set_style_text_align(label_21ic, LV_TEXT_ALIGN_CENTER, 0);
    lv_obj_align(label_21ic, LV_ALIGN_CENTER, 0, -80);

      lv_obj_t* label_artery = lv_label_create(lv_scr_act());
    lv_label_set_long_mode(label_artery, LV_LABEL_LONG_WRAP);   /*Break the long lines*/
    lv_label_set_recolor(label_artery, true);                      /*Enable re-coloring by commands in the text*/
      lv_label_set_text(label_artery, "#00FF33 Artery# -- An Innovation leader in 32-bit microcontrollers");
      lv_obj_set_width(label_artery, 280);/*Set smaller width to make the lines wrap*/
    lv_obj_set_style_text_align(label_artery, LV_TEXT_ALIGN_CENTER, 0);
    lv_obj_align(label_artery, LV_ALIGN_CENTER, 0, -20);

    lv_obj_t * label_url = lv_label_create(lv_scr_act());
    lv_label_set_long_mode(label_url, LV_LABEL_LONG_SCROLL_CIRCULAR);   /*Circular scroll*/
    lv_obj_set_width(label_url, 280);
    lv_label_set_text(label_url, "https://bbs.21ic.com/icview-3375936-1-1.html");
    lv_obj_align(label_url, LV_ALIGN_CENTER, 0, 40);
}

LVGL 运行



https://www.bilibili.com/video/BV1fb421t7T5/?vd_source=8f2bbf56b70c541bec2ea0b9f102ebee

代码量分析

使用 MicroLib, 优化等级 -Os balanced, Flash 占用 180KB



不使用 MicroLib,优化等级 -Os balanced, Flash 占用 180KB



编译结果分析

flash 占用 180KB,占大头的都是 lvgl 源码,我自己写的应用 init_task.c 才不到 1KB。

此处 180KB ,对应前文 LVGL 推荐 Flash 占用 180KB。符合预期。







chenqianqian 发表于 2024-5-11 07:53

对于一些小容量得MCU,比如128KBFLASH,这个资源还是有点捉襟见肘。

Antecer 发表于 2024-7-1 20:27

Demo工程呢? 来一份啊

micoccd 发表于 2024-7-4 16:33

看起来挺不错的
页: [1]
查看完整版本: 【AT-START-F405测评】移植LVGL