Edit online

功能配置

Read time: 14 minute(s)
Edit online

使能 LVGL 库和 LVGL demo

Read time: 14 minute(s)

Luban-Lite 根目录下执行 scons --menuconfig,进入 menuconfig 的功能配置界面,配置如下:
Application options  --->
    *** Filesystem related ***
    [*] Using File System Image 0  --->
        --- Using File System Image 0
        Select File System Type (FATFS)  --->
        (packages/artinchip/lvgl-ui/aic_demo/base_demo/lvgl_src/) Data Directory
        (app.fatfs) Image Name
        [*] auto calcuate image size
    [ ] Using File System Image 1  ----
    *** lvgl demo select related ***
    -*- LVGL (official): powerful and easy-to-use embedded GUI library  --->
        (20)  Priority of LVGL thread
        (32768) Stack size of LVGL thread
        (5)   Display refresh period (ms)
        [ ]   Support SquareLine Studio
        [ ]   Enable built-in examples
        [ ]   Enable built-in demos
    -*- ArtInChip lvgl demo
        select lvgl demo (lvgl demo with basic function)  --->
            (X) lvgl demo with basic function
            ( ) lvgl demo of meter
        (16)  LVGL color depth(32/16)
        (8)   LVGL image cached number
    (/rodata/lvgl_data) LVGL Resource Directory
根目录下有多个挂载点:
/ram        --挂载 ramdisk 文件系统
/rodata     --对应 Using File System Image 0 中 Data Directory 中的资源文件
/data       --对应 Using File System Image 1 中 Data Directory 中的资源文件
/sdcard     --挂载 SD 卡
/udisk      --挂载 U 盘
资源文件配置说明:
  1. 不同的 demo 需要配置对应的资源路径,例如:lvgl demo with basic function 对应的资源路径为:packages/artinchip/lvgl-ui/aic_demo/base_demo/lvgl_src/
  2. 上述配置中使用了 File System Image 0 分区来存储 demo 资源文件,所以我们配置 lvgl 的资源路径为/rodata/lvgl_data
注:
  1. LVGL color depth 可以配置为 16 或 32,16 表示显示 buffer 格式为 rgb565,32 表示显示格式为 argb8888, 此格式需要与 display 驱动中的 framebuffer 格式对应。
  2. 可以通过 Stack size of LVGL thread 配置 LVGL 线程的堆栈大小,需配置合适的大小避免出现 stack 溢出。
  3. 可以通过 LVGL image cached number 来配置图片缓存张数,可以通过图片缓存机制来提升 UI 流畅度,但是缓存越多,占用内存也越多。
Edit online

添加应用

Read time: 14 minute(s)

本章节演示如何添加一个名为 test_demo 的 LVGL 应用,来实现以下功能:

  1. 主界面添加一个 button 控件,按键时,在控件上显示当前后台计数。
  2. 后台线程进行计时,每一秒计数加一。

添加 APP 选项

application/Kconfig 中,添加以下代码:
config AIC_LVGL_METER_DEMO
    bool "LVGL demo of meter"

config AIC_LVGL_TEST_DEMO          # 添加 AIC_LVGL_TEST_DEMO,以便在 menuconfig 菜单中选择
    bool "LVGL demo of test"

config AIC_LVGL_LAUNCHER_DEMO
    bool "LVGL launcher demo"

配置 APP

使用 scons --menuconfigme 进入配置菜单,选择新添加的 test_demo 并保存:
Application options  --->
    [*] ArtInChip LVGL demo  --->
        select LVGL demo (LVGL demo of test)  --->
            ( ) LVGL demo with basic function
            ( ) LVGL demo of meter
            (X) LVGL demo of test
            ( ) LVGL launcher demo

源码适配

源代码
  1. 下载完整源码包 test_demo
  2. 将源码解压缩至 packages/artinchip/lvgl-ui/aic_demo 目录下,文件结构为:
    tree -h
    .
    └── [4.0K]  test_demo
        ├── [4.0K]  assets
        │   └── [   0]  readme.txt         # 该文件用于验证资源打包,本身为空文件
        ├── [ 571]  SConscript
        ├── [4.0K]  thread
        │   ├── [1.0K]  test_thread.c
        │   └── [ 211]  test_thread.h
        └── [4.0K]  ui
            ├── [1.3K]  test_ui.c
            └── [ 228]  test_ui.h
  3. SConscript 更改
    根据实际项目路径修改test_demo 中的 SConscript,解析如下:
    from building import *
    import os
    
    cwd = GetCurrentDir()
    group = []
    src = Glob('*.c')
    # 源文件路径
    src += Glob('./ui/*.c')
    src += Glob('./thread/*.c')
    
    CPPPATH = [cwd]
    # 头文件路径
    CPPPATH.append(cwd + './ui')
    CPPPATH.append(cwd + './thread')
    
    list = os.listdir(cwd)
    for d in list:
        path = os.path.join(cwd, d)
        if os.path.isfile(os.path.join(path, 'SConscript')):
            group = group + SConscript(os.path.join(d, 'SConscript'))
    
    # 资源安装的目标路径
    ins_dst='rodata/lvgl_data'
    
    # 资源安装的源路径为当前SConscript所在路径的相对路径
    ins_src = 'assets/'
    install = [(ins_src, ins_dst)]
    
    # AIC_LVGL_TEST_DEMO 宏需要与 application/Kconfig 中添加的宏一致
    group = group + DefineGroup('LVGL-port', src, depend = ['AIC_LVGL_TEST_DEMO'], CPPPATH = CPPPATH,
            INSTALL = install)
    
    Return('group')

