操作系统和中断

LVGL 默认情况下不是线程安全的

但是,在以下条件下调用与 LVGL 相关的函数是有效的:

  • 事件中。了解更多信息请参见 事件

  • lv_timer中。了解更多信息请参见 定时器

任务和线程

如果需要使用真正的任务或线程,则需要一个互斥锁,该锁应在调用 lv_timer_handler 之前获取,并在调用之后释放。 此外,您必须在其他任务和线程中围绕每个与 LVGL(lv_...)相关的函数调用和代码使用相同的互斥锁。 通过这种方式,您可以在真正的多任务环境中使用 LVGL。只需使用互斥锁即可避免并发调用 LVGL 函数。

以下是一些伪代码来说明这一概念:

static mutex_t lvgl_mutex;

void lvgl_thread(void)
{
    while(1) {
        mutex_lock(&lvgl_mutex);
        lv_task_handler();
        mutex_unlock(&lvgl_mutex);
        thread_sleep(10); /* 休眠 10 毫秒 */
    }
}

void other_thread(void)
{
    /* 使用 LVGL API 时必须始终持有互斥锁 */
    mutex_lock(&lvgl_mutex);
    lv_obj_t *img = lv_img_create(lv_scr_act());
    mutex_unlock(&lvgl_mutex);

    while(1) {
        mutex_lock(&lvgl_mutex);
        /* 切换到下一张图片 */
        lv_img_set_src(img, next_image);
        mutex_unlock(&lvgl_mutex);
        thread_sleep(2000);
    }
}

中断

尽量避免在中断处理程序中调用 LVGL 函数(lv_tick_inc()lv_disp_flush_ready() 除外)。但如果确实需要这样做,则必须在 lv_timer_handler 运行时禁用使用 LVGL 函数的中断。

更好的方法是在中断中设置一个标志或某个值,并在 LVGL 定时器(由 lv_timer_handler 运行)中定期检查它。