Enable Micropython gc (Garbage Collection) on lvgl. This is controlled by LV_ENABLE_GC macro defined in lv_conf.h. When enabled, lv_conf.h should also define LV_MEM_CUSTOM_REALLOC, LV_MEM_CUSTOM_GET_SIZE, LV_GC_INCLUDE and LV_GC_ROOT
This commit is contained in:
@@ -10,6 +10,11 @@
|
||||
#include <stddef.h>
|
||||
#include "lv_task.h"
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
# include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -28,12 +33,10 @@ static bool lv_task_exec(lv_task_t * lv_task_p);
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_ll_t lv_task_ll; /*Linked list to store the lv_tasks*/
|
||||
static bool lv_task_run = false;
|
||||
static uint8_t idle_last = 0;
|
||||
static bool task_deleted;
|
||||
static bool task_created;
|
||||
static lv_task_t * task_act;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -48,7 +51,7 @@ static lv_task_t * task_act;
|
||||
*/
|
||||
void lv_task_init(void)
|
||||
{
|
||||
lv_ll_init(&lv_task_ll, sizeof(lv_task_t));
|
||||
lv_ll_init(&LV_GC_ROOT(lv_task_ll), sizeof(lv_task_t));
|
||||
|
||||
/*Initially enable the lv_task handling*/
|
||||
lv_task_enable(true);
|
||||
@@ -84,33 +87,33 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void)
|
||||
end_flag = true;
|
||||
task_deleted = false;
|
||||
task_created = false;
|
||||
task_act = lv_ll_get_head(&lv_task_ll);
|
||||
while(task_act) {
|
||||
LV_GC_ROOT(task_act) = lv_ll_get_head(&LV_GC_ROOT(lv_task_ll));
|
||||
while(LV_GC_ROOT(task_act)) {
|
||||
/* The task might be deleted if it runs only once ('once = 1')
|
||||
* So get next element until the current is surely valid*/
|
||||
next = lv_ll_get_next(&lv_task_ll, task_act);
|
||||
next = lv_ll_get_next(&LV_GC_ROOT(lv_task_ll), LV_GC_ROOT(task_act));
|
||||
|
||||
/*We reach priority of the turned off task. There is nothing more to do.*/
|
||||
if(task_act->prio == LV_TASK_PRIO_OFF) {
|
||||
if(((lv_task_t *)LV_GC_ROOT(task_act))->prio == LV_TASK_PRIO_OFF) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*Here is the interrupter task. Don't execute it again.*/
|
||||
if(task_act == task_interrupter) {
|
||||
if(LV_GC_ROOT(task_act) == task_interrupter) {
|
||||
task_interrupter = NULL; /*From this point only task after the interrupter comes, so the interrupter is not interesting anymore*/
|
||||
task_act = next;
|
||||
LV_GC_ROOT(task_act) = next;
|
||||
continue; /*Load the next task*/
|
||||
}
|
||||
|
||||
/*Just try to run the tasks with highest priority.*/
|
||||
if(task_act->prio == LV_TASK_PRIO_HIGHEST) {
|
||||
lv_task_exec(task_act);
|
||||
if(((lv_task_t *)LV_GC_ROOT(task_act))->prio == LV_TASK_PRIO_HIGHEST) {
|
||||
lv_task_exec(LV_GC_ROOT(task_act));
|
||||
}
|
||||
/*Tasks with higher priority then the interrupted shall be run in every case*/
|
||||
else if(task_interrupter) {
|
||||
if(task_act->prio > task_interrupter->prio) {
|
||||
if(lv_task_exec(task_act)) {
|
||||
task_interrupter = task_act; /*Check all tasks again from the highest priority */
|
||||
if(((lv_task_t *)LV_GC_ROOT(task_act))->prio > task_interrupter->prio) {
|
||||
if(lv_task_exec(LV_GC_ROOT(task_act))) {
|
||||
task_interrupter = LV_GC_ROOT(task_act); /*Check all tasks again from the highest priority */
|
||||
end_flag = false;
|
||||
break;
|
||||
}
|
||||
@@ -119,8 +122,8 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void)
|
||||
/* It is no interrupter task or we already reached it earlier.
|
||||
* Just run the remaining tasks*/
|
||||
else {
|
||||
if(lv_task_exec(task_act)) {
|
||||
task_interrupter = task_act; /*Check all tasks again from the highest priority */
|
||||
if(lv_task_exec(LV_GC_ROOT(task_act))) {
|
||||
task_interrupter = LV_GC_ROOT(task_act); /*Check all tasks again from the highest priority */
|
||||
end_flag = false;
|
||||
break;
|
||||
}
|
||||
@@ -129,7 +132,7 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void)
|
||||
if(task_deleted) break; /*If a task was deleted then this or the next item might be corrupted*/
|
||||
if(task_created) break; /*If a task was deleted then this or the next item might be corrupted*/
|
||||
|
||||
task_act = next; /*Load the next task*/
|
||||
LV_GC_ROOT(task_act) = next; /*Load the next task*/
|
||||
}
|
||||
} while(!end_flag);
|
||||
|
||||
@@ -164,24 +167,24 @@ lv_task_t * lv_task_create(void (*task)(void *), uint32_t period, lv_task_prio_t
|
||||
lv_task_t * tmp;
|
||||
|
||||
/*Create task lists in order of priority from high to low*/
|
||||
tmp = lv_ll_get_head(&lv_task_ll);
|
||||
tmp = lv_ll_get_head(&LV_GC_ROOT(lv_task_ll));
|
||||
if(NULL == tmp) { /*First task*/
|
||||
new_lv_task = lv_ll_ins_head(&lv_task_ll);
|
||||
new_lv_task = lv_ll_ins_head(&LV_GC_ROOT(lv_task_ll));
|
||||
lv_mem_assert(new_lv_task);
|
||||
if(new_lv_task == NULL) return NULL;
|
||||
} else {
|
||||
do {
|
||||
if(tmp->prio <= prio) {
|
||||
new_lv_task = lv_ll_ins_prev(&lv_task_ll, tmp);
|
||||
new_lv_task = lv_ll_ins_prev(&LV_GC_ROOT(lv_task_ll), tmp);
|
||||
lv_mem_assert(new_lv_task);
|
||||
if(new_lv_task == NULL) return NULL;
|
||||
break;
|
||||
}
|
||||
tmp = lv_ll_get_next(&lv_task_ll, tmp);
|
||||
tmp = lv_ll_get_next(&LV_GC_ROOT(lv_task_ll), tmp);
|
||||
} while(tmp != NULL);
|
||||
|
||||
if(tmp == NULL) { /*Only too high priority tasks were found*/
|
||||
new_lv_task = lv_ll_ins_tail(&lv_task_ll);
|
||||
new_lv_task = lv_ll_ins_tail(&LV_GC_ROOT(lv_task_ll));
|
||||
lv_mem_assert(new_lv_task);
|
||||
if(new_lv_task == NULL) return NULL;
|
||||
}
|
||||
@@ -205,11 +208,11 @@ lv_task_t * lv_task_create(void (*task)(void *), uint32_t period, lv_task_prio_t
|
||||
*/
|
||||
void lv_task_del(lv_task_t * lv_task_p)
|
||||
{
|
||||
lv_ll_rem(&lv_task_ll, lv_task_p);
|
||||
lv_ll_rem(&LV_GC_ROOT(lv_task_ll), lv_task_p);
|
||||
|
||||
lv_mem_free(lv_task_p);
|
||||
|
||||
if(task_act == lv_task_p) task_deleted = true; /*The active task was deleted*/
|
||||
if(LV_GC_ROOT(task_act) == lv_task_p) task_deleted = true; /*The active task was deleted*/
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,16 +224,16 @@ void lv_task_set_prio(lv_task_t * lv_task_p, lv_task_prio_t prio)
|
||||
{
|
||||
/*Find the tasks with new priority*/
|
||||
lv_task_t * i;
|
||||
LL_READ(lv_task_ll, i) {
|
||||
LL_READ(LV_GC_ROOT(lv_task_ll), i) {
|
||||
if(i->prio <= prio) {
|
||||
if(i != lv_task_p) lv_ll_move_before(&lv_task_ll, lv_task_p, i);
|
||||
if(i != lv_task_p) lv_ll_move_before(&LV_GC_ROOT(lv_task_ll), lv_task_p, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*There was no such a low priority so far then add the node to the tail*/
|
||||
if(i == NULL) {
|
||||
lv_ll_move_before(&lv_task_ll, lv_task_p, NULL);
|
||||
lv_ll_move_before(&LV_GC_ROOT(lv_task_ll), lv_task_p, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user