概括
LVGL(Light and Versatile Graphics Library)是一个开源轻量级显示框架,支持多类型显示设备&&输入设备,作为一个开源图形库,自带了三十多种小组件供开发者使用。兼容低配置的嵌入式开发,可以以极低的配置要求完成丝滑动画。LVGL其强大的功能,使得它在物联网设备中应用比比皆是。
前一阵子开发了润和hispark_pegasus Hi3861开发板上的SSD1306,其提供的开发库开发起来还是较为困难,于是想尝试将LVGL移植到OpenHarmony轻量化系统上,便于后续OpenHarmony物联网设备的屏幕开发,大大降低屏幕开发的时间成本。
本文章将简单介绍LVGL的主要开发流程,OpenHarmony->LVGL的具体移植期待后续文章。
初始化
概括
LVGL的初始化主要流程为以下步骤:
- 调用lv_init()。
- 初始化驱动程序
- 初始化显示驱动和输入设备驱动程序。
- 设置一个定时器,每隔n(1-10)毫秒调用lv_tick_inc(n)以告知lvgl经过时间,该线程需要高于第五步的优先级。
- 主程序中每隔数毫秒(5ms)调用lv_timer_handler()处理LVGL界面(绘制显示界面,读取输入设备信息,展示动画等)。
初始化显示驱动
初始化lv_disp_draw_buf_t && lv_disp_drv_t这两个结构体然后对应初始化绘制缓冲区的内部图形缓冲区,显示驱动程序。
初始化缓存区
对于lv_disp_draw_buf_t:
更大的缓冲区能带来更高的性能,但超过1/10屏幕大小的缓冲区之后性能没有显著提升,因而建议稍微大于1/10屏幕大小的缓冲区即可.
只使用一个缓冲区,那么需要等待LVGL刷新了之后才能渲染下一帧.而使用到两个缓冲区后,LVGL可以同时进行刷新和渲染。
初始化显示驱动程序
对于lv_disp_drv_t:
初始化中可以启用 full_refresh 以强制 LVGL 始终重绘整个屏幕。这适用于单/双缓冲模式。
如果启用该模式并提供 2 个屏幕大小的绘制缓冲区,LVGL 的显示处理就像“传统”双缓冲一样工作。
这意味着在 flush_cb 中只有帧缓冲区的地址需要更改为提供的指针(color_p 参数)。 如果 MCU 具有 LCD 控制器外围设备而不是外部显示控制器(例如 ILI9341 或 SSD1963),则应使用此配置。
初始化流程
对于上面的缓冲区初始化完成之后,可以初始化显示驱动结构体lv_disp_drv_t。
- 用lv_disp_drv_init(&disp_drv)初始化。
- 以下的变量必须初始化。
- 指向上一章显示缓存的指针的 draw_buf 。
- hor_res 显示器的水平分辨率(以像素为单位)。
- ver_res 显示器的垂直分辨率(以像素为单位)。
- flush_cb 一个回调函数,用于将缓冲区的内容复制到显示器的特定区域。
- 需要在LVGL中用lv_disp_drv_register(&disp_drv)注册。
lv_disp_flush_ready(&disp_drv) 需要在刷新准备好时调用。 LVGL 可能会以多个块呈现屏幕,因此多次调用 flush_cb。要查看当前是否是渲染的最后一个块,请使用 lv_disp_flush_is_last(&disp_drv)。
结构体其余成员
对于lv_disp_drv_t对象而言,还有一些可选择的成员可以修改:
- color_chroma_key 将在镀铬键控图像上绘制为透明的颜色。从lv_conf.h默认设置为LV_COLOR_CHROMA_KEY。
- anti_aliasing 使用抗锯齿(边缘平滑)。如果在 lv_conf.h 中将 LV_COLOR_DEPTH 设置为至少 16,则默认启用。
- rotated 和 sw_rotate 硬件旋转屏幕和软件旋转屏幕.sw_rotate 置为1时执行旋转.
- screen_transp 如果 1 屏幕本身也可以具有透明度。 LV_COLOR_SCREEN_TRANSP 需要在 lv_conf.h 中启用并且需要 LV_COLOR_DEPTH 32。
- user_data 驱动程序的自定义void 用户数据…
- rounder_cb 四舍五入要重绘的区域的坐标。例如。 2x2 px 可以转换为 2x8。 如果显示控制器只能刷新具有特定高度或宽度的区域(单色显示器通常为 8 像素高度),则可以使用它。
- set_px_cb 一个自定义函数来写入绘制缓冲区。如果显示器具有特殊的颜色格式,它可用于将像素更紧凑地存储在绘图缓冲区中。 (例如 1 位单色、2 位灰度等) 这样,lv_disp_draw_buf_t 中使用的缓冲区可以更小,以仅容纳给定区域大小所需的位数。请注意,使用set_px_cb 渲染比普通渲染慢。
- monitor_cb 一个回调函数,告诉我们在多长时间内刷新了多少像素。当最后一个块被渲染并发送到显示器时调用。
- clean_dcache_cb 用于清理与显示相关的任何缓存的回调。
样例
初始化输入设备驱动
对于输入设备,首先要区分是何种类型输入设备,不同输入设备都有不同的初始化驱动API
LVGL将输入设备分成了四种类型:
- LV_INDEV_TYPE_POINTER 触摸板或鼠标。
- LV_INDEV_TYPE_KEYPAD 键盘。
- LV_INDEV_TYPE_ENCODER 编码器,带有左/右转和推动选项。
- LV_INDEV_TYPE_BUTTON 外部按钮。
初始化输入设备结构体lv_indev_drv_t
触摸板,鼠标
对于触摸板,鼠标等指针类的输入设备,他们的回调函数可以如下设置。
若是需要显示光标,则如下:
编码器
使用编码器可以做到以下事件:
- 按下按钮
- 长按按钮
- 左转
- 右转
- 注册一个带有 LV_INDEV_TYPE_ENCODER 类型的 read_cb 函数。
- 必须创建一个对象组:lv_group_t * g = lv_group_create() 并且对象必须使用 lv_group_add_obj(g, obj) 添加到其中。
- 创建的组必须分配给输入设备:lv_indev_set_group(my_indev, g)(my_indev 是 lv_indev_drv_register 的返回值)。
睡眠管理
由于屏幕驱动会占用系统的大量资源,所以在不需要屏幕驱动时,可以选择睡眠LVGL子系统,减少对资源的占用时,可以参考以下代码:
当需要唤醒时,对输入设备进行操作以唤醒LVGL。
将下面代码加入输入设备读取功能里面。