mirror of
https://github.com/lvgl/lvgl.git
synced 2025-02-04 07:13:00 +08:00
Merge 60be7c1ceecf26bcc7413e80ddb2f154a5f6b5e5 into dev
This commit is contained in:
commit
32b2381168
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @file lv_task.c
|
* @file lv_task.c
|
||||||
* An 'lv_task' is a void (*fp) (void* param) type function which will be called periodically.
|
* An 'lv_task' is a void (*fp) (struct _lv_task_t* param) type function which will be called periodically.
|
||||||
* A priority (5 levels + disable) can be assigned to lv_tasks.
|
* A priority (5 levels + disable) can be assigned to lv_tasks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -54,7 +54,6 @@ void _lv_task_core_init(void)
|
|||||||
{
|
{
|
||||||
_lv_ll_init(&LV_GC_ROOT(_lv_task_ll), sizeof(lv_task_t));
|
_lv_ll_init(&LV_GC_ROOT(_lv_task_ll), sizeof(lv_task_t));
|
||||||
|
|
||||||
task_list_changed = false;
|
|
||||||
/*Initially enable the lv_task handling*/
|
/*Initially enable the lv_task handling*/
|
||||||
lv_task_enable(true);
|
lv_task_enable(true);
|
||||||
}
|
}
|
||||||
@ -65,7 +64,6 @@ void _lv_task_core_init(void)
|
|||||||
*/
|
*/
|
||||||
LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void)
|
LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
LV_LOG_TRACE("lv_task_handler started");
|
LV_LOG_TRACE("lv_task_handler started");
|
||||||
|
|
||||||
/*Avoid concurrent running of the task handler*/
|
/*Avoid concurrent running of the task handler*/
|
||||||
@ -73,17 +71,15 @@ LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void)
|
|||||||
if(already_running) return 1;
|
if(already_running) return 1;
|
||||||
already_running = true;
|
already_running = true;
|
||||||
|
|
||||||
static uint32_t idle_period_start = 0;
|
|
||||||
static uint32_t handler_start = 0;
|
|
||||||
static uint32_t busy_time = 0;
|
|
||||||
static uint32_t time_till_next;
|
|
||||||
|
|
||||||
if(lv_task_run == false) {
|
if(lv_task_run == false) {
|
||||||
already_running = false; /*Release mutex*/
|
already_running = false; /*Release mutex*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
handler_start = lv_tick_get();
|
static uint32_t idle_period_start = 0;
|
||||||
|
static uint32_t busy_time = 0;
|
||||||
|
|
||||||
|
uint32_t handler_start = lv_tick_get();
|
||||||
|
|
||||||
/* Run all task from the highest to the lowest priority
|
/* Run all task from the highest to the lowest priority
|
||||||
* If a lower priority task is executed check task again from the highest priority
|
* If a lower priority task is executed check task again from the highest priority
|
||||||
@ -95,6 +91,7 @@ LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void)
|
|||||||
end_flag = true;
|
end_flag = true;
|
||||||
task_deleted = false;
|
task_deleted = false;
|
||||||
task_created = false;
|
task_created = false;
|
||||||
|
task_list_changed = false;
|
||||||
LV_GC_ROOT(_lv_task_act) = _lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));
|
LV_GC_ROOT(_lv_task_act) = _lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));
|
||||||
while(LV_GC_ROOT(_lv_task_act)) {
|
while(LV_GC_ROOT(_lv_task_act)) {
|
||||||
/* The task might be deleted if it runs only once ('once = 1')
|
/* The task might be deleted if it runs only once ('once = 1')
|
||||||
@ -102,7 +99,7 @@ LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void)
|
|||||||
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), LV_GC_ROOT(_lv_task_act));
|
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), LV_GC_ROOT(_lv_task_act));
|
||||||
|
|
||||||
/*We reach priority of the turned off task. There is nothing more to do.*/
|
/*We reach priority of the turned off task. There is nothing more to do.*/
|
||||||
if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio == LV_TASK_PRIO_OFF) {
|
if(LV_GC_ROOT(_lv_task_act)->prio == LV_TASK_PRIO_OFF) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,12 +112,12 @@ LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*Just try to run the tasks with highest priority.*/
|
/*Just try to run the tasks with highest priority.*/
|
||||||
if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio == LV_TASK_PRIO_HIGHEST) {
|
if(LV_GC_ROOT(_lv_task_act)->prio == LV_TASK_PRIO_HIGHEST) {
|
||||||
lv_task_exec(LV_GC_ROOT(_lv_task_act));
|
lv_task_exec(LV_GC_ROOT(_lv_task_act));
|
||||||
}
|
}
|
||||||
/*Tasks with higher priority than the interrupted shall be run in every case*/
|
/*Tasks with higher priority than the interrupted shall be run in every case*/
|
||||||
else if(task_interrupter) {
|
else if(task_interrupter) {
|
||||||
if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio > task_interrupter->prio) {
|
if(LV_GC_ROOT(_lv_task_act)->prio > task_interrupter->prio) {
|
||||||
if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) {
|
if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) {
|
||||||
if(!task_created && !task_deleted) {
|
if(!task_created && !task_deleted) {
|
||||||
/*Check all tasks again from the highest priority */
|
/*Check all tasks again from the highest priority */
|
||||||
@ -152,7 +149,6 @@ LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void)
|
|||||||
if(task_list_changed) {
|
if(task_list_changed) {
|
||||||
task_interrupter = NULL;
|
task_interrupter = NULL;
|
||||||
end_flag = false;
|
end_flag = false;
|
||||||
task_list_changed = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,28 +156,25 @@ LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void)
|
|||||||
}
|
}
|
||||||
} while(!end_flag);
|
} while(!end_flag);
|
||||||
|
|
||||||
|
uint32_t time_till_next = LV_NO_TASK_READY;
|
||||||
|
next = _lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));
|
||||||
|
while(next && next->prio != LV_TASK_PRIO_OFF) {
|
||||||
|
uint32_t delay = lv_task_time_remaining(next);
|
||||||
|
if(delay < time_till_next)
|
||||||
|
time_till_next = delay;
|
||||||
|
|
||||||
|
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), next); /*Find the next task*/
|
||||||
|
}
|
||||||
|
|
||||||
busy_time += lv_tick_elaps(handler_start);
|
busy_time += lv_tick_elaps(handler_start);
|
||||||
uint32_t idle_period_time = lv_tick_elaps(idle_period_start);
|
uint32_t idle_period_time = lv_tick_elaps(idle_period_start);
|
||||||
if(idle_period_time >= IDLE_MEAS_PERIOD) {
|
if(idle_period_time >= IDLE_MEAS_PERIOD) {
|
||||||
|
idle_last = (busy_time * 100) / idle_period_time; /*Calculate the busy percentage*/
|
||||||
idle_last = (uint32_t)((uint32_t)busy_time * 100) / IDLE_MEAS_PERIOD; /*Calculate the busy percentage*/
|
idle_last = idle_last > 100 ? 0 : 100 - idle_last; /*But we need idle time*/
|
||||||
idle_last = idle_last > 100 ? 0 : 100 - idle_last; /*But we need idle time*/
|
|
||||||
busy_time = 0;
|
busy_time = 0;
|
||||||
idle_period_start = lv_tick_get();
|
idle_period_start = lv_tick_get();
|
||||||
}
|
}
|
||||||
|
|
||||||
time_till_next = LV_NO_TASK_READY;
|
|
||||||
next = _lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));
|
|
||||||
while(next) {
|
|
||||||
if(next->prio != LV_TASK_PRIO_OFF) {
|
|
||||||
uint32_t delay = lv_task_time_remaining(next);
|
|
||||||
if(delay < time_till_next)
|
|
||||||
time_till_next = delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), next); /*Find the next task*/
|
|
||||||
}
|
|
||||||
|
|
||||||
already_running = false; /*Release the mutex*/
|
already_running = false; /*Release the mutex*/
|
||||||
|
|
||||||
LV_LOG_TRACE("lv_task_handler ready");
|
LV_LOG_TRACE("lv_task_handler ready");
|
||||||
@ -193,6 +186,21 @@ LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void)
|
|||||||
* @return pointer to the created task
|
* @return pointer to the created task
|
||||||
*/
|
*/
|
||||||
lv_task_t * lv_task_create_basic(void)
|
lv_task_t * lv_task_create_basic(void)
|
||||||
|
{
|
||||||
|
return lv_task_create(NULL, DEF_PERIOD, DEF_PRIO, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new lv_task
|
||||||
|
* @param task_xcb a callback which is the task itself. It will be called periodically.
|
||||||
|
* (the 'x' in the argument name indicates that its not a fully generic function because it not follows
|
||||||
|
* the `func_name(object, callback, ...)` convention)
|
||||||
|
* @param period call period in ms unit
|
||||||
|
* @param prio priority of the task (LV_TASK_PRIO_OFF means the task is stopped)
|
||||||
|
* @param user_data custom parameter
|
||||||
|
* @return pointer to the new task
|
||||||
|
*/
|
||||||
|
lv_task_t * lv_task_create(lv_task_cb_t task_xcb, uint32_t period, lv_task_prio_t prio, void * user_data)
|
||||||
{
|
{
|
||||||
lv_task_t * new_task = NULL;
|
lv_task_t * new_task = NULL;
|
||||||
lv_task_t * tmp;
|
lv_task_t * tmp;
|
||||||
@ -209,7 +217,7 @@ lv_task_t * lv_task_create_basic(void)
|
|||||||
/*Insert the new task to proper place according to its priority*/
|
/*Insert the new task to proper place according to its priority*/
|
||||||
else {
|
else {
|
||||||
do {
|
do {
|
||||||
if(tmp->prio <= DEF_PRIO) {
|
if(tmp->prio <= prio) {
|
||||||
new_task = _lv_ll_ins_prev(&LV_GC_ROOT(_lv_task_ll), tmp);
|
new_task = _lv_ll_ins_prev(&LV_GC_ROOT(_lv_task_ll), tmp);
|
||||||
LV_ASSERT_MEM(new_task);
|
LV_ASSERT_MEM(new_task);
|
||||||
if(new_task == NULL) return NULL;
|
if(new_task == NULL) return NULL;
|
||||||
@ -227,44 +235,20 @@ lv_task_t * lv_task_create_basic(void)
|
|||||||
}
|
}
|
||||||
task_list_changed = true;
|
task_list_changed = true;
|
||||||
|
|
||||||
new_task->period = DEF_PERIOD;
|
new_task->period = period;
|
||||||
new_task->task_cb = NULL;
|
new_task->task_cb = task_xcb;
|
||||||
new_task->prio = DEF_PRIO;
|
new_task->prio = prio;
|
||||||
|
|
||||||
new_task->repeat_count = -1;
|
new_task->repeat_count = -1;
|
||||||
new_task->last_run = lv_tick_get();
|
new_task->last_run = lv_tick_get();
|
||||||
|
|
||||||
new_task->user_data = NULL;
|
new_task->user_data = user_data;
|
||||||
|
|
||||||
task_created = true;
|
task_created = true;
|
||||||
|
|
||||||
return new_task;
|
return new_task;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new lv_task
|
|
||||||
* @param task_xcb a callback which is the task itself. It will be called periodically.
|
|
||||||
* (the 'x' in the argument name indicates that its not a fully generic function because it not follows
|
|
||||||
* the `func_name(object, callback, ...)` convention)
|
|
||||||
* @param period call period in ms unit
|
|
||||||
* @param prio priority of the task (LV_TASK_PRIO_OFF means the task is stopped)
|
|
||||||
* @param user_data custom parameter
|
|
||||||
* @return pointer to the new task
|
|
||||||
*/
|
|
||||||
lv_task_t * lv_task_create(lv_task_cb_t task_xcb, uint32_t period, lv_task_prio_t prio, void * user_data)
|
|
||||||
{
|
|
||||||
lv_task_t * new_task = lv_task_create_basic();
|
|
||||||
LV_ASSERT_MEM(new_task);
|
|
||||||
if(new_task == NULL) return NULL;
|
|
||||||
|
|
||||||
lv_task_set_cb(new_task, task_xcb);
|
|
||||||
lv_task_set_period(new_task, period);
|
|
||||||
lv_task_set_prio(new_task, prio);
|
|
||||||
new_task->user_data = user_data;
|
|
||||||
|
|
||||||
return new_task;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the callback the task (the function to call periodically)
|
* Set the callback the task (the function to call periodically)
|
||||||
* @param task pointer to a task
|
* @param task pointer to a task
|
||||||
@ -399,8 +383,6 @@ static bool lv_task_exec(lv_task_t * task)
|
|||||||
|
|
||||||
if(lv_task_time_remaining(task) == 0) {
|
if(lv_task_time_remaining(task) == 0) {
|
||||||
task->last_run = lv_tick_get();
|
task->last_run = lv_tick_get();
|
||||||
task_deleted = false;
|
|
||||||
task_created = false;
|
|
||||||
if(task->task_cb) task->task_cb(task);
|
if(task->task_cb) task->task_cb(task);
|
||||||
|
|
||||||
/*Delete if it was a one shot lv_task*/
|
/*Delete if it was a one shot lv_task*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @file lv_task.c
|
* @file lv_task.h
|
||||||
* An 'lv_task' is a void (*fp) (void* param) type function which will be called periodically.
|
* An 'lv_task' is a void (*fp) (struct _lv_task_t* param) type function which will be called periodically.
|
||||||
* A priority (5 levels + disable) can be assigned to lv_tasks.
|
* A priority (5 levels + disable) can be assigned to lv_tasks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ extern "C" {
|
|||||||
struct _lv_task_t;
|
struct _lv_task_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tasks execute this type type of functions.
|
* Tasks execute this type of functions.
|
||||||
*/
|
*/
|
||||||
typedef void (*lv_task_cb_t)(struct _lv_task_t *);
|
typedef void (*lv_task_cb_t)(struct _lv_task_t *);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user