项目背景

项目是一款车载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 + F1service 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开发。

源码:https://github.com/lvgl/lv_port_linux_frame_buffer