Linux使用/dev/fb0 设备显示LVGL图形
1:使用SquareLine导出project工程
根据自己的TFT屏幕,设置工程:屏幕大小128x160 ,颜色格式RGB565,所以颜色深度是16位
SquareLine默认使用的是SDL库来显示,所以导出的工程需要修改成使用fb设备来显示
2:打开导出的源码,修改部分内容
2.1:修改 lv_drv_conf.h
第一处:
#ifndef USE_SDL
# define USE_SDL 0 //关闭SDL库,设置为0
#endif
/* Hardware accelerated SDL driver */
#ifndef USE_SDL_GPU
# define USE_SDL_GPU 0
#endif
#if USE_SDL || USE_SDL_GPU
# define SDL_HOR_RES 128
# define SDL_VER_RES 160
/* Scale window by this factor (useful when simulating small screens) */
# define SDL_ZOOM 1
/* Used to test true double buffering with only address changing.
* Use 2 draw buffers, bith with SDL_HOR_RES x SDL_VER_RES size*/
# define SDL_DOUBLE_BUFFERED 0
/*Eclipse: <SDL2/SDL.h> Visual Studio: <SDL.h>*/
# define SDL_INCLUDE_PATH <SDL2/SDL.h>
/*Open two windows to test multi display support*/
# define SDL_DUAL_DISPLAY 0
#endif
第二处:
/*-----------------------------------------
* Linux frame buffer device (/dev/fbx)
*-----------------------------------------*/
#ifndef USE_FBDEV
#define USE_FBDEV 1 //打开fb设备驱动
#endif
#if USE_FBDEV
#define FBDEV_PATH "/dev/fb0"
# define SDL_HOR_RES 128 //增加设置屏幕长宽,此处定义是从SDL定义内拷贝过来的
# define SDL_VER_RES 160 //增加设置屏幕长宽
#endif
2.2:打开main.c
对照以下内容修改
/**
* @file main
*
*/
/*********************
* INCLUDES
*********************/
#define _DEFAULT_SOURCE /* needed for usleep() */
#include <unistd.h>
#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/
#include <SDL2/SDL.h>
#include "lvgl/lvgl.h"
#include "lv_drivers/sdl/sdl.h"
#include "ui/ui.h"
#include "lv_drivers/display/fbdev.h" //新增此头文件
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void hal_init(void);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* VARIABLES
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
int main(int argc, char **argv)
{
(void)argc; /*Unused*/
(void)argv; /*Unused*/
/*Initialize LVGL*/
lv_init();
/*Initialize the HAL (display, input devices, tick) for LVGL*/
hal_init();
ui_init();
while(1) {
/* Periodically call the lv_task handler.
* It could be done in a timer interrupt or an OS task too.*/
lv_tick_inc(5); //新增此函数,此函数可以放在这里,也可以放在其他周期性中断里面,反正就是5ms调用一次即可
lv_timer_handler();
usleep(5 * 1000);
}
return 0;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Initialize the Hardware Abstraction Layer (HAL) for LVGL
*/
static void hal_init(void)
{
/* Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/
#if USE_SDL
sdl_init(); //屏蔽了SDL
#endif
#if USE_FBDEV
fbdev_init(); //开启了fbdev
#endif
/*Create a display buffer*/
static lv_color_t buf[SDL_HOR_RES * SDL_VER_RES];
static lv_disp_draw_buf_t disp_draw_buf;
lv_disp_draw_buf_init(&disp_draw_buf, buf, NULL, SDL_HOR_RES * SDL_VER_RES);
/*Create a display*/
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.draw_buf = &disp_draw_buf;
// disp_drv.flush_cb = sdl_display_flush;
disp_drv.flush_cb = fbdev_flush; //修改了此处刷新画面控制回调
disp_drv.hor_res = SDL_HOR_RES;
disp_drv.ver_res = SDL_VER_RES;
lv_disp_drv_register(&disp_drv);
#if 0 //屏蔽了此处输入设备的代码
/* Add a mouse as input device */
static 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 = sdl_mouse_read;
indev_drv.read_cb = NULL;
lv_indev_drv_register(&indev_drv);
#endif
}
2.3 执行make clean && make -j8
根据这个第一次在linux下编译LVGL工程的方式
编译的时候如果报和sdl有关的错误, 说明程序编译了sdl的代码,在 .mk文件里面把编译sdl相关代码的指令关掉再重试
然后运行程序记得加上sudo
如果运行之后报错: ioctl(FBIOBLANK): Invalid argument ,则打开fbdev.c 找到报错信息的那一段函数屏蔽掉
//Make sure that the display is on.
//此函数是亮屏的操纵,如果报错可以屏蔽掉,但是得确保TFT屏幕已经亮了
if (ioctl(fbfd, FBIOBLANK, FB_BLANK_UNBLANK) != 0) {
perror("ioctl(FBIOBLANK)");
return;
}