X-TRACK 实战:基于 LVGL 8.3 的嵌入式图形界面开发与 PC 模拟器移植指南

原创2026-10-03 22:07:08937 阅读
文章标签:智能硬件嵌入式硬件开发

X-TRACK 实战:基于 LVGL 8.3 的嵌入式图形界面开发与 PC 模拟器移植指南

导读

本指南以 LVGL(Light and Versatile Graphics Library)官方中文文档(Software/X-Track/Simulator/LVGL.Simulator/lvgl/README_zh.md)为骨架,结合开源项目 X-TRACK 的源码实际使用情况,系统讲解这个嵌入式图形库的核心特性、硬件要求、入门路线与典型组件用法。读完本文,你将理解 LVGL 为何能支撑 X-TRACK 这类 240×240 小屏 GPS 码表的全部界面(表盘、实时地图、系统信息、状态栏等),掌握组件创建、事件回调、布局系统的实战写法,并弄清它是如何在 Windows 模拟器与 AT32 单片机真机两端跑通同一套 UI 代码的。

LVGL 概况:为什么嵌入式设备选择它

LVGL 是一个高度可裁剪、低资源占用、界面美观且易用的嵌入式系统图形库,官方定位为 "Light and Versatile"(轻量级通用型)。在 X-TRACK 仓库中,LVGL 源码以完整子库形式内嵌于模拟器工程(Software/X-Track/Simulator/LVGL.Simulator/lvgl/),同时被真机固件直接引用(Software/X-Track/USER/main.cpp 中 #include "lvgl/lvgl.h"),是项目 UI 层唯一依赖的图形引擎。

从版本宏定义可以确认本仓库携带的版本:在 Software/X-Track/Simulator/LVGL.Simulator/lvgl/lvgl.h 中明确写着 LVGL_VERSION_MAJOR 8、LVGL_VERSION_MINOR 3、LVGL_VERSION_PATCH 0,即 LVGL 8.3.0(dev 版)。下文所有 API 均基于该版本。

核心特性一览

官方中文文档列出以下关键能力,这些特性在 X-TRACK 中均有对应实践:

  • 丰富且强大的模块化图形组件:按钮(buttons)、图表(charts)、列表(lists)、滑动条(sliders)、图片(images)等。X-TRACK 的 LiveMap 页面就使用了 lv_slider 做地图缩放、lv_obj 做地图容器(见 LiveMap.cpp)。
  • 高级图形引擎:动画、抗锯齿、透明度、平滑滚动、图层混合。X-TRACK 的状态栏图标、页面切换动画均依赖于此。
  • 多输入设备支持:触摸屏、键盘、编码器、按键。X-TRACK 真机使用旋转编码器 + 按键组合交互,模拟器则由 lv_win32_add_all_input_devices_to_group 挂接鼠标键盘(见 LVGL.Simulator.cpp)。
  • 多显示设备支持:一套代码可驱动多个屏幕。
  • 平台无关:不依赖特定硬件平台,可在任何满足要求的显示屏上运行。
  • 配置可裁剪:官方给出的最低资源占用为 64 kB Flash、16 kB RAM。
  • UTF-8 多语种支持:中文、日文、韩文、阿拉伯文等。
  • 类 CSS 布局:支持 Flexbox 与 Grid 布局,可通过样式系统设计界面。
  • OS / 外置内存 / 硬件加速:内建支持 STM32 DMA2D、SWM341 DMA2D、NXP PXP 与 VGLite。
  • 单缓冲区也可流畅渲染:即便只有一个 frame buffer 也能保证渲染平滑,这对小内存 MCU 至关重要。
  • 纯 C 编写,支持 C++ 调用:X-TRACK 的页面代码(.cpp)即直接调用 LVGL C API。
  • 支持 MicroPython 编程。
  • 支持 PC 模拟器仿真:可无硬件依托进行开发,X-TRACK 正是通过 LVGL.Simulator 工程在 Windows 上完整复现整机 UI。
  • 丰富例程与详尽文档:仓库内自带 examples/、demos/ 目录可直接参考。

硬件要求

官方中文文档给出的参考硬件门槛如下(注意:实际资源占用与硬件平台、编译器相关,表中为参考值):

要求 最低要求 建议要求
架构 16/32/64 位 MCU 或 MPU 同左
时钟 > 16 MHz > 48 MHz
Flash/ROM > 64 kB > 180 kB
Static RAM > 16 kB > 48 kB
Draw buffer > 1 × 水平分辨率像素 > 1/10 屏幕大小
编译器 C99 或更新 同左

从仓库实际配置看,X-TRACK 的模拟器工程把颜色深度配置为 16 位(LV_COLOR_DEPTH 16),并把 LVGL 内存池设为 72 kB(LV_MEM_SIZE (72U * 1024U)),见 lv_conf.h。这组配置正是文档中"建议要求"档的工程化落地,也说明 16 位色深 + 几十 KB 内存池即可支撑完整的多页面应用。

已支持平台与生态

LVGL 本身不依赖特定硬件平台,任何满足硬件要求的 MCU 均可运行。文档列举了部分已验证平台:NXP(Kinetis、LPC、iMX、iMX RT)、STM32 全系(F1/F3/F4/F7/L4/L5/H7)、Microchip(dsPIC33、PIC24、PIC32MX、PIC32MZ)、Linux frame buffer(/dev/fb)、Raspberry Pi、ESP32、Infineon Aurix、Nordic NRF52、移远(Quectel)模组、SYNWIT SWM341 等;同时支持 Arduino library、PlatformIO package、Zephyr、ESP32 component、NXP MCUXpresso、NuttX、RT-Thread RTOS 等集成方式。X-TRACK 真机运行于雅特力 AT32 系列(仓库内同时提供 MDK-ARM_F403A 与 MDK-ARM_F435 两个工程),再次印证"平台无关"的实际效果——同一套 LVGL 代码从 AT32 单片机上无缝移植到了 Windows 桌面模拟器。

如何入门:官方推荐的 10 步学习路线

官方中文文档给出了一条循序渐进的学习路径,结合 X-TRACK 仓库可以这样落地:

  1. 3 分钟:用网页在线例程体验 LVGL 的视觉效果。
  2. 5 分钟:阅读文档"简介"章节初步了解设计思想。
  3. 15 分钟:阅读"快速概览"章节掌握基本概念(对象、样式、事件、布局)。
  4. 10 分钟:学习使用 PC 模拟器仿真。X-TRACK 的 Simulator/LVGL.Simulator 工程就是现成范例——无需硬件即可运行完整整机 UI。
  5. 动手实践:仓库内 lvgl/examples/ 目录提供了大量可直接编译的例程。
  6. 移植实践:参考移植指南把 LVGL 移植到开发板,X-TRACK 的 lv_port 目录(lv_port_disp.cpp、lv_port_indev.cpp、lv_port_fs_sdfat.cpp)正是显示、输入、文件系统三个移植层的完整参考实现。
  7. 2~3 小时:通读"总览"章节深入理解渲染与对象系统。
  8. 浏览组件章节:了解各 Widget 的 API 与使用方式。
  9. 遇到问题:到 LVGL 论坛提问。
  10. 贡献社区:按 CONTRIBUTING 指引参与开发。

组件与事件:官方例程的 C 语言实战

官方中文文档给出了最经典的按钮 + 标签示例(C 语言),这也是理解 LVGL 对象模型的起点:

lv_obj_t * btn = lv_btn_create(lv_scr_act());                   /*在当前屏幕创建一个按钮*/
lv_obj_set_pos(btn, 10, 10);                                    /*设置按钮位置*/
lv_obj_set_size(btn, 100, 50);                                  /*设置按钮尺寸*/
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL); /*为按钮注册点击回调*/

