从 32kB 内存起步,到 3D 渲染与 GPU 加速,LVGL 用一套 C 语言 API 覆盖从 MCU 到嵌入式 Linux 的整条 UI 链路。本文拆解它的定位、资源门槛、功能全景、工具链、集成生态与上手步骤,并附常见问题与性能优化清单——读完可以直接评估它适不适合你的下一个项目。
做嵌入式产品,最常被低估的一件事,是界面。
硬件调通、协议打通、算法跑稳,最后交付前用户打开屏一看——界面还停留在 2015 年的安卓 ROM。不是没人写,是写 UI 这件事,在嵌入式这条路上从来都太贵:要么自己画像素、算坐标、折腾抗锯齿,要么把整个屏幕外包给一块昂贵的主控芯片。
LVGL 要解决的,就是这个矛盾。
LVGL 是谁
LVGL,全称 Light and Versatile Graphics Library(轻量级通用图形库),是一个 MIT 许可的开源嵌入式 GUI 库,纯 C 编写、C++ 兼容、零外部依赖。它的目标很朴素:让单片机、MPU 上用同一套 API,快速做出带动画、样式、多语言的界面。

先看项目基本盘,数据截至本文调研,来源 GitHub 仓库页面:
| 指标 |
数值 |
| Stars |
24.9k |
| Forks |
4.4k |
| Watchers |
321 |
| Commits |
13,151 |
| Open Issues |
77 |
| Open PRs |
60 |
| License |
MIT |
24.9k star 在嵌入式圈是什么分量?它不是前端那种几小时冲上去的热度,而是一行行 C 代码、一个个版本攒下来的信任。13,151 次提交 对应的是一个活跃维护近十年的项目,而不是某次发布会后的临时仓库。
再往深看一层,这些数字背后有三个「不常见」:
- 不靠营销涨 star:LVGL 极少上新闻、极少做发布会式宣传,star 基本来自开发者自发推荐。
- 不靠版本号刷存在:v8 到 v9 是一次 API 大改,官方用了一年时间做迁移文档和兼容层,没有「弃坑就跑」。
- 不靠闭源赚钱:库本体 MIT 免费商用,商业化靠 LVGL Pro 工具链,逻辑非常清晰。
为什么这三点重要:因为嵌入式产品的生命周期是 5 到 10 年。你选一个 UI 库,等于把未来十年的维护成本也押上去了。一个活跃、透明、有商业支撑的开源项目,比一个功能更炫但半年不更新一次的库,值得多给几个星。
而真正让开发者愿意把它放进量产固件的,是下面这份资源账单。
为什么嵌入式 UI 这么难做
在理解 LVGL 之前,值得先看清它解决的问题。
嵌入式 UI 的传统路径,基本就三条,每条都有代价:
- 裸写显示驱动:直接往帧缓冲里写像素,效率最高,但一切都要自己算——文字、图标、触摸反馈、动画,一个都不能偷懒。
- 移植轻量 GUI:比如 uGUI、TinyGUI 这类极简库,省资源,但 widget 少、样式弱,做复杂交互要靠自己补。
- 上重型框架:QT、Chromium 这类,功能齐全,但对 MCU 来说是天文数字的内存与算力负担。

痛点其实很集中:
- 内存:一块 320×240 的屏幕,RGB565 就要 150kB 帧缓冲,小 MCU 吃不消。
- 算力:抗锯齿、圆角、阴影这些「现代 UI 感」全靠 CPU 画,主频不够就掉帧。
- 语言与字体:英文还好,CJK 字库动辄几 MB,小设备装不下。
- 碎片化:每块屏、每个触摸 IC、每颗 MCU 的驱动都不一样,重写一遍又一遍。
这里值得展开说内存这笔账。
一块 320×240 的屏,如果按 RGB565,也就是每像素 2 字节做全屏缓冲,就是 320×240×2 = 150kB RAM。而 STM32F103 才 64kB SRAM,STM32F407 也就 192kB。光缓冲就吃掉大半家当,剩下的留给堆栈、状态机、通信协议。
这就是为什么 LVGL 坚持用 局部渲染(partial rendering):它不是把整屏画完再推出去,而是 每次只渲染屏幕的一个条带。这样帧缓冲可以缩到屏幕的 1/10,320×240 的屏只需要 15kB 缓冲,普通 MCU 就能跑。
LVGL 对上面这几条,几乎是逐条对症下药。
资源门槛到底有多低
先分清两个口径,这很重要,也是社区里最容易混的地方。
官方文档 Introduction 给的最低门槛,能跑起来的下限:
| 项目 |
最低要求 |
| MCU 架构 |
16 / 32 / 64 位 |
| Flash |
> 64kB |
| 静态 RAM |
~2kB |
| 栈 |
> 2kB |
堆,LV_MEM_SIZE |
> 2kB |
| 编译器 |
C99 或更新 |
仓库 README 给的典型资源占用,一个像样项目的大致账单:
- 约 100kB RAM
- 约 200–300kB Flash
- 渲染缓冲为 屏幕大小的 1/10
- README 另列最低要求:32kB RAM、128kB Flash、帧缓冲、至少 1/10 屏幕的渲染缓冲

