正点原子RK3568 LVGL移值
由于LVGL是一个免费开源的图形库,且提供了嵌入式易于使用的图形元素、良好的视觉效果和低内存占用等GUI所需的功能。故将LVGL移植至正点原子RK3568开发板,开发一个简单的车辆仪表项目。
1. git代码获取
本文章所克隆的为V8.2的内容,后期再克隆最新版本吧!!!
首先,克隆lv_port_linux仓库:
git clone -b release/v8.2 https://github.com/lvgl/lv_port_linux.git
lv_port_linux仓库克隆完成后,执行如下指令克隆lvgl及lv_drivers:
git submodule update --init --recursive
2. lvgl 配置
lvgl配置主要是针对lv_conf.h与lv_drv_conf.h的内容进行配置。
- lv_conf.h用于配置LVGL图形库本身如内存、界面、组件等功能;
- lv_drv_conf.h用于配置LVGL所提供的硬件如显示屏、触摸、输入等驱动。
因此,根据实际需求将对上述两个文件进行配置,详细配置如下所示:
2.1 lv_confg.h配置
-
使能文件内容
将开头的 #if 0 更改为 #if 1 以使能其内容
-
修改色彩深度
根据自己设备所能支持的色彩深度进行设置:
-
使能显存
将LV_MEM_CUSTOM设置为1, 使系统能为LCD屏分配运行显存:
-
修改屏幕刷新时间
LVGL提供屏幕刷新时间设定,可根据自己需求进行刷新与读周期时间的更改:
-
使能demo
LVGL提供测试demo,可以使能LVGL所提供的demo进行功能验证:
注意:在lvgl_conf.h中还提供丰富的功能配置,可根据实际需求自行配置!!!
2.2 lv_drv_conf.h配置
- 使能文件内容
将开头的 #if 0 更改为 #if 1 以使能其内容
- 显示驱动
由于开发板的显示系统使用DRM(Direct Rendering Module)框架,因此需关闭USE_FBDEV并打开USE_DRM,配置详细如下图所示:
如何判断显示系统使用何种框架:
- 输入如下命令,查看屏幕是否出现雪花,若出现雪花则使用了fb0, 即FBD框架
cat /dev/random > /dev/fb0
-
触摸驱动
若需使用触摸功能,则需要对触摸进行配置:
a. 使能触摸
将USE_EVDEV置1,打开触摸功能:
b. 修改驱动
根据开发板的实际触摸驱动进行EVEDV_NAME的修改。如下图所示,开发板触摸设备为event2,从而将EVEDV_NAME的内容修改为 ”/dev/input/event2"。
若不知道当前触摸屏驱动名,则可通过hexdump命令查询当前触摸驱动,如输入hexdump /dev/input/event2后触摸屏幕,若存在数据显示则代表为设备驱动,否则继续测试其他设备驱动,adb显示效果如图所示:
3. main.c 修改
main.c为lvgl中的默认程序,特此用于测试lvgl移植是否完成。同时,由于开发采用drm框架进行显示,所以需要对main.c进行修改,详细修改内容如下:
#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "lv_drivers/display/drm.h" /* 添加drm.h头文件 */
#include "lv_drivers/indev/evdev.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#define DISP_BUF_SIZE (1080 * 1920) /* 根据实际屏幕大小进行设置 */
int main(void)
{
/*LittlevGL init*/
lv_init();
/*Linux frame buffer device init*/
drm_init(); // fvdev_init -> drm_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 = drm_flush; /* fbdev_flush -> drm_flush */
disp_drv.hor_res = 1080;
disp_drv.ver_res = 1920;
lv_disp_drv_register(&disp_drv);
evdev_init();
static lv_indev_drv_t indev_drv_1;
lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/
indev_drv_1.type = LV_INDEV_TYPE_POINTER;
/*This function will be called periodically (by the library) to get the mouse position and state*/
/*未使用鼠标,故注释该程序段*/
#if 0
indev_drv_1.read_cb = evdev_read;
lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1);
/*Set a cursor for the mouse*/
LV_IMG_DECLARE(mouse_cursor_icon)
lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */
lv_img_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/
lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image object to the driver*/
#endif
/*Create a Demo*/
lv_demo_widgets();
/*Handle LitlevGL tasks (tickless mode)*/
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;
}
4. 编译
4.1 makefile修改
CC设置为正点原子RK3568开发板的编译链,如:
CC = /opt/atk-dlrk3568-5_10_sdk-toolchain/bin/aarch64-buildroot-linux-gnu-gcc
4.2 make
make -j4
4.3 编译报错处理
通过make进行编译时会出现.h文件未发现及变量未定义等错误,其解决方法如下:
-
drm.h、drm_fourcc.h、drm_mode.h未发现

