第一章 课程导学与开发环境搭建

大家好,我是你们这门课的老朋友。做嵌入式显示这块十几年了,从最早的裸机画点,到后来用 Qt,再到现在捣鼓 LVGL,踩过的坑比走过的路还多。这一章咱们不急着写代码,先把家伙事儿备齐。

说白了,环境搭不好,后面全是白忙活。我见过太多新手卡在编译这一步,一卡就是一整天。所以这一章,咱们把 Qt Creator、LVGL 模拟器、交叉编译链,一个一个捋清楚。

1.1 课程整体脉络

先看看咱们这 30 章要干什么。我把它分成四个阶段:

阶段 章节 核心内容
基础搭建 1-5 环境配置、Qt/LVGL 基础框架、显示驱动接口封装
驱动调试 6-15 RGB/MIPI/LVDS 接口调试、时序参数调优、帧缓冲管理
性能调优 16-25 渲染管线分析、DMA2D 加速、双缓冲策略、CPU/GPU 负载均衡
实战项目 26-30 智能家居面板、车载仪表盘、工业 HMI 完整案例

嗯,这个结构我反复调整过。你想想看,如果一上来就讲 DMA2D 寄存器配置,你连 Qt 的 QScreen 都没摸过,那不是扯淡吗?所以咱们从最基础的开始,一步步来。

1.2 为什么选 Qt + LVGL?

这个问题我经常被问到。我的回答很简单:Qt 做复杂交互,LVGL 做轻量渲染。

  • Qt:生态成熟,QML 做动画效果一流,适合高端产品。但资源占用大,启动慢。
  • LVGL:纯 C 写的,RAM 占用可以压到几十 KB,适合 MCU 或低端 Linux。但复杂控件得自己画。

我在一个车载项目中试过只用 Qt,结果低配版芯片跑不动。后来换成 Qt 做上层逻辑,LVGL 做仪表盘渲染,问题就解决了。说白了,没有银弹,只有合适的组合。

核心思路:Qt 负责应用框架和复杂 UI,LVGL 负责显示驱动层和轻量渲染。两者通过共享帧缓冲或 Socket 通信。

1.3 开发环境全景图

先给你一张图,看看咱们整个环境长什么样。我习惯在动手之前,先把架构看清楚。

开发环境架构图 主机开发环境 (Windows/Linux) Qt Creator 6.x + LVGL Simulator 交叉编译工具链 (arm-linux-gnueabihf) SDK: Yocto / Buildroot 调试器: OpenOCD / J-Link 目标板 (ARM Cortex-A/M) Linux Kernel 5.x / RTOS DRM/KMS 或 Framebuffer 驱动 Qt EGLFS / LVGL Linux Framebuffer 显示接口: RGB / MIPI DSI / LVDS SSH / NFS / USB 显示设备 (LCD / OLED / eDP) 分辨率: 480x272 ~ 1920x1080 显示数据流 说明 主机上先用模拟器调试 UI 逻辑,再交叉编译部署到目标板 显示驱动调试时,建议用示波器抓取时序波形验证

这张图你看懂了吗?主机上写代码、模拟调试,然后交叉编译扔到目标板上跑。显示驱动这块,我建议你先在模拟器上验证逻辑,再上真机。不然每次烧写都要几分钟,效率太低了。

1.4 Qt Creator 安装与配置

Qt Creator 我用了快十年了。版本选择上,我个人建议用 Qt 6.5 LTS 或更高版本。为什么?因为 6.x 对 LVGL 的兼容性更好,而且 CMake 集成更顺滑。

1.4.1 安装步骤

  1. 去 Qt 官网下载在线安装器,选择 Qt 6.5.3 版本。
  2. 组件选择时,勾上:
    • Qt 6.5.3 → Desktop gcc 64-bit
    • Qt 6.5.3 → ARM64(如果你用 ARM 目标板)
    • Developer and Designer Tools → Qt Creator 12.x
    • Qt 6.5.3 → Additional Libraries → Qt Charts / Qt SVG
  3. 安装路径不要有中文和空格。我吃过这个亏,编译时莫名其妙报错。

小技巧:安装完成后,打开 Qt Creator → 帮助 → 关于插件,确保 ClangCodeModel 和 CMakeProjectManager 已启用。这两个插件能帮你自动补全和语法检查。

1.4.2 配置交叉编译套件

这一步很多人会卡住。我教你一个稳妥的方法:

# 假设你的交叉编译链在 /opt/arm-gcc 目录下
# 打开 Qt Creator → 工具 → 选项 → Kits → 编译器 → 添加 → GCC

# 编译器路径设置:
# C 编译器: /opt/arm-gcc/bin/arm-linux-gnueabihf-gcc
# C++ 编译器: /opt/arm-gcc/bin/arm-linux-gnueabihf-g++
# 调试器: /opt/arm-gcc/bin/arm-linux-gnueabihf-gdb

# 然后在 Kits 标签页,新建一个套件:
# 名称: ARM-Linux-Debug
# 设备类型: Generic Linux Device
# 编译器: 选择刚才添加的交叉编译器
# 调试器: 选择交叉 gdb
# Qt 版本: 选择你安装的 Qt 6.5.3 ARM64 版本
# CMake 工具: 使用系统自带的 cmake