一句话总结:「能跑」的门槛很低,「好用」的账单大约 100kB RAM 起。
这意味着什么?意味着 ESP32、STM32F4、RP2040 这类主流芯片都能跑出像样的界面,而不用为了 UI 单独换一颗带 GPU 的高价主控。
再说一遍推荐配置,官方给的是:
- 时钟 > 16MHz
- Flash > 180kB
- 栈 > 8kB
- 堆 > 48kB
对比一下常见 MCU:ESP32 有 520kB SRAM + 4MB Flash、STM32F429 有 256kB SRAM、RP2040 有 264kB SRAM——都在推荐配置之上。换句话说,如果你手上的板子是这几年的主流型号,LVGL 的资源约束基本可以忽略。
30+ 组件,一套样式系统
LVGL 的内置 widget 数量是 30+:
- Button(按钮)
- Label(文本)
- Slider(滑块)
- Chart(图表)
- Keyboard(键盘)
- Meter(仪表盘)
- Arc(弧形进度)
- Table(表格)
这些不是「能显示」的占位组件,而是带交互、带状态、带默认样式的成品。

做仪表盘的人会立刻喜欢 Meter:它不是让你自己画一个圆盘加指针,而是 原生支持刻度、指针、范围色带,改几个参数就能出成品。
做数据采集的人会喜欢 Chart:它支持多序列、X/Y 轴、缩放、滚轮浏览——在 MCU 上做示波器界面,这个组件几乎是标配。
动画系统也值得一提:LVGL 内置完整的动画框架,lv_anim_create 一条 API 就能做出 淡入淡出、滑动、缩放、旋转、颜色过渡、数值滚动。不是让你自己写一帧帧定时器,而是库帮你管理所有动画状态机。
- 数值滚动:仪表盘的指针从 0 转到目标值,一秒的过渡看起来「活」了。
- 颜色过渡:按钮按下变红、松开恢复,状态切换更直观。
- 列表滑动:惯性滚动、吸附到最近项,手感接近手机。
做交互反馈的人会特别受益:以前在 MCU 上做「按下变亮」这种反馈,得自己开定时器、自己算插值。LVGL 把这些封装成 几行代码,效果还比手写的平滑。
再补一个反直觉的点:LVGL 的动画引擎支持 多条动画并行,而且 动画对象会自动从屏幕上移除,不会泄漏内存——这在长期运行的嵌入式设备上是关键特性。
配合组件的是 100+ 样式属性,可以按 widget 状态配置——pressed、focused、disabled、checked 各有各的样式,做手感这件事不需要自己画三套状态图。
布局上,LVGL 内建 Flexbox 和 Grid 两套引擎。做过前端的人可以直接照搬思路:lv_obj_set_flex_flow、lv_obj_set_grid_dsc 一套下来,对齐、间距、换行都由库处理,不需要手算像素坐标。
为什么这是关键差异:以前在 MCU 上做界面,布局是「写死坐标」——x=10, y=20,字号一变、语言一换,整屏都要重排。LVGL 用 Flexbox/Grid 后,布局是「声明式」的,组件自己决定位置,改字号、加一行文字都不用手工挪。
交互设计:输入设备全家桶
UI 是给人用的,触摸之外,嵌入式还有大量非触摸场景。LVGL 对输入设备的支持是一等公民。
- Mouse:桌面、模拟器场景
- Touchpad:消费电子、工业面板
- Keypad:数字键盘、工业控制
- Keyboard:文字输入
- Encoder:旋转编码器,工业 HMI 最常用
- 外部按键:方向键 + 确认键的老式遥控方案

