LVGL

LVGL(Light and Versatile Graphics Library)是一个开源的嵌入式图形库,用于创建漂亮、高性能且可定制的图形用户界面(GUI)。它设计简单、灵活,适用于各种嵌入式平台,包括微控制器和单片机。

概述

本文介绍了基于 Realtek RTL8772GWP 的 LVGL 方案相关信息,旨在帮助用户搭建开发环境,包括了解 SDK、编译和烧录固件及系统测试方法等。开发者可烧录 SDK 中的测试文件,确保开发环境配置得当、EVB 可以正常工作。

备注

  • 本文所述示例方案采用 Realtek RTL8772GWP EVB,搭配 st7701s 驱动的 RGB(480 * 480) LCD 显示、gt911 驱动的触控屏模组,开发者若选用本文相同的硬件环境,可直接运行 SDK 中的样例工程。

  • 如需适配其他型号的显示屏和输入设备,请参考 GUI 任务 小节 ,适配到新的显示和输入设备。

  • Realtek RTL8772GWP 芯片支持的显示接口:i8080、qspi/spi、RGB888/RGB565。

实用案例

下图显示了 LVGL 应用包含的模块:

../../../../_images/fig_module1.jpeg

LVGL 系统模块组成

支持功能

Realtek LVGL 应用程序提供完备功能支持:

  • 支持 LVGL

  • 支持蓝牙 BLE OTA

环境需求

  1. RTL87x2GWP EVB

  2. LCD 屏幕模块 (480*480 st7701s + gt911)

  1. ARM Keil MDK: ArmMDK

  2. MPTool_kits: RealMCU

  3. DebugAnalyzer: RealMCU

  4. scons 4.4.0: python 环境运行 pip install scons==4.4.0

硬件连线

EVB

EVB 提供了用户开发和应用调试的硬件环境。LVGL 应用使用 Model B EVB 进行演示,EVB 由母板和子板组成。EVB 具有下载模式和工作模式,下载模式用于烧录固件等功能,工作模式为正常运行应用程序模式,开发者需要配置 EVB 以进入所需的模式。有关 EVB 母板的详细介绍和使用方法请参阅 评估板指南

../../../../_images/fig_evb1.png

LVGL EVB 接线

配置选项

SDK 中 LVGL 方案的配置在 SDK\applications\lvgl\proj\menu_config.h 中,可在 Keil 使用 Configuration Wizard 配置,默认 BLE 配置如下:

备注

当配置修改后,根据所支持的编译方式重新构建工程后配置生效,构建方法请参考 编译和下载 步骤。

  • CONFIG_REALTEK_BLE_DEMO, CONFIG_REALTEK_BLE_DEMO_APP:配置是否启用 ble demo app,及选择 demo。

  • CONFIG_REALTEK_BLE_OTA, CONFIG_REALTEK_DFU_SERVICE, CONFIG_REALTEK_OTA_SERVICE: ble OTA demo app 的底层支持,需与 OTA demo 一同启用,否则关闭配置。

编译和下载

请参阅 快速入门 进行编译和下载。值得注意的是:

  1. 生成Flash Map 步骤:
    开发者需要根据 SDK\applications\lvgl\proj\flash_map.h 生成 flash_map.ini
  2. 务必使能 psram power,其他功能可根据需要进行配置。
../../../../_images/fig_system_config1.png

system config 使能 psram power

  1. 构建 Keil MDK 工程,编译APP Image 步骤:

    1. LVGL SDK 工程路径为:SDK\applications\lvgl\proj

    2. Keil MDK 工程路径为: SDK\applications\lvgl\proj\mdk

    3. 当修改了工程的配置后,需要重新构建工程配置方可生效,构建后将会按配置生成全新工程文件,覆盖原有的工程文件。若开发者有手动在原工程中添加的文件或配置,将会在构建后失效不会保留到新的工程。

    4. 构建工程时,在工程路径下打开 cmd 窗口。

      运行命令 scons --target=mdk5 构建 mdk 工程,打开 mdk 工程进行编译,APP image 将生成在以下路径中:SDK\applications\lvgl\proj\mdk\bin

      SDK\applications\lvgl\proj> scons --target=mdk5
      scons: Reading SConscript files ...
      ...
      CC xxxx.o
      CC xxxx.o
      ...
      LINK app.elf
      fromelf --bin app.elf --output rtthread.bin
      fromelf -z app.elf
      scons: done building targets.
      
    5. 打开生成的 Keil MDK 工程,点击编译生成 app image,具体请参阅 编译APP Image

  2. 下载烧录方法请参阅 文件下载

  3. 生成和下载 User Data: 1. LVGL 工程 User Data 打包路径:SDK\subsys\gui\gui_engine\example\screen_lvgl 2. 工程用到的外部文件需要打包作为 User Data 下载,打开工程 User Data 打包路径,将需要打包的文件放置于 root\ 文件夹下,双击脚本 mkromfs_0x4600000.bat 生成 User Data 文件 root(0x4600000).bin 和资源映射地址 resource.h。 3. 请使用 MP Tool 的 User Data 功能下载 root(0x4600000).bin,写入地址: 0x04600000

