第一章 课程导学与开发环境搭建
大家好,我是你们这门课的老朋友。做嵌入式显示这块十几年了,从最早的裸机画点,到后来用 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 开发环境全景图
先给你一张图,看看咱们整个环境长什么样。我习惯在动手之前,先把架构看清楚。
这张图你看懂了吗?主机上写代码、模拟调试,然后交叉编译扔到目标板上跑。显示驱动这块,我建议你先在模拟器上验证逻辑,再上真机。不然每次烧写都要几分钟,效率太低了。
1.4 Qt Creator 安装与配置
Qt Creator 我用了快十年了。版本选择上,我个人建议用 Qt 6.5 LTS 或更高版本。为什么?因为 6.x 对 LVGL 的兼容性更好,而且 CMake 集成更顺滑。
1.4.1 安装步骤
- 去 Qt 官网下载在线安装器,选择 Qt 6.5.3 版本。
- 组件选择时,勾上:
Qt 6.5.3 → Desktop gcc 64-bitQt 6.5.3 → ARM64(如果你用 ARM 目标板)Developer and Designer Tools → Qt Creator 12.xQt 6.5.3 → Additional Libraries → Qt Charts / Qt SVG
- 安装路径不要有中文和空格。我吃过这个亏,编译时莫名其妙报错。
小技巧:安装完成后,打开 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 里,省心。
- 在 Qt Creator 中打开
lv_port_pc_eclipse目录下的CMakeLists.txt。 - 配置构建套件为 Desktop (gcc 64-bit)。
- 在项目设置中,添加 CMake 参数:
-DCMAKE_BUILD_TYPE=Debug。 - 点击构建,然后运行。你会看到模拟器窗口嵌入到 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 模拟器的开发环境。
- 安装了交叉编译工具链,并跑通了第一个显示测试程序。