Encoder(旋转编码器)是嵌入式 HMI 里最被低估的交互:一个旋钮 + 一个确认键,就能完成菜单选择、参数调节、页面切换。很多工业仪表、医疗设备都靠它,因为 戴手套也能操作,比触摸屏更耐用。
LVGL 的输入系统是 统一抽象 的:lv_indev_create() 建一个输入设备对象,然后告诉它类型,例如 LV_INDEV_TYPE_POINTER、LV_INDEV_TYPE_ENCODER,以及读取回调。你的代码不用关心用户到底是用手指、鼠标还是旋钮,只需要处理统一的 LV_EVENT_CLICKED 事件。
多输入并存是常见需求:一块屏同时支持触摸 + 编码器,触摸选参数,编码器微调。LVGL 能同时注册多个 lv_indev,各自独立工作。
字体与资源管理
嵌入式 UI 的一个隐性大坑是 字体——特别是中文。
LVGL 的字体系统有三条路:
- 内置字体:
lv_font_montserrat_14 等英文数字字体,零成本。
- 自定义字体:通过
lv_font_conv 工具从 TTF/OTF 生成 C 数组。
- 字体子集:只打包用到的字符,CJK 界面可控制在几十 kB。

中文字体的正确姿势:不要整包 GB2312,要 只打包你的界面里真正用到的几百个字。LVGL 的字体子集机制支持从完整字体里提取字符子集——这样中文界面也能压在 50kB 以内。
图标怎么办:LVGL 支持 Symbol 字体,把图标编码成 Unicode 私用区字符,一个字体文件里塞几十上百个图标,跟文字一样用 lv_label_set_text 引用。
图片资源:LVGL 的图片可以是 C 数组、SD 卡文件或二进制流,不需要全部加载到 RAM。大图可以按需从 flash 或 SD 读,避免 RAM 爆掉。
资源打包建议,来自个人经验:
- 文字、图标、小图 → 编进固件,也就是 C 数组。
- 大图、长图、背景图 → 放外部 flash 或 SD 卡。
- 需要动画 → 用 Lottie 文件,体积小、效果好。
渲染引擎:从 2D 到 3D
LVGL 的渲染能力,是它区别于早期嵌入式 GUI 库的核心分水岭。
2D 引擎内置这些特效:
- 渐变(Gradient)
- 抗锯齿(Anti-aliasing)
- 透明度(Opacity)
- 阴影(Shadow)
- 平滑滚动(Smooth scrolling)
- 图像变换(Image transformation)
3D:支持加载 glTF 模型 并经 OpenGL ES 渲染——这意味着在带 GPU 的 MPU 上,LVGL 不只是画仪表盘,还能显示真 3D 场景。

矢量图形、SVG、Lottie 动画也都有官方支持。做动画这件事,不再需要自己写一帧帧的定时器逻辑。
值得一提的是 抗锯齿。这是「现代 UI 感」与「嵌入式土味」的最大分界线。LVGL 的抗锯齿不是简单的二值化,而是 对曲线边缘做 alpha 混合,圆角、弧形、斜线在屏幕上看起来平滑自然,而不是锯齿状像素点。
平滑滚动 则是触摸设备上的体验关键——列表滚动不带惯性、不带缓动,用户会立刻觉得「卡」。LVGL 内置了滚动惯性、吸附与缓动曲线,开箱就有接近手机的滑动体验。
值得一提的细节:即使用了这些高级特效,LVGL 也可以只用单帧缓冲运行——这对 RAM 紧张的小 MCU 是救命的。
多语言与多显示
LVGL 的文本系统基于 UTF-8,官方明确覆盖:CJK(中日韩)、Thai、Hindi、Arabic、Persian。