对接 LVGL 框架

Luban-Lite SDK 中,已经融合了 LVGL 库并与 2D 硬件加速接口、图片硬件解码模块、触控等进行了对接,因此用户只需要将 UI 部分的功能接入即可。

packages/artinchip/lvgl-ui/aic_ui.c 中,添加:
/*
* Copyright (C) 2022-2025 ArtinChip Technology Co., Ltd.
* Authors:  Ning Fang <ning.fang@artinchip.com>
*/

#include "lvgl.h"
#include "aic_ui.h"
#include "aic_osal.h"

void aic_ui_init()
{
#if defined(AIC_LVGL_MUSIC_DEMO)
    lv_demo_music();
#elif defined(AIC_LVGL_DEMO_BENCHMARK)
    lv_demo_benchmark();
#elif defined(AIC_LVGL_DEMO_WIDGETS)
    lv_demo_widgets();
#else
    // 应用的入口函数
    extern void ui_init(void);
    ui_init();
#endif

    return;
}

效果展示

编译、烧录后,显示效果如下图:


test_demo_ui

Edit online

屏幕旋转

Read time: 14 minute(s)
本节展示了基于 LVGL 的 UI 框架,实现横屏竖用、竖屏横用的方式。以下方式任选一种,详细流程如下:
  • 静态旋转
    1. packages/artinchip/lvgl-ui/lv_driver/lv_fbdev.h 文件中,使能 USE_DRAW_BUF 宏定义,开启转屏缓存:
      ...
      #define USE_DRAW_BUF
      ...
    2. packages/artinchip/lvgl-ui/lv_driver/lv_port_disp.c 文件中,设置旋转角度。
      如下所示,旋转角度设置为 90 度:
      /* when define USE_DRAW_BUF, disp_drv.rotated can be
        LV_DISP_ROT_90/LV_DISP_ROT_180/LV_DISP_ROT_270
      */
      disp_drv.rotated = LV_DISP_ROT_90;      // 设置旋转 90 度,共有三种角度可选:90、180、270
  • 动态旋转

    在程序运行到需要进行旋转屏幕时,调用 lv_disp_set_rotation

    API 定义在 packages/artinchip/lvgl-ui/lvgl/src/hal/lv_hal_disp.c

Edit online

性能优化

Read time: 14 minute(s)

按照本节建议说明,可以优化 LVGL 库界面开发的性能。

Edit online

LVGL V8 性能优化

Read time: 14 minute(s)

设置图片缓存张数

当新的图片被加载时,如果当前缓存未达到设定的上限,该图片会被添加到缓存中。在内存有限的情况下,可以通过以下方式进一步优化:

  • 根据实际需求,动态调整图片缓存的大小。例如,在需要频繁切换的场景中,可以适当增加缓存数量以提高响应速度;而在其它场景中,则可以减少缓存数量以节省内存。
  • 释放不必要的缓存。在确定某些图片不再需要时,及时释放其缓存可以有效节省内存。例如,在场景切换时,可以调用lv_img_cache_invalidate_src(NULL)来释放所有缓存。
    // 释放对象 img_obj 的图片缓存
    lv_img_cache_invalidate_src(lv_img_get_src(img_obj));
    
    // 释放所有的图片缓存,在场景切换时候,确定不需要已有的图片缓存可以这么调用
    lv_img_cache_invalidate_src(NULL);
    如下配置中设置了八张图片缓存:
    Application options  --->
        *** Filesystem related ***
        [*] Using File System Image 0  --->
        [ ] Using File System Image 1  ----
        *** lvgl demo select related ***
        -*- LVGL (official): powerful and easy-to-use embedded GUI library  --->
        -*- ArtInChip lvgl demo
            select lvgl demo (lvgl demo with basic function)  --->
                (X) lvgl demo with basic function
                ( ) lvgl demo of meter
            (16)  LVGL color depth(32/16)
            (8)   LVGL image cached number
        (/rodata/lvgl_data) LVGL Resource Directory

采用 rgb565 格式

