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:
parent
caf9d16dc9
commit
4665fd9191
@ -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:
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user