这意味着什么?意味着 在 LVGL 上做中文界面不需要自己处理编码转换,lv_label_set_text 直接写中文就行。这是很多老 GUI 库做不到的——它们只认 ASCII 或单字节 GBK。
为什么这一点对中文开发者尤其重要:以前要在 MCU 上显示中文,得自己做 GBK/UTF-8 转码,甚至要处理字库切页、半角全角混排。LVGL 的 UTF-8 支持把这些脏活全包了——你只管写字符串,剩下的交给库。
顺带说下 字体:LVGL 支持 字体子集,可以只打包你界面里真正用到的几百个汉字,而不是把整个 GB2312 字库塞进去。这样 CJK 界面也能控制在几十 kB 以内。
显示层面,LVGL 支持 多显示,且 多个显示可以有不同色彩格式 混合共存。一块小 OLED 做主屏、一块大 TFT 做详情,同一份代码跑起来,不用为每块屏重写一遍渲染。
支持的显示类型包括:单色屏、ePaper、OLED、TFT、普通显示器——从墨水屏到 4K 触摸屏,都能挂到同一个 LVGL 上。
多显示的实际场景:智能手表用小 OLED 主界面,手机 App 遥控器用大 TFT 副界面,两块屏颜色深度不同——主屏 1-bit 单色,副屏 RGB565——同一个 LVGL 上下文里并存,代码只写一次。
GPU 加速:把重活交给硬件
如果只有软件渲染,嵌入式 UI 的天花板就摆在那。LVGL 的答案是接入 GPU。
官方内置的 GPU 加速器驱动包括:
- VG-Lite
- Dave2D(NXP)
- NeoChrome(Renesas)
- NXP PXP
- ThinkSilicon NemaGFX
- Arm-2D
- OpenGL ES

有了 GPU 驱动,旋转、缩放、混合这些重活交给硬件,CPU 主频不再是 UI 流畅度的唯一瓶颈。这也是 LVGL 能跑在 i.MX RT700、RA8D2 这类带加速的 MPU 上还能做 3D 的原因。
关键分水岭:在纯软件渲染下,一屏 320×240 的动画可能就要占满主核;而有了 GPU 驱动,旋转、缩放、alpha 混合这些重活全部下放硬件,CPU 可以去跑业务逻辑、通信协议。
Arm-2D 值得单独说——它是 Arm 官方提供的 2D 加速库,在 Cortex-M 上专门做像素级加速。LVGL 原生支持它,意味着 在 Arm 生态里 LVGL 几乎可以无痛吃满硬件加速。
LVGL Pro:从设计稿到 C 代码
LVGL 库本体 MIT 免费。但 LVGL Pro 是另一个概念——它是官方提供的 专业工具链,核心能力是从 XML 描述界面,自动生成纯 LVGL C 代码。
包含四件套:
- Editor:桌面 GUI 构建工具,支持数据绑定、翻译、动画、测试。
- Online Viewer:浏览器版编辑器,地址 viewer.lvgl.io,零安装试用。
- Figma 插件:Figma 设计稿一键转 LVGL Pro。
- CLI Tool:生成 C 代码,CI/CD 跑测试。

用 XML 描述界面的样子,官方 README 示例如下:
<screen>
<view>
<lv_button align="center">
<event_cb callback="button_clicked_cb" />
<lv_label text="Hello from LVGL!" />
</lv_button>
</view>
</screen>
为什么 XML 描述是重要创新:传统嵌入式 UI 开发是「代码写界面」——你在 C 代码里一行行创建对象、设置坐标、绑定事件,改一个间距要重编译。用 XML 后,界面结构和逻辑代码分离:设计师改 XML、工程师改 C,互不阻塞。
CI/CD 集成更是杀手锏:CLI 工具可以在流水线里自动生成 C 代码并跑测试——UI 变更可回归、可自动化验证,这在量产项目里几乎不可替代。
许可口径要分清:LVGL 库是 MIT,随便用;LVGL Pro 免费仅限非商业或评估用途,商用需付费授权。做产品前先算清楚这条账。
集成生态:芯片、RTOS、框架、开发板都对齐了
一个 UI 库能不能被量产采纳,看的不是功能清单,而是 生态对齐度——有没有驱动、有没有移植包、有没有官方的板级支持。
LVGL 在这块的布局是:
- 芯片厂商:ESP32、NXP MCUXpresso、Renesas FSP、STM32
- RTOS:Zephyr、NuttX、RT-Thread
- 框架:Arduino、PlatformIO、CMSIS-Pack
- 开发板:Seeed Studio、Elecrow、Riverdi、VIEWE

