目錄
- 準備
- 創建工程
- 修改配置
- 修改 lv_drv_conf.h
- 修改 lv_conf.h
- 修改 main.c
- 修改 Makefile
- 編譯運行
- 更多內容
LVGL(Light and Versatile Graphics Library)是一個輕量化的、開源的、在嵌入式系統中廣泛使用的圖形庫,它提供了一套豐富的控件和組件,只需要少量的內存和計算資源,使得在資源受限的設備上創建高端的圖形界面成為可能。本文記錄如何將 LVGL 移植到嵌入式 Linux 系統中。
- 編程環境:Windows11 VS Code
- 編譯環境:Ubuntu18.04 交叉編譯
- 測試平臺:正點原子 i.MX6ULL
- 顯示屏:5inch RGB 800×480
準備
打開 LVGL 的 Github 主頁,分別下載 lvgl、lv_drivers、lv_port_linux_frame_buffer 倉庫源碼,lvgl 和 lv_drivers 我這里選擇了當前最新的已發布版本:
創建工程
- 創建 lvgl_demo 文件夾;
- 將 lvgl、lv_drivers 復制到 lvgl_demo 中;
- 將 lv_port_linux_frame_buffer 倉庫中的 main.c 文件和 makefile 文件復制到 lvgl_demo 中;
- 將 lvgl 中的 lv_conf_template.h 文件復制到 lvgl_demo 中并且改名為 lv_conf.h;
- 將 lv_drivers 中的 lv_drv_conf_template.h 文件復制到 lvgl_demo 中并且改名為 lv_drv_conf.h;
- 創建好的工程目錄如圖所示:
修改配置
修改 lv_drv_conf.h
- 將
#if 0
改成#if 1
:
- 將
USE_FBDEV
的值改為1
,使能 frame buffer 設備:
- 將
USE_EVDEV
的值改為1
,配置觸控輸入設備的文件路徑:
修改 lv_conf.h
- 將
#if 0
改成#if 1
:
- 根據實際情況適當擴大內存:
- 這里可以修改刷新頻率,默認為 30ms:
- 配置 Tick:
- 使能 widgets demo:
修改 main.c
- 修改后的 main.c 文件如下所示:
#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "lv_drivers/display/fbdev.h"
#include "lv_drivers/indev/evdev.h"
#include <unistd.h>
#include <time.h>
#include <sys/time.h>#define DISP_BUF_SIZE (800 * 480)int main(void)
{lv_init();/*Linux frame buffer device init*/fbdev_init();/*A small buffer for LittlevGL to draw the screen's content*/static lv_color_t buf[DISP_BUF_SIZE];/*Initialize a descriptor for the buffer*/static lv_disp_draw_buf_t disp_buf;lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);/*Initialize and register a display driver*/static lv_disp_drv_t disp_drv;lv_disp_drv_init(&disp_drv);disp_drv.draw_buf = &disp_buf;disp_drv.flush_cb = fbdev_flush;disp_drv.hor_res = 800;disp_drv.ver_res = 480;lv_disp_drv_register(&disp_drv);/* Linux input device init */evdev_init();/* Initialize and register a display input driver */lv_indev_drv_t indev_drv;lv_indev_drv_init(&indev_drv); /*Basic initialization*/indev_drv.type = LV_INDEV_TYPE_POINTER;indev_drv.read_cb = evdev_read;lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv); /*Create a Demo*/lv_demo_widgets();/*Handle LVGL tasks*/while(1) {lv_timer_handler();usleep(5000);}return 0;
}/*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
uint32_t custom_tick_get(void)
{static uint64_t start_ms = 0;if(start_ms == 0) {struct timeval tv_start;gettimeofday(&tv_start, NULL);start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;}struct timeval tv_now;gettimeofday(&tv_now, NULL);uint64_t now_ms;now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;uint32_t time_ms = now_ms - start_ms;return time_ms;
}
修改 Makefile
- 指定編譯器,因為我在編譯前會設置編譯器環境變量,為避免錯誤,此處注釋掉該配置,使用環境下默認編譯器:
- 添加 lv_drivers.mk,注釋掉鼠標樣式源文件:
- 修改了下構建目標名稱:
- 若編譯過程中出現未識別的編譯選項,如
-Wshift-negative-value
,可刪除-Wshift-negative-value
選項,該選項的作用是檢查左移操作(<<)中可能出現的負數:
編譯運行
- 首先設置交叉編譯鏈的環境變量,執行 make 命令:
- 編譯成功后在工程目錄生成一個可執行文件
lvgl_demo
,將其復制到 IMX6U 開發板上; - 我這里使用 NFS 掛載的方式,將
lvgl_demo
復制到 NFS 工作目錄:
- 啟動 IMX6U,查看 IP,掛載 NFS:
- 切換到
/mnt/
目錄下,運行lvgl_demo
:
- 運行成功:
更多內容
- CSDN博客:@Hello阿爾法
- 嗶哩嗶哩:@Hello阿爾法
- 知乎:@Hello阿爾法