选择合适的颜色深度和图片格式可以有效减少处理的数据量,例如 rgb565 格式,从而提升 UI 的处理速度。

显示采用 rgb565 格式和 argb8888 相比减少了处理的数据量,可以提升 UI 的处理速度。以下示例中,LVGL color depth 为 16,并且配置 framebuffer 为 rgb565:
Application options  --->
    *** Filesystem related ***
    [*] Using File System Image 0  --->
    [ ] Using File System Image 1  ----
    *** lvgl demo select related ***
    -*- LVGL (official): powerful and easy-to-use embedded GUI library  --->
    -*- ArtInChip lvgl demo
        select lvgl demo (lvgl demo with basic function)  --->
            (X) lvgl demo with basic function
            ( ) lvgl demo of meter
        (16)  LVGL color depth(32/16)
        (8)   LVGL image cached number
    (/rodata/lvgl_data) LVGL Resource Directory
Board options  --->
    [*] Using Display Engine (DE)
        Display Parameter  --->
            select framebuffer format (rgb565)  --->
            [*] Support double framebuffer
            [*] Enable Display Dither

设置 FreeType 字体缓存个数

在 LVGL 中,FreeType 字体缓存的配置可以通过修改头文件 lv_conf.h 中的宏定义来实现。
1. lv_conf.h 中的宏定义
宏定义参数 描述
LV_FREETYPE_CACHE_SIZE 设置 FreeType 缓存的总大小 (以字节为单位)
  • 数值越大,运行速度越快,但是占用的内存也会越多。
  • 当设置为 -1 时,表示关闭缓存。
LV_FREETYPE_SBIT_CACHE: 选择位图缓存的类型。
  • 设置为 1 时,使用 sbit 缓存,这在处理小尺寸字体 (小于 256)时更加高效。
  • 设置为 0 时,使用图像缓存,适用于大尺寸字体 (大于等于 256)。
LV_FREETYPE_CACHE_FT_FACES 设置缓存管理的 FT_Face 对象的最大数量。
  • 设置为 0 时,使用系统默认值,默认值为 2。
  • 如需打开多个字体文件,增加缓存管理的 FT_Face 对象的最大数量,可以提升字体的运行速度。
LV_FREETYPE_CACHE_FT_SIZES 设置缓存管理的 FT_Size 对象的最大数量。
  • 设置为 0 时,使用系统默认值,默认值为 4。
  • 如需显示多种不同 size 的字体时,增加缓存管理的 FT_Size 对象的最大数量,可以提升字体的运行速度。
#define LV_USE_FREETYPE 1
    #if LV_USE_FREETYPE
        // Memory used by FreeType to cache characters [bytes]
        #define LV_FREETYPE_CACHE_SIZE (128 * 1024)
        #if LV_FREETYPE_CACHE_SIZE >= 0
            // 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache.
            // sbit cache:it is much more memory efficient for small bitmaps(font size < 256)
            // if font size >= 256, must be configured as image cache */
            #define LV_FREETYPE_SBIT_CACHE 0
            // Maximum number of opened FT_Face/FT_Size objects managed by this cache instance.
            // (0:use system defaults)
            #define LV_FREETYPE_CACHE_FT_FACES 0
            #define LV_FREETYPE_CACHE_FT_SIZES 0
        #endif
    #endif

其他优化方式

  1. 对于不透明的图片,可以选择采用 JPEG 格式。JPEG 图片的解码速度通常比 PNG 速度快。
  2. 在定时器或动画回调函数中,避免执行耗时过长的函数,以免影响 UI 的流畅性。可以考虑以下方法:
    • LVGL 的 UI 绘制是单线程的,将耗时操作放到后台线程中执行,避免阻塞主线程。
    • 将大任务拆分成多个小任务,通过多次调用来完成,每次只处理一小部分工作。
Edit online

LVGL V9 性能优化

Read time: 14 minute(s)

设置图片缓存张数

当新的图片被加载时,如果当前缓存未达到设定的上限,该图片会被添加到缓存中。在内存有限的情况下,可以通过以下方式进一步优化:

  • 根据实际需求,动态调整图片缓存的大小。例如,在需要频繁切换的场景中,可以适当增加缓存数量以提高响应速度;而在其它场景中,则可以减少缓存数量以节省内存。
  • 释放不必要的缓存。在确定某些图片不再需要时,及时释放其缓存可以有效节省内存。例如,在场景切换时,可以调用lv_img_cache_invalidate_src(NULL)来释放所有缓存。
    // 释放对象 img_obj 的图片缓存
    lv_image_cache_drop(lv_image_get_src(img_obj));
    
    // 释放所有的图片缓存,在场景切换时候,确定不需要已有的图片缓存可以这么调用
    lv_image_cache_drop(NULL);
    如下配置中设置了八张图片缓存:
    Application options  --->
        *** Filesystem related ***
        [*] Using File System Image 0  --->
        [ ] Using File System Image 1  ----
        *** lvgl demo select related ***
        -*- LVGL (official): powerful and easy-to-use embedded GUI library  --->
        -*- ArtInChip lvgl demo
            select lvgl demo (lvgl demo with basic function)  --->
                (X) lvgl demo with basic function
                ( ) lvgl demo of meter
            (16)  LVGL color depth(32/16)
            (8)   LVGL image cached number
        (/rodata/lvgl_data) LVGL Resource Directory