这条清单的分量在于:它不是社区第三方硬凑出来的,而是官方和厂商一起维护的。你选的芯片、你用的 RTOS、你手上的板子,大概率已经有现成的 LVGL 移植包,而不是让你从零对着数据手册写驱动。
举个具体例子:如果你用的是 ESP32 跑 Arduino 框架,那可以直接在 Arduino Library Manager 里搜 LVGL 装上,再配合 TFT_eSPI 之类显示库,半小时出第一个界面。
如果你用的是 Zephyr RTOS,LVGL 已经集成在 Zephyr 官方 modules 里,west build 时自动带上。
这就是生态的力量:不是「能不能跑」,而是「跑起来要多花多少时间」。
补充一个现实视角:很多嵌入式团队不是「不会写 UI」,而是「把 UI 当成最后一个环节」。等硬件、协议、算法都调完,才发现 UI 需要重写一遍。如果一开始就确认 LVGL 在你选定的平台上有官方集成,UI 开发可以和硬件调试并行进行——UI 工程师先跑 SDL 模拟器,硬件工程师同时调驱动,最后一步对接。
这样做的收益很直接:项目周期可以压掉 30%–40%。UI 不是最后的附加项,而应该是和硬件一起从第一天就启动的并行线程。
在云栈社区,也经常能看到嵌入式开发者讨论这类 GUI 选型与移植问题。
内置驱动:别自己写 SPI 了
UI 库最难啃的硬骨头,其实在 底层驱动。LVGL 官方把这些也打包了:
- 模拟器/桌面:SDL、X11、Wayland
- 显示控制器:MIPI-DBI/SPI LCD,如 ILI9341、ST7789;ST LTDC、NXP eLCDIF
- 嵌入式 Linux:fbdev、DRM/KMS、Wayland、libinput/evdev
- GPU 加速器:VG-Lite、NXP PXP、ThinkSilicon NemaGFX、Arm-2D、OpenGL ES

开发流程因此能拆成两层:先在 PC 上用 SDL 跑通界面逻辑,再无缝切到真实硬件。UI 开发和硬件调试不再互相阻塞——这在嵌入式项目里能省下一大半联调时间。
ILI9341 和 ST7789 这两块是嵌入式 LCD 的「国民级」屏,官方直接支持意味着 淘宝上几十块一套的模块就能用,不需要自己啃 datasheet 的时序图。
DRM/KMS + Wayland 则是嵌入式 Linux 的标准路径——如果你在跑 Raspberry Pi 或者工业 HMI 盒子,LVGL 可以直接接到 KMS 平面,不需要走 X11 的中间层。
手把手:最小 C 示例拆解
LVGL 的最小集成骨架只有十几个 API 调用。
先按官方步骤,把 lv_conf_template.h 复制为 lv_conf.h,并把第一段 #if 0 改成 #if 1。然后初始化:
#include "lvgl/lvgl.h"
void main(void)
{
lv_init();
lv_tick_set_cb(my_tick_cb);
lv_display_t * display = lv_display_create(320, 240);
static uint8_t buf[320 * 240 / 10 * 2]; /* partial buffer, RGB565 */
lv_display_set_buffers(display, buf, NULL, sizeof(buf), LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_flush_cb(display, my_flush_cb);
lv_indev_t * indev = lv_indev_create();
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev, my_touch_read_cb);
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_label_set_text(label, "Hello world");
lv_obj_center(label);
while(1) {
lv_timer_handler();
my_sleep_ms(5);
}
}

拆开看,其实只做五件事:
lv_init():库初始化。
lv_tick_set_cb():告诉 LVGL 时间怎么走。
lv_display_create():建显示对象,并注册帧缓冲与 flush 回调。
lv_indev_create():建输入设备对象,并注册触摸读取回调。
- 最后的
while(1) { lv_timer_handler(); }:定时器主循环,必须持续调用。
关键点:lv_timer_handler() 是心跳,漏调用界面就不会刷新。渲染缓冲取 1/10 屏幕是官方推荐的默认策略——RAM 更省,性能损失不明显。
再补一个容易被忽略的点:lv_tick_set_cb 是给 LVGL 提供 毫秒级时间源。如果你的系统已经有 tick,直接接上即可;如果没有,得自己写一个 millis() 回调。
为什么 lv_timer_handler 必须在循环里:LVGL 不是中断驱动,它是 轮询式 的。所有动画、超时、事件队列都在 lv_timer_handler 里跑,漏调一次,界面就停一帧。在 RTOS 环境下,通常把 lv_timer_handler 放在一个独立低优先级任务里,配合 vTaskDelay(5)。
MicroPython 也能玩 LVGL
如果你不想写 C,LVGL 也提供了 MicroPython 绑定,官方仓库里的 lv_binding_micropython 就是干这个的。

