- 概述
LVGL是由Gábor Kiss-Vámosi于2016年创建的一个开源项目,目前由来自世界各地的志愿者共同维护和开发。LVGL是用C语言编写的,遵循MIT协议,可以自由地使用和修改。LVGL支持多种操作系统,例如Linux、Windows、RTOS等,也可以在开发板上运行。LVGL还支持多种显示器驱动器和触摸屏驱动器,可以与不同大小和分辨率的显示器兼容。LVGL还提供了多种语言的绑定,例如Python、Micropython、JavaScript等,以及多种开发工具,例如模拟器、视觉化设计器、字体转换器等。
LVGL的主要特点有:
-- 轻量级:LVGL只需要少量的记忆体和运算资源,可以在低端的微控制器上运行。
-- 多功能:LVGL提供了超过40种控件,例如按钮、滑块、列表、图表等,以及多种主题、动画、字体、图像等元素,可以创建各种风格和效果的GUI。
-- 灵活性:LVGL采用了面向对象的设计,可以方便地创建和管理GUI的组件和属性。LVGL还支持自动和手动布局,可以适应不同的显示器和方向。LVGL还支持事件驱动和回调函数,可以实现GUI的交互和逻辑。
-- 可移植:LVGL可以在不同的硬件和软件平台上运行,只需要提供一个显示器刷新函数和一个触摸屏读取函数。LVGL还提供了多种预配置的平台,例如STM32、ESP32、Raspberry Pi等,可以快速地开始使用LVGL。
- 问题现象
设备进行多次重复开关机,初始化LVGL会概率性出现空指针问题,导致设备开机失败;
图1-1
- 问题分析
- 查看出现空指针的文件,查找可能出现空指针的错误语法;
该步骤没有发现会发生错误语法的地方;
2.查找出现空指针的具体语句;
该步骤通过串口打印排查出现空指针的语句,在排查的过程中,发现在该文件中,每次出现空指针的语句都不一样;
3.经过步骤2的排查,猜测如下原因:
(1)给LVGL开的缓存区有点临界值;
(2)LVGL在初始化过程中,被别的任务打断,导致出现该问题;
4.经过上面步骤的排查,发现是初始化LVGL过程中,多线程并发使用LVGL函数导致。
5.经过上面问题分析后,知道是由于函数调用并发导致,查看LVGL初始化过程
图1-2
在lvgl_init()函数中就已经初始化屏幕刷新任务
图1-3
在图1-2中可以看出,在执行完lvgl_init()后,接着初始化ui显示界面,而在图1-3中可以知道,已经初始化了屏幕刷新任务,所以在UI显示界面初始化的时候,会概率性导致并发的出现,从而出现空指针。如果UI显示界面不需要初始化很多东西,则该并发事件基本不会发生。
- 问题解决
经过问题分析,我们知道了该空指针的出现,是由于并发导致的,并且知道是UI初始化和刷新屏幕任务出现并发,所以处理一下他们的初始化过程就可以,如图1-4所示,将屏幕刷新任务放在UI初始化完成后,再进行初始化,可以解决该并发问题。
图1-4
- 问题总结
在该案例中,发现了LVGL出现并发问题,查看了LVGL的官方文档(操作系统和中断 — LVGL 文档),在默认情况下,LVGL不是线程安全的,因此,在使用操作系统的时候,通常建议 LVGL 主要使用单线程去做,在多线程中使用 LVGL 可能会出现线程之间并发调用 LVGL 函数的问题,在 LVGL 官方文档中给出的做法是在 lv_task_handler() 前加上互斥锁,执行完lv_task_handler() 后释放,并且在线程中调用每个 LVGL 相关函数都要加上相同互斥锁,来避免并发调用的问题。