打印
[活动专区]

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

[复制链接]
835|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 [鑫森淼焱垚] 于 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 = 320MY_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 运行





代码量分析

使用 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 | 只看该作者
看起来挺不错的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

75

帖子

0

粉丝