1. 课程导入

在嵌入式图形界面开发中,TouchGFX 与 LVGL 是两条极具代表性的技术路线。TouchGFX 由 ST 主推,深度绑定 STM32 生态,强调“设计工具 + 代码生成 + 硬件加速”的一体化体验;LVGL 则是开源、轻量、跨平台的通用 GUI 库,强调可移植性、组件丰富度和社区生态。很多项目在早期选择 TouchGFX 快速做出原型,但随着产品线扩展、芯片平台更换、成本控制或开源合规要求,团队需要把已有界面迁移到 LVGL。本课程要解决的,正是这类“从 TouchGFX 到 LVGL”的工程化迁移问题。

迁移不是简单的 API 替换,而是一次涉及架构、资源、事件模型、渲染机制和工程流程的系统性重构。理解两者的定位差异,是制定迁移策略的前提。

一、核心原理:定位差异决定迁移策略

TouchGFX 的核心是“框架 + 设计器 + 生成代码”。开发者通常在 TouchGFX Designer 中拖拽控件、配置交互,然后由工具生成 C++ 骨架代码,再在用户代码中补充业务逻辑。它天然适合 STM32 + LTDC + DMA2D 的硬件加速场景,渲染性能好,但代码与工具链耦合较深。

LVGL 的核心是“纯 C 库 + 可裁剪组件 + 事件驱动”。它不依赖特定芯片,通过显示驱动、输入驱动和 tick 接口完成移植。LVGL 的控件、样式、动画、布局系统都由库统一管理,开发者需要自己组织界面创建、事件回调和刷新逻辑。它更灵活,但也更依赖工程规范。

因此,迁移的本质可以概括为:从“工具生成式框架”转向“库驱动式框架”,从“Designer 配置”转向“代码化界面构建”,从“硬件加速强绑定”转向“可移植抽象层”。

TouchGFX → LVGL 迁移工程全景 定位差异 · 迁移目标 · 学习路径 · 最终交付物 TouchGFX 侧 典型特征 • Designer 可视化配置 • 生成 C++ 骨架代码 • 强绑定 STM32/LTDC/DMA2D • MVP 架构,Presenter/View 分离 • 资源由工具打包 迁移关注点 界面结构、交互逻辑、图片字体 定时器、动画、屏幕切换 业务代码与 UI 代码的边界 迁移工程层 核心任务 1. 资产盘点与分类 2. 界面结构映射 3. 事件与状态机重构 4. 显示/输入驱动适配 5. 资源转换与裁剪 关键原则 先分层,再替换;先跑通,再优化 UI 与业务解耦,接口稳定优先 用可验证的里程碑控制风险 LVGL 侧 典型特征 • 纯 C 库,跨平台可裁剪 • 代码化创建控件与样式 • 事件回调 + 定时器 + 动画 • 显示/输入/tick 三接口移植 • 资源可用转换工具生成 迁移落点 lv_obj / lv_label / lv_img / lv_btn lv_event_cb / lv_timer / lv_anim lv_disp_drv / lv_indev_drv 最终交付物:可编译运行的 LVGL 工程 + 界面还原报告 + 驱动适配层 + 资源转换脚本 + 迁移检查清单

二、方法流程:迁移工程的整体目标与推进路径

迁移工程的整体目标可以拆成四个层次:第一,功能等价,原有界面的显示、交互、跳转和状态变化在 LVGL 上可复现;第二,性能达标,刷新率、内存占用和响应延迟满足产品要求;第三,工程可维护,UI 代码与业务代码解耦,后续可继续迭代;第四,交付可验证,有明确的测试用例、检查清单和回滚方案。

推荐的学习与实施路径如下:

  1. 认知对齐:理解 TouchGFX 与 LVGL 的架构差异,明确哪些是“框架能力”,哪些是“业务逻辑”。
  2. 环境搭建:在目标板上跑通 LVGL 最小系统,包括显示驱动、输入驱动和 tick 源。
  3. 资产盘点:整理 TouchGFX 工程中的屏幕、控件、图片、字体、动画和交互事件。
  4. 界面映射:把 TouchGFX 的 Screen/View/Presenter 映射为 LVGL 的 screen、container、widget 和 event callback。
  5. 逻辑迁移:把业务逻辑从 Presenter 中剥离,改为通过接口层调用 LVGL UI 更新函数。
  6. 资源转换:将图片、字体、颜色和布局参数转换为 LVGL 可用的格式。
  7. 联调优化:处理刷新撕裂、内存碎片、事件冲突和性能瓶颈。
  8. 验收交付:输出迁移报告、测试记录和可维护的工程结构。

