summaryrefslogtreecommitdiff
path: root/src/libs/lvgl/src/lv_misc/lv_task.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/lvgl/src/lv_misc/lv_task.c')
m---------src/libs/lvgl0
-rw-r--r--src/libs/lvgl/src/lv_misc/lv_task.c415
2 files changed, 0 insertions, 415 deletions
diff --git a/src/libs/lvgl b/src/libs/lvgl
new file mode 160000
+Subproject 23430cf20e32294549fff9b2879a9466dacc19b
diff --git a/src/libs/lvgl/src/lv_misc/lv_task.c b/src/libs/lvgl/src/lv_misc/lv_task.c
deleted file mode 100644
index 147ada6..0000000
--- a/src/libs/lvgl/src/lv_misc/lv_task.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/**
- * @file lv_task.c
- * 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.
- */
-
-/*********************
- * INCLUDES
- *********************/
-#include <stddef.h>
-#include "lv_task.h"
-#include "../lv_misc/lv_debug.h"
-#include "../lv_hal/lv_hal_tick.h"
-#include "lv_gc.h"
-
-/*********************
- * DEFINES
- *********************/
-#define IDLE_MEAS_PERIOD 500 /*[ms]*/
-#define DEF_PRIO LV_TASK_PRIO_MID
-#define DEF_PERIOD 500
-
-/**********************
- * TYPEDEFS
- **********************/
-
-/**********************
- * STATIC PROTOTYPES
- **********************/
-static bool lv_task_exec(lv_task_t * task);
-static uint32_t lv_task_time_remaining(lv_task_t * task);
-
-/**********************
- * STATIC VARIABLES
- **********************/
-static bool lv_task_run = false;
-static uint8_t idle_last = 0;
-static bool task_deleted;
-static bool task_list_changed;
-static bool task_created;
-
-/**********************
- * MACROS
- **********************/
-
-/**********************
- * GLOBAL FUNCTIONS
- **********************/
-
-/**
- * Init the lv_task module
- */
-void _lv_task_core_init(void)
-{
- _lv_ll_init(&LV_GC_ROOT(_lv_task_ll), sizeof(lv_task_t));
-
- /*Initially enable the lv_task handling*/
- lv_task_enable(true);
-}
-
-/**
- * Call it periodically to handle lv_tasks.
- * @return the time after which it must be called again
- */
-LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void)
-{
- LV_LOG_TRACE("lv_task_handler started");
-
- /*Avoid concurrent running of the task handler*/
- static bool already_running = false;
- if(already_running) return 1;
- already_running = true;
-
- if(lv_task_run == false) {
- already_running = false; /*Release mutex*/
- return 1;
- }
-
- 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
- * If a lower priority task is executed check task again from the highest priority
- * but on the priority of executed tasks don't run tasks before the executed*/
- lv_task_t * task_interrupter = NULL;
- lv_task_t * next;
- bool end_flag;
- do {
- end_flag = true;
- task_deleted = false;
- task_created = false;
- task_list_changed = false;
- LV_GC_ROOT(_lv_task_act) = _lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));
- while(LV_GC_ROOT(_lv_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_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.*/
- if(LV_GC_ROOT(_lv_task_act)->prio == LV_TASK_PRIO_OFF) {
- break;
- }
-
- /*Here is the interrupter task. Don't execute it again.*/
- if(LV_GC_ROOT(_lv_task_act) == task_interrupter) {
- task_interrupter = NULL; /*From this point only task after the interrupter comes, so
- the interrupter is not interesting anymore*/
- LV_GC_ROOT(_lv_task_act) = next;
- continue; /*Load the next task*/
- }
-
- /*Just try to run the tasks with highest priority.*/
- if(LV_GC_ROOT(_lv_task_act)->prio == LV_TASK_PRIO_HIGHEST) {
- lv_task_exec(LV_GC_ROOT(_lv_task_act));
- }
- /*Tasks with higher priority than the interrupted shall be run in every case*/
- else if(task_interrupter) {
- if(LV_GC_ROOT(_lv_task_act)->prio > task_interrupter->prio) {
- if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) {
- if(!task_created && !task_deleted) {
- /*Check all tasks again from the highest priority */
- task_interrupter = LV_GC_ROOT(_lv_task_act);
- end_flag = false;
- break;
- }
- }
- }
- }
- /* It is no interrupter task or we already reached it earlier.
- * Just run the remaining tasks*/
- else {
- if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) {
- if(!task_created && !task_deleted) {
- task_interrupter = LV_GC_ROOT(_lv_task_act); /*Check all tasks again from the highest priority */
- end_flag = false;
- break;
- }
- }
- }
-
- /*If a task was created or deleted then this or the next item might be corrupted*/
- if(task_created || task_deleted) {
- task_interrupter = NULL;
- break;
- }
-
- if(task_list_changed) {
- task_interrupter = NULL;
- end_flag = false;
- break;
- }
-
- LV_GC_ROOT(_lv_task_act) = next; /*Load the next task*/
- }
- } 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);
- uint32_t idle_period_time = lv_tick_elaps(idle_period_start);
- if(idle_period_time >= IDLE_MEAS_PERIOD) {
- idle_last = (busy_time * 100) / idle_period_time; /*Calculate the busy percentage*/
- idle_last = idle_last > 100 ? 0 : 100 - idle_last; /*But we need idle time*/
- busy_time = 0;
- idle_period_start = lv_tick_get();
- }
-
- already_running = false; /*Release the mutex*/
-
- LV_LOG_TRACE("lv_task_handler ready");
- return time_till_next;
-}
-/**
- * Create an "empty" task. It needs to initialized with at least
- * `lv_task_set_cb` and `lv_task_set_period`
- * @return pointer to the created task
- */
-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 * tmp;
-
- /*Create task lists in order of priority from high to low*/
- tmp = _lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));
-
- /*It's the first task*/
- if(NULL == tmp) {
- new_task = _lv_ll_ins_head(&LV_GC_ROOT(_lv_task_ll));
- LV_ASSERT_MEM(new_task);
- if(new_task == NULL) return NULL;
- }
- /*Insert the new task to proper place according to its priority*/
- else {
- do {
- if(tmp->prio <= prio) {
- new_task = _lv_ll_ins_prev(&LV_GC_ROOT(_lv_task_ll), tmp);
- LV_ASSERT_MEM(new_task);
- if(new_task == NULL) return NULL;
- break;
- }
- tmp = _lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), tmp);
- } while(tmp != NULL);
-
- /*Only too high priority tasks were found. Add the task to the end*/
- if(tmp == NULL) {
- new_task = _lv_ll_ins_tail(&LV_GC_ROOT(_lv_task_ll));
- LV_ASSERT_MEM(new_task);
- if(new_task == NULL) return NULL;
- }
- }
- task_list_changed = true;
-
- new_task->period = period;
- new_task->task_cb = task_xcb;
- new_task->prio = prio;
-
- new_task->repeat_count = -1;
- new_task->last_run = lv_tick_get();
-
- new_task->user_data = user_data;
-
- task_created = true;
-
- return new_task;
-}
-
-/**
- * Set the callback the task (the function to call periodically)
- * @param task pointer to a task
- * @param task_cb the function to call periodically
- */
-void lv_task_set_cb(lv_task_t * task, lv_task_cb_t task_cb)
-{
- task->task_cb = task_cb;
-}
-
-/**
- * Delete a lv_task
- * @param task pointer to task created by task
- */
-void lv_task_del(lv_task_t * task)
-{
- _lv_ll_remove(&LV_GC_ROOT(_lv_task_ll), task);
- task_list_changed = true;
-
- lv_mem_free(task);
-
- if(LV_GC_ROOT(_lv_task_act) == task) task_deleted = true; /*The active task was deleted*/
-}
-
-/**
- * Set new priority for a lv_task
- * @param task pointer to a lv_task
- * @param prio the new priority
- */
-void lv_task_set_prio(lv_task_t * task, lv_task_prio_t prio)
-{
- if(task->prio == prio) return;
-
- /*Find the tasks with new priority*/
- lv_task_t * i;
- _LV_LL_READ(LV_GC_ROOT(_lv_task_ll), i) {
- if(i->prio <= prio) {
- if(i != task) _lv_ll_move_before(&LV_GC_ROOT(_lv_task_ll), task, 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_GC_ROOT(_lv_task_ll), task, NULL);
- }
- task_list_changed = true;
-
- task->prio = prio;
-}
-
-/**
- * Set new period for a lv_task
- * @param task pointer to a lv_task
- * @param period the new period
- */
-void lv_task_set_period(lv_task_t * task, uint32_t period)
-{
- task->period = period;
-}
-
-/**
- * Make a lv_task ready. It will not wait its period.
- * @param task pointer to a lv_task.
- */
-void lv_task_ready(lv_task_t * task)
-{
- task->last_run = lv_tick_get() - task->period - 1;
-}
-
-/**
- * Set the number of times a task will repeat.
- * @param task pointer to a lv_task.
- * @param repeat_count -1 : infinity; 0 : stop ; n>0: residual times
- */
-void lv_task_set_repeat_count(lv_task_t * task, int32_t repeat_count)
-{
- task->repeat_count = repeat_count;
-}
-
-/**
- * Reset a lv_task.
- * It will be called the previously set period milliseconds later.
- * @param task pointer to a lv_task.
- */
-void lv_task_reset(lv_task_t * task)
-{
- task->last_run = lv_tick_get();
-}
-
-/**
- * Enable or disable the whole lv_task handling
- * @param en: true: lv_task handling is running, false: lv_task handling is suspended
- */
-void lv_task_enable(bool en)
-{
- lv_task_run = en;
-}
-
-/**
- * Get idle percentage
- * @return the lv_task idle in percentage
- */
-uint8_t lv_task_get_idle(void)
-{
- return idle_last;
-}
-
-/**
- * Iterate through the tasks
- * @param task NULL to start iteration or the previous return value to get the next task
- * @return the next task or NULL if there is no more task
- */
-lv_task_t * lv_task_get_next(lv_task_t * task)
-{
- if(task == NULL) return _lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));
- else return _lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), task);
-}
-
-/**********************
- * STATIC FUNCTIONS
- **********************/
-
-/**
- * Execute task if its the priority is appropriate
- * @param task pointer to lv_task
- * @return true: execute, false: not executed
- */
-static bool lv_task_exec(lv_task_t * task)
-{
- bool exec = false;
-
- if(lv_task_time_remaining(task) == 0) {
- task->last_run = lv_tick_get();
- if(task->task_cb) task->task_cb(task);
-
- /*Delete if it was a one shot lv_task*/
- if(task_deleted == false) { /*The task might be deleted by itself as well*/
- if(task->repeat_count > 0) {
- task->repeat_count--;
- }
- if(task->repeat_count == 0) {
- lv_task_del(task);
- }
- }
- exec = true;
- }
-
- return exec;
-}
-
-/**
- * Find out how much time remains before a task must be run.
- * @param task pointer to lv_task
- * @return the time remaining, or 0 if it needs to be run again
- */
-static uint32_t lv_task_time_remaining(lv_task_t * task)
-{
- /*Check if at least 'period' time elapsed*/
- uint32_t elp = lv_tick_elaps(task->last_run);
- if(elp >= task->period)
- return 0;
- return task->period - elp;
-}