refactor(task): rename lv_task to lv_tmr and remove priorities
fixes #1925
This commit is contained in:
@@ -27,6 +27,11 @@ extern "C" {
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static LV_ATTRIBUTE_TMR_HANDLER uint32_t lv_task_handler(void)
|
||||
{
|
||||
return lv_tmr_handler();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -632,11 +632,11 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
#endif
|
||||
|
||||
/* Define a custom attribute to `lv_task_handler` function */
|
||||
#ifndef LV_ATTRIBUTE_TASK_HANDLER
|
||||
# ifdef CONFIG_LV_ATTRIBUTE_TASK_HANDLER
|
||||
# define LV_ATTRIBUTE_TASK_HANDLER CONFIG_LV_ATTRIBUTE_TASK_HANDLER
|
||||
#ifndef LV_ATTRIBUTE_TMR_HANDLER
|
||||
# ifdef CONFIG_LV_ATTRIBUTE_TMR_HANDLER
|
||||
# define LV_ATTRIBUTE_TMR_HANDLER CONFIG_LV_ATTRIBUTE_TMR_HANDLER
|
||||
# else
|
||||
# define LV_ATTRIBUTE_TASK_HANDLER
|
||||
# define LV_ATTRIBUTE_TMR_HANDLER
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -367,7 +367,7 @@ void lv_disp_clean_dcache(lv_disp_t * disp)
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * _lv_disp_get_refr_task(lv_disp_t * disp)
|
||||
lv_tmr_t * _lv_disp_get_refr_task(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
|
||||
@@ -145,7 +145,7 @@ void lv_disp_clean_dcache(lv_disp_t * disp);
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * _lv_disp_get_refr_task(lv_disp_t * disp);
|
||||
lv_tmr_t * _lv_disp_get_refr_task(lv_disp_t * disp);
|
||||
|
||||
/*------------------------------------------------
|
||||
* To improve backward compatibility
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "lv_refr.h"
|
||||
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "../lv_misc/lv_task.h"
|
||||
#include "../lv_misc/lv_tmr.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
@@ -70,7 +70,7 @@ void _lv_indev_init(void)
|
||||
* Called periodically to read the input devices
|
||||
* @param param pointer to and input device to read
|
||||
*/
|
||||
void _lv_indev_read_task(lv_task_t * task)
|
||||
void _lv_indev_read_task(lv_tmr_t * task)
|
||||
{
|
||||
LV_LOG_TRACE("indev read task started");
|
||||
|
||||
@@ -361,7 +361,7 @@ lv_obj_t * lv_indev_get_obj_act(void)
|
||||
* @param indev pointer to an input device
|
||||
* @return pointer to the indev read refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_indev_get_read_task(lv_disp_t * indev)
|
||||
lv_tmr_t * lv_indev_get_read_task(lv_disp_t * indev)
|
||||
{
|
||||
if(!indev) {
|
||||
LV_LOG_WARN("lv_indev_get_read_task: indev was NULL");
|
||||
|
||||
@@ -38,7 +38,7 @@ void _lv_indev_init(void);
|
||||
* Called periodically to read the input devices
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void _lv_indev_read_task(lv_task_t * task);
|
||||
void _lv_indev_read_task(lv_tmr_t * task);
|
||||
|
||||
/**
|
||||
* Get the currently processed input device. Can be used in action functions too.
|
||||
@@ -171,7 +171,7 @@ lv_obj_t * lv_indev_search_obj(lv_obj_t * obj, lv_point_t * point);
|
||||
* @param indev pointer to an inout device
|
||||
* @return pointer to the indev read refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_indev_get_read_task(lv_disp_t * indev);
|
||||
lv_tmr_t * lv_indev_get_read_task(lv_disp_t * indev);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
#include "../lv_misc/lv_task.h"
|
||||
#include "../lv_misc/lv_tmr.h"
|
||||
#include "../lv_misc/lv_async.h"
|
||||
#include "../lv_misc/lv_fs.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
@@ -100,7 +100,7 @@ void lv_init(void)
|
||||
|
||||
/*Initialize the lv_misc modules*/
|
||||
_lv_mem_init();
|
||||
_lv_task_core_init();
|
||||
_lv_tmr_core_init();
|
||||
|
||||
#if LV_USE_FILESYSTEM
|
||||
_lv_fs_init();
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "lv_disp.h"
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "../lv_hal/lv_hal_disp.h"
|
||||
#include "../lv_misc/lv_task.h"
|
||||
#include "../lv_misc/lv_tmr.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
@@ -144,7 +144,7 @@ void _lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
|
||||
lv_area_copy(&disp->inv_areas[disp->inv_p], &scr_area);
|
||||
}
|
||||
disp->inv_p++;
|
||||
lv_task_set_prio(disp->refr_task, LV_REFR_TASK_PRIO);
|
||||
lv_tmr_pause(disp->refr_task, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,20 +172,20 @@ void _lv_refr_set_disp_refreshing(lv_disp_t * disp)
|
||||
* Called periodically to handle the refreshing
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void _lv_disp_refr_task(lv_task_t * task)
|
||||
void _lv_disp_refr_task(lv_tmr_t * tmr)
|
||||
{
|
||||
LV_LOG_TRACE("lv_refr_task: started");
|
||||
|
||||
uint32_t start = lv_tick_get();
|
||||
uint32_t elaps = 0;
|
||||
|
||||
disp_refr = task->user_data;
|
||||
disp_refr = tmr->user_data;
|
||||
|
||||
#if LV_USE_PERF_MONITOR == 0
|
||||
/* Ensure the task does not run again automatically.
|
||||
* This is done before refreshing in case refreshing invalidates something else.
|
||||
*/
|
||||
lv_task_set_prio(task, LV_TASK_PRIO_OFF);
|
||||
lv_tmr_pause(tmr, true);
|
||||
#endif
|
||||
|
||||
/*Do nothing if there is no active screen*/
|
||||
|
||||
@@ -82,7 +82,7 @@ void _lv_refr_set_disp_refreshing(lv_disp_t * disp);
|
||||
* Called periodically to handle the refreshing
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void _lv_disp_refr_task(lv_task_t * task);
|
||||
void _lv_disp_refr_task(lv_tmr_t * task);
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
|
||||
@@ -137,7 +137,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
disp_def = disp; /*Temporarily change the default screen to create the default screens on the
|
||||
new display*/
|
||||
/*Create a refresh task*/
|
||||
disp->refr_task = lv_task_create(_lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, LV_REFR_TASK_PRIO, disp);
|
||||
disp->refr_task = lv_tmr_create(_lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, disp);
|
||||
LV_ASSERT_MEM(disp->refr_task);
|
||||
if(disp->refr_task == NULL) return NULL;
|
||||
|
||||
@@ -168,7 +168,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
|
||||
disp_def = disp_def_tmp; /*Revert the default display*/
|
||||
|
||||
lv_task_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/
|
||||
lv_tmr_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/
|
||||
|
||||
/*Can't handle this case later so add an error*/
|
||||
if(lv_disp_is_true_double_buf(disp) && disp->driver.set_px_cb) {
|
||||
|
||||
@@ -21,7 +21,7 @@ extern "C" {
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_ll.h"
|
||||
#include "../lv_misc/lv_task.h"
|
||||
#include "../lv_misc/lv_tmr.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -149,7 +149,7 @@ typedef struct _disp_t {
|
||||
lv_disp_drv_t driver;
|
||||
|
||||
/**< A task which periodically checks the dirty areas and refreshes them*/
|
||||
lv_task_t * refr_task;
|
||||
lv_tmr_t * refr_task;
|
||||
|
||||
/** Screens of the display*/
|
||||
lv_ll_t scr_ll;
|
||||
|
||||
@@ -92,7 +92,7 @@ lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
|
||||
indev->group = NULL;
|
||||
indev->btn_points = NULL;
|
||||
|
||||
indev->driver.read_task = lv_task_create(_lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, LV_TASK_PRIO_HIGH, indev);
|
||||
indev->driver.read_task = lv_tmr_create(_lv_indev_read_task, LV_INDEV_DEF_READ_PERIOD, indev);
|
||||
|
||||
return indev;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ extern "C" {
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_task.h"
|
||||
#include "../lv_misc/lv_tmr.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -100,7 +100,7 @@ typedef struct _lv_indev_drv_t {
|
||||
struct _disp_t * disp;
|
||||
|
||||
/**< Task to read the periodically read the input device*/
|
||||
lv_task_t * read_task;
|
||||
lv_tmr_t * read_task;
|
||||
|
||||
/**< Number of pixels to slide before actually drag the object*/
|
||||
uint8_t scroll_limit;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <string.h>
|
||||
#include "../lv_misc/lv_debug.h"
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "lv_task.h"
|
||||
#include "lv_tmr.h"
|
||||
#include "lv_math.h"
|
||||
#include "lv_gc.h"
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
*********************/
|
||||
#define LV_ANIM_RESOLUTION 1024
|
||||
#define LV_ANIM_RES_SHIFT 10
|
||||
#define LV_ANIM_TASK_PRIO LV_TASK_PRIO_HIGH
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@@ -35,7 +34,7 @@
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void anim_task(lv_task_t * param);
|
||||
static void anim_task(lv_tmr_t * param);
|
||||
static void anim_mark_list_change(void);
|
||||
static bool anim_ready_handler(lv_anim_t * a);
|
||||
|
||||
@@ -44,7 +43,7 @@ static bool anim_ready_handler(lv_anim_t * a);
|
||||
**********************/
|
||||
static uint32_t last_task_run;
|
||||
static bool anim_list_changed;
|
||||
static lv_task_t * _lv_anim_task;
|
||||
static lv_tmr_t * _lv_anim_tmr;
|
||||
const lv_anim_path_t lv_anim_path_def = {.cb = lv_anim_path_linear};
|
||||
|
||||
/**********************
|
||||
@@ -62,7 +61,7 @@ void _lv_anim_core_init(void)
|
||||
{
|
||||
_lv_ll_init(&LV_GC_ROOT(_lv_anim_ll), sizeof(lv_anim_t));
|
||||
last_task_run = lv_tick_get();
|
||||
_lv_anim_task = lv_task_create(anim_task, LV_DISP_DEF_REFR_PERIOD, LV_ANIM_TASK_PRIO, NULL);
|
||||
_lv_anim_tmr = lv_tmr_create(anim_task, LV_DISP_DEF_REFR_PERIOD, NULL);
|
||||
anim_mark_list_change(); /*Turn off the animation task*/
|
||||
anim_list_changed = false; /*The list has not actually changed*/
|
||||
}
|
||||
@@ -439,7 +438,7 @@ lv_anim_value_t lv_anim_path_step(const lv_anim_path_t * path, const lv_anim_t *
|
||||
* Periodically handle the animations.
|
||||
* @param param unused
|
||||
*/
|
||||
static void anim_task(lv_task_t * param)
|
||||
static void anim_task(lv_tmr_t * param)
|
||||
{
|
||||
(void)param;
|
||||
|
||||
@@ -555,8 +554,8 @@ static void anim_mark_list_change(void)
|
||||
{
|
||||
anim_list_changed = true;
|
||||
if(_lv_ll_get_head(&LV_GC_ROOT(_lv_anim_ll)) == NULL)
|
||||
lv_task_set_prio(_lv_anim_task, LV_TASK_PRIO_OFF);
|
||||
lv_tmr_pause(_lv_anim_tmr, true);
|
||||
else
|
||||
lv_task_set_prio(_lv_anim_task, LV_ANIM_TASK_PRIO);
|
||||
lv_tmr_pause(_lv_anim_tmr, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void lv_async_task_cb(lv_task_t * task);
|
||||
static void lv_async_task_cb(lv_tmr_t * task);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -45,7 +45,7 @@ lv_res_t lv_async_call(lv_async_cb_t async_xcb, void * user_data)
|
||||
|
||||
/* Create a new task */
|
||||
/* Use highest priority so that it will run before a refresh */
|
||||
lv_task_t * task = lv_task_create(lv_async_task_cb, 0, LV_TASK_PRIO_HIGHEST, info);
|
||||
lv_tmr_t * task = lv_tmr_create(lv_async_task_cb, 0, info);
|
||||
|
||||
if(task == NULL) {
|
||||
lv_mem_free(info);
|
||||
@@ -57,7 +57,7 @@ lv_res_t lv_async_call(lv_async_cb_t async_xcb, void * user_data)
|
||||
|
||||
/* Set the task's user data */
|
||||
task->user_data = info;
|
||||
lv_task_set_repeat_count(task, 1);
|
||||
lv_tmr_set_repeat_count(task, 1);
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ lv_res_t lv_async_call(lv_async_cb_t async_xcb, void * user_data)
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_async_task_cb(lv_task_t * task)
|
||||
static void lv_async_task_cb(lv_tmr_t * task)
|
||||
{
|
||||
lv_async_info_t * info = (lv_async_info_t *)task->user_data;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_task.h"
|
||||
#include "lv_tmr.h"
|
||||
#include "lv_types.h"
|
||||
|
||||
/*********************
|
||||
|
||||
@@ -17,7 +17,7 @@ extern "C" {
|
||||
#include <stdbool.h>
|
||||
#include "lv_mem.h"
|
||||
#include "lv_ll.h"
|
||||
#include "lv_task.h"
|
||||
#include "lv_tmr.h"
|
||||
#include "../lv_draw/lv_img_cache.h"
|
||||
#include "../lv_draw/lv_draw_mask.h"
|
||||
|
||||
@@ -26,7 +26,7 @@ extern "C" {
|
||||
*********************/
|
||||
|
||||
#define LV_ITERATE_ROOTS(f) \
|
||||
f(lv_ll_t, _lv_task_ll) /*Linked list to store the lv_tasks*/ \
|
||||
f(lv_ll_t, _lv_tmr_ll) /*Linked list to store the lv_tmr-s*/ \
|
||||
f(lv_ll_t, _lv_disp_ll) /*Linked list of screens*/ \
|
||||
f(lv_ll_t, _lv_indev_ll) /*Linked list of screens*/ \
|
||||
f(lv_ll_t, _lv_drv_ll) \
|
||||
@@ -36,11 +36,10 @@ extern "C" {
|
||||
f(lv_ll_t, _lv_img_defoder_ll) \
|
||||
f(lv_ll_t, _lv_obj_style_trans_ll) \
|
||||
f(lv_img_cache_entry_t*, _lv_img_cache_array) \
|
||||
f(lv_task_t*, _lv_task_act) \
|
||||
f(lv_tmr_t*, _lv_tmr_act) \
|
||||
f(lv_mem_buf_arr_t , _lv_mem_buf) \
|
||||
f(_lv_draw_mask_saved_arr_t , _lv_draw_mask_list) \
|
||||
f(void * , _lv_theme_material_styles) \
|
||||
f(void * , _lv_theme_template_styles) \
|
||||
f(void * , _lv_theme_mono_styles) \
|
||||
f(void * , _lv_theme_empty_styles) \
|
||||
f(uint8_t *, _lv_font_decompr_buf) \
|
||||
|
||||
@@ -1,439 +0,0 @@
|
||||
/**
|
||||
* @file lv_task.c
|
||||
* An 'lv_task' is a void (*fp) (void* 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"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* 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));
|
||||
|
||||
task_list_changed = false;
|
||||
/*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;
|
||||
|
||||
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) {
|
||||
already_running = false; /*Release mutex*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
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_task_t *)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_task_t *)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_task_t *)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;
|
||||
task_list_changed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
LV_GC_ROOT(_lv_task_act) = next; /*Load the next task*/
|
||||
}
|
||||
} while(!end_flag);
|
||||
|
||||
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 = (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*/
|
||||
busy_time = 0;
|
||||
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*/
|
||||
|
||||
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)
|
||||
{
|
||||
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 <= DEF_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 = DEF_PERIOD;
|
||||
new_task->task_cb = NULL;
|
||||
new_task->prio = DEF_PRIO;
|
||||
|
||||
new_task->repeat_count = -1;
|
||||
new_task->last_run = lv_tick_get();
|
||||
|
||||
new_task->user_data = NULL;
|
||||
|
||||
task_created = true;
|
||||
|
||||
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)
|
||||
* @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();
|
||||
task_deleted = false;
|
||||
task_created = false;
|
||||
if(task->task_cb) task->task_cb(task);
|
||||
LV_ASSERT_MEM_INTEGRITY();
|
||||
|
||||
/*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;
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
/**
|
||||
* @file lv_task.c
|
||||
* An 'lv_task' is a void (*fp) (void* param) type function which will be called periodically.
|
||||
* A priority (5 levels + disable) can be assigned to lv_tasks.
|
||||
*/
|
||||
|
||||
#ifndef LV_TASK_H
|
||||
#define LV_TASK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_mem.h"
|
||||
#include "lv_ll.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef LV_ATTRIBUTE_TASK_HANDLER
|
||||
#define LV_ATTRIBUTE_TASK_HANDLER
|
||||
#endif
|
||||
|
||||
#define LV_NO_TASK_READY 0xFFFFFFFF
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct _lv_task_t;
|
||||
|
||||
/**
|
||||
* Tasks execute this type type of functions.
|
||||
*/
|
||||
typedef void (*lv_task_cb_t)(struct _lv_task_t *);
|
||||
|
||||
/**
|
||||
* Possible priorities for lv_tasks
|
||||
*/
|
||||
enum {
|
||||
LV_TASK_PRIO_OFF = 0,
|
||||
LV_TASK_PRIO_LOWEST,
|
||||
LV_TASK_PRIO_LOW,
|
||||
LV_TASK_PRIO_MID,
|
||||
LV_TASK_PRIO_HIGH,
|
||||
LV_TASK_PRIO_HIGHEST,
|
||||
_LV_TASK_PRIO_NUM,
|
||||
};
|
||||
typedef uint8_t lv_task_prio_t;
|
||||
|
||||
/**
|
||||
* Descriptor of a lv_task
|
||||
*/
|
||||
typedef struct _lv_task_t {
|
||||
uint32_t period; /**< How often the task should run */
|
||||
uint32_t last_run; /**< Last time the task ran */
|
||||
lv_task_cb_t task_cb; /**< Task function */
|
||||
|
||||
void * user_data; /**< Custom user data */
|
||||
|
||||
int32_t repeat_count; /**< 1: Task times; -1 : infinity; 0 : stop ; n>0: residual times */
|
||||
uint8_t prio : 3; /**< Task priority */
|
||||
} lv_task_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init the lv_task module
|
||||
*/
|
||||
void _lv_task_core_init(void);
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
/**
|
||||
* Call it periodically to handle lv_tasks.
|
||||
* @return time till it needs to be run next (in ms)
|
||||
*/
|
||||
LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_task_handler(void);
|
||||
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Delete a lv_task
|
||||
* @param task pointer to task_cb created by task
|
||||
*/
|
||||
void lv_task_del(lv_task_t * 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Get idle percentage
|
||||
* @return the lv_task idle in percentage
|
||||
*/
|
||||
uint8_t lv_task_get_idle(void);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
340
src/lv_misc/lv_tmr.c
Normal file
340
src/lv_misc/lv_tmr.c
Normal file
@@ -0,0 +1,340 @@
|
||||
/**
|
||||
* @file lv_tmr.c
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stddef.h>
|
||||
#include "lv_tmr.h"
|
||||
#include "../lv_misc/lv_debug.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
|
||||
*********************/
|
||||
#define IDLE_MEAS_PERIOD 500 /*[ms]*/
|
||||
#define DEF_PERIOD 500
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static bool lv_tmr_exec(lv_tmr_t * tmr);
|
||||
static uint32_t lv_tmr_time_remaining(lv_tmr_t * tmr);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static bool lv_tmr_run = false;
|
||||
static uint8_t idle_last = 0;
|
||||
static bool tmr_deleted;
|
||||
static bool tmr_created;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init the lv_tmr module
|
||||
*/
|
||||
void _lv_tmr_core_init(void)
|
||||
{
|
||||
_lv_ll_init(&LV_GC_ROOT(_lv_tmr_ll), sizeof(lv_tmr_t));
|
||||
|
||||
/*Initially enable the lv_tmr handling*/
|
||||
lv_tmr_enable(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call it periodically to handle lv_tmrs.
|
||||
* @return the time after which it must be called again
|
||||
*/
|
||||
LV_ATTRIBUTE_TASK_HANDLER uint32_t lv_tmr_handler(void)
|
||||
{
|
||||
LV_LOG_TRACE("lv_tmr_handler started");
|
||||
|
||||
/*Avoid concurrent running of the tmr handler*/
|
||||
static bool already_running = false;
|
||||
if(already_running) return 1;
|
||||
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_tmr_run == false) {
|
||||
already_running = false; /*Release mutex*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
handler_start = lv_tick_get();
|
||||
|
||||
/* Run all tmr from the highest to the lowest priority
|
||||
* If a lower priority tmr is executed check tmr again from the highest priority
|
||||
* but on the priority of executed tmrs don't run tmrs before the executed*/
|
||||
lv_tmr_t * next;
|
||||
bool end_flag;
|
||||
do {
|
||||
end_flag = true;
|
||||
tmr_deleted = false;
|
||||
tmr_created = false;
|
||||
LV_GC_ROOT(_lv_tmr_act) = _lv_ll_get_head(&LV_GC_ROOT(_lv_tmr_ll));
|
||||
while(LV_GC_ROOT(_lv_tmr_act)) {
|
||||
/* The tmr might be deleted if it runs only once ('repeat_count = 1')
|
||||
* So get next element until the current is surely valid*/
|
||||
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_tmr_ll), LV_GC_ROOT(_lv_tmr_act));
|
||||
|
||||
if(lv_tmr_exec(LV_GC_ROOT(_lv_tmr_act))) {
|
||||
if(!tmr_created && !tmr_deleted) {
|
||||
end_flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*If a tmr was created or deleted then this or the next item might be corrupted*/
|
||||
if(tmr_created || tmr_deleted) {
|
||||
break;
|
||||
}
|
||||
|
||||
LV_GC_ROOT(_lv_tmr_act) = next; /*Load the next tmr*/
|
||||
}
|
||||
} while(!end_flag);
|
||||
|
||||
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 = (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*/
|
||||
busy_time = 0;
|
||||
idle_period_start = lv_tick_get();
|
||||
}
|
||||
|
||||
time_till_next = LV_NO_TMR_READY;
|
||||
next = _lv_ll_get_head(&LV_GC_ROOT(_lv_tmr_ll));
|
||||
while(next) {
|
||||
if(next->repeat_count) {
|
||||
uint32_t delay = lv_tmr_time_remaining(next);
|
||||
if(delay < time_till_next)
|
||||
time_till_next = delay;
|
||||
}
|
||||
|
||||
next = _lv_ll_get_next(&LV_GC_ROOT(_lv_tmr_ll), next); /*Find the next tmr*/
|
||||
}
|
||||
|
||||
already_running = false; /*Release the mutex*/
|
||||
|
||||
LV_LOG_TRACE("lv_tmr_handler ready");
|
||||
return time_till_next;
|
||||
}
|
||||
/**
|
||||
* Create an "empty" tmr. It needs to initialized with at least
|
||||
* `lv_tmr_set_cb` and `lv_tmr_set_period`
|
||||
* @return pointer to the created tmr
|
||||
*/
|
||||
lv_tmr_t * lv_tmr_create_basic(void)
|
||||
{
|
||||
lv_tmr_t * new_tmr = NULL;
|
||||
|
||||
new_tmr = _lv_ll_ins_head(&LV_GC_ROOT(_lv_tmr_ll));
|
||||
LV_ASSERT_MEM(new_tmr);
|
||||
if(new_tmr == NULL) return NULL;
|
||||
|
||||
new_tmr->period = DEF_PERIOD;
|
||||
new_tmr->tmr_cb = NULL;
|
||||
new_tmr->repeat_count = -1;
|
||||
new_tmr->paused = 0;
|
||||
new_tmr->last_run = lv_tick_get();
|
||||
new_tmr->user_data = NULL;
|
||||
|
||||
tmr_created = true;
|
||||
|
||||
return new_tmr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new lv_tmr
|
||||
* @param tmr_xcb a callback which is the tmr 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 tmr (LV_TASK_PRIO_OFF means the tmr is stopped)
|
||||
* @param user_data custom parameter
|
||||
* @return pointer to the new tmr
|
||||
*/
|
||||
lv_tmr_t * lv_tmr_create(lv_tmr_cb_t tmr_xcb, uint32_t period, void * user_data)
|
||||
{
|
||||
lv_tmr_t * new_tmr = lv_tmr_create_basic();
|
||||
LV_ASSERT_MEM(new_tmr);
|
||||
if(new_tmr == NULL) return NULL;
|
||||
|
||||
lv_tmr_set_cb(new_tmr, tmr_xcb);
|
||||
lv_tmr_set_period(new_tmr, period);
|
||||
new_tmr->user_data = user_data;
|
||||
|
||||
return new_tmr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the callback the tmr (the function to call periodically)
|
||||
* @param tmr pointer to a tmr
|
||||
* @param tmr_cb the function to call periodically
|
||||
*/
|
||||
void lv_tmr_set_cb(lv_tmr_t * tmr, lv_tmr_cb_t tmr_cb)
|
||||
{
|
||||
tmr->tmr_cb = tmr_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a lv_tmr
|
||||
* @param tmr pointer to tmr created by tmr
|
||||
*/
|
||||
void lv_tmr_del(lv_tmr_t * tmr)
|
||||
{
|
||||
_lv_ll_remove(&LV_GC_ROOT(_lv_tmr_ll), tmr);
|
||||
tmr_deleted = true;
|
||||
|
||||
lv_mem_free(tmr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause/resume a timer.
|
||||
* @param tmr pointer to an lv_tmr
|
||||
* @param pause true: pause the timer; false: resume
|
||||
*/
|
||||
void lv_tmr_pause(lv_tmr_t * tmr, bool pause)
|
||||
{
|
||||
tmr->paused = pause;
|
||||
|
||||
}
|
||||
/**
|
||||
* Set new period for a lv_tmr
|
||||
* @param tmr pointer to a lv_tmr
|
||||
* @param period the new period
|
||||
*/
|
||||
void lv_tmr_set_period(lv_tmr_t * tmr, uint32_t period)
|
||||
{
|
||||
tmr->period = period;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a lv_tmr ready. It will not wait its period.
|
||||
* @param tmr pointer to a lv_tmr.
|
||||
*/
|
||||
void lv_tmr_ready(lv_tmr_t * tmr)
|
||||
{
|
||||
tmr->last_run = lv_tick_get() - tmr->period - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of times a tmr will repeat.
|
||||
* @param tmr pointer to a lv_tmr.
|
||||
* @param repeat_count -1 : infinity; 0 : stop ; n >0: residual times
|
||||
*/
|
||||
void lv_tmr_set_repeat_count(lv_tmr_t * tmr, int32_t repeat_count)
|
||||
{
|
||||
tmr->repeat_count = repeat_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset a lv_tmr.
|
||||
* It will be called the previously set period milliseconds later.
|
||||
* @param tmr pointer to a lv_tmr.
|
||||
*/
|
||||
void lv_tmr_reset(lv_tmr_t * tmr)
|
||||
{
|
||||
tmr->last_run = lv_tick_get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable the whole lv_tmr handling
|
||||
* @param en: true: lv_tmr handling is running, false: lv_tmr handling is suspended
|
||||
*/
|
||||
void lv_tmr_enable(bool en)
|
||||
{
|
||||
lv_tmr_run = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get idle percentage
|
||||
* @return the lv_tmr idle in percentage
|
||||
*/
|
||||
uint8_t lv_tmr_get_idle(void)
|
||||
{
|
||||
return idle_last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate through the tmrs
|
||||
* @param tmr NULL to start iteration or the previous return value to get the next tmr
|
||||
* @return the next tmr or NULL if there is no more tmr
|
||||
*/
|
||||
lv_tmr_t * lv_tmr_get_next(lv_tmr_t * tmr)
|
||||
{
|
||||
if(tmr == NULL) return _lv_ll_get_head(&LV_GC_ROOT(_lv_tmr_ll));
|
||||
else return _lv_ll_get_next(&LV_GC_ROOT(_lv_tmr_ll), tmr);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Execute tmr if its the priority is appropriate
|
||||
* @param tmr pointer to lv_tmr
|
||||
* @return true: execute, false: not executed
|
||||
*/
|
||||
static bool lv_tmr_exec(lv_tmr_t * tmr)
|
||||
{
|
||||
if(tmr->paused) return false;
|
||||
|
||||
bool exec = false;
|
||||
if(lv_tmr_time_remaining(tmr) == 0) {
|
||||
tmr->last_run = lv_tick_get();
|
||||
tmr_deleted = false;
|
||||
tmr_created = false;
|
||||
if(tmr->tmr_cb) tmr->tmr_cb(tmr);
|
||||
LV_ASSERT_MEM_INTEGRITY();
|
||||
|
||||
/*Delete if it was a one shot lv_tmr*/
|
||||
if(tmr_deleted == false) { /*The tmr might be deleted by itself as well*/
|
||||
if(tmr->repeat_count > 0) {
|
||||
tmr->repeat_count--;
|
||||
}
|
||||
if(tmr->repeat_count == 0) {
|
||||
lv_tmr_del(tmr);
|
||||
}
|
||||
}
|
||||
exec = true;
|
||||
}
|
||||
|
||||
return exec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out how much time remains before a tmr must be run.
|
||||
* @param tmr pointer to lv_tmr
|
||||
* @return the time remaining, or 0 if it needs to be run again
|
||||
*/
|
||||
static uint32_t lv_tmr_time_remaining(lv_tmr_t * tmr)
|
||||
{
|
||||
/*Check if at least 'period' time elapsed*/
|
||||
uint32_t elp = lv_tick_elaps(tmr->last_run);
|
||||
if(elp >= tmr->period)
|
||||
return 0;
|
||||
return tmr->period - elp;
|
||||
}
|
||||
157
src/lv_misc/lv_tmr.h
Normal file
157
src/lv_misc/lv_tmr.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* @file lv_tmr.h
|
||||
*/
|
||||
|
||||
#ifndef LV_TMR_H
|
||||
#define LV_TMR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_mem.h"
|
||||
#include "lv_ll.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef LV_ATTRIBUTE_TMR_HANDLER
|
||||
#define LV_ATTRIBUTE_TMR_HANDLER
|
||||
#endif
|
||||
|
||||
#define LV_NO_TMR_READY 0xFFFFFFFF
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct _lv_tmr_t;
|
||||
|
||||
/**
|
||||
* Tasks execute this type type of functions.
|
||||
*/
|
||||
typedef void (*lv_tmr_cb_t)(struct _lv_tmr_t *);
|
||||
|
||||
/**
|
||||
* Descriptor of a lv_tmr
|
||||
*/
|
||||
typedef struct _lv_tmr_t {
|
||||
uint32_t period; /**< How often the tmr should run */
|
||||
uint32_t last_run; /**< Last time the tmr ran */
|
||||
lv_tmr_cb_t tmr_cb; /**< Task function */
|
||||
void * user_data; /**< Custom user data */
|
||||
int32_t repeat_count; /**< 1: One time; -1 : infinity; n>0: residual times */
|
||||
uint32_t paused :1;
|
||||
} lv_tmr_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init the lv_tmr module
|
||||
*/
|
||||
void _lv_tmr_core_init(void);
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
/**
|
||||
* Call it periodically to handle lv_tmrs.
|
||||
* @return time till it needs to be run next (in ms)
|
||||
*/
|
||||
LV_ATTRIBUTE_TMR_HANDLER uint32_t lv_tmr_handler(void);
|
||||
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
* Create an "empty" tmr. It needs to initialized with at least
|
||||
* `lv_tmr_set_cb` and `lv_tmr_set_period`
|
||||
* @return pointer to the created tmr
|
||||
*/
|
||||
lv_tmr_t * lv_tmr_create_basic(void);
|
||||
|
||||
/**
|
||||
* Create a new lv_tmr
|
||||
* @param tmr_xcb a callback to call 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 user_data custom parameter
|
||||
* @return pointer to the new timer
|
||||
*/
|
||||
lv_tmr_t * lv_tmr_create(lv_tmr_cb_t tmr_xcb, uint32_t period, void * user_data);
|
||||
|
||||
/**
|
||||
* Delete a lv_tmr
|
||||
* @param tmr pointer to an lv_tmr
|
||||
*/
|
||||
void lv_tmr_del(lv_tmr_t * tmr);
|
||||
|
||||
/**
|
||||
* Pause/resume a timer.
|
||||
* @param tmr pointer to an lv_tmr
|
||||
* @param pause true: pause the timer; false: resume
|
||||
*/
|
||||
void lv_tmr_pause(lv_tmr_t * tmr, bool pause);
|
||||
|
||||
/**
|
||||
* Set the callback the tmr (the function to call periodically)
|
||||
* @param tmr pointer to a tmr
|
||||
* @param tmr_cb the function to call periodically
|
||||
*/
|
||||
void lv_tmr_set_cb(lv_tmr_t * tmr, lv_tmr_cb_t tmr_cb);
|
||||
|
||||
/**
|
||||
* Make a lv_tmr ready. It will not wait its period.
|
||||
* @param tmr pointer to a lv_tmr.
|
||||
*/
|
||||
void lv_tmr_ready(lv_tmr_t * tmr);
|
||||
|
||||
/**
|
||||
* Set the number of times a tmr will repeat.
|
||||
* @param tmr pointer to a lv_tmr.
|
||||
* @param repeat_count -1 : infinity; 0 : stop ; n>0: residual times
|
||||
*/
|
||||
void lv_tmr_set_repeat_count(lv_tmr_t * tmr, int32_t repeat_count);
|
||||
|
||||
/**
|
||||
* Reset a lv_tmr.
|
||||
* It will be called the previously set period milliseconds later.
|
||||
* @param tmr pointer to a lv_tmr.
|
||||
*/
|
||||
void lv_tmr_reset(lv_tmr_t * tmr);
|
||||
|
||||
/**
|
||||
* Enable or disable the whole lv_tmr handling
|
||||
* @param en: true: lv_tmr handling is running, false: lv_tmr handling is suspended
|
||||
*/
|
||||
void lv_tmr_enable(bool en);
|
||||
|
||||
/**
|
||||
* Get idle percentage
|
||||
* @return the lv_tmr idle in percentage
|
||||
*/
|
||||
uint8_t lv_tmr_get_idle(void);
|
||||
|
||||
/**
|
||||
* Iterate through the tmrs
|
||||
* @param tmr NULL to start iteration or the previous return value to get the next tmr
|
||||
* @return the next tmr or NULL if there is no more tmr
|
||||
*/
|
||||
lv_tmr_t * lv_tmr_get_next(lv_tmr_t * tmr);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user