简介

LVGL(Light and Versatile Graphics Library)是一个免费且开源的图形库,提供了创建嵌入式 GUI 所需的一切功能,包括易于使用的图形元素、美观的视觉效果以及低内存占用。

主要特性

  • 强大的构建模块,例如按钮、图表、列表、滑块、图像等

  • 高级图形功能,包括动画、抗锯齿、不透明度、平滑滚动

  • 支持多种输入设备,例如触摸板、鼠标、键盘、编码器等

  • 支持多语言,采用 UTF-8 编码

  • 支持多显示器,例如同时使用多个 TFT 和单色显示器

  • 完全可自定义的图形元素,具有类似 CSS 的样式

  • 硬件无关:可与任何微控制器或显示器配合使用

  • 可扩展:能够在低内存环境下运行(64 kB Flash,16 kB RAM)

  • 支持但不依赖操作系统、外部存储和 GPU

  • 即使使用高级图形效果,也支持单帧缓冲操作

  • 使用 C 编写,具有最大兼容性(兼容 C++)

  • 模拟器可在没有嵌入式硬件的情况下在 PC 上开始嵌入式 GUI 设计

  • 支持 MicroPython 绑定

  • 提供教程、示例和主题以快速设计 GUI

  • 文档可在线访问,也可下载为 PDF

  • 免费且开源,采用 MIT 许可证

要求

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

  • 16、32 或 64 位微控制器或处理器

  • 推荐时钟速度 > 16 MHz

  • Flash/ROM:> 64 kB(用于基本组件,推荐 > 180 kB)

  • RAM:

    • 静态 RAM 使用量:约 2 kB,具体取决于使用的功能和对象类型

    • 堆栈:> 2 kB(推荐 > 8 kB)

    • 动态数据(堆):> 4 kB(如果使用多个对象,推荐 > 48 kB)。通过 LV_MEM_SIZElv_conf.h 中设置。

    • 显示缓冲区:> "水平分辨率" 像素(推荐 > 10 × "水平分辨率")

    • MCU 或外部显示控制器中的一个帧缓冲区

  • C99 或更新版本的编译器

  • 基本 C(或 C++)知识:

注意:内存使用量可能因架构、编译器和构建选项而异。

许可证

LVGL 项目(包括所有存储库)采用 MIT 许可证。 这意味着您甚至可以在商业项目中使用它。

这不是强制性的,但如果您在论坛的 我的项目 分类中或通过 lvgl.io 私信写几句话介绍您的项目,我们将非常感激。

尽管您可以免费获得 LVGL,但其背后有大量的工作。这是由一群志愿者在他们的空闲时间创建并提供给您的。

为了使 LVGL 项目可持续发展,请考虑为项目做贡献。 您可以选择多种不同的贡献方式,例如简单地发一条关于您使用 LVGL 的推文、修复错误、翻译文档,甚至成为维护者。

存储库布局

LVGL 项目的所有存储库都托管在 GitHub 上:https://github.com/lvgl

