项目背景
项目是一款车载HIFI播放器,平台是RK3128的嵌入式Linux。 资源有限,不想用QT等大型GUI开发工具,于是乎想到了经常用来写嵌入式项目的LVGL, LVGL用在这种情况下是最合适的,资源占用少,功能够用。 GUI开发的应用层面解决了,剩下就看底层怎么实现由于不安装任何GUI桌面,所以直接对设备的 底层进行开发,这时候Linux的帧缓冲器设备就派上用场了,下面来简单介绍各个技术的情况。
LVGL图形库
LVGL是一个图形库,面向资源有限的微控制器。但是,可以使用它来创建具有高端微处理器和运行Linux操作系统的电路板的嵌入式GUI。最知名的处理器内核是ARM Cortex A9(例如NXP i.MX6)和ARM Cortex A53(例如Raspbery PI 3)。您只需使用 Linux 的帧缓冲器设备(通常为 /dev/fb0),即可在此单板计算机上创建嵌入式 GUI。
为什么直接使用帧缓冲器?
帧缓冲器设备是一个非常低级的接口,用于在屏幕上显示某些内容。谈到嵌入式 GUI,直接使用帧缓冲区而不是窗口管理器有几个原因:
- 简单 只需将像素写入内存即可
- 快 没有窗口管理器,这意味着快速启动和更少的开销
- 便携式 独立于发行版,每个Linux系统都有一个帧缓冲器设备,因此它与所有系统兼容
开始使用 Linux 帧缓冲区
也许您熟悉Linux帧缓冲器设备。它是一个通常位于 /dev/fb0
的文件。
此文件包含显示器的像素数据。如果将某些内容写入帧缓冲区文件,
则更改将显示在显示屏上。
如果您在PC上使用Linux,则可以使用终端进行尝试:
按 Ctrl + Alt + F1
离开桌面并更改为简单字符终端
键入并键入您的密码sudo su
停止你的显示管理器(在Ubuntu上它是lightdm):
重要提示:它会把你注销,所以所有窗口都会关闭
service lightdm stop
将随机数据写入帧缓冲器设备:您应该在整个屏幕上看到随机彩色像素。
cat /dev/urandom > /dev/fb0
要返回到正常的图形用户界面:
service lightdm start
使用 urandom 的 Linux 帧缓冲区中的随机像素
它应该在基于Linux的单板计算机上工作
获取 LVGL 以创建嵌入式 GUI
现在,您知道如何更改显示器上的像素。
但是您仍然需要一些创建GUI元素而不是随机像素的东西。LVGL进入了画面。
该软件库设计用于在嵌入式系统的显示屏上创建GUI元素(如标签,按钮,图表,滑块,复选框等)。
在此处检查所有小部件。图形库是用C语言编写的,因此您肯定可以在项目中对其进行调整。
可以添加使您的GUI令人印象深刻的不透明度,流畅的动画,抗锯齿和阴影。
要使用LVGL,您需要从GitHub克隆它或从开发人员页面获取。将需要以下组件:
-
lvgl 图形库的核心
-
lv_drivers 包含一个 Linux 帧缓存器驱动程序
-
lv_examples(可选)加载演示应用程序以进行测试
图形用户界面项目设置
在 Linux PC 上测试基于 GUI 的帧缓冲器设备的最简单情况。稍后,您也可以在嵌入式设备上应用相同的代码。
在首选的 IDE 中创建新项目
复制 lvgl 旁边的模板配置文件,并lv_drivers文件夹:
lvgl/lv_conf_templ.h as lv_conf.h
lv_drivers/lv_drv_conf_templ.h
作为lv_drv_conf.h
在配置文件中,删除第一个和最后一个#if,并#endif以启用其内容。
在lv\_drv\_conf.h
中设置USE_FBDEV 1
在 lv_conf.h 中更改颜色深度:LV_COLOR_DEPTH 32
将项目根文件夹添加为包含路径
创建嵌入式 GUI 应用程序
在 main.c编写以下代码来创建 hello world 标签:
#include "lvgl/lvgl.h"
#include "lv_drivers/display/fbdev.h"
#include <unistd.h>
int main(void)
{
/*LVGL 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 = 800;
disp_drv.ver_res = 480;
lv_disp_drv_register(&disp_drv);
/*Create a "Hello world!" label*/
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Hello world!");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
/*Handle LitlevGL tasks (tickless mode)*/
while(1) {
lv_tick_inc(5);
lv_timer_handler();
usleep(5000);
}
return 0;
}
编译代码并返回字符终端模式(Ctrl + Alt + F1
和service lightdm stop
)
转到构建的可执行文件并键入:./file_name
使用演示应用程序进行测试,方法是将 Hello world 标签替换为:demo_create();
下载即用型项目
在lv_port_linux_frame_buffer
存储库中,您可以找到一个Eclipse CDT项目,用于在Linux PC上试用基于普通帧缓冲区的GUI。
还有一个Makefile可以在没有IDE的情况下在嵌入式硬件上编译项目。
隐藏光标
您可能会在屏幕上看到闪烁的光标。隐藏它的方式取决于平台,但作为一个例子,你可以看到如何在Raspberry上做到这一点:
编辑文件/boot/cmdline.txt
vt.global_cursor_default=0
总结
我希望您喜欢本教程,并发现它对基于微处理器的嵌入式Linux项目很有用。正如你所看到的,使用LVGL创建一个嵌入式GUI是非常容易的,只使用一个普通的Linux帧缓冲区。
要了解有关图形库的更多信息,请开始阅读文档:https://docs.lvgl.io
如果您现在没有嵌入式硬件,则可以在PC上开始GUI开发。