1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

feat(timer): implementation of adaptive call timer handler cycle method (#4236)

This commit is contained in:
_VIFEXTech 2023-06-14 19:57:34 +08:00 committed by GitHub
parent caf9d16dc9
commit 4665fd9191
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 5 deletions

View File

@ -32,6 +32,16 @@ the porting:
...
}
Or use the sleep time automatically calculated by LVGL:
.. code:: c
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:

View File

@ -29,6 +29,7 @@
**********************/
static bool lv_timer_exec(lv_timer_t * timer);
static uint32_t lv_timer_time_remaining(lv_timer_t * timer);
static void lv_timer_handler_resume(void);
/**********************
* STATIC VARIABLES
@ -37,6 +38,7 @@ static bool lv_timer_run = false;
static uint8_t idle_last = 0;
static bool timer_deleted;
static bool timer_created;
static uint32_t timer_time_until_next;
/**********************
* MACROS
@ -121,13 +123,13 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void)
}
} while(LV_GC_ROOT(_lv_timer_act));
uint32_t time_till_next = LV_NO_TIMER_READY;
uint32_t time_until_next = LV_NO_TIMER_READY;
next = _lv_ll_get_head(&LV_GC_ROOT(_lv_timer_ll));
while(next) {
if(!next->paused) {
uint32_t delay = lv_timer_time_remaining(next);
if(delay < time_till_next)
time_till_next = delay;
if(delay < time_until_next)
time_until_next = delay;
}
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_timer_ll), next); /*Find the next timer*/
@ -142,11 +144,23 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void)
idle_period_start = lv_tick_get();
}
timer_time_until_next = time_until_next;
already_running = false; /*Release the mutex*/
TIMER_TRACE("finished (%" LV_PRIu32 " ms until the next timer call)", time_till_next);
TIMER_TRACE("finished (%" LV_PRIu32 " ms until the next timer call)", time_until_next);
LV_PROFILER_END;
return time_till_next;
return time_until_next;
}
LV_ATTRIBUTE_TIMER_HANDLER void lv_timer_periodic_handler(void)
{
static uint32_t last_tick = 0;
if(lv_tick_elaps(last_tick) >= timer_time_until_next) {
TIMER_TRACE("calling lv_timer_handler()");
lv_timer_handler();
last_tick = lv_tick_get();
}
}
/**
@ -185,6 +199,8 @@ lv_timer_t * lv_timer_create(lv_timer_cb_t timer_xcb, uint32_t period, void * us
timer_created = true;
lv_timer_handler_resume();
return new_timer;
}
@ -222,6 +238,7 @@ void lv_timer_pause(lv_timer_t * timer)
void lv_timer_resume(lv_timer_t * timer)
{
timer->paused = false;
lv_timer_handler_resume();
}
/**
@ -261,6 +278,7 @@ void lv_timer_set_repeat_count(lv_timer_t * timer, int32_t repeat_count)
void lv_timer_reset(lv_timer_t * timer)
{
timer->last_run = lv_tick_get();
lv_timer_handler_resume();
}
/**
@ -270,6 +288,7 @@ void lv_timer_reset(lv_timer_t * timer)
void lv_timer_enable(bool en)
{
lv_timer_run = en;
if(en) lv_timer_handler_resume();
}
/**
@ -281,6 +300,15 @@ uint8_t lv_timer_get_idle(void)
return idle_last;
}
/**
* Get idle period start tick
* @return the lv_timer idle period start tick
*/
uint32_t lv_timer_get_time_until_next(void)
{
return timer_time_until_next;
}
/**
* Iterate through the timers
* @param timer NULL to start iteration or the previous return value to get the next timer
@ -351,3 +379,12 @@ static uint32_t lv_timer_time_remaining(lv_timer_t * timer)
return 0;
return timer->period - elp;
}
/**
* Call the ready lv_timer
*/
static void lv_timer_handler_resume(void)
{
/*If there is a timer which is ready to run then resume the timer loop*/
timer_time_until_next = 0;
}

View File

@ -87,6 +87,12 @@ static inline LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler_run_in_period
return 1;
}
/**
* Call it in the super-loop of main() or threads. It will automatically call lv_timer_handler() at the right time.
* This function is used to simplify the porting.
*/
LV_ATTRIBUTE_TIMER_HANDLER void lv_timer_periodic_handler(void);
/**
* Create an "empty" timer. It needs to be initialized with at least
* `lv_timer_set_cb` and `lv_timer_set_period`
@ -165,6 +171,12 @@ void lv_timer_enable(bool en);
*/
uint8_t lv_timer_get_idle(void);
/**
* Get the time remaining until the next timer will run
* @return the time remaining in ms
*/
uint32_t lv_timer_get_time_until_next(void);
/**
* Iterate through the timers
* @param timer NULL to start iteration or the previous return value to get the next timer