lv_obj_t * label = lv_label_create(btn);                        /*在按钮上创建一个标签*/
lv_label_set_text(label, "Button");                             /*设置标签文本*/
lv_obj_center(label);                                           /*将标签居中对齐*/
...
void btn_event_cb(lv_event_t * e)
{
  printf("Clicked\n");
}

这段代码揭示了 LVGL 对象模型的四个核心机制:

  • 一切皆对象(lv_obj_t *):按钮、标签、容器都是对象,lv_btn_create / lv_label_create 的返回值可被统一用 lv_obj_* 系列函数操作(位置、尺寸、样式、标志位)。
  • 父子树结构:lv_label_create(btn) 把标签挂到按钮之下,标签坐标相对按钮,lv_obj_center(label) 使其在父对象内居中。
  • 事件回调:lv_obj_add_event_cb(btn, cb, LV_EVENT_CLICKED, NULL) 将事件码(如 LV_EVENT_CLICKED)绑定到回调函数,回调通过 lv_event_t * 参数携带事件上下文。
  • C/C++ 双栖:X-TRACK 的页面代码用 C++ 编写,同样直接调用这些 C API,例如 LiveMap 页面中的 lv_slider_set_range、lv_obj_add_flag(View.ui.map.cont, LV_OBJ_FLAG_HIDDEN)(见 LiveMap.cpp),并通过 lv_timer_create 创建周期刷新定时器驱动地图与坐标数据更新。

文档同时给出 MicroPython 等价写法,便于脚本化原型验证:

def btn_event_cb(e):
  print("Clicked")

# 创建按钮与标签
btn = lv.btn(lv.scr_act())
btn.set_pos(10, 10)
btn.set_size(100, 50)
btn.add_event_cb(btn_event_cb, lv.EVENT.CLICKED, None)

label = lv.label(btn)
label.set_text("Button")
label.center()

组件、布局与扩展库的源码级盘点

