/** @file task.h * Module handling the task creation and management * * The module provides an API to create, run and manage lightweight, stack-less * threads (tasks). This system is based on protothreads, * see https://dunkels.com/adam/pt/index.html */ #ifndef _task_h_ #define _task_h_ //--includes-------------------------------------------------------------------- #include #include //--type definitions------------------------------------------------------------ struct TaskReturn { uint32_t delay_ms; uint8_t state; }; typedef struct TaskReturn(*Task)(uint8_t); //--functions------------------------------------------------------------------- #define TASK(fct_name) struct TaskReturn fct_name(uint8_t __task_state) #define TASK_ENTRY \ _TASK_COUNT_INIT; \ switch (__task_state) { #define TASK_CLEANUP \ case (_TASK_COUNT_CLEANUP): \ /* fall through */ #define TASK_EXIT \ } \ return (struct TaskReturn){0, _TASK_COUNT_EXIT}; #define TASK_YIELD() _TASK_YIELD(_TASK_COUNT_INCR) #define TASK_SLEEP(delay_ms) _TASK_SLEEP(delay_ms, _TASK_COUNT_INCR) #define TASK_WAIT_UNTIL(cond) _TASK_WAIT_UNTIL(cond, _TASK_COUNT_INCR) #define TASK_EXECUTE(task) _TASK_EXECUTE(task, _TASK_COUNT_INCR) void task_start_scheduler(void); void task_start(Task task); void task_stop(Task task); bool task_is_running(Task task); //--internal_functions---------------------------------------------------------- #define _TASK_COUNT_INIT enum { TASK_COUNTER_BASE = __COUNTER__ } #define _TASK_COUNT_INCR (uint8_t)(__COUNTER__ - TASK_COUNTER_BASE - 1) #define _TASK_COUNT_EXIT UINT8_MAX #define _TASK_COUNT_CLEANUP (UINT8_MAX - 1) #define _TASK(fct_name) #define _TASK_YIELD(count) do { \ return (struct TaskReturn){0, count}; \ case (count): \ /* fall through */ \ } while (0) #define _TASK_SLEEP(delay_ms, count) do { \ return (struct TaskReturn){delay_ms, count}; \ case (count): \ /* fall through */ \ } while (0) #define _TASK_WAIT_UNTIL(cond, count) do { \ case (count): \ if (!(cond)) { \ return (struct TaskReturn){0, count}; \ } \ /* fall through */ \ } while (0) #define _TASK_EXECUTE(task, count) do { \ task_start(Task task); \ return (struct TaskReturn){0, count); \ case (count): \ if (task_is_running(task)) { \ return (struct TaskReturn){0, count}; \ } \ /* fall through */ \ } while (0) #endif //_task_h_