Timer Handler

To drive the timers of LVGL you need to call lv_timer_handler() periodically in one of the following:

  • while(1) of main() function, or

  • an OS task periodically. (See LVGL and Threads.)

LVGL Data Flow

Example:

while(1) {
  uint32_t time_till_next = lv_timer_handler();
  if(time_till_next == LV_NO_TIMER_READY) time_till_next = LV_DEF_REFR_PERIOD; /*handle LV_NO_TIMER_READY. Another option is to `sleep` for longer*/
  my_delay_ms(time_till_next);
}

If you want to use lv_timer_handler() in a super-loop, a helper function lv_timer_handler_run_in_period() is provided to simplify supplying LVGL with time awareness:

while(1) {
   ...
   lv_timer_handler_run_in_period(5); /* run lv_timer_handler() every 5ms */
   ...
}

Or use the sleep time automatically calculated by LVGL:

while(1) {
  ...
  lv_timer_periodic_handler();
  ...
}

In an OS environment, you can use it together with the delay or sleep provided by OS to release CPU whenever possible:

while (1) {
   uint32_t time_till_next = lv_timer_handler();
   if(time_till_next == LV_NO_TIMER_READY) time_till_next = LV_DEF_REFR_PERIOD; /*handle LV_NO_TIMER_READY. Another option is to `sleep` for longer*/
   os_delay_ms(time_till_next); /* delay to avoid unnecessary polling */
}

See Timer (lv_timer) section to learn more about timers.

When No Timers Are Ready

lv_timer_handler() will return LV_NO_TIMER_READY (UINT32_MAX) if there are no running timers. This can happen if there are no indevs or they are disabled with lv_indev_enable(), running animations, or running user-created timers. lv_timer_handler() will continue to return LV_NO_TIMER_READY until there is a running timer. Display timers will stay paused when there is no reason to refresh. lv_timer_handler() should be called after something is created, deleted, or modified so that a refresh will be performed if necessary. In practice this means waiting without a timeout for some external event. After the external events are received and handled, lv_timer_handler() should be called again.

while (1) {
   uint32_t time_till_next = lv_timer_handler();
   int timeout;

   /* Wait forever for events upon LV_NO_TIMER_READY, because there
    * is no reason to call lv_timer_handler sooner. */
   if(time_till_next == LV_NO_TIMER_READY) timeout = -1; /*infinite timeout*/

   /*Otherwise, wait for events at least until the timeout expires.*/
   else timeout = time_till_next;

   if(poll(..., timeout)) {
      /*Handle events before calling `lv_timer_handler` again.*/
   }
}

If there is no external event source, you may choose to exit the loop or simply delay for a long time.

If another thread is calling LVGL functions, you may want to call lv_timer_handler() again very soon to handle the effects of those other threads.

API

lv_timer.h