侧边栏壁纸
博主头像
李振洋的博客博主等级

歌颂动荡的青春

  • 累计撰写 38 篇文章
  • 累计创建 6 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

IMX6ULL开发板移植LVGL v9

IMX6ULL开发板移植LVGL v9

基于韦东山的IMX6ULL Pro开发板,使用framebuffer

准备材料

IMX6ULL Pro开发板 7寸触摸屏

Cmake V3.12.4以上的版本

arm gcc交叉编译环境 arm-buildroot-linux-gnueabihf-gcc (Ubuntu18.04)

lvgl v9源码

移植

  1. 克隆lv_port_linux仓库并安装lvgl子模块

# 克隆lv_port_linux仓库并安装lvgl子模块
git clone https://github.com/lvgl/lv_port_linux.git
cd lv_port_linux_frame_buffer/
git submodule update --init --recursive
  1. 修改lv_port_linux_frame_buffer根目录的CMakeLists.txt文件

cmake_minimum_required(VERSION 3.10)

# 设置交叉编译
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# 设置编译器的路径,必须是绝对路径
set(CMAKE_C_COMPILER /home/lucas/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin/arm-buildroot-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER /home/lucas/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin/arm-buildroot-linux-gnueabihf-g++)



project(lvgl)

set(CMAKE_C_STANDARD 99)#C99 # lvgl officially support C99 and above
set(CMAKE_CXX_STANDARD 17)#C17
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

add_subdirectory(lvgl)
target_include_directories(lvgl PUBLIC ${PROJECT_SOURCE_DIR})

add_executable(main main.c mouse_cursor_icon.c)

#include(${CMAKE_CURRENT_LIST_DIR}/lvgl/tests/FindLibDRM.cmake)
#include_directories(${Libdrm_INCLUDE_DIRS})

#find_package(SDL2)
#find_package(SDL2_image)
#include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS})

target_link_libraries(main lvgl lvgl::examples lvgl::demos lvgl::thorvg ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES} ${Libdrm_LIBRARIES} m pthread)
add_custom_target (run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main DEPENDS main)
  1. 修改lv_conf.h

// 屏幕色深
#define LV_COLOR_DEPTH 32

// 14毫秒刷新一次
#define LV_DEF_REFR_PERIOD  14 

// 建议关闭
#define LV_USE_ASSERT_STYLE         0
#define LV_USE_ASSERT_MEM_INTEGRITY 0
#define LV_USE_ASSERT_OBJ           0

// 对象样式缓存默认0,设置20
#define LV_OBJ_STYLE_CACHE      20

// 显示帧率和cpu使用情况
#define LV_USE_PERF_MONITOR 1
#define LV_USE_MEM_MONITOR 1

// 开启framebuffer,确保这一项是开启的,如果要使用DRM驱动,配置LV_USE_LINUX_DRM 1
#define LV_USE_LINUX_FBDEV      1

// 开启输入设备驱动
#define LV_USE_EVDEV    1
  1. 修改mian.c

#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "lvgl/examples/lv_examples.h"
#include <src/core/lv_obj_pos.h>
#include <src/lv_api_map_v8.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

static const char * getenv_default(const char * name, const char * dflt)
{
    return getenv(name) ?: dflt;
}

#if LV_USE_LINUX_FBDEV
static void lv_linux_disp_init(void)
{
	// framebuffer默认为/dev/fb0
    const char * device = getenv_default("LV_LINUX_FBDEV_DEVICE", "/dev/fb0");
    lv_display_t * disp = lv_linux_fbdev_create();

    lv_linux_fbdev_set_file(disp, device);
}
#elif LV_USE_LINUX_DRM
static void lv_linux_disp_init(void)
{
    const char * device = getenv_default("LV_LINUX_DRM_CARD", "/dev/dri/card0");
    lv_display_t * disp = lv_linux_drm_create();

    lv_linux_drm_set_file(disp, device, -1);
}
#elif LV_USE_SDL
static void lv_linux_disp_init(void)
{
    const int width  = atoi(getenv("LV_SDL_VIDEO_WIDTH") ?: "800");
    const int height = atoi(getenv("LV_SDL_VIDEO_HEIGHT") ?: "480");

    lv_sdl_window_create(width, height);
}
#else
#error Unsupported configuration
#endif

static int led_fd;
typedef struct
{
    bool status;
    // 可以添加更多自定义变量
} custom_data_t;

static void event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * obj       = lv_event_get_target(e);
    char led_status;
    if(code == LV_EVENT_CLICKED) {
        LV_LOG_USER("Clicked");
        custom_data_t * retrieved_data = (custom_data_t *)lv_obj_get_user_data(obj);
        led_fd                         = open("/dev/bsp_led", O_RDWR);
        if(led_fd == -1) {
            LV_LOG_USER("can not open led_drv");
        }
        if(retrieved_data->status) {
            led_status = 0;

        } else {
            led_status = 1;
        }
        write(led_fd, &led_status, 1);
        retrieved_data->status = led_status;
        lv_obj_set_user_data(obj, retrieved_data);
        close(led_fd);
        printf("LV_EVENT_CLICKED");
    }
}

void user_demo()
{
    lv_obj_t * led_btn = lv_button_create(lv_screen_active());
    lv_obj_set_size(led_btn, 60, 48);
    lv_obj_center(led_btn);
    lv_obj_add_event_cb(led_btn, event_handler, LV_EVENT_ALL, NULL);

    custom_data_t * data = malloc(sizeof(custom_data_t));
    data->status         = false;
    lv_obj_set_user_data(led_btn, data);

    lv_obj_t * label = lv_label_create(led_btn);
    lv_label_set_text(label, "LED");
    lv_obj_center(label);
}
int main(void)
{
    lv_init();

    /*Linux display device init*/
    lv_linux_disp_init();

    // 触摸   可以使用hexdump /dev/input/eventx命令检查触摸是那个设备文件
    lv_indev_t * indev = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event1");

    /*Create a Demo*/
    lv_demo_music();
    /*Handle LVGL tasks*/
    while(1) {
        lv_timer_handler();
        usleep(5000);
    }

    return 0;
}
  1. 编译

mkdir build
cd build 
cmake ..
make -j

可执行文件为bin目录下的main

  1. 拷贝到开发板并运行

挂载网络文件系统

mount -t nfs -o nolock,vers=3 192.168.5.11:/home/lucas/nfs_rootfs /mnt

运行

./main

开机自动运行lvgl

编写启动脚本

#!/bin/sh
#
# Start lvgl....
#

start() {
        printf "Starting lvgl: "
        echo -n -e '\e[?17;14;224c'

        echo 0 > /sys/class/graphics/fbcon/cursor_blink
		echo -e "\033[9;0]" > /dev/tty0
        start-stop-daemon -S -q -m -b -p /var/run/lvgl.pid \
                        -x /usr/lvgl/main
      [ $? = 0 ] && echo "OK" || echo "FAIL"
}

stop() {
        printf "Stopping lvgl: "
        start-stop-daemon -K -q -p /var/run/lvgl.pid \
                          -x /usr/lvgl/main
        [ $? = 0 ] && echo "OK" || echo "FAIL"
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart|reload)
        stop
        start
        ;;
  *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac

exit $?

0

评论区