Good way to wait for LittleVGL UI Updates

I’m running on the RT1052 w/ FreeRTOS Kernel V10.2.1
And I’m using FreeRTOS to clock / run LittleVGL via 2 tasks:

  if (xTaskCreate(lv_ticker, "LV Ticker Task", 3000, NULL, 3, &lvgl_ticker_handle) != pdPASS){
    assert(0);
  }
  if (xTaskCreate(lv_redraw, "LV Redraw Task", 1024, NULL, 3, &lv_redraw_handle) != pdPASS){
    assert(0);
  }

I have the LV Redraw will do the standard lv_task_handler(), but also check every 100ms for a global system state to see if the system is busy, and if so, update the UI with a busy indicator…


If one of my critical (non-LVGL) tasks (like the command parser):

  if (xTaskCreate(cmd_parser_task, "CmdParser", 7000, NULL, 3, NULL ) != pdPASS) {
    return 1;
  }

gets an important job, right now it updates the system state (to busy), and then does

 eTaskState task_state;
 vTaskDelay(350); //hope LVGL update can complete in this time... but it doesn't
 task_state = eTaskGetState(lvgl_ticker_handle);
 if ((task_state != eSuspended) && (task_state != eDeleted)){
     vTaskSuspend(lvgl_ticker_handle);
  }
 task_state = eTaskGetState(lv_redraw_handle);
 if ((task_state != eSuspended) && (task_state != eDeleted)){
     vTaskSuspend(lv_redraw_handle);
  }

This solution is unreliable, but I don’t have a better one as I don’t know when Lvgl’s LV Redraw has sucessfully drawn the busy UI… so sometimes the Busy Spinner is only half drawn by the time the LVGL tasks are suspended to allow the system to work in critical tasks. Which is odd as I thought in 100ms (worst case 200ms), the Redraw Task would trigger and redraw / complete in well under 350ms.

If I temporarily raise priorities of the LVGL tasks to maxi pri, and use the above solution, then it works, but causes unpredictability / task deadlock/freeze issue in my system.



The more I think about it - the more this might be more a LVGL specific question, but I'm curious if any other FreeRTOS people have fought with this / have a solution?

I’m not familiar with LVGL workings, and am not sure I understand the specifics of your question, but if I were to simplify to say you have one task that wants to know when another task has finished an operation - would i be correct?

If I am correct, would an event group help? The task that is waiting can block on a bit in the event group, and the task it is waiting for can set that bit once it has completed its operation.

1 Like

Hi Richard,
Thanks for the feedback. My challenge is probably in the lvgl side - finding out where to put the event signal.

Once I have that figured out - I’ll follow your suggestion of the event group, as that seems pretty flexible (any task can wait on that group for the UI task to finish).

Thanks!