From 63c952711cc25260ecf00788ce7c283828261e01 Mon Sep 17 00:00:00 2001 From: Angoosh Leviocki Date: Wed, 16 Mar 2022 22:01:38 +0100 Subject: [PATCH] Added sheduler to rule them all --- Adv_Scheduler.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++ Adv_Scheduler.h | 33 ++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 Adv_Scheduler.c create mode 100644 Adv_Scheduler.h diff --git a/Adv_Scheduler.c b/Adv_Scheduler.c new file mode 100644 index 0000000..e081241 --- /dev/null +++ b/Adv_Scheduler.c @@ -0,0 +1,137 @@ +/* + * Adv_Scheduler.c + * + * Created on: Mar 16, 2022 + * Author: angoosh + */ + +#include "Adv_Scheduler.h" +#include "main.h" + +tTask tasks[MAX_TASKS]; +uint8_t n_o_tasks; +uint32_t disabled_tasks; + + +void Adv_Scheduler_Init(); +void Adv_Scheduler_Add_Task(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period); +int Adv_Scheduler_Remove_Task(void (*exec)(void *), void *handle); +int Adv_Scheduler_Disable_Task(void (*exec)(void *), void *handle); +int Adv_Scheduler_Enable_Task(void (*exec)(void *), void *handle); +void Adv_Scheduler_Update(); +void Adv_Scheduler_Exec(); + +/** + * @brief Initialize sheduler + * @retval none + */ +void Adv_Scheduler_Init(){ + n_o_tasks = 0; + disabled_tasks = 0; +} + +/** + * @brief Add task to scheduler + * @param function to be executed + * @param input parameters for the function + * @param initial delay after which execution will take place + * @param delay between executions + * @retval none + */ +void Adv_Scheduler_Add_Task(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period){ + tasks[n_o_tasks].delay = delay; + tasks[n_o_tasks].exec = exec; + tasks[n_o_tasks].handle = handle; + tasks[n_o_tasks].period = period; + n_o_tasks ++; +} + +/** + * @brief Remove task from scheduler + * @param function to be removed + * @param input parameters for the function, needed to identify concrete process + * @retval success if 0 + */ +int Adv_Scheduler_Remove_Task(void (*exec)(void *), void *handle){ + for(int task = 0; task < n_o_tasks; task++){ + if((tasks[task].exec == exec) && (tasks[task].handle == handle)){ + if(task != (n_o_tasks - 1)){ + for(int i = 0; i < (n_o_tasks - task); i++){ + tasks[task].delay = tasks[task + 1].delay; + tasks[task].exec = tasks[task + 1].exec; + tasks[task].handle = tasks[task + 1].handle; + tasks[task].period = tasks[task + 1].period; + tasks[task].run = tasks[task + 1].run; + } + } + n_o_tasks --; + return 0; + } + } + return 1;//task does not exist +} + +/** + * @brief Disable task. Doesn't remove the task, only disables it for future if needed + * @param function to be disabled + * @param input parameters for the function, needed to identify concrete process + * @retval success if 0 + */ +int Adv_Scheduler_Disable_Task(void (*exec)(void *), void *handle){ + for(int task = 0; task < n_o_tasks; task++){ + if((tasks[task].exec == exec) && (tasks[task].handle == handle)){ + disabled_tasks += (1 << task); + return 0; + } + } + return 1;//task does not exist +} + +/** + * @brief Enable existing task + * @param function to be enabled + * @param input parameters for the function, needed to identify concrete process + * @retval success if 0 + */ +int Adv_Scheduler_Enable_Task(void (*exec)(void *), void *handle){ + for(int task = 0; task < n_o_tasks; task++){ + if((tasks[task].exec == exec) && (tasks[task].handle == handle)){ + disabled_tasks = disabled_tasks & ~(1 << task); + return 0; + } + } + return 1;//task does not exist +} + +/** + * @brief Update scheduler state, should be executed by timer periodically. + * Period dictates how long will delay values be. + * @retval none + */ +void Adv_Scheduler_Update(){ + for(int task = 0; task < n_o_tasks; task++){ + if((disabled_tasks & (1 << task)) == 0){ + if(tasks[task].delay == 0){ + tasks[task].delay = tasks[task].period; + tasks[task].run ++; + } + else{ + tasks[task].delay --; + } + } + } +} + +/** + * @brief Execute all tasks which have to be executed (run value > 0) + * Task will be executed run number of times. + * @retval none + */ +void Adv_Scheduler_Exec(){ + for(int task = 0; task < n_o_tasks; task++){ + if(tasks[task].run != 0){ + tasks[task].exec(tasks[task].handle); + tasks[task].run --; + } + } +} diff --git a/Adv_Scheduler.h b/Adv_Scheduler.h new file mode 100644 index 0000000..2fb4708 --- /dev/null +++ b/Adv_Scheduler.h @@ -0,0 +1,33 @@ +/* + * Adv_Scheduler.h + * + * Created on: Mar 16, 2022 + * Author: angoosh + */ + +#ifndef INC_ADV_SCHEDULER_H_ +#define INC_ADV_SCHEDULER_H_ + +#include "stm32l0xx_hal.h" + +#define MAX_TASKS 32 + + +typedef struct { + uint32_t delay; + uint32_t period; + uint8_t run; + void (*exec)(void *handle); + void *handle; +} tTask; + + +void Adv_Scheduler_Init(); +void Adv_Scheduler_Add_Task(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period); +int Adv_Scheduler_Remove_Task(void (*exec)(void *), void *handle); +int Adv_Scheduler_Disable_Task(void (*exec)(void *), void *handle); +int Adv_Scheduler_Enable_Task(void (*exec)(void *), void *handle); +void Adv_Scheduler_Update(); +void Adv_Scheduler_Exec(); + +#endif /* INC_ADV_SCHEDULER_H_ */