Tina Linux 与 LVGL
关于 LVGL
LVGL 是一个免费的开源图形库,提供了创建嵌入式 GUI 所需的一切,具有易于使用的图形元素,美观的视觉效果和低内存占用,采用 MIT 许可协议,可以访问LittlevGL获取更多资料。
- 强大的构建块:按钮、图表、列表、滑块、图像等。
- 高级图形引擎:动画、抗锯齿、不透明度、平滑滚动、混合模式等。
- 支持各种输入设备:触摸屏、鼠标、键盘、编码器、按钮等。
- 支持多显示器。
- 独立于硬件,可与任何微控制器和显示器一起使用。
- 可扩展以使用少量内存(64 kB 闪存、16 kB RAM)运行。
- 多语言支持,支持 UTF-8 处理、CJK、双向和阿拉伯语。
- 通过类 CSS 样式完全可定制的图形元素。
- 受 CSS 启发的强大布局:Flexbox 和 Grid。
- 支持操作系统、外部内存和 GPU,但不是必需的。
- 使用单个帧缓冲区也能平滑渲染。
- 用 C 编写并与 C++ 兼容。
- Micropython Binding 在 Micropython 中公开 LVGL API。
- 可以在 PC 上使用模拟器开发。
- 100 多个简单的例子。
- 在线和 PDF 格式的文档和API参考。
目前 Tina Linux 中移植了 LVGL 8.3.2 核心组件与 Demo,下表列出 LVGL 相关库说明:
包名 | 说明 |
---|---|
lv_demos | lvgl的官方demo |
lv_drivers | lvgl的官方设备驱动程序,集成了sunxifb和sunximem |
lv_examples | lvgl测试用例,最终调用的是lv_demos中的函数 |
lvgl | lvgl核心库 |
sunxifb.mk | 公共配置文件,写应用Makefile时需要包含进去 |
LVGL 配置
make menuconfig
然后做如下配置
Gui --->
Littlevgl --->
<*> lv_examples (lvgl官方demo)
-*- lvgl-8.3.2 use sunxifb double buffer (使能双缓冲,解决撕裂问题)
[ ] lvgl-8.3.2 use freetype (自动链接freetype)
LVGL 源码框架
LVGL 源码位于 platform/thirdparty/gui/lvgl-8
, 其框架如图:
sunxifb
在 sunxifb
中,我们提供了一组显示接口,如下:
接口 | 说明 |
---|---|
sunxifb_init | 该函数主要功能是初始化显示引擎。带一个旋转参数,使能g2d旋转的话,就用这个参数指定旋转方向 |
sunxifb_exit | 该函数比较简单,实现关闭cache ,关闭g2d ,释放旋转buffer ,关闭fb0 |
sunxifb_flush | 该函数比较重要,负责把draw buffer 拷贝到back buffer 中,并且绘制最后一帧后,交换front 与back buffer 。应用不要调用该函数 |
sunxifb_get_sizes | 该函数获取屏幕分辨率,这样应用程序就可以不用写死初始化时的分辨率了 |
sunxifb_alloc | 该函数主要用来申请系统绘图内存,使能部分g2d 功能后,会申请连续物理内存 |
sunxifb_free | 该函数用来释放sunxifb_alloc 申请的内存 |
代码位置如下:
platform/thirdparty/gui/lvgl-8/lv_drivers/display/sunxifb.c
在sunxifb_init(rotated)
,中rotated
的旋转值可以为:
LV_DISP_ROT_NONE
,LV_DISP_ROT_90
,LV_DISP_ROT_180
,LV_DISP_ROT_270
。
最后还有赋值 disp_drv.rotated = rotated
。如果没有g2d旋转,也可以指定disp_drv.sw_rotate = 1
使用软件旋转。
sunximem
在sunximem
中,实现了管理物理内存的封装,这些函数都不需要应用调用,但能加深对整个框架的理解,如下:
接口 | 说明 |
---|---|
sunxifb_mem_init | 该函数会在sunxifb_init 中调用,初始化物理内存申请接口,使用的是 libuapi 中间件 |
sunxifb_mem_deinit | 该函数通过调用 SunxiMemClose ,释放申请的接口资源 |
sunxifb_mem_alloc | 该函数比较重要,许多地方都会用到,需要传入申请的字节数和使用说明 |
sunxifb_mem_free | 该函数用来释放调用 sunxifb_mem_alloc 申请的内存 |
sunxifb_mem_get_phyaddr | 该函数把 sunxifb_mem_alloc 申请内存的虚拟地址转换为物理地址,g2d 驱动只接受 buffer 的物理地址或者fd |
sunxifb_mem_flush_cache | 该函数用来刷 sunxifb_mem_alloc 申请buffer 的 cache |
代码位置如下:
platform/thirdparty/gui/lvgl-8/lv_drivers/display/sunxigmem.c
因为g2d
驱动只能使用物理连续内存,因此解码图片时,必须要通过 sunxifb_mem_alloc
来申请内存。
当前只实现了bmp、png和gif图片的内存申请,jpeg图片暂未实现
当使用 lv_canvas_set_buffer
时,传入的 buffer
需要是 sunxifb_alloc
申请的 buffer
,sunxifb_alloc
中会判断是否需要申请物理连续内存。
自定义画布lv_canvas暂未对接g2d缩放功能
evdev
触摸我们用的是lvgl
官方的evdev
代码位置如下:
platform/thirdparty/gui/lvgl-8/lv_drivers/indev/evdev.c
在应用lv_drv_conf.h
中修改EVDEV_NAME
为触摸屏对应生成的event
节点,例如lv_examples
的配置文件:
platform/thirdparty/gui/lvgl-8/lv_examples/src/lv_drv_conf.h
另外也可以用命令生成软连接touchscreen
,就会直接以 touchscreen
为触摸节点,方便调试:
ln -s /dev/input/eventX /dev/input/touchscreen
LVGL运行
我们提供了几个测试用例,直接执行:
lv_examples 0
lv_examples 0, is lv_demo_widgets
lv_examples 1, is lv_demo_music
lv_examples 2, is lv_demo_benchmark
lv_examples 3, is lv_demo_keypad_encoder
lv_examples 4, is lv_demo_stress
lv_g2d_test
lv_g2d_test 0 5 0 1
one num is rotate, range is 0~3
tow num is gif, range is 0~11, 11 is no show gif
three num is bmp, range is 0~2, 2 is no show bmp
four num is png, range is 0~3, 3 is no show png
lv_monitor
在初始化时,会有如下打印,根据配置的不同会有差异,表示打开了某项配置:
wh=1280x800, vwh=1280x1600, bpp=32, rotated=0
Turn on double buffering.