From 88b8e982b485368cc873860ba602a4cd315d674f Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 17 Oct 2018 14:31:16 +0200 Subject: [PATCH] lv_task and lv_ll: stability improvents --- lv_misc/lv_ll.c | 5 ++++- lv_misc/lv_task.c | 47 ++++++++++++++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/lv_misc/lv_ll.c b/lv_misc/lv_ll.c index d12de91f1..fd5561fb3 100644 --- a/lv_misc/lv_ll.c +++ b/lv_misc/lv_ll.c @@ -321,7 +321,10 @@ void lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after) if(n_act == n_after) return; /*Can't move before itself*/ - void * n_before = lv_ll_get_prev(ll_p, n_after); + void * n_before; + if(n_after != NULL) n_before = lv_ll_get_prev(ll_p, n_after); + else n_before = lv_ll_get_tail(ll_p); /*if `n_after` is NULL `n_act` should be the new tail*/ + if(n_act == n_before) return; /*Already before `n_after`*/ /*It's much easier to remove from the list and add again*/ diff --git a/lv_misc/lv_task.c b/lv_misc/lv_task.c index c2a9a48b6..160e066bc 100644 --- a/lv_misc/lv_task.c +++ b/lv_misc/lv_task.c @@ -32,6 +32,8 @@ 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 @@ -80,33 +82,35 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void) bool end_flag; do { end_flag = true; - lv_task_t * act = lv_ll_get_head(&lv_task_ll); - while(act) { + task_deleted = false; + task_created = false; + task_act = lv_ll_get_head(&lv_task_ll); + while(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, act); + next = lv_ll_get_next(&lv_task_ll, task_act); /*We reach priority of the turned off task. There is nothing more to do.*/ - if(act->prio == LV_TASK_PRIO_OFF) { + if(task_act->prio == LV_TASK_PRIO_OFF) { break; } /*Here is the interrupter task. Don't execute it again.*/ - if(act == task_interrupter) { + if(task_act == task_interrupter) { task_interrupter = NULL; /*From this point only task after the interrupter comes, so the interrupter is not interesting anymore*/ - act = next; + task_act = next; continue; /*Load the next task*/ } /*Just try to run the tasks with highest priority.*/ - if(act->prio == LV_TASK_PRIO_HIGHEST) { - lv_task_exec(act); + if(task_act->prio == LV_TASK_PRIO_HIGHEST) { + lv_task_exec(task_act); } /*Tasks with higher priority then the interrupted shall be run in every case*/ else if(task_interrupter) { - if(act->prio > task_interrupter->prio) { - if(lv_task_exec(act)) { - task_interrupter = act; /*Check all tasks again from the highest priority */ + 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 */ end_flag = false; break; } @@ -115,13 +119,17 @@ 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(act)) { - task_interrupter = act; /*Check all tasks again from the highest priority */ + if(lv_task_exec(task_act)) { + task_interrupter = task_act; /*Check all tasks again from the highest priority */ end_flag = false; break; } } - act = next; /*Load the next task*/ + + 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*/ } } while(!end_flag); @@ -186,6 +194,8 @@ lv_task_t * lv_task_create(void (*task)(void *), uint32_t period, lv_task_prio_t new_lv_task->once = 0; new_lv_task->last_run = lv_tick_get(); + task_created = true; + return new_lv_task; } @@ -199,7 +209,7 @@ void lv_task_del(lv_task_t * lv_task_p) lv_mem_free(lv_task_p); - task_deleted = true; + if(task_act == lv_task_p) task_deleted = true; /*The active task was deleted*/ } /** @@ -301,12 +311,15 @@ static bool lv_task_exec(lv_task_t * lv_task_p) uint32_t elp = lv_tick_elaps(lv_task_p->last_run); if(elp >= lv_task_p->period) { lv_task_p->last_run = lv_tick_get(); - task_deleted = false; + task_deleted = false; + task_created = false; lv_task_p->task(lv_task_p->param); /*Delete if it was a one shot lv_task*/ if(task_deleted == false) { /*The task might be deleted by itself as well*/ - if(lv_task_p->once != 0) lv_task_del(lv_task_p); + if(lv_task_p->once != 0) { + lv_task_del(lv_task_p); + } } exec = true; }