这意味着什么?意味着 用 Python 做嵌入式 UI 也可以很流畅:
- 交互式调试:不用每次改一行代码就重编译、烧录,直接在 REPL 里
import lvgl as lv 然后建控件。
- 快速原型:想试一个布局、一个动画效果,MicroPython 上几行 Python 就能验证,不需要动 C 工程。
- 教育场景:学生、新手入门 LVGL,Python 门槛远低于 C,能把精力集中在 UI 逻辑而不是内存管理。
什么时候该用 MicroPython,什么时候用 C:
- 用 MicroPython:原型验证、教学、功能简单、主控算力够,例如 ESP32 这类。
- 用 C:量产固件、性能敏感、代码体积紧张、需要精细控制内存。
注意:MicroPython 绑定 不是官方核心库的一部分,它独立存在于 lv_binding_* 仓库里。如果你的项目走 MicroPython 路线,需要确认你的固件是否已经编译进 LVGL 模块,否则要先自己交叉编译一遍固件。
除了 MicroPython,LVGL 还有 C++ 绑定 lv_binding_cpp——如果你的固件本来就是 C++,可以直接用类封装调用 LVGL,省掉一层 extern "C" 桥接。
官方学习路径
入门不需要先啃源码。
- 100+ C 与 XML 示例:lvgl.io/docs/open/examples,按 widget、按功能拆好。
- Online Viewer:viewer.lvgl.io,浏览器里直接改界面,零安装。
- AI-ready 文档:官方 docs 自带「Ask AI」功能,问文档不用去论坛翻帖。
- 仓库拆分清晰:
lvgl 库、lv_drivers 驱动、lv_port_* 板级移植、lv_binding_* 语言绑定。

最短路:打开 Online Viewer → 拖出你要的组件 → 复制生成的代码 → 粘进自己的工程。
为什么 Online Viewer 特别适合入门:你不需要买任何硬件、不需要装任何工具,打开浏览器就能试 LVGL 的所有组件和交互。先看到效果,再决定要不要学——这比看十篇教程都管用。
仓库拆分也是精心设计:lvgl 只放核心库,lv_drivers 放显示与输入驱动,lv_port_* 是针对具体开发板的移植包,lv_binding_* 是 MicroPython、C++ 等语言绑定。每个包职责单一,按需下载,不互相污染。
项目落地流程
如果要把 LVGL 真的塞进一个量产项目,通常走这五步:
- 评估资源:量出你的屏、CPU、RAM、Flash,对照官方「最低/推荐」配置,决定能用多大缓冲。
- 选版本:新项目直接用 v9.6.0,V9 最后一个稳定版;老项目评估 v8 到 v9 迁移成本。
- 接驱动:有官方内置驱动,如 ILI9341、ST7789、DRM/KMS,就直连;没有则自己实现
flush_cb 一个函数。
- 搭界面:用 LVGL Pro Editor 或 Online Viewer 拖界面,导出 C 或 XML。
- 集成业务:把 UI 事件接到你的状态机、通信协议、数据采集逻辑上。

这一步最关键的是第 3 步的 flush_cb:它是 LVGL 与你的硬件之间的唯一接口。它的职责只有一件事——把 LVGL 画好的一块缓冲,推到屏幕指定区域。其他一切,包括坐标转换、颜色深度、翻转,都在这个回调里完成。
第 4 步别急着上真机:先在 PC 上用 SDL 模拟器把界面逻辑跑通,界面没问题了再移植到真机。这样你能把「UI 逻辑问题」和「硬件驱动问题」完全分开排查。
版本史:从 v9.2.1 的教训到 v9.6.0
版本信息来自官方 GitHub Releases:
| 版本 |
发布日期 |
备注 |
| v9.6.0 |
2026-09-16 |
最新稳定版,V9 最后一个稳定版 |
| v9.5.0 |
2026-02-18 |
|
| v9.4.0 |
2025-10-16 |
|
| v9.3.0 |
2025-06-03 |
|
| v9.2.2 |
2024-10-30 |
修复 v9.2.1 Kconfig 问题 |
| v9.2.1 |
2024-10-24 |
官方公告「Kconfig 配置损坏」 |
| v9.1.0 |
2024-03-20 |
|
| v8.4.0 |
2024-03-19 |
v8 最后稳定版 |