测试验证

UI 测试流程

  1. 正确完成烧录固件后,令 EVB 切换到工作模式,复位重启。

  2. 设备重启后可以看到 LVGL 的 benchmark demo 运行,屏幕的左上角显示当前测试用例和测试进度,屏幕的右下角显示当前帧率和 CUP 占用率。

  3. 在完成所有测试用例前,不会有 log 输出,无触屏交互响应,完成所有测试用例后,测试结果将以 log 和表格的方式显示,可以触屏滑动浏览。

../../../../_images/fig_benchmark.gif

LVGL UI 演示

软件设计介绍

本章主要介绍 RTL8772GWP LVGL 解决方案的软件相关技术参数和行为规范,为 LVGL 的功能提供软件概述。

源代码目录

  • 工程文件目录: sdk\application\lvgl\proj

  • 源代码目录: sdk\application\lvgl\src

LVGL SDK中的源文件目前分为以下几类:

└── Project: lvgl
    └── app                            includes the LVGL user application implementation
        ├── menu_config.h              project construct configurations
        ├── main.c
        └── lvgl_init.c                includes task and hardware init
    ├── lib
    ├── device
    ├── peripheral                     includes all peripheral drivers and module code used by the application
    ├── profile                        includes BLE profiles or services
    ├── dfu
    ├── dfu_task
    ├── LVGL                           includes all LVGL source
    ├── lcd_low_driver                 includes display pannel IC driver implementation
    ├── touch_driver                   includes touch IC driver implementation
    ├── hal_drivers
    ├── database
    ├── fs                              include file system implementation
    ├──  port_lvgl
        ├── lv_port_disp.c              includes LVGL display interface
        ├── lv_port_indev.c             includes LVGL input device interface
        ├── lvgl_demo.c                 includes LVGL demo, benchmark demo
        └── lv_port_fs.c                includes LVGL filesystem interface
    └── lvgl_assets                     includes user image and font C files
    :
    └── ble_ota_app                    includes ble ota demo implementation
    :
    └── ble_app                        includes ble simple peripheral demo implementation

Flash布局

应用程序默认的 flash 布局头文件: sdk\application\lvgl\proj\flash_map.h

Flash布局说明

Example layout with a total flash size of 16 MB

Size(byte)

Start Address

Reserved

4K

0x04000000

OEM Header

4K

0x04001000

Bank0 Boot Patch

32K

0x04002000

Bank1 Boot Patch

32K

0x0400A000

OTA Bank0

2456K

0x04012000

  • OTA Header

4K

0x04012000

  • System Patch code

32K

0x04013000

  • BT Lowerstack Patch code

60K

0x0401B000

  • BT Host code

212K

0x0402A000

  • APP code

2148K

0x0405F000

  • APP Config File

0K

0x04278000

  • APP data1

0K

0x04278000

  • APP data2

0K

0x04278000

  • APP data3

0K

0x04278000

  • APP data4

0K

0x04278000

  • APP data5

0K

0x04278000

  • APP data6

0K

0x04278000

OTA Bank1

0K

0x04278000

Bank0 Secure APP code

16K

0x04278000

Bank0 Secure APP Data

0K

0x040AC000

Bank1 Secure APP code

0K

0x0427C000

Bank1 Secure APP Data

0K

0x0427C000

OTA Temp

2148K

0x0427C000

FTL

16K

0x04495000

APP Defined Section1

0K

0x04499000

APP Defined Section2

0K

0x04499000

重要

软件架构

系统软件架构如下图所示:

../../../../_images/fig_swArch1.png

系统软件架构

  • Platform feature: 包括 OTA、Flash、FTL 等。

  • Peripheral driver: 提供对 RTL87x2G 外设接口的应用层访问。

  • OSIF: 实时操作系统的抽象层。

  • GAP: 用户应用程序与 BLE 协议栈通信的抽象层。

  • Application: 应用层包含用户定义的各个应用任务。

任务和优先级

如下图所示,用户应用程序共创建了 5 个任务:

../../../../_images/fig_swTask1.png

任务和优先级

各任务描述及优先级如下表:

任务说明及优先级

任务

描述

优先级

Timer

实现 FreeRTOS 所需的软件定时器

6

BT Controller stack

实现 HCI 以下的BLE协议栈

6

BT Host stack

实现 HCI 以上的BLE协议栈

5

LVGL

处理 UI 显示及交互

1

Idle

运行后台任务

0

备注

开发者可创建多个应用任务,并相应地分配内存资源。

GUI 任务

关于 LVGL UI 的设计开发指南请参阅 使用 LVGL 设计应用程序

