Hi,
I've been working with LVGL (amazing project!) and I am wondering how to integrate it with an RTOS. The README mentions that OS support is available, and I see that you have tested it with FreeRTOS. However, I don't see any locking mechanisms. Is this required or does it "Just Work (TM)?"
I use lvgl with FreeRTOS. I will do a PR soon on the project esp-open-rtos for the esp8266.
Example link with ssd1306 example: example
i use:
lv_drivers => new_api branch
lvgl => dev-5.2 branch
Hope it is help.
Hi,
Right now there is no locking mechanism but in most cases it is not required to be inside the library.
Once you set up the GUI (create screens, objects etc) usually everything is handled by actions (e.g. button click actions). However, the actions and the related things are called from lv_task_handler (indev_read, disp_flush etc as well). Thus we are worging only from one task so far.
But what if when you need to e.g. update a label with the measured temperature? If you would call lv_label_set_text() from the measuring task it could mess things up because lv_task_handler can come in the middle of lv_label_set_text() or vice-versa. There are two solutions:
lv_task_handler and in other places where you use LittelvGL "asynchronously".lv_task to periodically update the required objects or add the GUI updater code below lv_task_handler. This way everything will be in the same task again.@kisvegabor @Zaltora Thanks for the quick replies!
So all I have to do is ensure that LVGL APIs are only called by one task at a time? That makes it very simple to implement!
This is how I do it.
static SemaphoreHandle_t uiMutex;
V UI_TakeMutex ( V )
{
while( xSemaphoreTake( uiMutex, portMAX_DELAY ) != pdTRUE )
;
}
V UI_GiveMutex ( V )
{
xSemaphoreGive( uiMutex );
}
static V TaskLVGL( PV p )
{
for( ; ; )
{
vTaskDelay( pdMS_TO_TICKS(10) );
UI_TakeMutex();
lv_task_handler();
UI_GiveMutex();
}
}
static V TaskUiEvery200ms ( PV p )
{
UF8 _400ms, _1000ms;
for( ; ; )
{
vTaskDelay( pdMS_TO_TICKS(200) );
if( ++_400ms >= 2 )
{
_400ms = 0;
Screens_Every400ms();
}
if( ++_1000ms >= 5 )
{
_1000ms = 0;
Screens_Every1000ms();
}
}
}
Screens_Every400ms() and Screens_Every1000ms() call UI_TakeMutex and UI_GiveMutex as and if lvgl API functions are called.
@markyi370 It seems your question is answered so I close this issue.
If you have further question, feel free to reopen it!
@kisvegabor Yes, my question is answered. Thank you for the quick responses everyone!
Most helpful comment
This is how I do it.
Screens_Every400ms() and Screens_Every1000ms() call UI_TakeMutex and UI_GiveMutex as and if lvgl API functions are called.