Secondly, you do not need to invalidate and set the text for the label every time the timer occurs. Just set the label once upon creation, and don’t call invalidate.
Thirdly, I would just use the blink variable as follows:
Maybe the example is not representative because what I want is a generic method of asynchronous widget modification, outside of timers and animations. Adding both lv_timer_handler() and lv_tick_inc() into the loop seems to help.
I want to make clear here that you really are not supposed to call LVGL functions outside of timing/loops setup by LVGL itself.
Could you tell why? Maybe show an example of an asynchronous, trivial one-time widget state change “inside of timing/loops setup by LVGL itself” and why it is required?
I would want to know these details, in order to understand better what is happening behind.