FreeRTOS-Cpp
Loading...
Searching...
No Matches
Task.hpp
1/*
2 * FreeRTOS-Cpp
3 * Copyright (C) 2021 Jon Enz. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * https://github.com/jonenz/FreeRTOS-Cpp
26 */
27
28#ifndef FREERTOS_TASK_HPP
29#define FREERTOS_TASK_HPP
30
31#include <FreeRTOS/Kernel.hpp>
32#include <bitset>
33#include <utility>
34
35#include "FreeRTOS.h"
36#include "task.h"
37
46void callTaskFunction(void* task);
47
48namespace FreeRTOS {
49
60class TaskBase {
61 public:
62 friend class Task;
63 template <UBaseType_t>
64 friend class StaticTask;
65
66 TaskBase(const TaskBase&) = delete;
67 TaskBase& operator=(const TaskBase&) = delete;
68
69 static void* operator new(size_t) = delete;
70 static void* operator new[](size_t) = delete;
71
72 static void* operator new(size_t, void* ptr) {
73 return ptr;
74 }
75
76 static void* operator new[](size_t, void* ptr) {
77 return ptr;
78 }
79
80 enum class State {
81 Running = eRunning,
82 Ready = eReady,
83 Blocked = eBlocked,
84 Suspended = eSuspended,
85 Deleted = eDeleted,
86 Invalid = eInvalid,
87 };
88
89 enum class NotifyAction {
90 NoAction = eNoAction,
91 SetBits = eSetBits,
92 Increment = eIncrement,
93 SetValueWithOverwrite = eSetValueWithOverwrite,
94 SetValueWithoutOverwrite = eSetValueWithoutOverwrite,
95 };
96
97 using NotificationBits = std::bitset<32>; // NOLINT
98
110 virtual inline void taskEntry() final {
112 taskFunction();
113 };
114
115#if (INCLUDE_vTaskDelay == 1)
150 inline static void delay(const TickType_t ticksToDelay = 0) {
151 vTaskDelay(ticksToDelay);
152 }
153#endif /* INCLUDE_vTaskDelay */
154
155#if (INCLUDE_xTaskDelayUntil == 1)
196 inline static bool delayUntil(TaskBase& task,
197 const TickType_t timeIncrement = 0) {
198 return (xTaskDelayUntil(&task.previousWakeTime, timeIncrement) == pdTRUE);
199 }
200#endif /* INCLUDE_xTaskDelayUntil */
201
202#if (INCLUDE_uxTaskPriorityGet == 1)
221 inline UBaseType_t getPriority() const {
222 return uxTaskPriorityGet(handle);
223 }
224#endif /* INCLUDE_uxTaskPriorityGet */
225
226#if (INCLUDE_vTaskPrioritySet == 1)
248 inline void setPriority(const UBaseType_t newPriority) const {
249 vTaskPrioritySet(handle, newPriority);
250 }
251#endif /* INCLUDE_vTaskPrioritySet */
252
253#if ((INCLUDE_uxTaskPriorityGet == 1) && (configUSE_MUTEXES == 1))
271 inline UBaseType_t getBasePriority() const {
272 return uxTaskBasePriorityGet(handle);
273 }
274
287 inline UBaseType_t getBasePriorityFromISR() const {
288 return uxTaskBasePriorityGetFromISR(handle);
289 }
290#endif /* (INCLUDE_uxTaskPriorityGet == 1) && (configUSE_MUTEXES == 1) */
291
292#if (INCLUDE_vTaskSuspend == 1)
314 inline void suspend() const {
315 vTaskSuspend(handle);
316 }
317
337 inline void resume() const {
338 vTaskResume(handle);
339 }
340
341#if (INCLUDE_xTaskResumeFromISR == 1)
371 inline bool resumeFromISR() const {
372 return (xTaskResumeFromISR(handle) == pdTRUE);
373 }
374#endif /* INCLUDE_xTaskResumeFromISR */
375#endif /* INCLUDE_vTaskSuspend */
376
377#if (INCLUDE_xTaskAbortDelay == 1)
405 inline bool abortDelay() const {
406 return (xTaskAbortDelay(handle) == pdPASS);
407 }
408#endif /* INCLUDE_xTaskAbortDelay */
409
410#if (INCLUDE_xTaskGetIdleTaskHandle == 1)
428 inline static TaskHandle_t getIdleHandle() {
429 return xTaskGetIdleTaskHandle();
430 }
431#endif /* INCLUDE_xTaskGetIdleTaskHandle */
432
433#if (INCLUDE_uxTaskGetStackHighWaterMark == 1)
460 inline UBaseType_t getStackHighWaterMark() const {
461 return uxTaskGetStackHighWaterMark(handle);
462 }
463#endif /* INCLUDE_uxTaskGetStackHighWaterMark */
464
465#if (INCLUDE_uxTaskGetStackHighWaterMark2 == 1)
489 inline configSTACK_DEPTH_TYPE getStackHighWaterMark2() const {
490 return uxTaskGetStackHighWaterMark2(handle);
491 }
492#endif /* INCLUDE_uxTaskGetStackHighWaterMark2 */
493
494#if (INCLUDE_eTaskGetState == 1)
515 inline State getState() const {
516 return static_cast<State>(eTaskGetState(handle));
517 }
518#endif /* INCLUDE_eTaskGetState */
519
533 inline const char* getName() const {
534 return pcTaskGetName(handle);
535 }
536
537#if (INCLUDE_xTaskGetHandle == 1)
556 inline static TaskHandle_t getHandle(const char* name) {
557 return xTaskGetHandle(name);
558 }
559#endif /* INCLUDE_xTaskGetHandle */
560
561#if (configUSE_TASK_NOTIFICATIONS == 1)
611 inline void notifyGive(const UBaseType_t index = 0) const {
612 xTaskNotifyGiveIndexed(handle, index);
613 }
614
640 inline void notifyGiveFromISR(bool& higherPriorityTaskWoken,
641 const UBaseType_t index = 0) const {
642 BaseType_t taskWoken = pdFALSE;
643 vTaskNotifyGiveIndexedFromISR(handle, index, &taskWoken);
644 if (taskWoken == pdTRUE) {
645 higherPriorityTaskWoken = true;
646 }
647 }
648
660 inline void notifyGiveFromISR(const UBaseType_t index = 0) const {
661 vTaskNotifyGiveIndexedFromISR(handle, index, NULL);
662 }
663
746 inline bool notify(const NotifyAction action,
747 const NotificationBits value = 0,
748 const UBaseType_t index = 0) const {
749 return (xTaskNotifyIndexed(handle, index, value.to_ulong(),
750 static_cast<eNotifyAction>(action)) == pdPASS);
751 }
752
806 inline std::pair<bool, NotificationBits> notifyAndQuery(
807 const NotifyAction action, const NotificationBits value = 0,
808 const UBaseType_t index = 0) const {
809 uint32_t pulNotificationValue;
810 const bool result =
811 (xTaskNotifyAndQueryIndexed(handle, index, value.to_ulong(),
812 static_cast<eNotifyAction>(action),
813 &pulNotificationValue) == pdPASS);
814
815 return std::make_pair(result, NotificationBits(pulNotificationValue));
816 }
817
891 inline std::pair<bool, NotificationBits> notifyAndQueryFromISR(
892 bool& higherPriorityTaskWoken, const NotifyAction action,
893 const NotificationBits value = 0, const UBaseType_t index = 0) const {
894 BaseType_t taskWoken = pdFALSE;
895 uint32_t pulNotificationValue;
896 const bool result = (xTaskNotifyAndQueryIndexedFromISR(
897 handle, index, value.to_ulong(),
898 static_cast<eNotifyAction>(action),
899 &pulNotificationValue, &taskWoken) == pdPASS);
900
901 if (taskWoken == pdTRUE) {
902 higherPriorityTaskWoken = true;
903 }
904
905 return std::make_pair(result, NotificationBits(pulNotificationValue));
906 }
907
921 inline std::pair<bool, NotificationBits> notifyAndQueryFromISR(
922 const NotifyAction action, const NotificationBits value = 0,
923 const UBaseType_t index = 0) const {
924 uint32_t pulNotificationValue;
925 const bool result = (xTaskNotifyAndQueryIndexedFromISR(
926 handle, index, value.to_ulong(),
927 static_cast<eNotifyAction>(action),
928 &pulNotificationValue, NULL) == pdPASS);
929
930 return std::make_pair(result, NotificationBits(pulNotificationValue));
931 }
932
995 inline bool notifyFromISR(bool& higherPriorityTaskWoken,
996 const NotifyAction action,
997 const NotificationBits value = 0,
998 const UBaseType_t index = 0) const {
999 BaseType_t taskWoken = pdFALSE;
1000 const bool result =
1001 (xTaskNotifyIndexedFromISR(handle, index, value.to_ulong(),
1002 static_cast<eNotifyAction>(action),
1003 &taskWoken) == pdPASS);
1004 if (taskWoken == pdTRUE) {
1005 higherPriorityTaskWoken = true;
1006 }
1007 return result;
1008 }
1009
1021 inline bool notifyFromISR(const NotifyAction action,
1022 const NotificationBits value = 0,
1023 const UBaseType_t index = 0) const {
1024 return (xTaskNotifyIndexedFromISR(handle, index, value.to_ulong(),
1025 static_cast<eNotifyAction>(action),
1026 NULL) == pdPASS);
1027 }
1028
1111 inline static std::pair<bool, NotificationBits> notifyWait(
1112 const TickType_t ticksToWait = portMAX_DELAY,
1113 const NotificationBits bitsToClearOnEntry = 0,
1114 const NotificationBits bitsToClearOnExit = 0,
1115 const UBaseType_t index = 0) {
1116 uint32_t pulNotificationValue;
1117 const bool result =
1118 (xTaskNotifyWaitIndexed(index, bitsToClearOnEntry.to_ulong(),
1119 bitsToClearOnExit.to_ulong(),
1120 &pulNotificationValue, ticksToWait) == pdTRUE);
1121 return std::make_pair(result, NotificationBits(pulNotificationValue));
1122 }
1123
1160 inline bool notifyStateClear(const UBaseType_t index = 0) const {
1161 return (xTaskNotifyStateClearIndexed(handle, index) == pdTRUE);
1162 }
1163
1197 inline NotificationBits notifyValueClear(
1198 const NotificationBits bitsToClear = 0,
1199 const UBaseType_t index = 0) const {
1200 return NotificationBits(
1201 ulTaskNotifyValueClearIndexed(handle, index, bitsToClear.to_ulong()));
1202 }
1203#endif /* configUSE_TASK_NOTIFICATIONS */
1204
1205 protected:
1212 virtual void taskFunction() = 0;
1213
1214#if (INCLUDE_xTaskDelayUntil == 1)
1255 inline bool delayUntil(const TickType_t timeIncrement = 0) {
1256 return (xTaskDelayUntil(&previousWakeTime, timeIncrement) == pdTRUE);
1257 }
1258#endif /* INCLUDE_xTaskDelayUntil */
1259
1344 inline static NotificationBits notifyTake(
1345 const TickType_t ticksToWait = portMAX_DELAY,
1346 const bool clearCountOnExit = true, const UBaseType_t index = 0) {
1347 return NotificationBits(
1348 ulTaskNotifyTakeIndexed(index, clearCountOnExit, ticksToWait));
1349 }
1350
1351 private:
1358 TaskBase() = default;
1359
1360 TaskBase(TaskBase&&) noexcept = default;
1361 TaskBase& operator=(TaskBase&&) noexcept = default;
1362
1389#if (INCLUDE_vTaskDelete == 1)
1390
1391 if (handle != NULL) {
1392 vTaskDelete(handle);
1393 }
1394
1395#endif /* INCLUDE_vTaskDelete */
1396 }
1397
1401 TaskHandle_t handle = NULL;
1402
1406 TickType_t previousWakeTime = 0;
1407};
1408
1409#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
1410
1427class Task : public TaskBase {
1428 public:
1429 Task(const Task&) = delete;
1430 Task& operator=(const Task&) = delete;
1431
1441 bool isValid() const {
1442 return taskCreatedSuccessfully;
1443 }
1444
1445 protected:
1484 explicit Task(
1485 const UBaseType_t priority = tskIDLE_PRIORITY,
1486 const configSTACK_DEPTH_TYPE stackDepth = configMINIMAL_STACK_SIZE,
1487 const char* name = "") {
1488 taskCreatedSuccessfully = (xTaskCreate(callTaskFunction, name, stackDepth,
1489 this, priority, &handle) == pdPASS);
1490 }
1491
1492 ~Task() = default;
1493
1494 Task(Task&&) noexcept = default;
1495 Task& operator=(Task&&) noexcept = default;
1496
1497 private:
1498 bool taskCreatedSuccessfully = false;
1499};
1500
1501#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
1502
1503#if (configSUPPORT_STATIC_ALLOCATION == 1)
1504
1528template <UBaseType_t N = configMINIMAL_STACK_SIZE>
1529class StaticTask : public TaskBase {
1530 public:
1531 StaticTask(const StaticTask&) = delete;
1532 StaticTask& operator=(const StaticTask&) = delete;
1533
1534 protected:
1563 explicit StaticTask(const UBaseType_t priority = tskIDLE_PRIORITY,
1564 const char* name = "") {
1565 handle = xTaskCreateStatic(callTaskFunction, name, N, this, priority, stack,
1566 &taskBuffer);
1567 }
1568 ~StaticTask() = default;
1569
1570 StaticTask(StaticTask&&) noexcept = default;
1571 StaticTask& operator=(StaticTask&&) noexcept = default;
1572
1573 private:
1574 StaticTask_t taskBuffer;
1575 StackType_t stack[N];
1576};
1577
1578#endif /* configSUPPORT_STATIC_ALLOCATION */
1579
1580} // namespace FreeRTOS
1581
1582inline void callTaskFunction(void* task) {
1583 static_cast<FreeRTOS::TaskBase*>(task)->taskEntry();
1584}
1585
1586#endif // FREERTOS_TASK_HPP
Class that encapsulates the functionality of a FreeRTOS task.
Definition Task.hpp:1529
StaticTask(const UBaseType_t priority=tskIDLE_PRIORITY, const char *name="")
Construct a new Task object by calling TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,...
Definition Task.hpp:1563
Base class that provides the standard task interface to FreeRTOS::Task and FreeRTOS::StaticTask.
Definition Task.hpp:60
std::pair< bool, NotificationBits > notifyAndQueryFromISR(const NotifyAction action, const NotificationBits value=0, const UBaseType_t index=0) const
Function that calls BaseType_t xTaskNotifyAndQueryIndexedFromISR( TaskHandle_t xTaskToNotify,...
Definition Task.hpp:921
bool notifyFromISR(const NotifyAction action, const NotificationBits value=0, const UBaseType_t index=0) const
Function that calls BaseType_t xTaskNotifyIndexedFromISR( TaskHandle_t xTaskToNotify,...
Definition Task.hpp:1021
bool notifyStateClear(const UBaseType_t index=0) const
Function that calls BaseType_t xTaskNotifyStateClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexT...
Definition Task.hpp:1160
static TaskHandle_t getIdleHandle()
Function that calls TaskHandle_t xTaskGetIdleTaskHandle( void )
Definition Task.hpp:428
UBaseType_t getPriority() const
Function that calls UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask )
Definition Task.hpp:221
void notifyGiveFromISR(const UBaseType_t index=0) const
Function that calls void vTaskNotifyGiveIndexedFromISR( TaskHandle_t xTaskHandle, UBaseType_t uxIndex...
Definition Task.hpp:660
bool notify(const NotifyAction action, const NotificationBits value=0, const UBaseType_t index=0) const
Function that calls BaseType_t xTaskNotifyIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToN...
Definition Task.hpp:746
virtual void taskFunction()=0
Abstraction function that acts as the entry point of the task for the user.
static void delay(const TickType_t ticksToDelay=0)
Function that calls void vTaskDelay( const TickType_t xTicksToDelay )
Definition Task.hpp:150
void setPriority(const UBaseType_t newPriority) const
Function that calls void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )
Definition Task.hpp:248
static std::pair< bool, NotificationBits > notifyWait(const TickType_t ticksToWait=portMAX_DELAY, const NotificationBits bitsToClearOnEntry=0, const NotificationBits bitsToClearOnExit=0, const UBaseType_t index=0)
Function that calls BaseType_t xTaskNotifyWaitIndexed( UBaseType_t uxIndexToWaitOn,...
Definition Task.hpp:1111
virtual void taskEntry() final
Function that acts as the entry point of the task instance. This function initializes the previous wa...
Definition Task.hpp:110
std::pair< bool, NotificationBits > notifyAndQuery(const NotifyAction action, const NotificationBits value=0, const UBaseType_t index=0) const
Function that calls BaseType_t xTaskNotifyAndQueryIndexed( TaskHandle_t xTaskToNotify,...
Definition Task.hpp:806
bool notifyFromISR(bool &higherPriorityTaskWoken, const NotifyAction action, const NotificationBits value=0, const UBaseType_t index=0) const
Function that calls BaseType_t xTaskNotifyIndexedFromISR( TaskHandle_t xTaskToNotify,...
Definition Task.hpp:995
static bool delayUntil(TaskBase &task, const TickType_t timeIncrement=0)
Function that calls BaseType_t xTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTim...
Definition Task.hpp:196
State getState() const
Function that calls UBaseType_t uxTaskGetStackHighWaterMark2( TaskHandle_t xTask )
Definition Task.hpp:515
bool resumeFromISR() const
Function that calls BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
Definition Task.hpp:371
NotificationBits notifyValueClear(const NotificationBits bitsToClear=0, const UBaseType_t index=0) const
Function that calls uint32_t ulTaskNotifyValueClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexTo...
Definition Task.hpp:1197
UBaseType_t getStackHighWaterMark() const
Function that calls UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )
Definition Task.hpp:460
bool abortDelay() const
Function that calls BaseType_t xTaskAbortDelay( TaskHandle_t xTask )
Definition Task.hpp:405
TaskBase()=default
Construct a new TaskBase object. This default constructor is deliberately private as this class is no...
TaskHandle_t handle
Handle used to refer to the task when using the FreeRTOS interface.
Definition Task.hpp:1401
std::pair< bool, NotificationBits > notifyAndQueryFromISR(bool &higherPriorityTaskWoken, const NotifyAction action, const NotificationBits value=0, const UBaseType_t index=0) const
Function that calls BaseType_t xTaskNotifyAndQueryIndexedFromISR( TaskHandle_t xTaskToNotify,...
Definition Task.hpp:891
configSTACK_DEPTH_TYPE getStackHighWaterMark2() const
Function that calls UBaseType_t uxTaskGetStackHighWaterMark2( TaskHandle_t xTask )
Definition Task.hpp:489
static TaskHandle_t getHandle(const char *name)
Function that calls TaskHandle_t xTaskGetHandle( const char *pcNameToQuery )
Definition Task.hpp:556
UBaseType_t getBasePriority() const
Function that calls UBaseType_t uxTaskBasePriorityGet( const TaskHandle_t xTask )
Definition Task.hpp:271
static NotificationBits notifyTake(const TickType_t ticksToWait=portMAX_DELAY, const bool clearCountOnExit=true, const UBaseType_t index=0)
Function that calls uint32_t ulTaskNotifyTakeIndexed( UBaseType_t uxIndexToWaitOn,...
Definition Task.hpp:1344
void notifyGive(const UBaseType_t index=0) const
Function that calls BaseType_t xTaskNotifyGiveIndexed( TaskHandle_t xTaskToNotify,...
Definition Task.hpp:611
TickType_t previousWakeTime
Variable that holds the time at which the task was last unblocked.
Definition Task.hpp:1406
void notifyGiveFromISR(bool &higherPriorityTaskWoken, const UBaseType_t index=0) const
Function that calls void vTaskNotifyGiveIndexedFromISR( TaskHandle_t xTaskHandle, UBaseType_t uxIndex...
Definition Task.hpp:640
void resume() const
Function that calls void vTaskResume( TaskHandle_t xTaskToResume )
Definition Task.hpp:337
bool delayUntil(const TickType_t timeIncrement=0)
Function that calls BaseType_t xTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTim...
Definition Task.hpp:1255
void suspend() const
Function that calls void vTaskSuspend( TaskHandle_t xTaskToSuspend )
Definition Task.hpp:314
const char * getName() const
Function that calls char *pcTaskGetName( TaskHandle_t xTaskToQuery )
Definition Task.hpp:533
UBaseType_t getBasePriorityFromISR() const
Function that calls UBaseType_t uxTaskBasePriorityGetFromISR( const TaskHandle_t xTask )
Definition Task.hpp:287
Class that encapsulates the functionality of a FreeRTOS task.
Definition Task.hpp:1427
bool isValid() const
Function that checks the return value of the call to xTaskCreate in the constructor....
Definition Task.hpp:1441
Task(const UBaseType_t priority=tskIDLE_PRIORITY, const configSTACK_DEPTH_TYPE stackDepth=configMINIMAL_STACK_SIZE, const char *name="")
Construct a new Task object by calling BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,...
Definition Task.hpp:1484
TickType_t getTickCount()
Function that calls xTaskGetTickCount()
Definition Kernel.hpp:124