lvgl
lvgl copied to clipboard
[Error] (19234.671, +0) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #212)
00
What's the problem here?
We need some feedback on this issue.
Now we mark this as "stale" because there was no activity here for 14 days.
Remove the "stale" label or comment else this will be closed in 7 days.
As there was no activity here for a while we close this issue. But don't worry, the conversation is still here and you can get back to it at any time.
So feel free to comment if you have remarks or ideas on this topic.
What does this error mean. I get them all time also.
What does this error mean. I get them all time also.
It normally means widget's properties have been modified during rendering(such as DRAW_MAIN event callback). It will cause rendering issues thus are forbidden.
Using FreeRTOS where the UI is being altered in a different thread than the LVGL refresh loop, what is the proper pattern to prevent this kind of conflict?
LVGL is not thread safe. You can only call LVGL APIs from one thread.
@XuNeo I'm thinking about something like this:
lv_lock(); /*LVGL is not thread safe, so lock it before using any `lv_...` functions in any threads. */
lv_timer_handler(); /*/*Process timers, events, animations, display refreshed, and input devices*/
lv_unlock();
lv_lock and lv_unlock are using an lv_mutex internally if LV_USE_OS is set. Without OS they set/clear a bool variable for which we can ASSERT on some critical places. In case of LV_OS_CUSTOM the user can implement these functions.
This practice can be shown all the places so people will intuitively know that is locking is required.
What do you think?
Take for example a screen that shows data from an api call. The main loop is calling lv_timer_handler() and another thread calls the API and then updates screen labels when the data cones back. It seems like it's not possible to have this on the same thread without blocking the UI during the API wait period.
Adding a global lock to lvgl will work. I'm not sure if it's a best practice.
Operation to lvgl normally should be done in signal thread and never block it. Move block operations outside of lvgl's thread like using libuv etc.
Once people have an OS, they will use it for sure and will attempt to adjust the widgets from an other thread as well.
@kisvegabor I don't see a lv_lock() function available anywhere in the LVGL code... I am using the Arduino framework / FreeRTOS.
lv_lock is not added yet, we are just talking about it.
If you are calling LVGL function from multiple threads take look at this.
Thank you. Wanted to share for FreeRTOS the code looks like this:
SemaphoreHandle_t xLVGLMutexHandle;
TaskHandle_t tUIHandle;
TaskHandle_t tLVGLHandle;
xLVGLMutexHandle = xSemaphoreCreateMutex();
xTaskCreate(uiCallback, "tUIHandle", 3000, (void *)0, tskIDLE_PRIORITY, &tUIHandle);
xTaskCreate(lvglCallback, "tLVGLHandle", 3000, (void *)0, tskIDLE_PRIORITY + 1, &tLVGLHandle);
void lvglCallback(void *p)
{
while (1)
{
// use mutex to insure nothing writes to LVGL during the render
if (xSemaphoreTake(xLVGLMutexHandle, (TickType_t)10) == pdTRUE)
{
lv_timer_handler();
xSemaphoreGive(xLVGLMutexHandle);
}
vTaskDelay(5 / portTICK_PERIOD_MS);
}
}
void uiCallback(void *p)
{
while (1)
{
// use mutex to lock LVGL before updating UI
if (xSemaphoreTake(xLVGLMutexHandle, (TickType_t)10) == pdTRUE)
{
/* update LVGL UI here */
xSemaphoreGive(xLVGLMutexHandle);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}