迁移的核心判断:如果 TouchGFX 工程中大量逻辑写在 View 的虚函数和 Designer 的交互配置里,迁移工作量会显著增加;如果业务逻辑已经集中在 Presenter 或独立服务层,迁移会顺利很多。因此,迁移前先做“逻辑边界审计”,比直接改代码更重要。

三、案例/场景:一个典型迁移项目的拆解

假设有一个基于 STM32F429 + TouchGFX 的工业 HMI 项目,包含开机画面、主菜单、参数设置、曲线显示和报警记录五个界面。迁移到 LVGL 后,目标平台改为 STM32H750 + 外部 SDRAM,显示分辨率 800×480。

迁移时,首先保留业务层:参数读写、报警判断、曲线数据采样都不变。然后重建 UI 层:用 lv_obj_create 创建屏幕容器,用 lv_label_create 显示文本,用 lv_img_create 显示图标,用 lv_event_cb 处理按钮点击。TouchGFX 中的 handleTickEvent 可以映射为 LVGL 的 lv_timer;TouchGFX 的 GotoScreen 可以映射为 lv_scr_load_anim 或自定义屏幕管理器。

/* LVGL 最小初始化顺序示例 */
lv_init();
lv_port_disp_init();   /* 注册显示驱动,设置 flush_cb */
lv_port_indev_init();  /* 注册触摸或按键输入 */
lv_tick_inc(1);        /* 在 SysTick 或定时器中调用 */

/* 创建一个按钮并绑定事件 */
lv_obj_t *btn = lv_btn_create(lv_scr_act());
lv_obj_set_pos(btn, 40, 60);
lv_obj_set_size(btn, 160, 56);
lv_obj_t *label = lv_label_create(btn);
lv_label_set_text(label, "开始");
lv_obj_center(label);
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);

这个案例说明:迁移不是把 TouchGFX 的每一行代码翻译成 LVGL,而是重新组织“界面构建、事件响应、数据更新”三件事。TouchGFX 的 Designer 配置在 LVGL 中会变成显式的 C 代码,因此代码量可能增加,但可控性和可移植性也更强。

四、误区与复盘:迁移中最容易踩的坑

  • 误区一:逐行翻译 API。TouchGFX 的控件模型和 LVGL 并不一一对应,强行翻译会导致代码臃肿且难以维护。
  • 误区二:忽略 tick 与刷新机制。LVGL 需要稳定的 tick 源和正确的 flush 回调,否则会出现界面卡顿、闪烁或不刷新。
  • 误区三:资源直接复用。TouchGFX 的图片格式、字体格式和颜色格式与 LVGL 不同,必须经过转换和裁剪。
  • 误区四:业务逻辑留在 UI 层。迁移后如果业务逻辑仍散落在界面回调中,后续换屏或换平台会再次付出高成本。
  • 误区五:没有验收标准。只凭“看起来差不多”判断迁移完成,容易遗漏边界状态、异常提示和性能指标。
维度 TouchGFX LVGL 迁移动作
界面构建 Designer 拖拽 + 生成代码 C 代码创建控件树 重建界面结构,封装创建函数
事件模型 View 虚函数 + 交互配置 事件回调 + 用户数据 统一事件入口,绑定业务接口
渲染加速 LTDC + DMA2D 强绑定 可配置 GPU/软件渲染 实现 flush_cb,按需启用加速
资源管理 工具打包为 C++ 数组 图片/字体转换后注册 批量转换,建立资源索引
定时与动画 handleTickEvent + Animator lv_timer + lv_anim 替换定时源,重写动画逻辑

学习建议:本课程后续章节会沿着“环境搭建 → 界面映射 → 事件迁移 → 资源转换 → 性能优化 → 工程交付”的主线推进。建议你在学习过程中同步维护一份迁移检查清单,每完成一个模块就打勾,避免遗漏。

重要提醒:迁移前务必对原 TouchGFX 工程做完整备份,并建立可回滚的版本分支。迁移过程中不要同时修改业务逻辑和 UI 框架,否则一旦出现问题,很难判断是迁移引入的还是业务改动引入的。

最终交付物不是“能跑起来的 demo”,而是一个结构清晰、可编译、可测试、可继续迭代的 LVGL 工程。它至少应包含:LVGL 移植层、界面模块、业务接口层、资源转换脚本、迁移对照表和验收记录。只有把这些交付物固定下来,迁移才算真正完成。