v9.2.1 是个活教材:官方在 release 页面直接标注「Kconfig settings are broken,请用 v9.2.2」。一个 UI 库的坑不在界面,而在构建配置——这提醒所有人,嵌入式项目升级前一定要看 release note,别被 minor 版本号麻痹。
版本策略也值得说:官方采用 语义化版本,major 代表不兼容 API 变更、minor 代表向后兼容的新功能、patch 代表 bug 修复。v8 起每个 minor 版本支持 1 年,这给了企业用户一个可预期的时间表。
v9.6.0 的亮点,据官方 CHANGELOG 并经媒体转述:软件渲染器的混合与变换路径从「逐像素处理」改为 逐字处理,无需 GPU 或 SIMD 即可生效;官方称在 Renesas RA8D2 上平均渲染时间降低 25%、NXP i.MX RT700 降低约 2x。
需要说明的是:这个百分比是官方宣称值,不是我们实测。真实收益取决于你的硬件与场景,建议在自己板子上跑一遍再下结论。
关于 V10:官方已宣布 V9.6.0 是 V9 系列的最后一个稳定版,V10 会移除部分旧功能。这意味着如果你正在新项目选型,直接上 V9.6.0 是当前最稳的选择;如果已经用 V8,需要考虑升级路径,而不是一直钉在旧版本上。
常见问题:7 个官方口径
官方文档列出的常见问题与对策,直接照抄即可:
- 崩溃或什么都不显示:加大
LV_MEM_SIZE、启用日志与断言、加大 RTOS 任务栈。
- 显示驱动没被调用:调用
lv_tick_inc(x) 和 lv_timer_handler()。
- 显示只刷新一次:在 flush 回调末尾调用
lv_display_flush_ready(drv)。
- 屏幕花屏或乱码:先断开 LVGL 单独测试显示驱动,问题多半在驱动。
- 颜色不对:检查
LV_COLOR_DEPTH 是否与屏幕一致。
- RTOS 下崩溃:LVGL 函数不要并发调用,注意线程模型。
- 界面卡顿:见下一节的提速清单。

记住这条:出问题先看 LV_MEM_SIZE 和驱动,别急着怀疑库本身。
第一条值得展开:LVGL 使用自己的内存池 LV_MEM_SIZE,默认堆不够大就会崩溃。这在移植时是最常见的坑——你以为代码没问题,其实是 lv_conf.h 里 LV_MEM_SIZE 给太小。
第二条是另一个高频坑:lv_display_flush_ready(drv) 必须在 flush 回调的 末尾 调用,告诉 LVGL「这一块缓冲已经推给屏了,可以继续渲染下一块」。漏调用,界面就只刷新一次然后死掉。
性能优化:提速与省资源
提速 5 招:
- 开编译器优化与缓存。
- 加大显示缓冲。
- 双缓冲 + DMA 后台刷新。
- 提升 SPI/并口时钟。
- 缓冲放内部 RAM,尽量用并口替代 SPI。
省资源 5 招:
lv_conf.h 里禁用不用的功能与 widget。
- GCC/CLANG 加
-fdata-sections -ffunction-sections --gc-sections。
- 加
-flto,GCC;或 -Oz,CLANG。
- 降低显示缓冲与
LV_MEM_SIZE。
- 按需创建/销毁 widget,不要全屏常驻。

平衡点在哪:提速和省资源本质是同一个旋钮——缓冲大小。缓冲越大越流畅,RAM 越紧张;1/10 屏幕是官方的默认甜点,但你可以根据自己的 RAM 余量上下调。
双缓冲 + DMA 是个分水岭:单缓冲时,CPU 必须等 flush 完成后才能画下一帧,动画会有停顿。双缓冲下,一块在 DMA 推给屏幕,另一块 CPU 继续画,流水线并行,帧率直接翻倍。
-flto,即 Link Time Optimization 值得单独推荐:它能跨编译单元做优化,把没用到的 widget 和样式代码 在链接阶段自动裁掉,Flash 占用能省下 20–40%。代价是编译时间变长,但 CI 里跑一次也就多等一两分钟。
谁在用:生态就是最好的背书
采用不是我们说的,是厂商自己做的:
- NXP 的 MCUXpresso、Renesas 的 FSP 里都有 LVGL 集成。
- Espressif 的 ESP32 生态里 LVGL 是默认 UI 选项之一。
- Zephyr、NuttX、RT-Thread 三个主流 RTOS 都有官方 LVGL 集成。
- Riverdi、Seeed Studio 等开发板厂商直接在板级包里带 LVGL。

