1. LVGL与显示驱动概述

各位同学好,我是你们这门课的老朋友。今天咱们聊聊LVGL和显示驱动那些事儿。

先说说我自己的经历。几年前我接手一个智能家居项目,MCU端跑着LVGL,一切顺利。后来客户要求移植到Linux平台,我心想「不就是换个编译链嘛」——结果被显示驱动折腾了整整两周。从那以后我就明白:显示驱动不是简单的「画点」函数,它是整个GUI系统的命脉。

1.1 LVGL是什么

LVGL(Light and Versatile Graphics Library),说白了就是一个开源的嵌入式图形库。它帮你把按钮、滑块、图表这些UI元素画到屏幕上,你只需要调用API就行。

我个人习惯把它比作「乐高积木」:

  • 基础积木:按钮、标签、进度条等基础控件
  • 高级积木:图表、键盘、动画系统
  • 胶水:显示驱动和输入驱动,把积木粘到硬件上

LVGL的核心优势在于:

特性 说明
轻量级 最小配置仅需16KB RAM + 64KB Flash
跨平台 MCU、Linux、RTOS都能跑
硬件加速 支持DMA2D、GPU等硬件加速
丰富控件 30+内置控件,支持自定义

核心认知:LVGL不直接操作硬件,它通过显示驱动这个「翻译官」来和屏幕对话。驱动写得好,LVGL就跑得顺;驱动写得烂,再好的UI设计也是白搭。

1.2 显示驱动的作用

显示驱动到底在干什么?我画个图你就明白了。

LVGL显示驱动架构 LVGL应用层 按钮、标签、动画 LVGL核心层 对象管理、事件分发 显示驱动接口 flush_cb、rounder_cb 硬件抽象层 SPI/I2C/FrameBuffer 硬件层 LCD屏幕、GPU 显示驱动的核心职责: 1. 接收LVGL的绘制命令(flush_cb) 2. 将像素数据写入显存或发送到屏幕 3. 处理屏幕旋转、颜色格式转换等适配

显示驱动就是LVGL和硬件之间的桥梁。它要做三件事:

  1. 接收绘制命令:LVGL告诉你「在坐标(10,20)画一个红色像素」
  2. 数据搬运:把像素数据通过SPI/I2C/并行总线送到屏幕
  3. 适配硬件特性:处理屏幕旋转、颜色深度、双缓冲等

我的经验:很多新手把显示驱动想得太复杂。其实LVGL的显示驱动接口就两个核心回调:flush_cb(刷新缓冲区)和rounder_cb(坐标对齐)。你只要把这两个函数实现好,LVGL就能跑起来。

1.3 MCU与Linux的差异

这个问题我当年踩过坑。MCU和Linux下写显示驱动,完全是两码事。

对比维度 MCU环境 Linux环境
显存管理 手动分配,通常用全局数组 通过FrameBuffer或DRM/KMS管理
硬件接口 直接操作GPIO、SPI寄存器 通过设备文件(/dev/fb0)操作
多任务 裸机或RTOS,需自行处理同步 内核态/用户态隔离,有锁机制
调试手段 串口打印、逻辑分析仪 dmesg、strace、GDB
性能瓶颈 CPU频率低,需优化像素操作 系统调用开销,上下文切换

举个例子。在MCU上写驱动,你直接往某个内存地址写数据就行:

// MCU风格:直接操作显存
#define LCD_BASE_ADDR 0x60000000
void lcd_draw_pixel(int x, int y, uint16_t color) {
    *(volatile uint16_t *)(LCD_BASE_ADDR + (y * 320 + x) * 2) = color;
}

但在Linux下,你得先打开设备文件,再通过ioctl或mmap操作:

// Linux风格:通过FrameBuffer
int fb_fd = open("/dev/fb0", O_RDWR);
struct fb_var_screeninfo vinfo;
ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);
uint16_t *fbp = mmap(NULL, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
fbp[y * vinfo.xres + x] = color;

避坑指南:我曾经在Linux上直接用了MCU那套「死等」的延时逻辑,结果整个系统卡死。Linux下驱动必须考虑进程调度,不能用delay_ms(10)这种阻塞方式,要用usleep或定时器。

1.4 课程目标与前置知识

这门课的目标很明确:让你在MCU和Linux两个平台上,都能写出稳定高效的LVGL显示驱动。

具体来说,学完这门课你能做到:

  • 理解LVGL显示驱动的完整工作流程
  • 在STM32等MCU上从零搭建显示驱动
  • 在Linux上使用FrameBuffer和DRM/KMS驱动
  • 优化显示性能,解决撕裂、闪烁等问题
  • 适配不同屏幕(RGB、SPI、MIPI DSI)

前置知识方面,我建议你具备:

  1. C语言基础:指针、结构体、回调函数要熟练
  2. 嵌入式基础:了解GPIO、SPI、I2C等外设
  3. Linux基础:会基本的文件操作、编译、调试
  4. LVGL基础:知道怎么创建控件、处理事件

我的建议:如果你对LVGL还不太熟,可以先花一天时间跑个官方demo。不用深入,知道它长什么样就行。驱动部分我会从最基础的讲起,手把手带你写代码。

嗯,第一章就到这里。记住一句话:显示驱动是GUI的根基,根基不稳,楼盖得再高也得塌。后面咱们就一步步把这个根基打牢。