嗯,这里要注意:交叉编译链的版本必须和你的目标板内核匹配。我曾经用 gcc 9 编译的程序,放到 gcc 7 的板子上,跑起来直接段错误。后来查了半天,是 libstdc++ ABI 不兼容。

1.5 LVGL 模拟器环境搭建

LVGL 官方提供了模拟器,基于 SDL2 或 X11。我推荐用 SDL2 版本,因为它在 Windows 和 Linux 上表现一致。

1.5.1 下载与编译

# 克隆 LVGL 仓库
git clone https://github.com/lvgl/lv_port_pc_eclipse.git
cd lv_port_pc_eclipse

# 初始化子模块(lvgl 核心库)
git submodule update --init --recursive

# 使用 CMake 构建
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug
make -j4

# 运行模拟器
./lv_sim_eclipse_sdl

如果一切顺利,你会看到一个灰色的窗口,上面有 LVGL 的 demo 界面。我第一次跑起来的时候,心里还挺激动的——毕竟在 PC 上就能看到嵌入式 UI 的效果,调试效率翻了好几倍。

避坑指南:如果你在 Windows 上编译,记得安装 SDL2 开发库。我曾经忘了装,结果编译报错说找不到 SDL.h。去 libsdl.org 下载开发包,解压后把路径加到 CMake 的 -DCMAKE_PREFIX_PATH 里就行。

1.5.2 集成到 Qt Creator

我个人习惯把 LVGL 模拟器作为一个 Qt Creator 项目来管理。这样代码补全、调试、版本控制都在一个 IDE 里,省心。

  1. 在 Qt Creator 中打开 lv_port_pc_eclipse 目录下的 CMakeLists.txt。
  2. 配置构建套件为 Desktop (gcc 64-bit)。
  3. 在项目设置中,添加 CMake 参数:-DCMAKE_BUILD_TYPE=Debug。
  4. 点击构建,然后运行。你会看到模拟器窗口嵌入到 Qt Creator 的输出面板旁边。

你想想看,一边写代码一边看效果,是不是比每次烧写到板子上快多了?

1.6 交叉编译工具链安装

交叉编译链的选择取决于你的目标芯片。这里我以 ARM Cortex-A7 为例,这是目前工业 HMI 上最常用的架构之一。

1.6.1 获取工具链

我推荐两种方式:

方式 来源 适用场景
Linaro 预编译版 https://releases.linaro.org/components/toolchain/binaries/ 快速上手,通用性高
Yocto SDK 由你的 BSP 提供 与目标板内核完全匹配,推荐生产环境使用

我个人建议初学者用 Linaro 版。Yocto SDK 虽然更精确,但生成一次要编译好几个小时,太折腾了。

1.6.2 安装与验证

# 下载 Linaro gcc 7.5 版本(ARM 32位)
wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz

# 解压到 /opt
sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz -C /opt

# 添加环境变量
echo 'export PATH=$PATH:/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin' >> ~/.bashrc
source ~/.bashrc

# 验证安装
arm-linux-gnueabihf-gcc --version
# 输出: arm-linux-gnueabihf-gcc (Linaro GCC 7.5-2019.12) 7.5.0

关键检查点:运行 arm-linux-gnueabihf-gcc -v,查看最后一行是否显示 gcc version 7.5.0。如果报错 command not found,说明 PATH 没加对,检查一下路径。

1.7 第一个测试程序:Hello 显示驱动

环境搭好了,咱们写个最简单的程序,验证整个链路是否通。这个程序会在 LVGL 模拟器上画一个蓝色的矩形,然后交叉编译到目标板上运行。

// main.c - LVGL 显示驱动测试程序
#include "lvgl.h"

int main(void)
{
    // 初始化 LVGL
    lv_init();

    // 初始化显示驱动(模拟器或真实硬件)
    lv_port_disp_init();

    // 创建一个蓝色矩形
    lv_obj_t *rect = lv_obj_create(lv_scr_act());
    lv_obj_set_size(rect, 200, 100);
    lv_obj_align(rect, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_style_bg_color(rect, lv_color_hex(0x3498db), 0);

    // 主循环
    while(1) {
        lv_task_handler();
        lv_tick_inc(5);
        lv_delay_ms(5);
    }

    return 0;
}

在模拟器上编译运行,你会看到屏幕中央出现一个蓝色的矩形。嗯,虽然简单,但这是你显示驱动调试的第一步——确认像素能正确输出。

调试技巧:如果矩形显示不出来,先检查 lv_port_disp_init() 中的缓冲区大小和像素格式。我遇到过好几次,缓冲区太小导致显示撕裂。建议缓冲区至少为屏幕分辨率的 1/10。

1.8 本章小结

这一章我们做了三件事:

  • 理清了课程的整体脉络,知道后面要学什么。
  • 搭建了 Qt Creator + LVGL 模拟器的开发环境。
  • 安装了交叉编译工具链,并跑通了第一个显示测试程序。