FreeRTOScpp
TaskCPP.h
Go to the documentation of this file.
1 /**
2  * @file TaskCPP.h
3  * @brief FreeRTOS Task Wrapper
4  *
5  * This file contains a set of lightweight wrappers for tasks using FreeRTOS
6  *
7  * @copyright (c) 2007-2024 Richard Damon
8  * @author Richard Damon <richard.damon@gmail.com>
9  * @parblock
10  * MIT License:
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy
13  * of this software and associated documentation files (the "Software"), to deal
14  * in the Software without restriction, including without limitation the rights
15  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16  * copies of the Software, and to permit persons to whom the Software is
17  * furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included in
20  * all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28  * THE SOFTWARE.
29  *
30  * It is requested (but not required by license) that any bugs found or
31  * improvements made be shared, preferably to the author.
32  * @endparblock
33  *
34  * @ingroup FreeRTOSCpp
35  *
36  * Tasks are built with a selction of options:
37  *
38  * Task Function Type:
39  * + Simple void fun(void* parm);
40  * + task memberfuncion of a derived class
41  *
42  * TasK Allocation:
43  * + Static (specified by a template parameter)
44  * + Dynamic (specified by that template parameter being 0)
45  * + Static with suppied stack
46  *
47  * @todo Look at options to create "restricted" tasks with xTaskCreateRestricted
48  * Basically needs another parrallel construciton of this tree.
49  */
50 
51 #ifndef TaskCPP_H
52 #define TaskCPP_H
53 
54 #include "FreeRTOScpp.h"
55 
56 extern "C" {
57  extern void taskcpp_task_thunk(void*);
58 }
59 
60 #if FREERTOSCPP_USE_NAMESPACE
61 namespace FreeRTOScpp {
62 #endif
63 
64 
65 /**
66  * @brief Names for Base set of Priorities.
67  *
68  * Assigns used based names to priority levels, optimized for configMAX_PRIORITIES = 6 for maximal distinctions
69  * with reasonable collapsing for smaller values. If configMAX_PRIORITIES is >6 then some values won't have names here, but
70  * values could be created and cast to the enum type.
71  *
72  * | configMAX_PRIORITIES: | 1 | 2 | 3 | 4 | 5 | 6 | N>6 | Use |
73  * | --------------------: | - | - | - | - | - | - | :-: | :------------------------------------------------- |
74  * | TaskPrio_Idle | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Non-Real Time operations, Tasks that don't block |
75  * | TaskPrio_Low | 0 | 1 | 1 | 1 | 1 | 1 | 1 | Non-Critical operations |
76  * | TaskPrio_HMI | 0 | 1 | 1 | 1 | 1 | 2 | 2 | Normal User Interface |
77  * | TaskPrio_Mid | 0 | 1 | 1 | 2 | 2 | 3 | N/2 | Semi-Critical, Deadlines, not much processing |
78  * | TaskPrio_High | 0 | 1 | 2 | 3 | 3 | 4 | N-2 | Urgent, Short Deadlines, not much processing |
79  * | TaskPrio_Highest | 0 | 1 | 2 | 3 | 4 | 5 | N-1 | Critical, do NOW, must be quick (Used by FreeRTOS) |
80  *
81  * @ingroup FreeRTOSCpp
82  */
84  TaskPrio_Idle = 0, ///< Non-Real Time operations. tasks that don't block
85  TaskPrio_Low = ((configMAX_PRIORITIES)>1), ///< Non-Critical operations
86  TaskPrio_HMI = (TaskPrio_Low + ((configMAX_PRIORITIES)>5)), ///< Normal User Interface Level
87  TaskPrio_Mid = ((configMAX_PRIORITIES)/2), ///< Semi-Critical, have deadlines, not a lot of processing
88  TaskPrio_High = ((configMAX_PRIORITIES)-1-((configMAX_PRIORITIES)>4)), ///< Urgent tasks, short deadlines, not much processing
89  TaskPrio_Highest = ((configMAX_PRIORITIES)-1) ///< Critical Tasks, Do NOW, must be quick (Used by FreeRTOS)
90 };
91 
92 /**
93  * Allow adjment to Task Priority.
94  *
95  * Mostly for configMAX_PRIORITIES > 6
96  */
97 constexpr TaskPriority operator+(TaskPriority p, int offset) {
98  configASSERT((static_cast<int>(p) + offset) >= 0);
99  configASSERT((static_cast<int>(p) + offset) < configMAX_PRIORITIES);
100  return static_cast<TaskPriority>(static_cast<int>(p) + offset);
101 }
102 
103 /**
104  * Allow adjment to Task Priority.
105  *
106  * Mostly for configMAX_PRIORITIES > 6
107  */
108 constexpr TaskPriority operator-(TaskPriority p, int offset) {
109  configASSERT((static_cast<int>(p) - offset) >= 0);
110  configASSERT((static_cast<int>(p) - offset) < configMAX_PRIORITIES);
111  return static_cast<TaskPriority>(static_cast<int>(p) - offset);
112 }
113 
114 /**
115  * @brief Lowest Level Wrapper.
116  * Create the specified task with a provided task function.
117  *
118  * If the TaskBase object is destroyed, the FreeRTOS Task will be deleted (if deletion has been enabled)
119  * @ingroup FreeRTOSCpp
120  * @todo Fully implement task manipulation functions
121  *
122  * @ingroup FreeRTOSCpp
123  */
124 
125 class TaskBase {
126 protected:
127  /**
128  * @brief Default Constructor: Needs a subclass to fill in the handle later, so protected.
129  */
130 
131  TaskBase() : taskHandle(nullptr) {}
132 
133 public:
134  /**
135  * @brief Constructor
136  *
137  */
138  TaskBase(TaskHandle_t handle) : taskHandle(handle) {
139 
140  }
141 
142  /**
143  * @brief Destructor.
144  *
145  * If deletion is enabled, delete the task.
146  */
147  virtual ~TaskBase() {
148 #if INCLUDE_vTaskDelete
149  if(taskHandle){
150  vTaskDelete(taskHandle);
151  }
152 #endif
153  return;
154  }
155  /**
156  * @brief Get Task Handle.
157  * @return the task handle.
158  */
159  TaskHandle_t getTaskHandle() const { return taskHandle; }
160  /**
161  * @brief Delay for a period of time
162  * @param time the number of ticks to delay
163  *
164  * This is a static member function as it affects the CALLING task, not the task it might be called on
165  */
166  static void delay(TickType_t time) { vTaskDelay(time); }
167 #if FREERTOSCPP_USE_CHRONO
168  /**
169  * @brief Delay for a period of time, specified in milliseconds
170  * @param ms The number of milliseconds to delay
171  *
172  * This is a static member function as it affects the CALLING task, not the task it might be called on
173  */
174  static void delay(Time_ms ms) { vTaskDelay(ms2ticks(ms)); }
175 #endif
176 
177 #if INCLUDE_xTaskDelayUntil
178  /**
179  * @brief Delay a periodic task
180  * @param prev The time the last unblock was scheduled to happen
181  * @param time The time in ticks to unblock next. If all calls use the same value, this will cause the task to run at
182  * the given period with long term stablity.
183  * @returns true if delay happend (false if fallen behind and no delay occured)
184  *
185  * Delays the task until the time mark prev + time.
186  *
187  * @code
188  * TickType_t last = xTaskGetTickCount()
189  * while(1) {
190  * // Wait for the next cycle
191  * bool delayed = delayUntil(last, 5);
192  * // Do the work for the cycle
193  * // if delayed is false, we have fallen behind, so delay didn't actually delay any time
194  * // so possibly skip some processing
195  * }
196  * @endcode
197  */
198  static bool delayUntil(TickType_t& prev, TickType_t time) { return xTaskDelayUntil(&prev, time);}
199 #if FREERTOSCPP_USE_CHRONO
200  /**
201  * @brief Delay a periodic task
202  * @param prev The time the last unblock was scheduled to happen
203  * @param ms The time in milli-seconds to unblock next. If all calls use the same value, this will cause the task to run at
204  * the given period with long term stablity.
205  * @returns true if delay happend (false if fallen behind and no delay occured)
206  *
207  * Delays the task until the time mark prev + ms.
208  *
209  * @code
210  * TickType_t last = xTaskGetTickCount()
211  * while(1) {
212  * // Wait for the next cycle
213  * bool delayed = delayUntil(last, 100_ms);
214  * // Do the work for the cycle
215  * // if delayed is false, we have fallen behind, so delay didn't actually delay any time
216  * // so possibly skip some processing
217  * }
218  * @endcode
219  */
220  static bool delayUntil(TickType_t& prev, Time_ms ms) { return xTaskDelayUntil(&prev, ms2ticks(ms)); }
221 #endif
222 #elif INCLUDE_vTaskDelayUntil
223  /**
224  * @brief Delay a periodic task
225  * @param prev The time the last unblock was scheduled to happen
226  * @param time The time in ticks to unblock next. If all calls use the same value, this will cause the task to run at
227  * the given period with long term stablity.
228  *
229  * Delays the task until the time mark prev + time.
230  *
231  * @code
232  * TickType_t last = xTaskGetTickCount()
233  * while(1) {
234  * // Wait for the next cycle
235  * delayUntil(last, 5);
236  * // Do the work for the cycle
237  * }
238  * @endcode
239  */
240  static void delayUntil(TickType_t& prev, TickType_t time) { vTaskDelay(&prev, time); }
241 #if FREERTOSCPP_USE_CHRONO
242  /**
243  * @brief Delay a periodic task
244  * @param prev The time the last unblock was scheduled to happen
245  * @param ms The time in milli-seconds to unblock next. If all calls use the same value, this will cause the task to run at
246  * the given period with long term stablity.
247  *
248  * Delays the task until the time mark prev + ms.
249  *
250  * @code
251  * TickType_t last = xTaskGetTickCount()
252  * while(1) {
253  * // Wait for the next cycle
254  * delayUntil(last, 5);
255  * // Do the work for the cycle
256  * }
257  * @endcode
258  */
259  static void delayUntil(TickType_t& prev, Time_ms ms) { vTaskDelay(&prev, ms2ticks(ms)); }
260 #endif
261 #endif
262 
263 #if INCLUDE_xTaskAbortDelay
264  /**
265  * @brief Abort the Delay of a Task.
266  * @returns true if the task was blocking.
267  */
268  bool abortDelay() { return xTaskAbortDelay(taskHandle); }
269 #endif
270 
271 #if INCLUDE_uxTaskPriorityGet
272  /**
273  * @brief Get Task priority
274  *
275  * Only available if INCLUDE_vTaskPriorityGet == 1
276  * @return The priority of the Task.
277  */
278  TaskPriority priority() const { return static_cast<TaskPriority>(uxTaskPriorityGet(taskHandle)); }
279  #endif
280 
281  #if INCLUDE_vTaskPrioritySet
282  /**
283  * @brief Set Task priority
284  *
285  * Only available if INCLUDE_vTaskPrioritySet == 1
286  * @param priority_ The TaskPriority to give the Task.
287  */
288  void priority(TaskPriority priority_) { vTaskPrioritySet(taskHandle, priority_); }
289  #endif
290 
291  #if INCLUDE_vTaskSuspend
292  /**
293  * @brief Suspend the Task.
294  *
295  * Only available if INCLUDE_vTaskSuspend == 1
296  */
297  void suspend() { vTaskSuspend(taskHandle); }
298 
299  /**
300  * @brief Resume the Task.
301  *
302  * Only available if INCLUDE_vTaskSuspend == 1
303  */
304  void resume() { vTaskResume(taskHandle); }
305  # endif
306 
307  # if INCLUDE_xTaskResumeFromISR
308  /**
309  * @brief Resume task from ISR.
310  *
311  * Note: Only functions with _ISR should be used inside Interupt service routines.
312  *
313  * Only available if INCLUDE_vTaskSuspend == 1 and INCLUDE_vTaskResumeFromISR == 1
314  * @returns True if ISR should request a context switch.
315  */
316  bool resume_ISR() { return xTaskResumeFromISR(taskHandle); }
317  #endif
318 
319  /**
320  * @brief Notify a Task.
321  *
322  * Generic Task Notification operation
323  */
324  bool notify(uint32_t value, eNotifyAction act)
325  { return xTaskNotify(taskHandle, value, act); }
326  bool notify_ISR(uint32_t value, eNotifyAction act, portBASE_TYPE& waswoken)
327  { return xTaskNotifyFromISR(taskHandle, value, act, &waswoken);}
328  bool notify_query(uint32_t value, eNotifyAction act, uint32_t &old)
329  {return xTaskNotifyAndQuery(taskHandle, value, act, &old); }
330  bool notify_query_ISR(uint32_t value, eNotifyAction act, uint32_t &old, portBASE_TYPE& waswoken)
331  {return xTaskNotifyAndQueryFromISR(taskHandle, value, act, &old, &waswoken); }
332 #if FREERTOS_VERSION_ALL >= 10'004'000
333  bool notifyIndex(UBaseType_t idx, uint32_t value, eNotifyAction act)
334  { return xTaskNotifyIndexed(taskHandle, idx, value, act); }
335  bool notifyIndex_ISR(UBaseType_t idx, uint32_t value, eNotifyAction act, portBASE_TYPE& waswoken)
336  { return xTaskNotifyIndexedFromISR(taskHandle, idx, value, act, &waswoken);}
337  bool notifyIndex_query(UBaseType_t idx, uint32_t value, eNotifyAction act, uint32_t &old)
338  {return xTaskNotifyAndQueryIndexed(taskHandle, idx, value, act, &old); }
339  bool notifyIndex_query_ISR(UBaseType_t idx, uint32_t value, eNotifyAction act, uint32_t &old, portBASE_TYPE& waswoken)
340  {return xTaskNotifyAndQueryIndexedFromISR(taskHandle, idx, value, act, &old, &waswoken); }
341 #endif
342 
343 #if FREERTOS_VERSION_ALL >= 10'003'000
344  bool notifyStateClear() { return xTaskNotifyStateClear(taskHandle); }
345  uint32_t notifyValueClear(uint32_t bits) { return ulTaskNotifyValueClear(taskHandle, bits); }
346 #if FREERTOS_VERSION_ALL >= 10'004'000
347  bool notifyStateClearIndex(UBaseType_t idx) { return xTaskNotifyStateClearIndexed(taskHandle, idx); }
348  uint32_t notifyValueClearIndex(UBaseType_t idx, uint32_t bits) { return ulTaskNotifyValueClearIndexed(taskHandle, idx, bits); }
349 #endif
350 #endif
351  /**
352  * @brief Notify a Task as a semaphore
353  *
354  * Sends a notification to a task using a semaphore based protocol. Generally the task should we using
355  * the take() function to receive the notification.
356  */
357  bool give() { return xTaskNotifyGive(taskHandle); }
358  void give_ISR(portBASE_TYPE& waswoken)
359  { vTaskNotifyGiveFromISR(taskHandle, &waswoken); }
360 
361 #if FREERTOS_VERSION_ALL >= 10'004'000
362  bool giveIndex(UBaseType_t idx) { return xTaskNotifyGiveIndexed(taskHandle, idx); }
363  void giveIndex_ISR(UBaseType_t idx, portBASE_TYPE& waswoken)
364  { vTaskNotifyGiveIndexedFromISR(taskHandle, idx, &waswoken); }
365 #endif
366  // Static as always affect the current (calling) task
367  /**
368  * @brief Wait for task notification.
369  */
370  static uint32_t wait(uint32_t clearEnter, uint32_t clearExit = 0xFFFFFFFF, uint32_t* value = nullptr, TickType_t ticks = portMAX_DELAY)
371  { return xTaskNotifyWait(clearEnter, clearExit, value, ticks); }
372 #if FREERTOSCPP_USE_CHRONO
373  static uint32_t wait(uint32_t clearEnter, uint32_t clearExit, uint32_t* value, Time_ms ms)
374  { return xTaskNotifyWait(clearEnter, clearExit, value, ms2ticks(ms)); }
375 #endif
376 #if FREERTOS_VERSION_ALL >= 10'004'000
377  static uint32_t waitIndex(UBaseType_t idx, uint32_t clearEnter, uint32_t clearExit = 0xFFFFFFFF, uint32_t* value = nullptr, TickType_t ticks = portMAX_DELAY)
378  { return xTaskNotifyWaitIndexed(idx, clearEnter, clearExit, value, ticks); }
379 #if FREERTOSCPP_USE_CHRONO
380  static uint32_t waitIndex(UBaseType_t idx, uint32_t clearEnter, uint32_t clearExit, uint32_t* value, Time_ms ms)
381  { return xTaskNotifyWaitIndexed(idx, clearEnter, clearExit, value, ms2ticks(ms)); }
382 #endif // FREERTOSCPP_USE_CHRONO
383 #endif // FREERTOS_VERSION_ALL >= 10'004'000
384 
385  /**
386  * @brief Wait for a task Give notification
387  *
388  * Specialized wait() designed to work with the give()/give_ISR() notifications.
389  *
390  * @param clear Flag to indicate if the action on succesful take is to clear (True) or decrement (False) the notification value.
391  * Effectively decides between a binary (True) or counting (False) semaphore behavior.
392  *
393  * @param ticks The time to wait for the semaphore.
394  *
395  * @returns Returns the notification word (prior to being adjusted for the take() ), Will be zero if
396  * the take() timed out.
397  */
398  static uint32_t take(bool clear = true, TickType_t ticks = portMAX_DELAY)
399  { return ulTaskNotifyTake(clear, ticks); }
400 #if FREERTOSCPP_USE_CHRONO
401  /**
402  * @brief Wait for a task Give notification
403  *
404  * Specialized wait() designed to work with the give()/give_ISR() notifications.
405  *
406  * @param clear Flag to indicate if the action on successful take is to clear (True) or decrement (False) the notification value.
407  * Effectively decides between a binary (True) or counting (False) semaphore behavior.
408  *
409  * @param ticks The time to wait for the semaphore.
410  *
411  * @returns Returns the notification word (prior to being adjusted for the take() ), Will be zero if
412  * the take() timed out.
413  */
414  static uint32_t take(bool clear, Time_ms ticks)
415  { return ulTaskNotifyTake(clear, ms2ticks(ticks)); }
416 #endif
417  protected:
418  TaskHandle_t taskHandle; ///< Handle for the task we are managing.
419 
420  private:
421 #if __cplusplus < 201101L
422  TaskBase(TaskBase const&); ///< We are not copyable.
423  void operator =(TaskBase const&); ///< We are not assignable.
424 #else
425  TaskBase(TaskBase const&) = delete; ///< We are not copyable.
426  void operator =(TaskBase const&) = delete; ///< We are not assignable.
427 #endif // __cplusplus
428 
429 };
430 
431 /**
432  * @brief Statically Created Task Wrapper.
433  * Create the specified task with a provided task function.
434  *
435  * @tparam stackDepth Size of the stack to give to the task
436  *
437  * If the Task object is destroyed, the class will be deleted (if deletion has been enabled)
438  * @ingroup FreeRTOSCpp
439  */
440 
441 template<uint32_t stackDepth
442 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
443  =0
444 #endif
445  > class TaskS : public TaskBase {
446 public:
447  /**
448  * @brief Constructor.
449  *
450  * @param name The name of the task.
451  * @param taskfun The function implementing the task, should have type void (*taskfun)(void *)
452  * @param priority_ The priority of the task. Use the TaskPriority enum values or a related value converted to a TaskPriority
453  * @param myParm the parameter passed to taskFun. Defaults to NULL.
454  *
455  * Upon construction the task will be created.
456  *
457  */
458  TaskS(char const*name, void (*taskfun)(void *), TaskPriority priority_, void * myParm = 0) :
459  TaskBase() {
460 
461 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
462  taskHandle = xTaskCreateStatic(taskfun, name, stackDepth, myParm, priority_, stack, &tcb);
463 #else
464  xTaskCreate(taskfun, name, stackSize, myParm, priority_, &taskHandle);
465 #endif
466  }
467 
468 private:
469 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
470  StaticTask_t tcb;
471  StackType_t stack[stackDepth];
472 #endif
473 };
474 
475 
476 /**
477  * @brief Dynamically Created Task Wrapper
478  */
479 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
480 
481 template<> class TaskS<0> : public TaskBase {
482 public:
483  /**
484  * @brief Constructor.
485  *
486  * @param name The name of the task.
487  * @param taskfun The function implementing the task, should have type void (*taskfun)(void *)
488  * @param priority_ The priority of the task. Use the TaskPriority enum values or a related value converted to a TaskPriority
489  * @param stackSize Size of the stack to give to the task
490  * @param myParm the parameter passed to taskFun. Defaults to NULL.
491  *
492  * Upon construction the task will be created.
493  *
494  */
495  TaskS(char const*name, void (*taskfun)(void *), TaskPriority priority_,
496  unsigned portSHORT stackSize, void * myParm = nullptr) :
497  TaskBase() {
498  xTaskCreate(taskfun, name, stackSize, myParm, priority_, &taskHandle);
499  }
500 };
501 
502 typedef TaskS<0> Task;
503 #endif
504 
505 /**
506  * @brief Base Class for all Class based tasks.
507 */
509 public:
512  /**
513  * @brief task function.
514  * The member function task needs to
515  */
516  virtual void task() = 0;
517 
518 };
519 
520 /**
521  * @brief Make a class based task.
522  * Derive from TaskClass and the 'task()' member function will get called as the task based on the class.
523  *
524  * @tparam stackDepth Size of the stack to give to the task
525  *
526  * If task() returns the task will be deleted if deletion has been enabled.
527  * @ingroup FreeRTOSCpp
528  */
529 
530 template<uint32_t stackDepth> class TaskClassS : public TaskClassBase, public TaskS<stackDepth> {
531 public:
532  /**
533  * @brief Constructor
534  *
535  * @param name The name of the task.
536  * @param priority_ The priority of the task. Use the TaskPriority enum values or a related value converted to a TaskPriority
537  * @param stackDepth_ How many words of stack to allocate to the task. Only used if the template parameter stackDepth is 0
538  *
539  * API CHANGE!
540  * If at constrtuction time, the scheduler is not running, we can release the task. If the scheduler is running, because
541  * the task may startup before we finish constructing the task, the most derived constructor will need to give the task.
542  *
543  * Change from previous API to support SMP mode where the previous trick won't work anymore.
544  */
545  TaskClassS(char const*name, TaskPriority priority_, unsigned portSHORT stackDepth_=0) :
546  TaskS<stackDepth>(name, &taskcpp_task_thunk, priority_, static_cast<TaskClassBase*>(this))
547  {
548  (void) stackDepth_;
549  // API CHANGE: We give if Scheduer not running, otherwise final constructor needs to give.
550  if(xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) {
551  this->TaskBase::give();
552  }
553  }
554 
555  virtual ~TaskClassS() {}
556 
557  /**
558  * @brief task function.
559  * The member function task needs to
560  */
561  void task() override = 0;
562 
563 };
564 
565 
566 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
567 template<> class TaskClassS<0> : public TaskClassBase, public TaskS<0> {
568 public:
569  /**
570  * @brief Constructor
571  *
572  * @param name The name of the task.
573  * @param priority_ The priority of the task. Use the TaskPriority enum values or a related value converted to a TaskPriority
574  * @param stackDepth_ How many words of stack to allocate to the task. Only used if the template parameter stackDepth is 0
575  *
576  * API CHANGE!
577  * If at constrtuction time, the scheduler is not running, we can release the task. If the scheduler is running, because
578  * the task may startup before we finish constructing the task, the most derived constructor will need to give the task.
579  *
580  * Change from previous API to support SMP mode where the previous trick won't work anymore.
581  */
582  TaskClassS(char const*name, TaskPriority priority_, unsigned portSHORT stackDepth_) :
583  TaskS<0>(name, &taskcpp_task_thunk, priority_, stackDepth_, static_cast<TaskClassBase*>(this))
584  {
585  // API CHANGE: We give if Scheduer not running, otherwise final constructor needs to give.
586  if(xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) {
587  this->TaskBase::give();
588  }
589  }
590 
591  virtual ~TaskClassS() {}
592 
593  /**
594  * @brief task function.
595  * The member function task needs to
596  */
597  void task() override = 0;
598 
599 };
600 
601 typedef TaskClassS<0> TaskClass;
602 #endif
603 
604 #if FREERTOSCPP_USE_NAMESPACE
605 } // namespace FreeRTOScpp
606 #endif
607 
608 #endif
static uint32_t take(bool clear, Time_ms ticks)
Wait for a task Give notification.
Definition: TaskCPP.h:414
TaskPriority
Names for Base set of Priorities.
Definition: TaskCPP.h:83
Critical Tasks, Do NOW, must be quick (Used by FreeRTOS)
Definition: TaskCPP.h:89
static uint32_t waitIndex(UBaseType_t idx, uint32_t clearEnter, uint32_t clearExit=0xFFFFFFFF, uint32_t *value=nullptr, TickType_t ticks=portMAX_DELAY)
Definition: TaskCPP.h:377
TaskHandle_t taskHandle
Handle for the task we are managing.
Definition: TaskCPP.h:418
Dynamically Created Task Wrapper.
Definition: TaskCPP.h:508
TaskClassS(char const *name, TaskPriority priority_, unsigned portSHORT stackDepth_=0)
Constructor.
Definition: TaskCPP.h:545
Lowest Level Wrapper.
Definition: TaskCPP.h:125
Urgent tasks, short deadlines, not much processing.
Definition: TaskCPP.h:88
constexpr TickType_t ms2ticks(Time_ms ms)
Definition: FreeRTOScpp.h:81
bool notify_query(uint32_t value, eNotifyAction act, uint32_t &old)
Definition: TaskCPP.h:328
std::chrono::milliseconds Time_ms
Definition: FreeRTOScpp.h:79
void taskcpp_task_thunk(void *)
Thunk for FreeRTOS to C++ Task Wrapper.
Definition: TaskCpp.cpp:47
Definition: CallBack.h:63
FreeRTOS Wrapper.
static uint32_t take(bool clear=true, TickType_t ticks=portMAX_DELAY)
Wait for a task Give notification.
Definition: TaskCPP.h:398
static uint32_t waitIndex(UBaseType_t idx, uint32_t clearEnter, uint32_t clearExit, uint32_t *value, Time_ms ms)
Definition: TaskCPP.h:380
virtual ~TaskClassS()
Definition: TaskCPP.h:555
Normal User Interface Level.
Definition: TaskCPP.h:86
TaskBase()
Default Constructor: Needs a subclass to fill in the handle later, so protected.
Definition: TaskCPP.h:131
void suspend()
Suspend the Task.
Definition: TaskCPP.h:297
Non-Real Time operations. tasks that don&#39;t block.
Definition: TaskCPP.h:84
Statically Created Task Wrapper.
Definition: TaskCPP.h:445
~TaskClassBase()
Definition: TaskCPP.h:511
constexpr TaskPriority operator+(TaskPriority p, int offset)
Allow adjment to Task Priority.
Definition: TaskCPP.h:97
Make a class based task.
Definition: TaskCPP.h:530
static void delay(Time_ms ms)
Delay for a period of time, specified in milliseconds.
Definition: TaskCPP.h:174
virtual ~TaskBase()
Destructor.
Definition: TaskCPP.h:147
void resume()
Resume the Task.
Definition: TaskCPP.h:304
Semi-Critical, have deadlines, not a lot of processing.
Definition: TaskCPP.h:87
void priority(TaskPriority priority_)
Set Task priority.
Definition: TaskCPP.h:288
Non-Critical operations.
Definition: TaskCPP.h:85
void operator=(TaskBase const &)=delete
We are not assignable.
bool notify_query_ISR(uint32_t value, eNotifyAction act, uint32_t &old, portBASE_TYPE &waswoken)
Definition: TaskCPP.h:330
TaskBase(TaskHandle_t handle)
Constructor.
Definition: TaskCPP.h:138
bool notify(uint32_t value, eNotifyAction act)
Notify a Task.
Definition: TaskCPP.h:324
TaskClassBase()
Definition: TaskCPP.h:510
TaskS(char const *name, void(*taskfun)(void *), TaskPriority priority_, void *myParm=0)
Constructor.
Definition: TaskCPP.h:458
void give_ISR(portBASE_TYPE &waswoken)
Definition: TaskCPP.h:358
bool notify_ISR(uint32_t value, eNotifyAction act, portBASE_TYPE &waswoken)
Definition: TaskCPP.h:326
static uint32_t wait(uint32_t clearEnter, uint32_t clearExit=0xFFFFFFFF, uint32_t *value=nullptr, TickType_t ticks=portMAX_DELAY)
Wait for task notification.
Definition: TaskCPP.h:370
constexpr TaskPriority operator-(TaskPriority p, int offset)
Allow adjment to Task Priority.
Definition: TaskCPP.h:108
TaskHandle_t getTaskHandle() const
Get Task Handle.
Definition: TaskCPP.h:159
bool give()
Notify a Task as a semaphore.
Definition: TaskCPP.h:357
static void delay(TickType_t time)
Delay for a period of time.
Definition: TaskCPP.h:166
static uint32_t wait(uint32_t clearEnter, uint32_t clearExit, uint32_t *value, Time_ms ms)
Definition: TaskCPP.h:373