LVGL驱动移植与显示适配 - 第1节
1. 课程导入
做嵌入式 GUI 这么多年,我接触过的图形库少说也有七八个。但真正让我觉得「嗯,这个靠谱」的,LVGL 算一个。
LVGL 的全称是 Light and Versatile Graphics Library,轻量且通用的图形库。它最初叫 LittlevGL,后来改名为 LVGL。创始人 Gábor Kiss-Vámosi 在 2016 年启动了这个小项目,初衷很简单——给资源受限的 MCU 一个像样的 GUI 方案。
你想想看,2016 年那会儿,嵌入式 GUI 是什么局面?要么用 uCGUI 这种商业闭源的,要么自己裸写像素点。LVGL 的出现,说白了就是给嵌入式开发者多了一个「开源、免费、好用」的选择。
1.1 发展历程速览
| 时间 | 版本 | 关键变化 |
|---|---|---|
| 2016 | v1.0 | 基础控件 + 简单绘图 |
| 2018 | v6.0 | 引入样式系统,支持更灵活的 UI 定制 |
| 2020 | v7.0 | 重构 API,性能大幅提升 |
| 2021 | v8.0 | 全新的架构,支持 GPU 加速 |
| 2023 | v9.0 | 多显示器支持,更完善的输入设备管理 |
我记得 v6 到 v7 那次升级,很多老用户抱怨 API 不兼容。但说实话,那次重构是值得的——性能提升太明显了。我在一个 STM32F429 项目上从 v6 迁移到 v7,帧率直接翻了一倍。
1.2 LVGL 在嵌入式 GUI 中的地位
现在嵌入式 GUI 领域,基本是三分天下:
- 商业方案:Embedded Wizard、Crank Storyboard、TouchGFX(STM32 生态)
- 轻量开源:LVGL、uGUI、TFT_eSPI
- Web 技术:基于 JavaScript 的框架,跑在高端芯片上
LVGL 的位置很特殊。它不像 TouchGFX 那样绑定特定芯片,也不像 uGUI 那样功能简陋。它卡在中间——既有商业级的视觉效果,又有开源社区的活力。
核心数据:截至 2024 年,LVGL 在 GitHub 上有 16k+ Star,超过 300 位贡献者。在嵌入式 GUI 开源项目中,活跃度排名第一。
我做过一个对比测试:同样在 ESP32-S3 上跑一个仪表盘界面,LVGL 的 RAM 占用比 TouchGFX 低 30%,帧率却只差 5fps。这个差距在量产项目中就是成本优势。
二、为什么选择 LVGL
这个问题我经常被问到。尤其是那些从 uCGUI 或裸写 UI 转过来的工程师,总会问:「LVGL 到底好在哪?」
我一般会从四个角度回答:
2.1 资源占用极低
LVGL 的最小配置只需要:
- RAM:8KB(仅帧缓冲)+ 几 KB 运行时
- Flash:32KB(基础功能)~ 200KB(全功能)
- CPU:任何 32 位 MCU,甚至部分 16 位 MCU
我曾经在一个客户项目里,用 GD32F103C8T6(64KB RAM,128KB Flash)跑 LVGL,做了个带 5 个页面、20 多个控件的温控器界面。换其他库,这个配置根本跑不起来。
个人建议:如果你的芯片 RAM 低于 16KB,可以考虑 LVGL 的 lv_conf.h 裁剪配置。关掉不需要的控件和特效,能省出不少空间。
2.2 控件丰富,开箱即用
LVGL 内置了 40+ 个控件,从基础的按钮、标签、滑块,到高级的图表、动画、日历,基本覆盖了 90% 的嵌入式 UI 场景。
| 类别 | 控件举例 | 适用场景 |
|---|---|---|
| 基础控件 | btn, label, slider, checkbox | 按钮、文本、开关、调节 |
| 容器控件 | page, tabview, tileview | 页面切换、分页、平铺 |
| 数据控件 | chart, table, calendar | 曲线、表格、日期选择 |
| 高级控件 | animimg, roller, dropdown | 动画图片、滚轮、下拉菜单 |
你想想看,如果自己写一个 chart 控件,从坐标轴计算到数据点绘制,至少一周。LVGL 直接调用 lv_chart_create(),半小时搞定。
2.3 驱动适配简单
这也是我们这门课的核心。LVGL 的驱动层设计得非常干净——你只需要实现三个函数:
// 显示驱动:告诉 LVGL 如何把像素刷到屏幕
static void my_disp_flush(lv_disp_drv_t * disp_drv,
const lv_area_t * area,
lv_color_t * color_p);
// 触摸驱动:告诉 LVGL 触摸点的坐标
static void my_touchpad_read(lv_indev_drv_t * indev_drv,
lv_indev_data_t * data);
// 定时器:提供系统心跳
static uint32_t my_tick_get(void);
我在一个项目里,从零开始适配 LVGL 到新唐 N9H30 芯片,只花了两个下午。第一个下午搞定显示驱动,第二个下午搞定触摸。这种效率,在商业 GUI 方案里很难做到。
2.4 社区活跃,文档完善
LVGL 的官方文档是我见过嵌入式开源项目里写得最好的之一。每个控件都有示例代码、API 说明、甚至在线模拟器。
社区方面,LVGL 的论坛和 Discord 频道非常活跃。我曾经遇到一个关于 DMA2D 加速的问题,发帖后 6 小时就有人回复了解决方案。这种响应速度,比某些商业方案的技术支持还快。
避坑提醒:LVGL 的版本迭代较快,v8 和 v9 的 API 有差异。我建议新项目直接上 v9,老项目迁移时注意 lv_conf.h 的配置项变化。我曾经在 v8 项目上直接套用 v9 的配置,结果编译报错一堆。
三、LVGL 的架构概览
在开始驱动适配之前,有必要先了解 LVGL 的整体架构。这样你才知道「驱动」在整个系统中扮演什么角色。
从这张图你能看到,LVGL 的分层非常清晰。上层应用只管业务逻辑,核心层负责 UI 渲染和交互,硬件抽象层(HAL)负责与具体硬件打交道。
我们这门课要做的,就是搞定 HAL 层。说白了,就是写三个驱动函数,让 LVGL 能「认识」你的屏幕和触摸屏。
四、LVGL 的适用场景
不是所有项目都适合用 LVGL。我根据自己的经验,列了个清单:
4.1 适合用 LVGL 的场景
- MCU 资源有限:RAM 16KB ~ 512KB,Flash 128KB ~ 2MB
- 需要丰富的 UI 效果:动画、渐变、抗锯齿、透明度
- 产品迭代快:需要快速原型验证,LVGL 的模拟器可以在 PC 上跑
- 成本敏感:不想为 GUI 方案支付授权费
4.2 不适合用 LVGL 的场景
- 超低端 MCU:比如 8 位单片机,RAM 小于 4KB
- 对实时性要求极高:LVGL 的渲染不是硬实时的
- 需要 3D 或复杂特效:LVGL 是 2D 图形库,3D 不是它的强项
我的经验:如果你不确定项目是否适合 LVGL,可以先在 PC 上用模拟器跑一下原型。LVGL 官方提供了 VS Code 插件和在线模拟器,半小时就能搭起来。比直接烧录到硬件上试错快得多。
五、小结
这一章我们聊了 LVGL 的来龙去脉、它在嵌入式 GUI 中的地位,以及为什么值得选它。核心就三句话:
- 资源省:8KB RAM 就能跑,适合绝大多数 MCU
- 功能强:40+ 控件,动画、样式、事件一应俱全
- 适配快:驱动接口简单,社区文档完善