在嵌入式平台上当前还是挺多UI的库可选择,有开源的、闭源的,收费的完全免费的!自己用过的有emWIN,MiniGUI,QT,也有自己实现过的一套UI库。比较早了解了一下LVGL,但并没有深入的了解,以前看起来感觉还是缺少很多UI库的组件,可能用在产品开发中会有一些多的东西需要自己处理。
最近这几年做的产品都有人机交互界面,都涉及到UI界面交互,主要用的是QT,但在嵌入式LINUX系统这一块,QT在内存占用,及在大屏显示,并有UI交互操作时,响应方面都很吃力,借助硬件的2D加速也并不太好进行,高分辨率上,还是需要很多的优化,效果也一般。之前做过一个VGA输出的嵌入式产品,用QT输出时,刷新速度明显很慢,后来低层也是换成DFB才有一些改进,但效果也是一般。
最近在想,做新的产品时还是考虑换其他的UI方案来实现吧,了解了多个UI方案,看了LVGL的DEMO,感觉在嵌入式系统中这UI效果,紧紧一个Demo都感觉很现代,看里面的代码,实现方式,元素属性,控制方式都很现代的感觉。再看代码结构都很简洁,在嵌入式系统中,保持简单性,可以花很少的层次就直代底层,这样的方式,表示我们可以很快,很深入的简单的定制在我们的系统,应用产品中,UI的功能感觉也正好合用。LVGL同时现在更新很快,不像其他的老旧的UI库基本停止更新或几年都难得更新一次,原生控件更是只能用古老来形容,操作体验也是很旧的MFC的风格体验。
https://lvgl.io/
https://github.com/lvgl
这里直接使用最新的一个8.1的版本。
lvgl-8.1.0.tar.gz
LVGL UI库。
lv_drivers-release-v8.1
涉及到底层绘图方式如Framebuffer方式,还是DRM方式,是否使用SDL,输入输出如鼠标,键盘,触摸等。
lv_port_linux_frame_buffer-master,这里使用Framebuffer方式,所以在git上直接下载一个配置好的工程。
lv_demos-release-v8.1 相应的一些demo。
1:解压lv_port_linux_frame_buffer-master在一个目录,在目录中会用空的lv_demos,lv_drivers,lvgl空目录,并有相关的配置文件;
2:解压lvgl-8.1.0.tar.gz ,lv_drivers-release-v8.1,并放在上一步的lv_port中;
3:为了方便与应用集成,我们把LVGL编译成一个库,这里修改一下lv_port里的Makefile,在里面加入下面的一个配置:
lib: $(AOBJS) $(COBJS)
$(AR) rv liblvgl.a $(AOBJS) $(COBJS)
4:这样即可在应用中集成我们的UI了。
如果想在Hi3536c平台上运行lvgl的程序,我们第一步基本需要以下两件事:
这里在PUPANVR工程实现,在PUPANVR里实现了一个hal_media的库,在这个库里实现了硬件相关平台的初始化操作。
下面代码实现运行LVGL的Demo操作:
#include "lvgl/examples/lv_examples.h"
#include "lvgl/lvgl.h"
#include "lvgl/lv_port_indev.h"
#include "lv_drivers/display/fbdev.h"
#include "lv_drivers/indev/evdev.h"
#include "lv_demos/lv_demo.h"
#include
#include
#include
#include
int lvgl_test(void)
{
/*LittlevGL init*/
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 = 1920;
disp_drv.ver_res = 1080;
lv_disp_drv_register(&disp_drv);
//lv_port_indev_init();
/*Create a Demo*/
lv_demo_widgets();
//lv_demo_benchmark();
//lv_demo_keypad_encoder();
//lv_demo_music();
//lv_demo_stress();
//lv_example_arc_1();
/*Handle LitlevGL tasks (tickless mode)*/
while(1) {
lv_task_handler();
usleep(5000);
}
return 0;
}
int main(int argc, char** argv)
{
int ret = 0;
ret = sys_init();
if(ret != 0)
{
LOG(ERROR) << "sys_init failure! ret:" << ret << endl;
return -1;
}
ret = hal_media_init();
if(ret != 0)
{
LOG(ERROR) << "hal_media_init failure!" << endl;
return -1;
}
lvgl_test();
while(1)
{
sleep(1);
}
return 0;
}
hal_media_init初始化了海思平以的操作, lvgl_test即调用lvgl的demo程序。
这里使用lv_drivers/indev/evdev.h方式引入鼠标的支持。
首先在lv_drivers里的USE_EVDEV宏开启,在上面的代码里的lvgl_test()添加一个indev的设备操作注册支持。
lv_indev_t * indev_mouse;
int lv_indev_init()
{
static lv_indev_drv_t indev_drv;
evdev_init();
/*Register a mouse input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = evdev_read;
indev_mouse = lv_indev_drv_register(&indev_drv);
/*Set cursor. For simplicity set a HOME symbol now.*/
lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act());
lv_img_set_src(mouse_cursor, LV_SYMBOL_SETTINGS);
lv_indev_set_cursor(indev_mouse, mouse_cursor);
return 0;
}
在lvgl_test里的 lv_disp_drv_register之及调用lv_indev_init即可!
这样跑起来的Demo就可以UI中使用鼠标交互了!
UI很清新,现代的感觉,很多种现在手机,平台交互的方式都能在上面体现!省去嵌入式系统中,在UI中需要实现特别效果。
从上面使用过程看,LVGL连一个完整的编译工程都没有做好!但这又恰恰表现他的简单性!说不是是缺点,反面更像是优点!
抽像层次很少,很容易移植!没有什么其他的负担!