由于drm.h、drm_fourcc.h、drm_mode.h存放于"/opt/atk-dlrk3568-5_10_sdk-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/include/drm" 路径中,但头文件引用时仅在“/opt/atk-dlrk3568-5_10_sdk-toolchain/aarch64-buildroot-linux-gnu/sysroot/usr/include”路径下进行查找,故未发现.h文件。因此,可直接修改.h文件代码,如下图所示:
或者,可将缺失文件直接拷贝至include路径下。 -
undefined reference
因编译时drm相关链接器不能自动加载,从而出现与drm相关的undefined reference报错,如下所示:
/opt/atk-dlrk3568-5_10_sdk-toolchain/bin/../lib/gcc/aarch64-buildroot-linux-gnu/10.4.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: /home/royal/Program/lv_port_linux/lv_drivers/display/drm.o: in function `drm_allocate_dumb':
drm.c:(.text+0x78): undefined reference to `drmIoctl'
/opt/atk-dlrk3568-5_10_sdk-toolchain/bin/../lib/gcc/aarch64-buildroot-linux-gnu/10.4.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: drm.c:(.text+0xac): undefined reference to `drmIoctl'
/opt/atk-dlrk3568-5_10_sdk-toolchain/bin/../lib/gcc/aarch64-buildroot-linux-gnu/10.4.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: drm.c:(.text+0x11c): undefined reference to `drmModeAddFB2'
/opt/atk-dlrk3568-5_10_sdk-toolchain/bin/../lib/gcc/aarch64-buildroot-linux-gnu/10.4.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: /home/royal/Program/lv_port_linux/lv_drivers/display/drm.o: in function `drm_add_crtc_property.isra.0':
drm.c:(.text+0x234): undefined reference to `drmModeAtomicAddProperty'
/opt/atk-dlrk3568-5_10_sdk-toolchain/bin/../lib/gcc/aarch64-buildroot-linux-gnu/10.4.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: /home/royal/Program/lv_port_linux/lv_drivers/display/drm.o: in function `drm_add_plane_property.isra.0':
drm.c:(.text+0x324): undefined reference to `drmModeAtomicAddProperty'
......
若出现该报错,则在Makefile文件中添加LDFLAGS += -ldrm,实现的drm链接器加载。
LDFLAGS += -ldrm
5. 上传
打开cmd,使用adb push demo资源到指定路径XXX(自定义)。
adb push ./demo XXX
6. 运行
上传成功后,可通过adb shell进入adb界面,为demo赋可执行权限后,便可运行demo, 详细步骤如下:
adb shell
root@ATK-DLRK3568:/# chmod +x xxx/demo
root@ATK-DLRK3568:/# ./xxx/demo
若demo正常运行,显示如下图所示:
注意:由于,当前开发板未关闭系统自带QT,所以需先kill系统U进程后,再运行demo。否则,demo显示内容不能持续显示,仅闪烁一次便被systemui抢占。
root@ATK-DLRK3568:/# killall systemui
7. 运行效果
显示效果如下图所示:
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)