ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

LVGL嵌入式UI开发:WSL2+VSCode环境搭建与Linux帧缓冲示例运行指南

LVGL嵌入式UI开发:WSL2+VSCode环境搭建与Linux帧缓冲示例运行指南 1. 项目缘起为什么选择LVGLWSL2VSCode这套组合拳如果你是一名嵌入式软件工程师或者正在学习嵌入式开发那么“UI”这个词对你来说可能既熟悉又头疼。熟悉的是我们每天都在和各种带屏幕的设备打交道头疼的是在资源极其有限的MCU上要做出流畅、美观的交互界面传统方法往往意味着无尽的底层驱动调试、复杂的状态机管理和低效的绘图操作。几年前我接手一个基于STM32F4的工业HMI项目客户要求一个能滑动、有点击动画的列表界面。当时尝试过自己写框架也用过一些简单的GUI库结果不是内存爆了就是帧率惨不忍睹调试过程更是噩梦。直到遇到了LVGL我才发现原来在嵌入式设备上做UI可以如此优雅。LVGL是一个开源的嵌入式图形库它提供了丰富的控件、动画和主题而且对硬件要求极低。但它的官方开发环境推荐是在Linux下这对于习惯了Windows的嵌入式开发者尤其是单片机方向来说是个不小的门槛。难道要为了一个UI库去装双系统或者搞个虚拟机太折腾了。这就是WSL2的价值所在。Windows Subsystem for Linux 2它不是一个虚拟机而是Windows内核层面的Linux兼容层。你可以理解为它在你的Windows里原生地、高性能地运行了一个完整的Linux系统。编译、调试LVGL这种源于Linux生态的工具链在WSL2里变得无比顺畅。而VSCode则是连接这一切的桥梁。通过Remote - WSL插件你可以直接用VSCode打开WSL2里的项目文件夹享受Windows下熟悉的编辑体验同时调用WSL2里的GCC编译器、CMake等工具进行构建。代码在Windows这边写编译和运行在Linux那边两全其美。所以这个系列的目标很明确手把手带你搭建一套零割裂感的LVGL开发环境让你在Windows下用最熟悉的工具最高效地开发出能在嵌入式硬件上运行的漂亮UI。本篇作为开篇我们将聚焦于环境基石资料收集与在WSL2中运行LVGL的官方示例。2. 核心资料全收集从官方仓库到社区精华在动手之前把“弹药”备齐是资深工程师的习惯。盲目搜索只会浪费时间精准收集才能高效入门。以下是为你梳理的LVGL学习与开发核心资料库请务必收藏。2.1 官方一手资料权威与基准官方资料是绝对的地基任何偏离官方文档的“技巧”都可能在未来埋下坑。LVGL主仓库 (GitHub)地址:https://github.com/lvgl/lvgl核心价值: 这里是所有一切的源头。你需要的不仅仅是git clone代码更要关注README.md: 项目总览、快速开始。docs/目录: 这是宝藏包含了从入门到精通的全部英文文档。特别是/docs/get-started目录下的平台移植指南。examples/目录: 官方示例代码是学习控件使用和架构的最佳范本。release notes: 升级前必看了解API变更和已知问题。LVGL模拟器仓库 (GitHub)地址:https://github.com/lvgl/lv_port_linux_frame_buffer或https://github.com/lvgl/lv_port_windows核心价值: 官方提供的在桌面系统Linux帧缓冲/SDL或Windows上运行LVGL的移植工程。我们将主要使用Linux帧缓冲版本因为它最贴近嵌入式Linux的显示驱动模式且能在WSL2中完美运行。这个仓库展示了如何将LVGL核心库与显示、输入设备驱动对接是理解移植关键步骤的蓝本。LVGL在线文档与示例文档站:https://docs.lvgl.io/master/在线示例:https://docs.lvgl.io/master/widgets/index.html核心价值: 比本地文档更新更快。在线示例功能极其强大你可以直接在网页上交互式地修改控件属性代码并实时看到渲染效果是学习和调试控件属性的神器无需编译。2.2 社区与辅助工具提效关键独行者速众行者远。这些社区资源能帮你解决90%的常见问题。LVGL官方论坛地址:https://forum.lvgl.io/核心价值: 活跃的开发者社区。遇到任何诡异问题先用英文关键词在这里搜索大概率已有讨论。提问时附上代码和日志回复效率很高。GUI Guider (NXP官方工具但支持LVGL)地址:https://www.nxp.com/design/software/development-software/gui-guider:GUI-GUIDER核心价值: 一个基于LVGL的拖拽式UI设计器。你可以用鼠标设计界面它会自动生成C代码。对于快速原型开发、学习LVGL对象树结构、事件回调机制非常有帮助。生成的代码结构清晰是优秀的参考。SquareLine Studio地址:https://squareline.io/核心价值: 另一款强大的LVGL可视化设计工具功能更丰富部分高级功能需付费。如果项目UI复杂值得投资。2.3 本系列配套资源为了让你能跟着操作一遍就成功我已经将必要的代码和配置整理好。你可以访问这个仓库获取本篇的所有配套文件https://github.com/your-repo/lvgl-wsl2-vscode-tutorial(这是一个示例地址请替换为你实际存放代码的仓库)。里面包含了为WSL2环境预配置好的lv_port_linux_frame_buffer项目以及VSCode的配置文件可以帮你跳过初期的配置坑。3. WSL2环境精讲不只是安装更是优化很多人以为安装完WSL2就结束了其实优化配置才是流畅开发的开始。这里我会分享从安装到调优的全流程包括一些官方文档没细说的坑。3.1 安装与发行版选择启用WSL2以管理员身份打开PowerShell运行wsl --install这个命令会默认安装Ubuntu发行版。如果你想安装其他版本如Debian可以先运行wsl --install -d Debian。为什么推荐Ubuntu LTS生态最好遇到任何Linux环境问题Ubuntu的解决方案最多。长期支持LTS版本稳定软件源维护周期长避免因版本迭代带来的兼容性问题。工具链齐全ARM GCC、CMake等嵌入式开发工具链在Ubuntu源中安装最方便。设置默认版本和用户安装后确保WSL2为默认版本wsl --set-default-version 2首次启动Ubuntu会提示创建用户名和密码。强烈建议使用纯英文用户名避免后续在路径中产生乱码。3.2 必须进行的系统优化配置安装完系统后不要急着装软件先做这几件事体验提升巨大。更换国内软件源大幅提升apt安装速度。备份原列表sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak编辑源列表sudo vim /etc/apt/sources.list(或用nano)将文件内容替换为阿里云或清华的Ubuntu源根据你的Ubuntu版本号如22.04是jammy。例如阿里云deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ jammy-backdates main restricted universe multiverse更新sudo apt update sudo apt upgrade -y配置Windows Terminal (可选但强烈推荐)从Microsoft Store安装Windows Terminal。将其设为默认终端并配置Ubonda的启动目录、字体推荐Cascadia Code、配色方案。一个美观高效的终端能极大提升编码心情。文件系统互访性能黄金法则在WSL2中操作Linux文件位于\\wsl$\Ubuntu\home\...速度极快在Windows中操作WSL2里的Linux文件速度较慢。反之亦然在WSL2中访问Windows文件/mnt/c/Users/...性能有损耗。最佳实践将项目代码完全放在WSL2的Linux文件系统内如~/projects。让VSCode通过Remote-WSL去打开这个纯Linux路径。这样能保证编译工具链获得最佳I/O性能。3.3 开发基础工具链安装这是为编译LVGL及其模拟器准备的环境。# 1. 安装编译器和构建工具 sudo apt install -y build-essential gcc g gdb cmake ninja-build # 2. 安装LVGL模拟器依赖帧缓冲和SDL # 帧缓冲(fbdev)相关用于在Linux终端内直接渲染 sudo apt install -y libsdl2-dev libgles2-mesa-dev libgl1-mesa-dev libegl1-mesa-dev # 一些基础工具 sudo apt install -y libwayland-dev libxkbcommon-dev wayland-protocols # 3. 安装Git sudo apt install -y git # 验证安装 gcc --version cmake --version关键点解释build-essential包含了GCC、G、make等一整套基础编译工具。libsdl2-devSDL库的开发文件。LVGL的Linux模拟器可以使用SDL作为后端在窗口中显示这对于调试非常方便。我们同时安装帧缓冲和SDL以备不同需求。ninja-build一个比make更快的构建系统CMake可以生成Ninja的构建文件大幅提升编译速度。4. 获取并运行LVGL官方Linux帧缓冲示例这是检验环境是否就绪的关键一步。我们将使用官方提供的lv_port_linux_frame_buffer项目它已经做好了LVGL与Linux帧缓冲接口的对接。4.1 克隆与准备项目进入工作目录并克隆项目cd ~ mkdir -p projects/lvgl cd projects/lvgl git clone https://github.com/lvgl/lv_port_linux_frame_buffer.git cd lv_port_linux_frame_buffer同步LVGL子模块 这个仓库通过Git子模块引用了LVGL主库需要同步更新。git submodule update --init --recursive这一步会下载LVGL核心库代码到lvgl/目录下。如果网络慢可以多试几次或者配置Git代理。4.2 理解项目结构与编译配置在编译前先花两分钟看看目录结构这能帮你以后自己移植时心里有数。lv_port_linux_frame_buffer/ ├── CMakeLists.txt # 顶层的CMake构建配置文件 ├── lv_conf.h # **LVGL库的核心配置文件**至关重要 ├── main.c # 应用入口创建显示、输入设备并启动任务 ├── lvgl/ # LVGL核心库子模块 ├── linux_fbdev/ # Linux帧缓冲显示驱动实现 │ ├── lv_linux_fbdev.c │ └── lv_linux_fbdev.h └── ...关键文件lv_conf.h 这个文件决定了LVGL的功能、内存和性能。默认是一个模板我们需要启用它。# 将配置文件模板复制为正式文件 cp lv_conf_template.h lv_conf.h然后用编辑器打开lv_conf.h找到开头的#if 0将其改为#if 1以启用该配置。你可以先保持其他默认设置后续优化时会再调整。4.3 编译与运行第一个LVGL窗口我们使用CMake进行“外部构建”(Out-of-source build)保持源码目录清洁。创建构建目录并编译mkdir build cd build cmake .. -G Ninja # 使用Ninja生成器 ninja # 开始编译如果一切顺利你会在build目录下看到生成的可执行文件默认名称可能是lvgl_example或demo。在WSL2中运行帧缓冲模式 帧缓冲模式需要直接访问Linux的图形帧缓冲设备在WSL2中我们需要一个X Server来显示窗口。在Windows端安装一个X Server推荐使用VcXsrv免费且稳定。从官网下载安装后启动XLaunch。配置XLaunch一路默认但在“Extra settings”中务必勾选“Disable access control”。这一步非常重要否则WSL2无法连接。在WSL2中设置显示环境变量export DISPLAY$(cat /etc/resolv.conf | grep nameserver | awk {print $2}):0这个命令会自动获取Windows主机的IP并设置给DISPLAY变量。运行程序./lvgl_example此时你应该能看到一个独立的窗口弹出里面运行着LVGL的示例UI可以用鼠标进行交互。使用SDL后端运行更简单 官方示例可能默认使用帧缓冲。我们可以改用SDL后端它更容易设置。确保CMakeLists.txt中启用了SDL选项通常通过set(USE_SDL yes)。或者直接使用一个我修改好的、默认启用SDL的版本见第2章提到的配套资源。重新编译运行SDL会直接创建一个窗口无需复杂的DISPLAY设置只要SDL安装正确。运行成功的效果你会看到一个包含按钮、滑块、图表、列表等控件的演示界面。滑动滑块、点击按钮体验一下LVGL的流畅动画。这不仅仅是“跑通了”更重要的是它证明了你的WSL2环境、编译工具链、图形库依赖全部工作正常为后续的深度开发扫清了环境障碍。5. VSCode远程开发环境无缝对接命令行编译运行没问题了但真正的生产力来自于一个强大的IDE。下面将VSCode配置成LVGL的远程开发利器。5.1 安装必备插件在Windows的VSCode中安装以下插件Remote - WSL核心插件允许VSCode将WSL作为远程开发环境。C/C(Microsoft)提供C语言智能感知、调试等功能。CMake Tools(Microsoft)提供CMake项目的图形化配置、构建、调试支持。LVGL Snippets(可选)LVGL代码片段提示提高编码效率。5.2 连接WSL并打开项目在VSCode中点击左下角的绿色远程状态按钮选择“New WSL Window using Distro...”然后选择你安装的Ubuntu。这会打开一个新的VSCode窗口此时左下角显示“WSL: Ubuntu”。这表示VSCode的核心进程如语言服务已经运行在WSL内部了。在这个新窗口中点击“File” - “Open Folder...”然后浏览到WSL中的项目路径例如\\wsl$\Ubuntu\home\你的用户名\projects\lvgl\lv_port_linux_frame_buffer或者直接输入/home/你的用户名/projects/lvgl/lv_port_linux_frame_buffer。打开后VSCode会提示检测到CMake项目并自动进行配置。如果没有可以按CtrlShiftP输入“CMake: Configure”手动触发。5.3 配置智能感知与调试解决头文件智能感知 打开项目后C/C插件可能会提示找不到lvgl/lvgl.h等头文件。这是因为默认的包含路径配置不对。按CtrlShiftP输入“C/C: Edit Configurations (UI)”。在“Include path”中添加以下路径根据你的实际项目位置调整${workspaceFolder}/lvgl ${workspaceFolder}/linux_fbdev ${workspaceFolder}/**也可以在项目根目录创建.vscode/c_cpp_properties.json文件进行配置。使用CMake Tools插件构建VSCode底部状态栏会出现CMake相关的按钮如选择的Kit、构建目标等。点击“Select a Kit”选择“GCC ...”通常会自动检测到WSL里的GCC。点击“Build”按钮小齿轮即可编译项目输出信息在终端面板比命令行更直观。配置调试以SDL后端为例确保项目已编译。切换到“Run and Debug”侧边栏点击“create a launch.json file”。选择“C (GDB/LLDB)”然后选择“Default Configuration”。修改生成的launch.json关键配置如下{ version: 0.2.0, configurations: [ { name: (gdb) Launch, type: cppdbg, request: launch, program: ${workspaceFolder}/build/lvgl_example, // 你的可执行文件路径 args: [], stopAtEntry: false, cwd: ${workspaceFolder}, environment: [ { name: DISPLAY, value: localhost:0 // 如果使用SDL且无需X转发可能不需要 } ], externalConsole: false, MIMode: gdb, setupCommands: [ { description: Enable pretty-printing for gdb, text: -enable-pretty-printing, ignoreFailures: true } ], miDebuggerPath: /usr/bin/gdb } ] }设置断点然后按F5即可开始图形化调试。你可以观察变量、单步执行这对于理解LVGL的事件循环和回调机制至关重要。6. 踩坑实录WSL2图形显示与输入的那些“坎”理论很顺利但实操中总会遇到些意想不到的问题。这里把我趟过的坑总结出来帮你快速排雷。6.1 坑一DISPLAY环境变量设置无效无法打开窗口现象在WSL2中运行程序提示Error: Cant open display。排查首先确认X Server如VcXsrv已启动且“Disable access control”已勾选。在WSL2中执行echo $DISPLAY检查输出。如果是空的说明变量未设置。使用export DISPLAY:0或前述自动获取IP的命令。如果还不行尝试在Windows防火墙中为VcXsrv放行。根治方案将DISPLAY设置命令写入WSL2的shell配置文件中如~/.bashrc或~/.zshrc这样每次启动shell都会自动设置。# 在 ~/.bashrc 末尾添加 export DISPLAY$(grep -m 1 nameserver /etc/resolv.conf | awk {print $2}):06.2 坑二程序运行后鼠标键盘无响应现象窗口能打开LVGL界面也显示但鼠标点击、键盘输入没反应。排查检查输入设备初始化在main.c中确认输入设备如鼠标、键盘的驱动初始化函数被正确调用并且注册到了LVGL。检查SDL视频驱动模式如果使用SDL确保初始化时设置了正确的视频驱动标志。有时需要指定SDL_INIT_VIDEO | SDL_INIT_EVENTS。WSL2的输入焦点问题这是一个经典坑。WSL2的图形应用窗口有时无法正确获取焦点。尝试点击窗口标题栏或者按一下Alt键再试试。多任务处理问题LVGL需要一个周期性的任务处理器lv_timer_handler()在主循环中被调用。检查你的main.c中的主循环是否在不断地调用它并且没有长时间的阻塞操作。6.3 坑三编译时找不到SDL2或OpenGL相关头文件/库现象CMake配置或make编译失败报错如fatal error: SDL2/SDL.h: No such file or directory。排查确认已安装开发包sudo apt install libsdl2-dev。注意是-dev包不是只有libsdl2。对于OpenGL ES错误可能需要安装libgles2-mesa-dev。如果使用CMake检查CMakeLists.txt中find_package(SDL2 REQUIRED)是否成功。可以在CMake配置后查看CMakeCache文件或输出信息。库文件路径问题在WSL2中有时32位和64位库会冲突。确保你安装的是与系统架构一致的包。使用uname -m查看架构x86_64对应64位。6.4 坑四程序运行时出现Segmentation fault (核心已转储)现象程序启动后立即崩溃。排查使用GDB调试在WSL2中编译时加上-g调试符号然后使用gdb ./your_program运行崩溃后输入bt查看调用栈能精确定位到出错的代码行。检查内存操作LVGL大量使用动态内存分配。检查lv_conf.h中的LV_MEM_SIZE是否设置过小。初期可以适当调大。检查未初始化的指针特别是在显示驱动(lv_linux_fbdev.c)或输入驱动中确保所有函数指针、结构体都被正确初始化。线程安全问题LVGL本身不是线程安全的。确保所有LVGL API调用如创建对象、设置属性都在同一个线程通常是主循环中执行。如果在定时器回调或其它线程中调用需要加锁或使用lv_timer_create将任务派发到主线程。7. 从示例到自己的项目搭建专属开发框架成功运行示例只是第一步。我们的目标是开发自己的LVGL应用。下面教你如何基于官方示例搭建一个干净、可扩展的专属项目框架。7.1 项目目录结构规划一个好的结构能让后续开发、移植、维护事半功倍。我推荐如下结构my_lvgl_app/ ├── CMakeLists.txt # 项目主构建文件 ├── lv_conf.h # LVGL配置文件从官方复制后修改 ├── main.c # 应用入口硬件/平台初始化主循环 ├── src/ # 应用业务逻辑源码 │ ├── app_ui.c # 主界面创建逻辑 │ ├── app_ui.h │ ├── page_home.c # 各个页面的实现 │ ├── page_home.h │ └── ... ├── drivers/ # 硬件驱动层与平台强相关 │ ├── display/ # 显示驱动 │ │ ├── display.c # 抽象接口初始化显示、注册LVGL驱动 │ │ ├── display.h │ │ └── linux_fbdev.c # Linux帧缓冲具体实现从官方移植 │ ├── input/ # 输入设备驱动 │ │ ├── touchpad.c # 触摸板/鼠标实现 │ │ └── ... │ └── ... ├── components/ # 可复用的UI组件 │ ├── my_button.c │ └── ... ├── assets/ # 资源文件图片、字体 │ ├── fonts/ │ └── images/ ├── lvgl/ # LVGL核心库作为子模块或直接复制 │ ├── src/ │ └── ... └── build/ # 构建输出目录.gitignore忽略设计思路分层清晰drivers隔离硬件src专注业务components复用UI。便于移植换平台如从Linux模拟器到STM32时只需替换drivers/下的具体实现上层app_ui和components基本不用动。资源管理assets集中存放资源方便打包和更新。7.2 编写核心的CMakeLists.txt这是项目的构建蓝图。一个基础的CMakeLists.txt如下cmake_minimum_required(VERSION 3.16) project(my_lvgl_app C) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) # 设置输出目录 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) # 查找SDL2库用于模拟器 find_package(SDL2 REQUIRED) include_directories(${SDL2_INCLUDE_DIRS}) # 添加LVGL核心库假设lvgl目录在项目根下 add_subdirectory(lvgl) # 添加你的应用源文件 set(APP_SOURCES main.c src/app_ui.c drivers/display/display.c drivers/display/linux_fbdev.c drivers/input/touchpad.c # ... 其他源文件 ) # 添加头文件包含路径 include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/drivers/display ${CMAKE_CURRENT_SOURCE_DIR}/drivers/input ${CMAKE_CURRENT_SOURCE_DIR}/lvgl ) # 创建可执行文件 add_executable(${PROJECT_NAME} ${APP_SOURCES}) # 链接库 target_link_libraries(${PROJECT_NAME} lvgl # 链接LVGL核心库 ${SDL2_LIBRARIES} # 链接SDL2库 m # 数学库 pthread # 线程库如果用到 )7.3 定制lv_conf.h性能与功能的平衡直接从模板复制的lv_conf.h是功能全开的这在模拟器上没问题但放到资源紧张的MCU上就是灾难。现在就要养成按需配置的习惯。打开lv_conf.h重点关注以下部分颜色深度(LV_COLOR_DEPTH)模拟器上可以设为32ARGB8888但在STM32上可能只支持16位RGB565。提前适配。内存配置(LV_MEM_SIZE)模拟器可以给很大如1MB嵌入式上需要精确计算。初期可以设大点后期优化。功能开关这是瘦身的关键。把你暂时用不到的控件和功能关掉。#define LV_USE_ANIMATION 1 // 动画必开 #define LV_USE_FLEX 1 // 弹性布局现代UI推荐 #define LV_USE_GRID 1 // 网格布局推荐 #define LV_USE_BTN 1 // 按钮 #define LV_USE_LABEL 1 // 标签 // ... 其他控件 #define LV_USE_CHART 0 // 图表如果不用就关掉 #define LV_USE_CALENDAR 0 // 日历 #define LV_USE_VIDEO 0 // 视频播放很重字体(LV_FONT_...)默认字体可能包含很多不用的字符占用Flash。可以只启用需要的字体和字号或者添加自定义小字体。配置完成后在main.c开头包含这个头文件并调用lv_init()初始化库。7.4 编写主循环与任务处理一个典型的LVGL模拟器主循环如下它同样适用于许多RTOS或裸机环境的主线程#include lvgl/lvgl.h #include drivers/display/display.h #include drivers/input/touchpad.h int main(void) { /* 1. 初始化LVGL库 */ lv_init(); /* 2. 初始化硬件抽象层 */ display_init(); // 初始化显示并注册LVGL显示驱动 touchpad_init(); // 初始化触摸并注册LVGL输入驱动 /* 3. 创建你的用户界面 */ create_app_ui(); /* 4. 主循环处理LVGL任务和系统事件 */ while(1) { lv_timer_handler(); /* 让LVGL处理定时器、动画等任务建议调用间隔5~30ms */ usleep(5 * 1000); /* 休眠5ms降低CPU占用 */ // 在这里也可以处理其他非LVGL相关的任务 } return 0; }关键点lv_timer_handler()必须被周期性地调用它是LVGL的心跳。间隔时间决定了动画的流畅度和系统响应速度。usleep用于控制循环频率。在真实硬件上你可能需要一个硬件定时器来精确控制这个周期或者放在RTOS的任务中。至此你已经拥有了一个在WSL2VSCode环境下从资料准备、环境搭建、示例运行到自定义项目框架的完整路线图。这个环境不仅能用于学习LVGL其“Windows编辑 Linux编译调试”的模式同样是开发其他嵌入式Linux应用、交叉编译工具链的绝佳沙盒。在接下来的系列文章中我们将深入LVGL的内部机制并开始打造第一个属于自己的嵌入式UI界面。
返回列表