在Linux中創建LVGL應用
簡介
上一篇文章介紹了在imx6上開發UI的流程 .
這篇接上文, 介紹具體的開發步驟。
1. 創建項目主目錄
mkdir my_lvgl_project
cd my_lvgl_project
2. 初始化 Git 倉庫 (可選但推薦)
git init
echo "# My Project with Dependencies" > README.md
git add README.md
git commit -m "Initial commit: Add README"
3. 添加LVGL源碼
這里有2種方式:
- 將lvgl倉庫作為整個工程的子模塊(推薦)
- 直接將LVGL源代碼加入到工程中
3.1 添加 LVGL 作為子模塊
git submodule add https://github.com/lvgl/lvgl.git
然后git開始下載
下載完成后查看git狀態
這里有兩個關鍵變化:
- .gitmodules 文件:這是一個新創建的配置文件,它記錄了你的項目包含了哪些子模塊,以及它們的 URL 和本地路徑。
[submodule "lvgl"]path = lvglurl = https://github.com/lvgl/lvgl.git
- lvgl 目錄:這是 lvgl 倉庫被克隆下來的地方。它看起來像一個普通目錄,但它實際上是一個獨立的 Git 倉庫。
現在,提交這次變更:
git commit -m "feat: Add lvgl as a submodule"
3.2 直接從其他地方復制LVGL源碼到工程目錄
4. 創建工程文件
4.1 lv_conf.h文件
從LVGL源碼里復制lv_conf_template.h 為lv_conf.hmkdir src
cd src
copy …/lvgl/lv_conf_template.h ./lv_conf.h
使能整個文件
4.2 應用程序文件
創建 lvgl_ui.c: 為了兼容ubuntu和imx6ull兩個平臺, 這里使用了宏定義來區分。
#include "lv_conf.h"
#include "lvgl.h"
#if LV_USE_SDL
#include "src/drivers/sdl/lv_sdl_window.h"
#endif
#if LV_USE_LINUX_FBDEV
#include "src/drivers/display/fb/lv_linux_fbdev.h"
#endif
#include <stdio.h>
#include <unistd.h>#ifndef FRAMEBUF_DEV_PATH
#define FRAMEBUF_DEV_PATH "/dev/fb0"
#endiflv_display_t * disp;int main(void)
{// 1. 初始化 LVGLlv_init();
#if LV_USE_SDL// 2. 初始化 SDL 顯示驅動disp = lv_sdl_window_create(800, 480); // 設置窗口大小
#endif
#if LV_USE_LINUX_FBDEV// 2. 初始化 LVGL 顯示驅動lv_linux_fbdev_set_file(disp, FRAMEBUF_DEV_PATH);
#endif// 3. 創建測試對象lv_obj_t * label = lv_label_create(lv_scr_act());char buf[100] = {0};sprintf(buf, "Hello, Ubuntu & LVGL(%s: V%d.%d.%d)!", LVGL_VERSION_INFO, LVGL_VERSION_MAJOR, LVGL_VERSION_MINOR, LVGL_VERSION_PATCH);lv_label_set_text(label, buf);lv_obj_center(label);// 4. 主循環while(1) {lv_timer_handler();usleep(5000);}return 0;
}
4.3 創建CMakeList.txt 和 build文件夾
4.3.1 Ubuntu 上運行LVGL的必要設置
在 Ubuntu 上運行 LVGL 應用時,使用 SDL (Simple DirectMedia Layer) 作為顯示驅動是一個非常棒的選擇,尤其是在開發和調試階段。SDL 允許 LVGL 在一個桌面窗口中渲染,而不需要配置物理幀緩沖設備(/dev/fb0),這大大簡化了開發流程。
- 安裝 SDL 及其開發庫
#1. 更新包管理器的列表
sudo apt update# 2. 安裝 SDL2 開發庫
sudo apt install -y libsdl2-dev
- 啟用 SDL 驅動
可以在CMakeList里設置, 也可以在代碼里設置
#define LV_USE_SDL 1
- Ubuntu 的 CMakeList.txt
# run below command to build project for Ubuntu
# cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ ..# CMake 最低版本要求
cmake_minimum_required(VERSION 3.15)# 定義項目名稱和版本
project(MyLVGLProject VERSION 1.0.0 LANGUAGES C CXX)# 設置 C 標準
set(CMAKE_C_STANDARD 99)# --- 編譯選項 ---
# 添加Ubuntu所需的編譯選項
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -O2")# --- 包含目錄 ---
# 包含 LVGL 頭文件
include_directories(${PROJECT_SOURCE_DIR}/lvgl)
include_directories(${PROJECT_SOURCE_DIR}/src)
# 添加SDL2頭文件目錄
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
include_directories(${SDL2_INCLUDE_DIRS})# --- 源文件定義 ---# 1. LVGL 源文件
file(GLOB_RECURSE LVGL_SOURCES "lvgl/src/*.c")# 2. LVGL 驅動源文件
file(GLOB_RECURSE DRIVERS_SOURCES "lv_drivers/src/*.c")# 3. 應用程序源文件
file(GLOB APP_SOURCES "src/*.c")# --- 可執行文件 ---add_executable(my_app_ubuntu${LVGL_SOURCES}${DRIVERS_SOURCES}${APP_SOURCES}
)# --- 鏈接庫和依賴 ---
# 添加Ubuntu系統所需的庫
target_link_libraries(my_app_ubuntu${SDL2_LIBRARIES}pthreadrtmdl
)# --- LVGL配置 ---
target_compile_definitions(my_app_ubuntu PRIVATELV_CONF_INCLUDE_SIMPLE# 添加SDL驅動支持LV_USE_SDL=1LV_USE_LINUX_FBDEV=0# 設置顯示分辨率LV_HOR_RES_MAX=800LV_VER_RES_MAX=480# 設置顏色深度LV_COLOR_DEPTH=16
)# --- Ubuntu特定配置 ---
if(UNIX AND NOT APPLE)# 針對Linux/Unix系統的配置target_compile_definitions(my_app_ubuntu PRIVATEUSE_SDL=1MY_DISP_FLUSH_LINUX)
endif()# --- 打印信息 ---
message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")
message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
message(STATUS "SDL2_INCLUDE_DIRS: ${SDL2_INCLUDE_DIRS}")
message(STATUS "SDL2_LIBRARIES: ${SDL2_LIBRARIES}")
4.3.2 Imx6 上運行LVGL的必要設置
- 啟用 framebuffer device 驅動
可以在CMakeList里設置, 也可以在代碼里設置
#define LV_USE_LINUX_FBDEV 1
- 屏幕尺寸被代碼里固定了, 可以通過修改源代碼來修改尺寸
lvgl/src/drivers/display/fb/lv_linux_fbdev.c: lv_linux_fbdev_create
- imx6 的 CMakeList.txt
# before run cmake .., cross-compile environment should be set
# e.g.
#"source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi"# CMake 最低版本要求
cmake_minimum_required(VERSION 3.15)# 定義項目名稱和版本
project(MyLVGLProject VERSION 1.0.0 LANGUAGES C CXX)# 設置 C 標準
set(CMAKE_C_STANDARD 99)# --- 編譯選項 ---
# 如果你的平臺需要特殊的編譯器標志,可以在這里添加
# 例如,為 ARM 交叉編譯添加:
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfloat-abi=hard")# --- 包含目錄 ---
# 包含 LVGL 頭文件
include_directories(${PROJECT_SOURCE_DIR}/lvgl)
include_directories(${PROJECT_SOURCE_DIR}/src)# --- 源文件定義 ---# 1. LVGL 源文件
# 使用 GLOB_RECURSE 遞歸查找所有 .c 文件
file(GLOB_RECURSE LVGL_SOURCES "lvgl/src/*.c")# 打印找到的文件列表,用于調試和驗證
message(STATUS "Found sources in A and its subdirectories:")
foreach(source ${LVGL_SOURCES})message(STATUS " - ${source}")
endforeach()# 2. LVGL 驅動源文件
# file(GLOB_RECURSE DRIVERS_SOURCES "lv_drivers/src/*.c")# 3. 應用程序源文件
file(GLOB APP_SOURCES "src/*.c")# --- 可執行文件 ---# add_executable 定義最終要生成的可執行文件
# 它將所有源文件鏈接在一起
add_executable(my_app_imx6${LVGL_SOURCES}${DRIVERS_SOURCES}${APP_SOURCES}
)# --- 鏈接庫和依賴 ---# 如果你的應用程序需要鏈接其他庫(如 pthread, rt 等),在這里添加
# 例如,如果需要實時時鐘支持:
target_link_libraries(my_app_imx6 pthread rt)# --- (可選但推薦) 手動定義 LV_CONF_INCLUDE_SIMPLE ---
# 雖然根據 LVGL 的邏輯,如果路徑正確,它會自動定義。
# 但在 CMake 中顯式地定義它,可以增強構建系統的明確性和可預測性。
# 它覆蓋了 LVGL 的自動檢測,強制使用簡單包含模式。
# 這是一種防御性編程,確保即使 LVGL 的自動檢測在某些邊緣情況下失敗,我們的構建依然穩定。
target_compile_definitions(my_app_imx6 PRIVATELV_CONF_INCLUDE_SIMPLE# 添加SDL驅動支持LV_USE_SDL=0LV_USE_LINUX_FBDEV=1
)# --- 特定平臺配置 ---# 這是一個示例,展示如何為不同平臺進行配置
# 你可以根據你的實際需求修改這部分
if(UNIX AND NOT APPLE)# 針對 Linux/Unix 系統的配置# 假設你的顯示刷新函數在 src/my_disp_flush.c 中# 并且你定義了一個宏來啟用它target_compile_definitions(my_app_imx6 PRIVATE MY_DISP_FLUSH_LINUX)# 假設你使用了特定的庫,如 libinput# find_package(PkgConfig REQUIRED)# pkg_check_modules(LIBINPUT REQUIRED libinput)# target_link_libraries(my_app_imx6 ${LIBINPUT_LIBRARIES})# target_include_directories(my_app_imx6 PRIVATE ${LIBINPUT_INCLUDE_DIRS})
endif()# if(DEFINED ENV{CMAKE_TOOLCHAIN_FILE})
# # 如果定義了交叉編譯工具鏈文件,則應用它
# include($ENV{CMAKE_TOOLCHAIN_FILE})
# endif()# --- 打印信息 (可選,用于調試) ---
message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")
message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
最終文件結構:
my_lvgl_project/
├── CMakeLists.txt # 根 CMake 配置文件
├── CMakeLists.txt-imx6ull # imx6ull的 CMake 配置文件
├── CMakeLists.txt-ubuntu #ubuntu 的 CMake 配置文件
├── lvgl/ # LVGL 源碼目錄 (可以是子模塊或直接下載)
├── src/ # 你的應用程序源碼目錄
│ ├── lvgl_conf.h
│ ├── lvgl_ui.c
└── build/ # 構建目錄 (將在外部創建)
5. 編譯
5.1 編譯Ubuntu的應用
5.1.1 指定gcc作為編譯工具
cd build
cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ ..
make -j4
5.1.2. 編譯完成后,運行
5.2 編譯imx6ull的應用
5.2.1 source交叉編譯工具
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-
poky-linux-gnueabi
5.2.2 驗證交叉編譯工具是否正確
echo $CC
echo $CXX