LVGL 8.3 通过 lvgl.h 一个头文件汇总所有模块,从源码结构看可分为四个层次:

  1. 基础层(src/misc、src/hal、src/core):内存、定时器、日志、数学工具,HAL 抽象(显示、输入、时钟、像素),以及对象/组/输入设备/刷新/主题等核心机制。
  2. 标准组件(src/widgets):lv_arc、lv_btn、lv_img、lv_label、lv_line、lv_table、lv_bar、lv_slider、lv_dropdown、lv_roller、lv_textarea、lv_canvas、lv_switch 等。
  3. 扩展组件(src/extra):lv_extra.h 统一聚合了扩展布局、扩展库、扩展组件与主题四类内容:
    • 扩展布局(layouts/lv_layouts.h):Flexbox 与 Grid。X-TRACK 的模拟器工程在 lv_conf.h 中明确开启 LV_USE_FLEX 1 与 LV_USE_GRID 1,状态栏等页面的自动排布即依赖这两套类 CSS 布局。
    • 扩展库(libs/lv_libs.h):BMP/PNG/GIF/SJPG 图片解码、二维码(qrcode)、FreeType 字体、RLottie 动画、FFmpeg 等。X-TRACK 的启动动画与地图瓦片显示正是图像解码能力的实际应用场景。
    • 扩展组件(widgets/lv_widgets.h):lv_chart 图表、lv_meter 仪表、lv_menu 菜单、lv_msgbox 消息框、lv_tabview、lv_tileview、lv_spinbox、lv_spinner、lv_calendar、lv_keyboard、lv_colorwheel、lv_span 富文本等。X-TRACK 的"系统信息""菜单"页面大量使用这些高级组件。
    • 扩展主题(themes/lv_themes.h):lv_theme_default、lv_theme_mono、lv_theme_basic 等,其中 mono 单色主题特别适合低色深屏。

从实现看,lvgl.h 的 include 顺序也体现了模块化设计:先 misc 基础设施,再 HAL,再 core 对象系统,最后 widget 与 extra,开发者可以按需裁剪对应 .c 文件与 lv_conf.h 中的 LV_USE_* 开关实现最小化编译。

在 X-TRACK 中的两套运行形态:模拟器与真机

LVGL 官方文档强调"支持模拟器仿真、可无硬件依托进行开发",X-TRACK 是最典型的落地案例——同一套 App/Pages 代码在两端运行:

PC 模拟器(Windows)

模拟器主程序 LVGL.Simulator.cpp 展示了完整的 LVGL 接入流程:

  1. lv_init():初始化 LVGL 核心;
  2. lv_fs_if_init():初始化文件系统抽象(SD 卡/地图资源);
  3. lv_win32_init(..., 240, 240, ...):创建 240×240 的 Windows 窗口作为显示设备,与真机屏幕分辨率一致;
  4. lv_win32_add_all_input_devices_to_group(NULL):把鼠标键盘统一挂到输入设备组;
  5. HAL::HAL_Init():初始化项目自定义硬件抽象层;
  6. App_Init():创建全部页面;
  7. 主循环 while (!lv_win32_quit_signal) { lv_timer_handler(); HAL::HAL_Update(); Sleep(1); }:周期驱动 LVGL 定时器与虚拟外设更新。

工程文件为 LVGL.Simulator.sln(Visual Studio 解决方案),可直接编译运行;构建脚本 BuildAllTargets.cmd 提供一键构建能力。

AT32 真机固件

真机入口 Software/X-Track/USER/main.cpp 走的是 Arduino 风格的 setup()/loop():

static void setup()
{
    HAL::HAL_Init();
    lv_init();
    lv_port_init();      // 初始化显示、输入设备、文件系统移植层
    App_Init();
    HAL::Power_SetEventCallback(App_Uninit);
    HAL::Memory_DumpInfo();
}

static void loop()
{
    HAL::HAL_Update();
    lv_task_handler();   // 对应模拟器里的 lv_timer_handler()
    __wfi();             // 进入低功耗等待中断
}

两端的差异只在"显示/输入/文件系统"的移植层(lv_port 与 lv_drivers),而 App_Init() 创建的页面逻辑、组件代码、样式与动画完全复用。这正体现了文档所述"不依赖特定硬件平台"的价值:先模拟器调试 UI,再真机验证硬件,开发效率显著提升。

另外,真机工程还提供了 LV_USE_DEMO_BENCHMARK 宏开关(main.cpp),开启后可加载官方 benchmark 压测 demo 来评估目标 MCU 上 LVGL 的渲染性能,对应仓库中的 benchmark.inc。

服务与社区

官方中文文档说明,LVGL 责任有限公司面向使用者提供图形设计、UI 设计与技术咨询/技术支持等服务;同时 LVGL 是开源项目,欢迎通过介绍作品、编写例程、完善文档、修复 bug 等方式参与社区贡献(详见仓库内 lvgl/README_zh.md 的"服务"与"如何向社区贡献"章节)。X-TRACK 本身即是一个"基于 LVGL 设计的作品"的完整范例,其 UI 与源码是学习 LVGL 嵌入式开发的绝佳教材。

登录后查看全文
X-TRACK