我的判断,个人观点,非官方结论:在嵌入式开源 GUI 这个赛道,LVGL 已经是 选择面最广的那个——不是因为它功能最全,而是因为它把「库、驱动、工具链、板级支持」四条腿都做齐了。
再给一个量化视角:一个项目如果同时满足「芯片厂商官方集成 + 你的 RTOS 有移植包 + 你用的板子有示例代码」这三条,那 学习成本几乎为零。LVGL 对大多数主流组合都能覆盖到,而其他开源 GUI 库往往只能满足其中一两条。
选型对比:LVGL vs 其他方案
这里给一个 非穷尽 的对比表,只覆盖主流开源嵌入式 GUI 方案。数据均来自各项目 README,不是实测,仅作定位参考:
| 维度 |
LVGL |
Qt for MCUs |
TouchGFX |
emWin |
| 许可 |
MIT |
商业/GPL 双轨 |
商业免费,STM32 |
商业授权 |
| 适用主控 |
16/32/64 位 MCU+MPU |
MCU+MPU,偏高端 |
仅 STM32 |
广泛 MCU |
| 典型 RAM |
100kB |
数百 kB 起 |
视配置 |
视配置 |
| 内置 widget |
30+ |
多 |
多 |
多 |
| 布局引擎 |
Flexbox/Grid |
QML |
Designer |
无 |
| GPU 支持 |
多厂商 |
是 |
ST 系 |
部分 |
| 社区/生态 |
24.9k star |
中 |
中 |
低 |
| 上手成本 |
低 |
中 |
低 |
中 |

结论,个人观点:如果你的项目需要 跨 MCU 平台、想用现成驱动、希望开源可控,LVGL 是目前最均衡的选择。如果你 只做 STM32 且预算充足,TouchGFX 的 Designer 体验也很舒服;如果项目 必须走 Qt 生态,Qt for MCUs 是唯一答案。
但请记住:任何对比表都只是「定位参考」,不是「选购答案」。最好的方式是在你的硬件上跑通一个 demo,用真实帧率、真实 RAM 占用说话。
最后给你一个可复用的评估模板:拿到一个新 GUI 库,先问自己五个问题——
- 它支持我的 MCU 吗?官方驱动还是自己写?
- 我的 RAM 余量够跑它一个典型界面吗?
- 我的 UI 需求,例如图表、仪表、多语言,它有现成组件吗?
- 它有没有 PC 模拟器,能让我先不碰硬件就把界面做出来?
- 它的许可允许我商用吗?商业工具链是否收费?
这五个问题全部回答完,你基本就知道该不该用 LVGL 了。剩下的都是执行问题。
适用场景与边界
写到这里,也该把话说清楚——LVGL 不是万能的。它在下面这些场景非常合适:
- 小屏设备:智能手表、温控器、门锁面板、家电面板,屏幕小于 5 英寸。
- 工业 HMI:示波器、频谱仪、数控机床面板、医疗仪器显示屏。
- 仪表盘/数据可视化:充电桩、电表、车载中控、无人机地面站。
- 开源项目/教学:ESP32 学习套件、MicroPython 爱好者、毕业设计。
但有些场景 不一定最适合 LVGL:
- 极高帧率 3D:LVGL 的 3D 是「UI 层里嵌 3D 内容」,不是游戏引擎。真要做 3D 游戏,选 Vulkan/OpenGL ES 专用方案。
- 超大型信息密度界面:几十列数据、复杂图表、实时流式渲染,可能需要专业图表库。
- 已有 Qt/嵌入式 Linux 全套栈的项目:如果你已经跑着 Qt/GTK,没必要为了一个页面引 LVGL。

一句话:LVGL 是「嵌入式 UI 的通用底座」,不是「嵌入式 UI 的万能答案」。用它做仪表盘、控制面板、信息展示界面,几乎都是正解;做需要极高性能图形渲染的场景,它只是辅助。
结语
嵌入式 UI 的困局,本质不是「没有库」,而是「没有一套能跑通全链路、还不吃资源、还有厂商背书的库」。

LVGL 用 24.9k star、MIT 许可、100kB RAM 起步 三件事回答了它:开源、够轻、够通用。
但也要说清楚它的边界:它解决的是「怎么画」,不是「画什么」。产品逻辑、交互设计、信息层级,还得你来。
如果你也在纠结嵌入式 UI 怎么选,建议走一遍这条最短路径:Online Viewer 拖界面 → 拷贝 C 代码 → 接上你的驱动 → 上板验证。跑通一次,比看十篇对比文章都管用。
相关链接