设置图片缓存大小

设置图片的缓存 size,缓存越大,运行速度越快,但是占用的内存也会越多。
Application options  --->
    *** Filesystem related ***
    [*] Using File System Image 0  --->
    [ ] Using File System Image 1  ----
    *** lvgl demo select related ***
    -*- LVGL (official): powerful and easy-to-use embedded GUI library  --->
    -*- ArtInChip lvgl demo
        select lvgl demo (lvgl demo with basic function)  --->
            (X) lvgl demo with basic function
            ( ) lvgl demo of meter
        (16)  LVGL color depth(32/16)
        (8)   LVGL image cached number
        (0x800000) LVGL image cached size
        (20)  LVGL image header cached number
    (/rodata/lvgl_data) LVGL Resource Directory

设置图片头信息缓存个数

对图片的头信息进行缓存,图片的头信息一般占用内存不多,但是如果图像的头信息需要频繁的从文件系统中去读取,也会影响运行速度, 用户可以根据需要,设置合适的图片头信息缓存个数。
Application options  --->
    *** Filesystem related ***
    [*] Using File System Image 0  --->
    [ ] Using File System Image 1  ----
    *** lvgl demo select related ***
    -*- LVGL (official): powerful and easy-to-use embedded GUI library  --->
    -*- ArtInChip lvgl demo
        select lvgl demo (lvgl demo with basic function)  --->
            (X) lvgl demo with basic function
            ( ) lvgl demo of meter
        (16)  LVGL color depth(32/16)
        (8)   LVGL image cached number
        (0x800000) LVGL image cached size
        (20)  LVGL image header cached number
    (/rodata/lvgl_data) LVGL Resource Directory

采用 rgb565 格式

选择合适的颜色深度和图片格式可以有效减少处理的数据量,例如 rgb565 格式,从而提升 UI 的处理速度。

显示采用 rgb565 格式和 argb8888 相比减少了处理的数据量,可以提升 UI 的处理速度。以下示例中,LVGL color depth 为 16,并且配置 framebuffer 为 rgb565:
Application options  --->
    *** Filesystem related ***
    [*] Using File System Image 0  --->
    [ ] Using File System Image 1  ----
    *** lvgl demo select related ***
    -*- LVGL (official): powerful and easy-to-use embedded GUI library  --->
    -*- ArtInChip lvgl demo
        select lvgl demo (lvgl demo with basic function)  --->
            (X) lvgl demo with basic function
            ( ) lvgl demo of meter
        (16)  LVGL color depth(32/16)
        (8)   LVGL image cached number
    (/rodata/lvgl_data) LVGL Resource Directory
Board options  --->
    [*] Using Display Engine (DE)
        Display Parameter  --->
            select framebuffer format (rgb565)  --->
            [*] Support double framebuffer
            [*] Enable Display Dither

设置 Freetype 字体缓存个数

在 LVGL 中,FreeType 字体缓存的配置可以通过修改头文件 lv_conf.h 中的宏定义来实现。
2. lv_conf.h 中的宏定义
宏定义参数 描述
LV_FREETYPE_USE_LVGL_PORT 决定是否让 FreeType 使用 LVGL 的内存和文件接口。
  • 设置为 0 时,表示不使用 LVGL 的内存和文件接口。
LV_FREETYPE_CACHE_FT_GLYPH_CNT 设置 FreeType 缓存的字形数量。
  • 数值越大,运行速度越快,但占用的内存也会越多。
#define LV_USE_FREETYPE 1
#if LV_USE_FREETYPE
    /*Let FreeType to use LVGL memory and file porting*/
    #define LV_FREETYPE_USE_LVGL_PORT 0

    /*Cache count of the glyphs in FreeType. It means the number of glyphs that can be cached.
    *The higher the value, the more memory will be used.*/
    #define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256
#endif

其他优化方式

  1. 对于不透明的图片,可以选择采用 JPEG 格式。JPEG 图片的解码速度通常比 PNG 速度快。
  2. 在定时器或动画回调函数中,避免执行耗时过长的函数,以免影响 UI 的流畅性。可以考虑以下方法:
    • LVGL 的 UI 绘制是单线程的,将耗时操作放到后台线程中执行,避免阻塞主线程。
    • 将大任务拆分成多个小任务,通过多次调用来完成,每次只处理一小部分工作。