2. LVGL基础架构

说实话,很多初学者一上来就对着开发板烧录调试,效率其实不高。我个人的习惯是——先在PC上把逻辑跑通,再移植到板子上。这样迭代快,调试也方便。

这一章,我们就来搭建一套基于 VS Code + SDL 模拟器 的开发环境。你不需要任何硬件,就能在电脑上看到 LVGL 的界面跑起来。

2.1 为什么选择 VS Code + SDL?

市面上能跑 LVGL 的方案不少,比如用 Qt、用 Eclipse,或者直接用 Keil 加个模拟器插件。但我为什么推荐 VS Code + SDL?

  • VS Code 轻量:启动快,插件生态好,写代码、调试、Git 都在一个窗口里搞定。
  • SDL 跨平台:SDL(Simple DirectMedia Layer)是一个底层多媒体库,Windows、Linux、macOS 都能跑。LVGL 官方就提供了 SDL 的移植示例。
  • 调试方便:PC 上你可以用 printf、断点、内存查看,甚至用 VS Code 的图形化调试器。这在嵌入式板子上可没那么容易。

一句话总结:这套环境让你把 80% 的界面开发工作放在 PC 上完成,最后只花 20% 的时间做硬件适配。

2.2 整体架构:代码是怎么跑起来的?

在动手之前,我们先看一眼整体流程。这样你心里有个谱,知道每一步在干什么。

LVGL PC 模拟器运行架构 你的 LVGL 应用代码 (UI 逻辑、控件、事件) LVGL 核心库 (lvgl 源码) SDL 显示/输入驱动 (lv_drivers) SDL 窗口 (模拟屏幕) 操作系统 (Windows/Linux/macOS) 说明 你的应用代码调用 LVGL API → LVGL 内部渲染 → 通过 SDL 驱动把像素画到窗口上。 鼠标/键盘事件也通过 SDL 捕获,再传给 LVGL 的输入组。

说白了,你的代码和 LVGL 库编译成一个可执行文件,SDL 负责开一个窗口来模拟屏幕。鼠标点击、键盘输入都会被 SDL 捕获,然后转发给 LVGL 的事件系统。

2.3 具体步骤:从零开始搭建

好,我们开始动手。我假设你已经装好了 VS Code 和 Git。如果没有,先去官网下载安装,几分钟的事。

2.3.1 安装 CMake 和编译器

LVGL 官方推荐用 CMake 来管理构建。你需要一个 C 编译器:

  • Windows:安装 MinGW-w64 或者直接用 Visual Studio Build Tools。
  • Linux:sudo apt install build-essential cmake 搞定。
  • macOS:安装 Xcode Command Line Tools,然后 brew install cmake。

我的建议:Windows 用户直接用 MSYS2 装 MinGW-w64,省心。我之前用 VS 的编译器踩过坑,SDL 的链接参数折腾了半天。

2.3.2 克隆 LVGL 官方模拟器项目

LVGL 官方在 GitHub 上提供了一个现成的模拟器仓库 lv_port_pc_eclipse。虽然名字带 Eclipse,但它也支持 VS Code + CMake。

git clone https://github.com/lvgl/lv_port_pc_eclipse.git
cd lv_port_pc_eclipse

这个仓库里已经包含了 LVGL 核心库(lvgl 子模块)和 SDL 驱动(lv_drivers 子模块)。你只需要拉一下子模块:

git submodule update --init --recursive

嗯,这一步容易忘。我刚开始就忘了拉子模块,编译报了一堆找不到头文件的错误。

2.3.3 用 VS Code 打开项目

在 VS Code 里打开 lv_port_pc_eclipse 文件夹。你会看到这样的目录结构:

lv_port_pc_eclipse/
├── lvgl/              # LVGL 核心库
├── lv_drivers/        # SDL 驱动
├── lv_examples/       # 官方示例
├── main.c             # 主入口
├── CMakeLists.txt     # 构建配置
└── README.md

VS Code 会提示你安装 CMake 插件和 C/C++ 插件。装就对了。

2.3.4 配置 CMake 并编译

在 VS Code 里按 Ctrl+Shift+P,输入 CMake: Configure,选择编译器(比如 MinGW 或 GCC)。然后按 F7 编译。

如果一切顺利,你会在终端看到编译成功的消息。生成的可执行文件在 build/bin 目录下。

注意:Windows 用户如果遇到 SDL.h 找不到的错误,说明系统没有安装 SDL2 开发库。去 libsdl.org 下载 SDL2-devel,把 include 和 lib 路径加到 CMakeLists.txt 里。

2.3.5 运行模拟器

在终端里执行:

./build/bin/main

你会看到一个窗口弹出来,里面显示 LVGL 的默认演示界面。鼠标可以点击按钮,键盘可以输入文本。

我第一次看到这个窗口的时候,说实话挺激动的。一个嵌入式 GUI 库,在 PC 上跑得这么流畅。

2.4 常见问题与避坑指南

搭建环境的过程中,你可能会遇到一些问题。我把常见的列出来:

问题 原因 解决方法
编译时报 lvgl.h 找不到 子模块未拉取 执行 git submodule update --init --recursive
链接时报 undefined reference to SDL_* SDL2 库未安装或路径不对 安装 SDL2 开发库,并在 CMakeLists.txt 中设置 find_package(SDL2 REQUIRED)
窗口黑屏,没有界面 LVGL 的 lv_init() 或 lv_disp_drv_register 未正确调用 检查 main.c 中的初始化顺序
鼠标点击无反应 输入设备驱动未注册 在 main.c 中调用 lv_indev_drv_register 注册鼠标驱动

我曾经遇到过一个问题:在 Windows 上用 MSYS2 编译,SDL 窗口死活不显示。折腾了半天,发现是 MSYS2 的 SDL2 包版本太旧。换成从 SDL 官网下载的最新版就好了。所以,优先用官网的 SDL2 开发包,别偷懒用包管理器。

2.5 验证环境:跑一个自己的界面

环境搭好了,我们来验证一下。在 main.c 里找到 lv_demo_widgets() 这行,把它注释掉,换成你自己的代码:

#include "lvgl.h"

void my_ui(void)
{
    lv_obj_t *btn = lv_btn_create(lv_scr_act());
    lv_obj_set_size(btn, 120, 50);
    lv_obj_center(btn);

    lv_obj_t *label = lv_label_create(btn);
    lv_label_set_text(label, "Hello LVGL");
    lv_obj_center(label);
}

int main(void)
{
    lv_init();

    // ... 初始化显示和输入驱动 ...

    my_ui();

    while(1) {
        lv_task_handler();
        SDL_Delay(5);
    }
}

重新编译运行,你会看到一个居中的按钮,上面写着 "Hello LVGL"。点击它,虽然现在还没绑定事件,但至少证明你的环境完全跑通了。

2.6 小结

这一章我们做了三件事:

  • 理解了 LVGL 在 PC 上模拟运行的架构
  • 从零搭建了 VS Code + SDL 的开发环境
  • 跑通了第一个 LVGL 界面

有了这套环境,后面的开发会非常顺畅。你可以随时修改代码,按 F7 编译,看效果。不用反复烧录,不用等开发板启动。说白了,这才是现代嵌入式开发的正确姿势。

一个小技巧:在 VS Code 里配置 tasks.json,把编译和运行绑定到一个快捷键上。我习惯用 Ctrl+Shift+B 一键编译运行,效率翻倍。