Scheduler.h 10.4 KB
Newer Older
 Dean Camera committed May 08, 2010 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 /* LUFA Library Copyright (C) Dean Camera, 2010. dean [at] fourwalledcubicle [dot] com www.fourwalledcubicle.com */ /* Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. */ /** \file * \brief Simple round-robbin pseudo-task scheduler. * * Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need * to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group. * * \deprecated This module is deprecated and will be removed in a future library release. */ /** @defgroup Group_Scheduler Simple Task Scheduler - LUFA/Scheduler/Scheduler.h * * \deprecated This module is deprecated and will be removed in a future library release. * * \section Sec_Dependencies Module Source Dependencies * The following files must be built with any user project that uses this module:  Dean Camera committed Jul 19, 2010 46  * - LUFA/Scheduler/Scheduler.c (Makefile source module name: LUFA_SRC_SCHEDULER)  Dean Camera committed May 08, 2010 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89  * * \section Module Description * Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need * to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group. * * For a task to yield it must return, thus each task should have persistent data marked with the static attribute. * * Usage Example: * \code * #include * * TASK(MyTask1); * TASK(MyTask2); * * TASK_LIST * { * { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1 }, * { .Task = MyTask2, .TaskStatus = TASK_RUN, .GroupID = 1 }, * } * * int main(void) * { * Scheduler_Start(); * } * * TASK(MyTask1) * { * // Implementation Here * } * * TASK(MyTask2) * { * // Implementation Here * } * \endcode * * @{ */ #ifndef __SCHEDULER_H__ #define __SCHEDULER_H__ /* Includes: */  Dean Camera committed Jul 21, 2010 90  #include  Dean Camera committed May 08, 2010 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113  #include #include #include "../Common/Common.h" /* Enable C linkage for C++ Compilers: */ #if defined(__cplusplus) extern "C" { #endif /* Public Interface - May be used in end-application: */ /* Macros: */ /** Creates a new scheduler task body or prototype. Should be used in the form: * \code * TASK(TaskName); // Prototype * * TASK(TaskName) * { * // Task body * } * \endcode */  Dean Camera committed May 16, 2010 114  #define TASK(name) void name (void)  Dean Camera committed May 08, 2010 115 116 117 118 119 120 121 122 123 124 125 126 127  /** Defines a task list array, containing one or more task entries of the type TaskEntry_t. Each task list * should be encased in curly braces and ended with a comma. * * Usage Example: * \code * TASK_LIST * { * { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1 }, * // More task entries here * } * \endcode */  Dean Camera committed May 16, 2010 128  #define TASK_LIST TaskEntry_t Scheduler_TaskList[] =  Dean Camera committed May 08, 2010 129 130  /** Constant, giving the maximum delay in scheduler ticks which can be stored in a variable of type  Dean Camera committed Jun 17, 2010 131  * \ref SchedulerDelayCounter_t.  Dean Camera committed May 08, 2010 132  */  Dean Camera committed May 16, 2010 133  #define TASK_MAX_DELAY (MAX_DELAYCTR_COUNT - 1)  Dean Camera committed May 08, 2010 134   Dean Camera committed Jun 17, 2010 135  /** Task status mode constant, for passing to \ref Scheduler_SetTaskMode() or \ref Scheduler_SetGroupTaskMode(). */  Dean Camera committed May 16, 2010 136  #define TASK_RUN true  Dean Camera committed May 08, 2010 137   Dean Camera committed Jun 17, 2010 138  /** Task status mode constant, for passing to \ref Scheduler_SetTaskMode() or \ref Scheduler_SetGroupTaskMode(). */  Dean Camera committed May 16, 2010 139  #define TASK_STOP false  Dean Camera committed May 08, 2010 140 141 142 143 144 145 146 147 148 149 150 151 152 153  /* Pseudo-Function Macros: */ #if defined(__DOXYGEN__) /** Starts the scheduler in its infinite loop, executing running tasks. This should be placed at the end * of the user application's main() function, as it can never return to the calling function. */ void Scheduler_Start(void); /** Initializes the scheduler so that the scheduler functions can be called before the scheduler itself * is started. This must be executed before any scheduler function calls other than Scheduler_Start(), * and can be omitted if no such functions could be called before the scheduler is started. */ void Scheduler_Init(void); #else  Dean Camera committed May 16, 2010 154 155  #define Scheduler_Start() Scheduler_GoSchedule(TOTAL_TASKS); #define Scheduler_Init() Scheduler_InitScheduler(TOTAL_TASKS);  Dean Camera committed May 08, 2010 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182  #endif /* Type Defines: */ /** Type define for a pointer to a scheduler task. */ typedef void (*TaskPtr_t)(void); /** Type define for a variable which can hold a tick delay value for the scheduler up to the maximum delay * possible. */ typedef uint16_t SchedulerDelayCounter_t; /** \brief Scheduler Task List Entry Structure. * * Structure for holding a single task's information in the scheduler task list. */ typedef struct { TaskPtr_t Task; /**< Pointer to the task to execute. */ bool TaskStatus; /**< Status of the task (either TASK_RUN or TASK_STOP). */ uint8_t GroupID; /**< Group ID of the task so that its status can be changed as a group. */ } TaskEntry_t; /* Global Variables: */ /** Task entry list, containing the scheduler tasks, task statuses and group IDs. Each entry is of type * TaskEntry_t and can be manipulated as desired, although it is preferential that the proper Scheduler * functions should be used instead of direct manipulation. */  Dean Camera committed May 16, 2010 183  exter TaskEntry_t Scheduler_TaskList[];  Dean Camera committed May 08, 2010 184 185  /** Contains the total number of tasks in the task list, irrespective of if the task's status is set to  Dean Camera committed Jun 17, 2010 186  * \ref TASK_RUN or \ref TASK_STOP.  Dean Camera committed May 08, 2010 187 188 189  * * \note This value should be treated as read-only, and never altered in user-code. */  Dean Camera committed May 16, 2010 190  extern volatile uint8_t Scheduler_TotalTasks;  Dean Camera committed May 08, 2010 191 192 193 194 195  /** Contains the current scheduler tick count, for use with the delay functions. If the delay functions * are used in the user code, this should be incremented each tick period so that the delays can be * calculated. */  Dean Camera committed May 16, 2010 196  extern volatile SchedulerDelayCounter_t Scheduler_TickCounter;  Dean Camera committed May 08, 2010 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214  /* Inline Functions: */ /** Resets the delay counter value to the current tick count. This should be called to reset the period * for a delay in a task which is dependant on the current tick value. * * \param[out] DelayCounter Counter which is storing the starting tick count for a given delay. */ static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *DelayCounter = Scheduler_TickCounter; } } /* Function Prototypes: */  Dean Camera committed Jun 17, 2010 215  /** Determines if the given tick delay has elapsed, based on the given delay period and tick counter value.  Dean Camera committed May 08, 2010 216  *  Dean Camera committed Jun 17, 2010 217 218  * \param[in] Delay The delay to test for, measured in ticks. * \param[in] DelayCounter The counter which is storing the starting tick value for the delay.  Dean Camera committed May 08, 2010 219  *  Dean Camera committed Jun 17, 2010 220  * \return Boolean true if the delay has elapsed, false otherwise.  Dean Camera committed May 08, 2010 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238  * * Usage Example: * \code * static SchedulerDelayCounter_t DelayCounter = 10000; // Force immediate run on start-up * * // Task runs every 10000 ticks, 10 seconds for this demo * if (Scheduler_HasDelayElapsed(10000, &DelayCounter)) * { * // Code to execute after delay interval elapsed here * } * \endcode */ bool Scheduler_HasDelayElapsed(const uint16_t Delay, SchedulerDelayCounter_t* const DelayCounter) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(2); /** Sets the task mode for a given task. *  Dean Camera committed Jun 17, 2010 239 240  * \param[in] Task Name of the task whose status is to be changed. * \param[in] TaskStatus New task status for the task (\ref TASK_RUN or \ref TASK_STOP).  Dean Camera committed May 08, 2010 241 242 243 244 245 246  */ void Scheduler_SetTaskMode(const TaskPtr_t Task, const bool TaskStatus); /** Sets the task mode for a given task group ID, allowing for an entire group of tasks to have their * statuses changed at once. *  Dean Camera committed Jun 17, 2010 247 248  * \param[in] GroupID Value of the task group ID whose status is to be changed. * \param[in] TaskStatus New task status for tasks in the specified group (\ref TASK_RUN or \ref TASK_STOP).  Dean Camera committed May 08, 2010 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292  */ void Scheduler_SetGroupTaskMode(const uint8_t GroupID, const bool TaskStatus); /* Private Interface - For use in library only: */ #if !defined(__DOXYGEN__) /* Macros: */ #define TOTAL_TASKS (sizeof(Scheduler_TaskList) / sizeof(TaskEntry_t)) #define MAX_DELAYCTR_COUNT 0xFFFF /* Inline Functions: */ static inline void Scheduler_InitScheduler(const uint8_t TotalTasks) ATTR_ALWAYS_INLINE; static inline void Scheduler_InitScheduler(const uint8_t TotalTasks) { Scheduler_TotalTasks = TotalTasks; } static inline void Scheduler_GoSchedule(const uint8_t TotalTasks) ATTR_NO_RETURN ATTR_ALWAYS_INLINE ATTR_DEPRECATED; static inline void Scheduler_GoSchedule(const uint8_t TotalTasks) { Scheduler_InitScheduler(TotalTasks); for (;;) { TaskEntry_t* CurrTask = &Scheduler_TaskList[0]; while (CurrTask != &Scheduler_TaskList[TotalTasks]) { if (CurrTask->TaskStatus == TASK_RUN) CurrTask->Task(); CurrTask++; } } } #endif /* Disable C linkage for C++ Compilers: */ #if defined(__cplusplus) } #endif #endif /** @} */