您将在那里找到以下存储库:

  • lvgl 库本身,包含许多示例演示

  • lv_drivers 显示和输入设备驱动程序

  • blog 博客网站的源码(https://blog.lvgl.io)

  • sim 在线模拟器网站的源码(https://sim.lvgl.io)

  • lv_port_... LVGL 的开发板或环境移植

  • lv_binding_.. 绑定到其他语言

发布策略

核心存储库遵循 语义化版本控制 的规则:

  • 主版本用于不兼容的 API 更改。例如 v5.0.0、v6.0.0

  • 次版本用于新的但向后兼容的功能。例如 v6.1.0、v6.2.0

  • 补丁版本用于向后兼容的错误修复。例如 v6.1.1、v6.1.2

每次发布都会创建类似 vX.Y.Z 的标签。

发布周期

  • 错误修复:按需发布,甚至每周一次

  • 次版本发布:每 3-4 个月

  • 主版本发布:大约每年一次

分支

核心存储库至少有以下分支:

  • master 最新版本,补丁直接合并到此处。

  • release/vX.Y 次版本的稳定版本

  • fix/some-description 用于错误修复的临时分支

  • feat/some-description 用于新功能的临时分支

更新日志

更改记录在 CHANGELOG.md 中。

版本支持

在 v8 之前,每个主系列的最后一个次版本支持 1 年。 从 v8 开始,每个次版本支持 1 年。

版本 发布日期 支持结束日期 活跃状态
v5.3 2019 年 2 月 1 日 2020 年 2 月 1 日
v6.1 2019 年 11 月 26 日 2020 年 11 月 26 日
v7.11 2021 年 3 月 16 日 2022 年 3 月 16 日
v8.0 2021 年 6 月 1 日 2022 年 6 月 1 日
v8.1 2021 年 11 月 10 日 2022 年 11 月 10 日
v8.2 2022 年 1 月 31 日 2023 年 1 月 31 日
v8.3 开发中

常见问题

我可以在哪里提问?

您可以在论坛提问:https://forum.lvgl.io/

我们使用 GitHub 问题 进行与开发相关的讨论。 仅当您的问题或问题与库的开发密切相关时才使用它们。

在发布问题之前,请阅读此常见问题部分,因为您可能会在此处找到问题的答案。

我的 MCU/硬件是否受支持?

任何能够通过并行端口、SPI、RGB 接口或其他方式驱动显示器并满足要求的 MCU 都受 LVGL 支持。

这包括:

  • “常见” MCU,例如 STM32F、STM32H、NXP Kinetis、LPC、iMX、dsPIC33、PIC32、SWM341 等

  • 蓝牙、GSM、Wi-Fi 模块,例如 Nordic NRF 和 Espressif ESP32

  • 带有帧缓冲设备(如 /dev/fb0)的 Linux。这包括树莓派等单板计算机

  • 任何其他具有足够强大 MCU 和驱动显示器的外设的设备

我的显示器是否受支持?

LVGL 只需要一个简单的驱动函数,将像素数组复制到显示器的指定区域。 如果您可以使用显示器完成此操作,那么您可以将其与 LVGL 一起使用。

支持的显示器类型示例:

  • 具有 16 或 24 位颜色深度的 TFT

  • 带 HDMI 接口的显示器

  • 小型单色显示器

  • 灰度显示器

  • 甚至 LED 矩阵

  • 或任何其他可以控制像素颜色/状态的显示器

请参阅 移植 部分了解更多信息。

LVGL 无法启动、随机崩溃或显示器上没有绘制任何内容。可能是什么问题?

  • 尝试增加 LV_MEM_SIZE

  • 确保 lv_disp_drv_tlv_indev_drv_tlv_fs_drv_t 是全局或 static 的。

  • 确保您的显示器在没有 LVGL 的情况下可以正常工作。例如,在启动时将其绘制为红色。

  • 启用 日志记录

  • lv_conf.h 中启用断言(LV_USE_ASSERT_...)。

  • 如果您使用 RTOS:

    • 增加调用 lv_timer_handler() 的任务的堆栈大小。

    • 确保您按照此处描述使用了互斥锁。

为什么我的显示驱动程序没有被调用?我可能遗漏了什么?

确保您在中断中调用了 lv_tick_inc(x),并在主 while(1) 中调用了 lv_timer_handler()

了解更多信息,请参阅 TickTimer handler 部分。

为什么显示驱动程序只被调用了一次?只有显示器的上部被刷新。

确保您在 "显示刷新回调" 的末尾调用了 lv_disp_flush_ready(drv)

为什么屏幕上显示的是乱码?

可能是您的显示驱动程序中存在错误。尝试以下代码而不使用 LVGL。您应该会看到一个带有红蓝渐变的方块。

#define BUF_W 20
#define BUF_H 10

lv_color_t buf[BUF_W * BUF_H];
lv_color_t * buf_p = buf;
uint16_t x, y;
for(y = 0; y < BUF_H; y++) {
    lv_color_t c = lv_color_mix(LV_COLOR_BLUE, LV_COLOR_RED, (y * 255) / BUF_H);
    for(x = 0; x < BUF_W; x++){
        (*buf_p) =  c;
        buf_p++;
    }
}

lv_area_t a;
a.x1 = 10;
a.y1 = 40;
a.x2 = a.x1 + BUF_W - 1;
a.y2 = a.y1 + BUF_H - 1;
my_flush_cb(NULL, &a, buf);

为什么屏幕上显示的是无意义的颜色?

可能是 LVGL 的颜色格式与您的显示器的颜色格式不兼容。检查 lv_conf.h 中的 LV_COLOR_DEPTH

如果您使用的是带 SPI(或其他字节导向接口)的 16 位颜色,可能需要在 lv_conf.h 中将 LV_COLOR_16_SWAP 设置为 1。 它会交换像素的高字节和低字节。

如何加速我的 UI?

  • 打开编译器优化,并启用 MCU 的缓存(如果有)

  • 增大显示缓冲区的大小

  • 使用两个显示缓冲区,并在后台使用 DMA(或类似外设)刷新缓冲区

  • 如果您使用 SPI 或并行端口驱动显示器,请增加其时钟速度

  • 如果您的显示器有 SPI 接口,考虑更换为具有并行接口的型号,因为它具有更高的吞吐量

  • 将显示缓冲区放在内部 RAM(而不是外部 SRAM)中,因为 LVGL 经常使用它,并且它应该具有快速访问时间

如何减少 Flash/ROM 使用量?

您可以在 lv_conf.h 中禁用所有未使用的功能(例如动画、文件系统、GPU 等)和对象类型。

如果您使用的是 GCC/CLANG,可以添加 -fdata-sections -ffunction-sections 编译器标志和 --gc-sections 链接器标志,以从最终二进制文件中删除未使用的函数和变量。如果可能,添加 -flto 编译器标志以启用链接时优化,并与 GCC 的 -Os 或 CLANG 的 -Oz 一起使用。

如何减少 RAM 使用量?

  • 降低显示缓冲区的大小

  • lv_conf.h 中减少 LV_MEM_SIZE。此内存用于创建按钮、标签等对象。

  • 为了使用较低的 LV_MEM_SIZE,您可以仅在需要时创建对象,并在不再需要时删除它们。

如何与操作系统一起工作?

要在任务可以抢占彼此的操作系统中工作,您应该使用互斥锁保护与 LVGL 相关的函数调用。 请参阅 操作系统和中断 部分了解更多信息。