在本示例工程中 GUI 默认任务为 LVGL benchmark demo 工程,测试并展示了 LVGL 在该平台上各个场景下的性能表现,包括帧率和 CUP 负载水平。

LVGL 主要的配置项目都在 src\lvgl_port\lv_conf.h 中进行配置,包括显示设备尺寸和颜色深度、堆栈接口配置等,开发者可以根据需求定制。

  1. 当开发者需要更换显示设备时,完成显示设备的驱动后,需要将显示设备驱动对接到 LVGL 的显示接口,在 src\lvgl_port\lv_conf.h 中适配显示设备参数,并在 src\lvgl_port\lv_port_disp.c 中分配合适的 frame buffer,具体请参阅 LVGL Display Porting

本示例应用使用的 display IC 不带有 RAM,需要为其分配整屏尺寸的 frame buffer,因此在 PSRAM 上分配了两个整屏尺寸的 frame buffer 用于显示。若使用的 display IC 带有 RAM,则 frame buffer 的大小不必为整屏尺寸,需要配置 src\lvgl_port\lv_port_disp.c 中的 LVGL_USE_EDPI 为不启用(0),以更换 disp_flush 函数适配刷屏。

// lv_conf.h
/*====================
   COLOR SETTINGS
*====================*/
#define MY_DISP_HOR_RES    480
#define MY_DISP_VER_RES    480
/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH 16

// lv_port_disp.c
#define LV_PORT_BUF1        (uint32_t)0x08000000
#define LV_PORT_BUF2        (uint32_t)(0x08000000 + MY_DISP_HOR_RES * MY_DISP_VER_RES * LV_COLOR_DEPTH / 8)

void lv_port_disp_init(void)
{
   ...
   static lv_disp_draw_buf_t draw_buf_dsc_3;
   lv_color_t *buf_3_1 = (lv_color_t *)LV_PORT_BUF1;           /*A screen sized buffer*/
   lv_color_t *buf_3_2 = (lv_color_t *)LV_PORT_BUF2;           /*Another screen sized buffer*/
   lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2,
                        MY_DISP_VER_RES * MY_DISP_HOR_RES);   /*Initialize the display buffer*/

   /*Set a display buffer*/
   disp_drv.draw_buf = &draw_buf_dsc_3;

   /*Required for Example 3)*/
   disp_drv.full_refresh = 1;
   ...
}

2. 当开发者需要更换输入设备时,完成输入设备的驱动后,需要将输入设备驱动对接到 LVGL 的输入接口,在 src\lvgl_port\lv_port_indev.c 中选择对应的输入设备类型,并将驱动对接到对应的接口, 具体请参阅 LVGL Input Porting

本示例应用中,搭配对接了触屏作为输入设备。

// lv_port_indev.c
void lv_port_indev_init(void)
{
   ...
   /*Register a touchpad input device*/
   lv_indev_drv_init(&indev_drv);
   indev_drv.type = LV_INDEV_TYPE_POINTER;
   indev_drv.read_cb = touchpad_read;
   indev_touchpad = lv_indev_drv_register(&indev_drv);
   ...
}

/*------------------
* Touchpad
* -----------------*/

static uint16_t touch_x = 0;
static uint16_t touch_y = 0;
static bool touch_pressing = 0;

/*Will be called by the library to read the touchpad*/
static void touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
{
   static lv_coord_t last_x = 0;
   static lv_coord_t last_y = 0;

   /* rt touch read port */
   if (drv_touch_read(&touch_x, &touch_y, &touch_pressing) == false)
   {
      return;
   }

   /*Save the pressed coordinates and the state*/
   if (touchpad_is_pressed())
   {
      touchpad_get_xy(&last_x, &last_y);
      data->state = LV_INDEV_STATE_PR;
   }
   else
   {
      data->state = LV_INDEV_STATE_REL;
   }

   /*Set the last pressed coordinates*/
   data->point.x = last_x;
   data->point.y = last_y;
}
/*Return true is the touchpad is pressed*/
// static lv_coord_t touch_x;
// static lv_coord_t touch_y;
static bool touchpad_is_pressed(void)
{
   /*Your code comes here*/
   return touch_pressing;
}

/*Get the x and y coordinates if the touchpad is pressed*/
static void touchpad_get_xy(lv_coord_t *x, lv_coord_t *y)
{
   /*Your code comes here*/
   (*x) = touch_x;
   (*y) = touch_y;
}
  1. 开发者用到的图片和字体等定制资源时,lvgl 提供了对应工具支持 LVGL Font ConverterLVGL Image Converter,使用方法请参阅官方文档 LVGL Font , LVGL Image

  2. 关于 LVGL 进一步的开发细节,请参阅官方文档 LVGL Documentation

BLE 任务

BLE_OTA_DEMO 请参阅 OTA , BLE_PERIPHERAL_DEMO 请参阅 LE Peripheral