diff --git a/source/freertos_blinky/.settings/language.settings.xml b/source/freertos_blinky/.settings/language.settings.xml index 7c7e381..e193533 100644 --- a/source/freertos_blinky/.settings/language.settings.xml +++ b/source/freertos_blinky/.settings/language.settings.xml @@ -4,7 +4,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/source/lpc_board_nxp_lpcxpresso_11u68/.settings/language.settings.xml b/source/lpc_board_nxp_lpcxpresso_11u68/.settings/language.settings.xml index b6f5121..fd5195d 100644 --- a/source/lpc_board_nxp_lpcxpresso_11u68/.settings/language.settings.xml +++ b/source/lpc_board_nxp_lpcxpresso_11u68/.settings/language.settings.xml @@ -4,7 +4,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/source/lpc_chip_11u6x/.settings/language.settings.xml b/source/lpc_chip_11u6x/.settings/language.settings.xml index 8c3fa5c..fd4d259 100644 --- a/source/lpc_chip_11u6x/.settings/language.settings.xml +++ b/source/lpc_chip_11u6x/.settings/language.settings.xml @@ -4,7 +4,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/source/shoh/.settings/language.settings.xml b/source/shoh/.settings/language.settings.xml index dd46a03..db4f94c 100644 --- a/source/shoh/.settings/language.settings.xml +++ b/source/shoh/.settings/language.settings.xml @@ -4,7 +4,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/source/shoh/src/FreeRTOSCPP/EventGroups.hpp b/source/shoh/src/FreeRTOSCPP/EventGroups.hpp deleted file mode 100644 index 6aa7a1b..0000000 --- a/source/shoh/src/FreeRTOSCPP/EventGroups.hpp +++ /dev/null @@ -1,503 +0,0 @@ -/* - * FreeRTOS-Cpp - * Copyright (C) 2021 Jon Enz. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * https://github.com/jonenz/FreeRTOS-Cpp - */ - -#ifndef FREERTOS_EVENTGROUPS_HPP -#define FREERTOS_EVENTGROUPS_HPP - -#include - -#include "FreeRTOS.h" -#include "event_groups.h" - -namespace FreeRTOS { - -/** - * @class EventGroupBase EventGroupBase.hpp - * - * @brief Base class that provides the standard event group interface to - * FreeRTOS::EventGroup and FreeRTOS::StaticEventGroup. - * - * @note This class is not intended to be instantiated by the user. Use - * FreeRTOS::EventGroup or FreeRTOS::StaticEventGroup. - */ -class EventGroupBase { - public: - friend class EventGroup; - friend class StaticEventGroup; - - EventGroupBase(const EventGroupBase&) = delete; - EventGroupBase& operator=(const EventGroupBase&) = delete; - - static void* operator new(size_t, void* ptr) { return ptr; } - static void* operator new[](size_t, void* ptr) { return ptr; } - static void* operator new(size_t) = delete; - static void* operator new[](size_t) = delete; - - // NOLINTNEXTLINE - using EventBits = std::bitset<((configUSE_16_BIT_TICKS == 1) ? 8 : 24)>; - - /** - * EventGroups.hpp - * - * @brief Function that checks if the underlying event group handle is not - * NULL. This should be used to ensure an event group has been created - * correctly. - * - * @retval true the handle is not NULL. - * @retval false the handle is NULL. - */ - inline bool isValid() const { return (handle != NULL); } - - /** - * EventGroups.hpp - * - * @brief Function that calls EventBits_t xEventGroupWaitBits( const - * EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const - * BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t - * xTicksToWait ) - * - * @see - * - * Read bits within an RTOS event group, optionally entering the Blocked state - * (with a timeout) to wait for a bit or group of bits to become set. - * - * @warning This function cannot be called from an interrupt. - * - * @param bitsToWaitFor A bitwise value that indicates the bit or bits to test - * inside the event group. bitsToWaitFor must not be set to 0. - * @param clearOnExit If clearOnExit is set to true then any bits set in the - * value passed as the bitsToWaitFor parameter will be cleared in the event - * group before wait() returns if wait() returns for any reason other than a - * timeout. The timeout value is set by the ticksToWait parameter. If - * clearOnExit is set to false then the bits set in the event group are not - * altered when the call to wait() returns. - * @param waitForAllBits waitForAllBits is used to create either a logical AND - * test (where all bits must be set) or a logical OR test (where one or more - * bits must be set) as follows: If waitForAllBits is set to true then wait() - * will return when either all the bits set in the value passed as the - * bitsToWaitFor parameter are set in the event group or the specified block - * time expires. If waitForAllBits is set to false then wait() will return - * when any of the bits set in the value passed as the bitsToWaitFor parameter - * are set in the event group or the specified block time expires. - * @param ticksToWait The maximum amount of time (specified in 'ticks') to - * wait for one/all (depending on the waitForAllBits value) of the bits - * specified by bitsToWaitFor to become set. - * @return EventBits The value of the event group at the time either the event - * bits being waited for became set, or the block time expired. The current - * value of the event bits in an event group will be different to the returned - * value if a higher priority task or interrupt changed the value of an event - * bit between the calling task leaving the Blocked state and exiting the - * wait() function. Test the return value to know which bits were set. If - * wait() returned because its timeout expired then not all the bits being - * waited for will be set. If wait() returned because the bits it was waiting - * for were set then the returned value is the event group value before any - * bits were automatically cleared because the clearOnExit parameter was set - * to true. - * - * Example Usage - * @include EventGroups/wait.cpp - */ - inline EventBits wait(const EventBits& bitsToWaitFor = 0, - const bool clearOnExit = false, - const bool waitForAllBits = false, - const TickType_t ticksToWait = portMAX_DELAY) const { - return EventBits(xEventGroupWaitBits( - handle, bitsToWaitFor.to_ulong(), (clearOnExit ? pdTRUE : pdFALSE), - (waitForAllBits ? pdTRUE : pdFALSE), ticksToWait)); - } - - /** - * EventGroups.hpp - * - * @brief Function that calls EventBits_t xEventGroupSetBits( - * EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) - * - * @see - * - * Set bits (flags) within an RTOS event group. This function cannot be called - * from an interrupt. setFromISR() is a version that can be called from an - * interrupt. - * - * Setting bits in an event group will automatically unblock tasks that are - * blocked waiting for the bits. - * - * @param bitsToSet A bitwise value that indicates the bit or bits to set in - * the event group. - * @return EventBits The value of the event group at the time the call to - * set() returns. There are two reasons why the returned value might have the - * bits specified by the uxBitsToSet parameter cleared: - * 1. If setting a bit results in a task that was waiting for the bit leaving - * the blocked state then it is possible the bit will have been cleared - * automatically (see the clearOnExit parameter of wait()). - * 2. Any unblocked (or otherwise Ready state) task that has a priority above - * that of the task that called set() will execute and may change the event - * group value before the call to set() returns. - * - * Example Usage - * @include EventGroups/set.cpp - */ - inline EventBits set(const EventBits& bitsToSet) const { - return EventBits(xEventGroupSetBits(handle, bitsToSet.to_ulong())); - } - - /** - * EventGroups.hpp - * - * @brief Function that calls BaseType_t xEventGroupSetBitsFromISR( - * EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t - * *pxHigherPriorityTaskWoken ) - * - * @see - * - * Set bits (flags) within an RTOS event group. A version of set() that can be - * called from an interrupt service routine (ISR). - * - * Setting bits in an event group will automatically unblock tasks that are - * blocked waiting for the bits. - * - * Setting bits in an event group is not a deterministic operation because - * there are an unknown number of tasks that may be waiting for the bit or - * bits being set. FreeRTOS does not allow non-deterministic operations to be - * performed in interrupts or from critical sections. Therefore - * xEventGroupSetBitFromISR() sends a message to the RTOS daemon task to have - * the set operation performed in the context of the daemon task - where a - * scheduler lock is used in place of a critical section. - * - * @note As mentioned in the paragraph above, setting bits from an ISR will - * defer the set operation to the RTOS daemon task (also known as the timer - * service task). The RTOS daemon task is scheduled according to its priority, - * just like any other RTOS task. Therefore, if it is essential the set - * operation completes immediately (before a task created by the application - * executes) then the priority of the RTOS daemon task must be higher than the - * priority of any application task that uses the event group. The priority of - * the RTOS daemon task is set by the configTIMER_TASK_PRIORITY definition in - * FreeRTOSConfig.h. - * - * @param higherPriorityTaskWoken As mentioned above, calling this function - * will result in a message being sent to the RTOS daemon task. If the - * priority of the daemon task is higher than the priority of the currently - * running task (the task the interrupt interrupted) then - * higherPriorityTaskWoken will be set to true by setFromISR(), indicating - * that a context switch should be requested before the interrupt exits. For - * that reason higherPriorityTaskWoken must be initialised to false. See the - * example code below. - * @param bitsToSet A bitwise value that indicates the bit or bits to set in - * the event group. - * @retval true If the message was sent to the RTOS daemon task. - * @retval false Otherwise or if the timer service queue was full - * - * Example Usage - * @include EventGroups/setFromISR.cpp - */ - inline bool setFromISR(bool& higherPriorityTaskWoken, - const EventBits& bitsToSet) const { - BaseType_t taskWoken = pdFALSE; - bool result = (xEventGroupSetBitsFromISR(handle, bitsToSet.to_ulong(), - &taskWoken) == pdPASS); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * EventGroups.hpp - * - * @brief Function that calls BaseType_t xEventGroupSetBitsFromISR( - * EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t - * *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline bool setFromISR(const EventBits& bitsToSet) const { - return (xEventGroupSetBitsFromISR(handle, bitsToSet.to_ulong(), NULL) == - pdPASS); - } - - /** - * EventGroups.hpp - * - * @brief Function that calls EventBits_t xEventGroupClearBits( - * EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) - * - * @see - * - * Clear bits (flags) within an RTOS event group. This function cannot be - * called from an interrupt. See clearFromISR() for a version that can be - * called from an interrupt. - * - * @param bitsToClear A bitwise value that indicates the bit or bits to clear - * in the event group. - * @return EventBits The value of the event group before the specified bits - * were cleared. - * - * Example Usage - * @include EventGroups/clear.cpp - */ - inline EventBits clear(const EventBits& bitsToClear) const { - return EventBits(xEventGroupClearBits(handle, bitsToClear.to_ulong())); - } - - /** - * EventGroups.hpp - * - * @brief Function that calls BaseType_t xEventGroupClearBitsFromISR( - * EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) - * - * @see - * - * A version of clear() that can be called from an interrupt. The clear - * operation is deferred to the RTOS daemon task which is also known as the - * timer service task. The priority of the daemon task is set by the - * configTIMER_TASK_PRIORITY setting in FreeRTOSConfig.h. - * - * @param bitsToClear A bitwise value that indicates the bit or bits to clear - * in the event group. - * @return true If the operation was successfully deferred to the RTOS daemon - * task. - * @return false If the timer command queue is full. - * - * Example Usage - * @include EventGroups/clearFromISR.cpp - */ - inline bool clearFromISR(const EventBits& bitsToClear) const { - return (xEventGroupClearBitsFromISR(handle, bitsToClear.to_ulong()) == - pdPASS); - } - - /** - * EventGroups.hpp - * - * @brief Function that calls EventBits_t xEventGroupGetBits( - * EventGroupHandle_t xEventGroup ) - * - * @see - * - * Returns the current value of the event bits (event flags) in an RTOS event - * group. This function cannot be used from an interrupt. See getFromISR() for - * a version that can be used in an interrupt. - * - * @return EventBits The value of the event bits in the event group at the - * time get() was called. - */ - inline EventBits get() const { return EventBits(xEventGroupGetBits(handle)); } - - /** - * EventGroups.hpp - * - * @brief Function that calls EventBits_t xEventGroupGetBitsFromISR( - * EventGroupHandle_t xEventGroup ) - * - * @see - * - * A version of get() that can be called from an interrupt. - * - * @return EventBits The value of the event bits in the event group at the - * time getFromISR() was called. - */ - inline EventBits getFromISR() const { - return EventBits(xEventGroupGetBitsFromISR(handle)); - } - - /** - * EventGroups.hpp - * - * @brief Function that calls EventBits_t xEventGroupSync( - * EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const - * EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) - * - * @see - * - * Atomically set bits (flags) within an RTOS event group, then wait for a - * combination of bits to be set within the same event group. This - * functionality is typically used to synchronize multiple tasks (often called - * a task rendezvous), where each task has to wait for the other tasks to - * reach a synchronization point before proceeding. - * - * This function cannot be used from an interrupt. - * - * The function will return before its block time expires if the bits - * specified by the bitsToWait parameter are set, or become set within that - * time. In this case all the bits specified by bitsToWait will be - * automatically cleared before the function returns. - * - * @param bitsToSet The bit or bits to set in the event group before - * determining if (and possibly waiting for), all the bits specified by the - * bitsToWait parameter are set. - * @param bitsToWaitFor A bitwise value that indicates the bit or bits to test - * inside the event group. - * @param ticksToWait The maximum amount of time (specified in 'ticks') to - * wait for all the bits specified by the uxBitsToWaitFor parameter value to - * become set. - * @return EventBits - * - * Example Usage - * @include EventGroups/sync.cpp - */ - inline EventBits sync(const EventBits& bitsToSet = 0, - const EventBits& bitsToWaitFor = 0, - const TickType_t ticksToWait = portMAX_DELAY) const { - return EventBits(xEventGroupSync(handle, bitsToSet.to_ulong(), - bitsToWaitFor.to_ulong(), ticksToWait)); - } - - private: - /** - * EventGroups.hpp - * - * @brief Construct a new EventGroupBase object. - * - * @note Default constructor is deliberately private as this class is not - * intended to be instantiated or derived from by the user. Use - * FreeRTOS::EventGroup or FreeRTOS::StaticEventGroup. - */ - EventGroupBase() = default; - - /** - * EventGroup.hpp - * - * @brief Destroy the EventGroupBase object by calling void - * vEventGroupDelete( EventGroupHandle_t xEventGroup ) - * - * @see - * - * Delete an event group. - * - * Tasks that are blocked on the event group being deleted will be unblocked, - * and report an event group value of 0. - */ - ~EventGroupBase() { vEventGroupDelete(this->handle); }; - - EventGroupBase(EventGroupBase&&) noexcept = default; - EventGroupBase& operator=(EventGroupBase&&) noexcept = default; - - /** - * @brief Handle used to refer to the event group when using the FreeRTOS - * interface. - */ - EventGroupHandle_t handle = NULL; -}; - -#if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - -/** - * @class EventGroup EventGroups.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS event group. - * - * Each event group requires a [very] small amount of RAM that is used to hold - * the event group's state. If an event group is created using this class then - * the required RAM is automatically allocated from the FreeRTOS heap. If an - * event group is created using FreeRTOS::StaticEventGroup then the RAM is - * provided by the application writer, which requires an additional parameter, - * but allows the RAM to be statically allocated at compile time. See the Static - * Vs Dynamic allocation page for more information. - */ -class EventGroup : public EventGroupBase { - public: - /** - * EventGroup.hpp - * - * @brief Construct a new EventGroup object by calling EventGroupHandle_t - * xEventGroupCreate( void ) - * - * @see - * - * @warning The user should call isValid() on this object to verify that the - * queue was created successfully in case the memory required to create the - * queue could not be allocated. - * - * Example Usage - * @include EventGroups/eventGroup.cpp - */ - EventGroup() { this->handle = xEventGroupCreate(); } - ~EventGroup() = default; - - EventGroup(const EventGroup&) = delete; - EventGroup& operator=(const EventGroup&) = delete; - - EventGroup(EventGroup&&) noexcept = default; - EventGroup& operator=(EventGroup&&) noexcept = default; -}; - -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - -#if (configSUPPORT_STATIC_ALLOCATION == 1) - -/** - * @class StaticEventGroup EventGroups.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS event group. - * - * Each event group requires a [very] small amount of RAM that is used to hold - * the event group's state. If an event group is created using - * FreeRTOS::EventGroup then the required RAM is automatically allocated from - * the FreeRTOS heap. If an event group is created using this class then the RAM - * is provided by the application writer, which requires an additional - * parameter, but allows the RAM to be statically allocated at compile time. See - * the Static Vs Dynamic allocation page for more information. - */ -class StaticEventGroup : public EventGroupBase { - public: - /** - * EventGroups.hpp - * - * @brief Construct a new StaticEventGroup object by calling - * EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t - * *pxEventGroupBuffer ) - * - * @see - * - * @warning This class contains the storage buffer for the event group, so the - * user should create this object as a global object or with the static - * storage specifier so that the object instance is not on the stack. - * - * Example Usage - * @include EventGroups/staticEventGroup.cpp - */ - StaticEventGroup() { - this->handle = xEventGroupCreateStatic(&staticEventGroup); - } - ~StaticEventGroup() = default; - - StaticEventGroup(const StaticEventGroup&) = delete; - StaticEventGroup& operator=(const StaticEventGroup&) = delete; - - StaticEventGroup(StaticEventGroup&&) noexcept = default; - StaticEventGroup& operator=(StaticEventGroup&&) noexcept = default; - - private: - StaticEventGroup_t staticEventGroup; -}; - -#endif /* configSUPPORT_STATIC_ALLOCATION */ - -} // namespace FreeRTOS - -#endif // FREERTOS_EVENTGROUPS_HPP diff --git a/source/shoh/src/FreeRTOSCPP/Kernel.hpp b/source/shoh/src/FreeRTOSCPP/Kernel.hpp deleted file mode 100644 index 0f28646..0000000 --- a/source/shoh/src/FreeRTOSCPP/Kernel.hpp +++ /dev/null @@ -1,409 +0,0 @@ -/* - * FreeRTOS-Cpp - * Copyright (C) 2021 Jon Enz. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * https://github.com/jonenz/FreeRTOS-Cpp - */ - -#ifndef FREERTOS_KERNEL_HPP -#define FREERTOS_KERNEL_HPP - -#include "FreeRTOS.h" -#include "task.h" - -namespace FreeRTOS { - -/** - * @brief Kernel namespace that provides an interface to kernel functions. - * - */ -namespace Kernel { -enum class SchedulerState : BaseType_t { - Suspended = taskSCHEDULER_SUSPENDED, - NotStarted = taskSCHEDULER_NOT_STARTED, - Running = taskSCHEDULER_RUNNING, -}; - -/** - * @brief If versionNumber ends with + it represents the version in development - * after the numbered release. - */ -inline constexpr char versionNumber[] = tskKERNEL_VERSION_NUMBER; -inline constexpr BaseType_t versionMajor = tskKERNEL_VERSION_MAJOR; -inline constexpr BaseType_t versionMinor = tskKERNEL_VERSION_MINOR; -inline constexpr BaseType_t versionBuild = tskKERNEL_VERSION_BUILD; - -#if (INCLUDE_xTaskGetSchedulerState == 1) -/** - * Kernel.hpp - * - * @brief Function that calls xTaskGetSchedulerState() - * - * @see - * - * @retval SchedulerState Returns the scheduler state as Running, NotStarted, or - * Suspended. - */ -inline SchedulerState getSchedulerState() { - return static_cast(xTaskGetSchedulerState()); -} -#endif /* INCLUDE_xTaskGetSchedulerState */ - -/** - * Kernel.hpp - * - * @brief Function that calls uxTaskGetNumberOfTasks() - * - * @see - * - * @retval UBaseType_t The number of tasks that the real time kernel is - * currently managing. This includes all ready, blocked and suspended tasks. A - * task that has been deleted but not yet freed by the idle task will also be - * included in the count. - */ -inline UBaseType_t getNumberOfTasks() { return uxTaskGetNumberOfTasks(); } - -#if (INCLUDE_xTaskGetIdleTaskHandle == 1 && configGENERATE_RUN_TIME_STATS == 1) -/** - * Kernel.hpp - * - * @brief Function that calls xTaskGetIdleRunTimeCounter() - * - * @see - * - * @retval TickType_t The run-time counter for the Idle task. - * - * This function can be used to determine how much CPU time the idle task - * receives. See the Run Time Stats page for a full description of the - * run-time-stats feature. - * - * configGENERATE_RUN_TIME_STATS and INCLUDE_xTaskGetIdleTaskHandle must both be - * defined as 1 for this function to be available. The application must also - * then provide definitions for portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and - * portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral timer/counter and - * return the timer's current count value respectively. It is recommended to - * make the timer at least 10 times the frequency of the tick count. - */ -inline TickType_t getIdleRunTimeCounter() { - return xTaskGetIdleRunTimeCounter(); -} -#endif /* INCLUDE_xTaskGetIdleTaskHandle && configGENERATE_RUN_TIME_STATS*/ - -/** - * Kernel.hpp - * - * @brief Function that calls xTaskGetTickCount() - * - * @see - * - * @retval TickType_t The count of ticks since - * FreeRTOS::Kernel::startScheduler() was called. - */ -inline TickType_t getTickCount() { return xTaskGetTickCount(); } - -/** - * Kernel.hpp - * - * @brief Function that calls xTaskGetTickCountFromISR() - * - * @see - * - * @retval TickType_t The count of ticks since - * FreeRTOS::Kernel::startScheduler() was called. - * - * This is a version of FreeRTOS::Kernel::getTickCount() that is safe to be - * called from an ISR - provided that TickType_t is the natural word size of the - * microcontroller being used or interrupt nesting is either not supported or - * not being used. - */ -inline TickType_t getTickCountFromISR() { return xTaskGetTickCountFromISR(); } - -/** - *Kernel.hpp - * - * @brief Function that calls taskYIELD() - * - * @see - * - * FreeRTOS::Kernel::yield() is used to request a context switch to another - *task. However, if there are no other tasks at a higher or equal priority to - *the task that calls FreeRTOS::Kernel::yield() then the RTOS scheduler will - *simply select the task that called FreeRTOS::Kernel::yield() to run again. - */ -inline void yield() { taskYIELD(); } - -/** - * Kernel.hpp - * - * @brief Function that calls taskENTER_CRITICAL() - * - * @see - * - * Function to mark the start of a critical code region. Preemptive context - * switches cannot occur when in a critical region. - * - * @note This may alter the stack (depending on the portable implementation) so - * must be used with care! - * - * Example Usage - * @include Kernel/enterExitCritical.cpp - */ -inline void enterCritical() { taskENTER_CRITICAL(); } - -/** - * Kernel.hpp - * - * @brief Function that calls taskENTER_CRITICAL_FROM_ISR() - * - * @see - * - * - * @retval uint32_t the interrupt mask state as it was before the macro was - * called. The value returned by FreeRTOS::Kernel::enterCriticalFromISR() must - * be used as the interruptStatus parameter in the matching call to - * FreeRTOS::Kernel::exitCriticalFromISR(). - * - * Function to mark the start of a critical code region. Preemptive context - * switches cannot occur when in a critical region. - * - * @note This may alter the stack (depending on the portable implementation) so - * must be used with care! - * - * Example Usage - * @include Kernel/enterExitCriticalFromISR.cpp - */ -inline uint32_t enterCriticalFromISR() { return taskENTER_CRITICAL_FROM_ISR(); } - -/** - * Kernel.hpp - * - * @brief Function that calls taskEXIT_CRITICAL() - * - * @see - * - * Function to mark the end of a critical code region. Preemptive context - * switches cannot occur when in a critical region. - * - * @note This may alter the stack (depending on the portable implementation) so - * must be used with care! - * - * Example Usage - * @include Kernel/enterExitCritical.cpp - */ -inline void exitCritical() { taskEXIT_CRITICAL(); } - -/** - * Kernel.hpp - * - * @brief Function that calls taskEXIT_CRITICAL_FROM_ISR() - * - * @see - * - * - * @param interruptStatus The value used as the interruptStatus parameter must - * be the value returned from the matching call to - * FreeRTOS::Kernel::enterCriticalFromISR(). - * - * Function to mark the end of a critical code region. Preemptive context - * switches cannot occur when in a critical region. - * - * @note This may alter the stack (depending on the portable implementation) so - * must be used with care! - * - * Example Usage - * @include Kernel/enterExitCriticalFromISR.cpp - */ -inline void exitCriticalFromISR(const uint32_t interruptStatus) { - taskEXIT_CRITICAL_FROM_ISR(interruptStatus); -} - -/** - * Kernel.hpp - * - * @brief Function that calls taskDISABLE_INTERRUPTS() - * - * @see - * - * Function to disable all maskable interrupts. - */ -inline void disableInterrupts() { taskDISABLE_INTERRUPTS(); } - -/** - * Kernel.hpp - * - * @brief Function that calls taskENABLE_INTERRUPTS() - * - * @see - * - * Function to enable microcontroller interrupts. - */ -inline void enableInterrupts() { taskENABLE_INTERRUPTS(); } - -/** - * Kernel.hpp - * - * @brief Function that calls vTaskStartScheduler() - * - * @see - * - * Starts the real time kernel tick processing. After calling the kernel has - * control over which tasks are executed and when. - * - * Example Usage - * @include Kernel/startScheduler.cpp - */ -inline void startScheduler() { vTaskStartScheduler(); } - -/** - * Kernel.hpp - * - * @brief Function that calls vTaskEndScheduler() - * - * @see - * - * @note At the time of writing only the x86 real mode port, which runs on a PC - * in place of DOS, implements this function. - * - * Stops the real time kernel tick. All created tasks will be automatically - * deleted and multitasking (either preemptive or cooperative) will stop. - * Execution then resumes from the point where - * FreeRTOS::Kernel::startScheduler() was called, as if - * FreeRTOS::Kernel::startScheduler() had just returned. - * - * See the demo application file main. c in the demo/PC directory for an example - * that uses FreeRTOS::Kernel::endScheduler(). - * - * FreeRTOS::Kernel::endScheduler() requires an exit function to be defined - * within the portable layer (see vPortEndScheduler () in port. c for the PC - * port). This performs hardware specific operations such as stopping the - * kernel tick. - * - * FreeRTOS::Kernel::endScheduler() will cause all of the resources allocated by - * the kernel to be freed - but will not free resources allocated by application - * tasks. - * - * Example Usage - * @include Kernel/endScheduler.cpp - */ -inline void endScheduler() { vTaskEndScheduler(); } - -/** - * Kernel.hpp - * - * @brief Function that calls vTaskSuspendAll() - * - * @see - * - * Suspends the scheduler without disabling interrupts. Context switches will - * not occur while the scheduler is suspended. - * - * After calling FreeRTOS::Kernel::suspendAll() the calling task will continue - * to execute without risk of being swapped out until a call to - * FreeRTOS::Kernel::resumeAll() has been made. - * - * API functions that have the potential to cause a context switch (for example, - * FreeRTOS::Task::delayUntil(), FreeRTOS::Queue::send(), etc.) must not be - * called while the scheduler is suspended. - * - * Example Usage - * @include Kernel/suspendAll.cpp - */ -inline void suspendAll() { vTaskSuspendAll(); } - -/** - * Kernel.hpp - * - * @brief Function that calls xTaskResumeAll() - * - * @see - * - * Resumes scheduler activity after it was suspended by a call to - * FreeRTOS::Kernel::suspendAll(). - * - * FreeRTOS::Kernel::resumeAll() only resumes the scheduler. It does not - * unsuspend tasks that were previously suspended by a call to - * FreeRTOS::Task::suspend(). - * - * @retval true If resuming the scheduler caused a context switch. - * @retval false Otherwise. - * - * Example Usage - * @include Kernel/resumeAll.cpp - */ -inline bool resumeAll() { return (xTaskResumeAll() == pdTRUE); } - -/** - * Kernel.hpp - * - * @brief Function that calls vTaskStepTick( const TickType_t xTicksToJump - * ) - * - * @see - * - * Only available when configUSE_TICKLESS_IDLE is set to 1. If tickless mode is - * being used, or a low power mode is implemented, then the tick interrupt will - * not execute during idle periods. When this is the case, the tick count value - * maintained by the scheduler needs to be kept up to date with the actual - * execution time by being skipped forward by a time equal to the idle period. - * - * @param ticksToJump The number of RTOS ticks that have passed since the tick - * interrupt was stopped. - */ -inline void stepTick(const TickType_t ticksToJump) { - vTaskStepTick(ticksToJump); -} - -/** - * Kernel.hpp - * - * @brief Function that calls xTaskCatchUpTicks( TickType_t xTicksToCatchUp - * ) - * - * @see - * - * This function corrects the tick count value after the application code has - * held interrupts disabled for an extended period resulting in tick interrupts - * having been missed. - * - * This function is similar to FreeRTOS::Kernel::stepTick(), however, unlike - * FreeRTOS::Kernel::stepTick(), FreeRTOS::Kernel::catchUpTicks() may move the - * tick count forward past a time at which a task should be removed from the - * blocked state. That means tasks may have to be removed from the blocked - * state as the tick count is moved. - * - * @param ticksToCatchUp The number of tick interrupts that have been missed due - * to interrupts being disabled. Its value is not computed automatically, so - * must be computed by the application writer. - * - * @retval true If moving the tick count forward resulted in a task leaving the - * blocked state and a context switch being performed. - * @retval false Otherwise. - */ -inline bool catchUpTicks(const TickType_t ticksToCatchUp) { - return (xTaskCatchUpTicks(ticksToCatchUp) == pdTRUE); -} -} // namespace Kernel - -} // namespace FreeRTOS - -#endif // FREERTOS_KERNEL_HPP diff --git a/source/shoh/src/FreeRTOSCPP/MessageBuffer.hpp b/source/shoh/src/FreeRTOSCPP/MessageBuffer.hpp deleted file mode 100644 index 0e9fdad..0000000 --- a/source/shoh/src/FreeRTOSCPP/MessageBuffer.hpp +++ /dev/null @@ -1,518 +0,0 @@ -/* - * FreeRTOS-Cpp - * Copyright (C) 2021 Jon Enz. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * https://github.com/jonenz/FreeRTOS-Cpp - */ - -#ifndef FREERTOS_MESSAGEBUFFER_HPP -#define FREERTOS_MESSAGEBUFFER_HPP - -#include "FreeRTOS.h" -#include "message_buffer.h" - -namespace FreeRTOS { - -/** - * @class MessageBufferBase MessageBuffer.hpp - * - * @brief Base class that provides the standard message buffer interface to - * FreeRTOS::MessageBuffer and FreeRTOS::StaticMessageBuffer. - * - * @note This class is not intended to be instantiated by the user. Use - * FreeRTOS::MessageBuffer or FreeRTOS::StaticMessageBuffer. - * - * @warning Uniquely among FreeRTOS objects, the stream buffer implementation - * (so also the message buffer implementation, as message buffers are built on - * top of stream buffers) assumes there is only one task or interrupt that will - * write to the buffer (the writer), and only one task or interrupt that will - * read from the buffer (the reader). It is safe for the writer and reader to - * be different tasks or interrupts, but, unlike other FreeRTOS objects, it is - * not safe to have multiple different writers or multiple different readers. If - * there are to be multiple different writers then the application writer must - * place each call to a writing API function (such as send()) inside a critical - * section and set the send block time to 0. Likewise, if there are to be - * multiple different readers then the application writer must place each call - * to a reading API function (such as read()) inside a critical section and set - * the receive block time to 0. - */ -class MessageBufferBase { - public: - friend class MessageBuffer; - template - friend class StaticMessageBuffer; - - MessageBufferBase(const MessageBufferBase&) = delete; - MessageBufferBase& operator=(const MessageBufferBase&) = delete; - - static void* operator new(size_t, void* ptr) { return ptr; } - static void* operator new[](size_t, void* ptr) { return ptr; } - static void* operator new(size_t) = delete; - static void* operator new[](size_t) = delete; - - /** - * MessageBuffer.hpp - * - * @brief Function that checks if the underlying message buffer handle is not - * NULL. This should be used to ensure a message buffer has been created - * correctly. - * - * @retval true If the handle is not NULL. - * @retval false If the handle is NULL. - */ - inline bool isValid() const { return (handle != NULL); } - - /** - * MessageBuffer.hpp - * - * @brief Function that calls size_t xMessageBufferSend( - * MessageBufferHandle_t xMessageBuffer, const void *pvTxData, size_t - * xDataLengthBytes, TickType_t xTicksToWait ) - * - * @see - * - * Sends a discrete message to the message buffer. The message can be any - * length that fits within the buffer's free space, and is copied into the - * buffer. - * - * Use send() to write to a message buffer from a task. Use sendFromISR() to - * write to a message buffer from an interrupt service routine (ISR). - * - * @param data A pointer to the message that is to be copied into the message - * buffer. - * @param length The length of the message. That is, the number of bytes to - * copy from data into the message buffer. When a message is written to the - * message buffer an additional sizeof( size_t ) bytes are also written to - * store the message's length. sizeof( size_t ) is typically 4 bytes on a - * 32-bit architecture, so on most 32-bit architecture setting length to 20 - * will reduce the free space in the message buffer by 24 bytes (20 bytes of - * message data and 4 bytes to hold the message length). - * @param ticksToWait The maximum amount of time the calling task should - * remain in the Blocked state to wait for enough space to become available in - * the message buffer, should the message buffer have insufficient space when - * send() is called. The calling task will never block if ticksToWait is - * zero. The block time is specified in tick periods, so the absolute time it - * represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() - * can be used to convert a time specified in milliseconds into a time - * specified in ticks. Setting ticksToWait to portMAX_DELAY will cause the - * task to wait indefinitely (without timing out), provided - * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any - * CPU time when they are in the Blocked state. - * @return size_t The number of bytes written to the message buffer. If the - * call to send() times out before there was enough space to write the message - * into the message buffer then zero is returned. If the call did not time - * out then length is returned. - * - * Example Usage - * @include MessageBuffer/send.cpp - */ - inline size_t send(const void* data, const size_t length, - const TickType_t ticksToWait = portMAX_DELAY) const { - return xMessageBufferSend(handle, data, length, ticksToWait); - } - - /** - * MessageBuffer.hpp - * - * @brief Function that calls size_t xMessageBufferSendFromISR( - * MessageBufferHandle_t xMessageBuffer, const void *pvTxData, size_t - * xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * Interrupt safe version of the API function that sends a discrete message to - * the message buffer. The message can be any length that fits within the - * buffer's free space, and is copied into the buffer. - * - * Use send() to write to a message buffer from a task. Use sendFromISR() to - * write to a message buffer from an interrupt service routine (ISR). - * - * @param higherPriorityTaskWoken It is possible that a message buffer will - * have a task blocked on it waiting for data. Calling sendFromISR() can make - * data available, and so cause a task that was waiting for data to leave the - * Blocked state. If calling sendFromISR() causes a task to leave the Blocked - * state, and the unblocked task has a priority higher than the currently - * executing task (the task that was interrupted), then, internally, - * sendFromISR() will set higherPriorityTaskWoken to true. If sendFromISR() - * sets this value to true, then normally a context switch should be performed - * before the interrupt is exited. This will ensure that the interrupt returns - * directly to the highest priority Ready state task. higherPriorityTaskWoken - * should be set to false before it is passed into the function. See the code - * example below for an example. - * @param data A pointer to the message that is to be copied into the message - * buffer. - * @param length The length of the message. That is, the number of bytes to - * copy from data into the message buffer. When a message is written to the - * message buffer an additional sizeof( size_t ) bytes are also written to - * store the message's length. sizeof( size_t ) is typically 4 bytes on a - * 32-bit architecture, so on most 32-bit architecture setting length to 20 - * will reduce the free space in the message buffer by 24 bytes (20 bytes of - * message data and 4 bytes to hold the message length). - * @return size_t The number of bytes actually written to the message buffer. - * If the message buffer didn't have enough free space for the message to be - * stored then 0 is returned, otherwise length is returned. - * - * Example Usage - * @include MessageBuffer/sendFromISR.cpp - */ - inline size_t sendFromISR(bool& higherPriorityTaskWoken, const void* data, - const size_t length) const { - BaseType_t taskWoken = pdFALSE; - size_t result = xMessageBufferSendFromISR(handle, data, length, &taskWoken); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * MessageBuffer.hpp - * - * @brief Function that calls size_t xMessageBufferSendFromISR( - * MessageBufferHandle_t xMessageBuffer, const void *pvTxData, size_t - * xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline size_t sendFromISR(const void* data, const size_t length) const { - return xMessageBufferSendFromISR(handle, data, length, NULL); - } - - /** - * MessageBuffer.hpp - * - * @brief Function that calls size_t xMessageBufferReceive( - * MessageBufferHandle_t xMessageBuffer, void *pvRxData, size_t - * xBufferLengthBytes, TickType_t xTicksToWait ) - * - * @see - * - * Use receive() to read from a message buffer from a task. - * UsereceiveFromISR() to read from a message buffer from an interrupt service - * routine (ISR). - * - * @param buffer A pointer to the buffer into which the received message is to - * be copied. - * @param bufferLength The length of the buffer pointed to by the buffer - * parameter. This sets the maximum length of the message that can be - * received. If bufferLength is too small to hold the next message then the - * message will be left in the message buffer and 0 will be returned. - * @param ticksToWait The maximum amount of time the task should remain in the - * Blocked state to wait for a message, should the message buffer be empty. - * receive() will return immediately if ticksToWait is zero and the message - * buffer is empty. The block time is specified in tick periods, so the - * absolute time it represents is dependent on the tick frequency. The macro - * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds - * into a time specified in ticks. Setting ticksToWait to portMAX_DELAY will - * cause the task to wait indefinitely (without timing out), provided - * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any - * CPU time when they are in the Blocked state. - * @return size_t The length, in bytes, of the message read from the message - * buffer, if any. If receive() times out before a message became available - * then zero is returned. If the length of the message is greater than - * bufferLength then the message will be left in the message buffer and zero - * is returned. - * - * Example Usage - * @include MessageBuffer/receive.cpp - */ - inline size_t receive(void* buffer, const size_t bufferLength, - const TickType_t ticksToWait = portMAX_DELAY) const { - return xMessageBufferReceive(handle, buffer, bufferLength, ticksToWait); - } - - /** - * MessageBuffer.hpp - * - * @brief Function that calls size_t xMessageBufferReceiveFromISR( - * MessageBufferHandle_t xMessageBuffer, void *pvRxData, size_t - * xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * Use receive() to read from a message buffer from a task. - * UsereceiveFromISR() to read from a message buffer from an interrupt service - * routine (ISR). - * - * @param higherPriorityTaskWoken It is possible that a message buffer will - * have a task blocked on it waiting for space to become available. Calling - * receiveFromISR() can make space available, and so cause a task that is - * waiting for space to leave the Blocked state. If calling receiveFromISR() - * causes a task to leave the Blocked state, and the unblocked task has a - * priority higher than the currently executing task (the task that was - * interrupted), then, internally, receiveFromISR() will set - * higherPriorityTaskWoken to true. If receiveFromISR() sets this value to - * true, then normally a context switch should be performed before the - * interrupt is exited. That will ensure the interrupt returns directly to the - * highest priority Ready state task. higherPriorityTaskWoken should be set - * to false before it is passed into the function. See the code example below - * for an example. - * @param buffer A pointer to the buffer into which the received message is to - * be copied. - * @param bufferLength The length of the buffer pointed to by the buffer - * parameter. This sets the maximum length of the message that can be - * received. If bufferLength is too small to hold the next message then the - * message will be left in the message buffer and 0 will be returned. - * @return size_t The length, in bytes, of the message read from the message - * buffer, if any. - * - * Example Usage - * @include MessageBuffer/receiveFromISR.cpp - */ - inline size_t receiveFromISR(bool& higherPriorityTaskWoken, void* buffer, - const size_t bufferLength) const { - BaseType_t taskWoken = pdFALSE; - size_t result = - xMessageBufferReceiveFromISR(handle, buffer, bufferLength, &taskWoken); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * MessageBuffer.hpp - * - * @brief Function that calls size_t xMessageBufferReceiveFromISR( - * MessageBufferHandle_t xMessageBuffer, void *pvRxData, size_t - * xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline size_t receiveFromISR(void* buffer, const size_t bufferLength) const { - return xMessageBufferReceiveFromISR(handle, buffer, bufferLength, NULL); - } - - /** - * MessageBuffer.hpp - * - * @brief Function that calls size_t xMessageBufferSpacesAvailable( - * MessageBufferHandle_t xMessageBuffer ) - * - * @see - * - * Queries a message buffer to see how much free space it contains, which is - * equal to the amount of data that can be sent to the message buffer before - * it is full. The returned value is 4 bytes larger than the maximum message - * size that can be sent to the message buffer. - * - * @return size_t The number of bytes that can be written to the message - * buffer before the message buffer would be full. When a message is written - * to the message buffer an additional sizeof( size_t ) bytes are also written - * to store the message's length. sizeof( size_t ) is typically 4 bytes on a - * 32-bit architecture, so if spacesAvailable() returns 10, then the size of - * the largest message that can be written to the message buffer is 6 bytes. - */ - inline size_t spacesAvailable() const { - return xMessageBufferSpacesAvailable(handle); - } - - /** - * MessageBuffer.hpp - * - * @brief Function that calls BaseType_t xMessageBufferReset( - * MessageBufferHandle_t xMessageBuffer ) - * - * @see - * - * Resets a message buffer to its initial, empty, state. Any data that was in - * the message buffer is discarded. A message buffer can only be reset if - * there are no tasks blocked waiting to either send to or receive from the - * message buffer. - * - * @retval true If the message buffer is reset. - * @retval false If there was a task blocked waiting to send to or read from - * the message buffer then the message buffer will not be reset. - */ - inline bool reset() const { return (xMessageBufferReset(handle) == pdPASS); } - - /** - * MessageBuffer.hpp - * - * @brief Function that calls BaseType_t xMessageBufferIsEmpty( - * MessageBufferHandle_t xMessageBuffer ) - * - * @see - * - * Queries a message buffer to see if it is empty. A message buffer is empty - * if it does not contain any messages. - * - * @retval true If the message buffer is empty. - * @retval false Otherwise. - */ - inline bool isEmpty() const { - return (xMessageBufferIsEmpty(handle) == pdTRUE); - } - - /** - * MessageBuffer.hpp - * - * @brief Function that calls BaseType_t xMessageBufferIsFull( - * MessageBufferHandle_t xMessageBuffer ) - * - * @see - * - * Queries a message buffer to see if it is full. A message buffer is full if - * it cannot accept any more messages, of any size, until space is made - * available by a message being removed from the message buffer. - * - * @retval true If the message buffer is full. - * @retval false Otherwise. - */ - inline bool isFull() const { - return (xMessageBufferIsFull(handle) == pdTRUE); - } - - private: - MessageBufferBase() = default; - - /** - * MessageBuffer.hpp - * - * @brief Destroy the MessageBufferBase object by calling void - * vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer ) - * - * @see - * - * Delete a queue - freeing all the memory allocated for storing of items - * placed on the queue. - */ - ~MessageBufferBase() { vMessageBufferDelete(this->handle); } - - MessageBufferBase(MessageBufferBase&&) noexcept = default; - MessageBufferBase& operator=(MessageBufferBase&&) noexcept = default; - - MessageBufferHandle_t handle = NULL; -}; - -#if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - -/** - * @class MessageBuffer MessageBuffer.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS message - * buffer. - * - * A message buffer using dynamically allocated memory from the FreeRTOS heap. - * See FreeRTOS::StaticMessageBuffer for a version that uses statically - * allocated memory (memory that is allocated at compile time). - */ -class MessageBuffer : public MessageBufferBase { - public: - /** - * MessageBuffer.hpp - * - * @brief Construct a new MessageBuffer object by calling - * MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes - * ) - * - * @see - * - * @warning The user should call isValid() on this object to verify that the - * message buffer was created successfully in case the memory required to - * create the message buffer could not be allocated. - * - * @param size The total number of bytes (not messages) the message buffer - * will be able to hold at any one time. When a message is written to the - * message buffer an additional sizeof( size_t ) bytes are also written to - * store the message's length. sizeof( size_t ) is typically 4 bytes on a - * 32-bit architecture, so on most 32-bit architectures a 10 byte message will - * take up 14 bytes of message buffer space. - * - * Example Usage - * @include MessageBuffer/messageBuffer.cpp - */ - explicit MessageBuffer(size_t size) { - this->handle = xMessageBufferCreate(size); - } - ~MessageBuffer() = default; - - MessageBuffer(const MessageBuffer&) = delete; - MessageBuffer& operator=(const MessageBuffer&) = delete; - - MessageBuffer(MessageBuffer&&) noexcept = default; - MessageBuffer& operator=(MessageBuffer&&) noexcept = default; -}; - -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - -#if (configSUPPORT_STATIC_ALLOCATION == 1) - -/** - * @class StaticMessageBuffer MessageBuffer.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS message - * buffer. - * - * If a message buffer is created using this class then the RAM is provided by - * the application writer as part of the object instance and allows the RAM to - * be statically allocated at compile time. - * - * @tparam N The size, in bytes, of the storage for the message buffer. - */ -template -class StaticMessageBuffer : public MessageBufferBase { - public: - /** - * MessageBuffer.hpp - * - * @brief Construct a new StaticMessageBuffer object by calling - * MessageBufferHandle_t xMessageBufferCreateStatic( size_t - * xBufferSizeBytes, uint8_t *pucMessageBufferStorageArea, - * StaticMessageBuffer_t *pxStaticMessageBuffer ) - * - * @see - * - * @warning This class contains the storage buffer for the message buffer, so - * the user should create this object as a global object or with the static - * storage specifier so that the object instance is not on the stack. - * - * Example Usage - * @include MessageBuffer/staticMessageBuffer.cpp - */ - StaticMessageBuffer() : MessageBufferBase() { - this->handle = xMessageBufferCreateStatic(sizeof(storage), storage, - &staticMessageBuffer); - } - ~StaticMessageBuffer() = default; - - StaticMessageBuffer(const StaticMessageBuffer&) = delete; - StaticMessageBuffer& operator=(const StaticMessageBuffer&) = delete; - - StaticMessageBuffer(StaticMessageBuffer&&) noexcept = default; - StaticMessageBuffer& operator=(StaticMessageBuffer&&) noexcept = default; - - private: - StaticMessageBuffer_t staticMessageBuffer; - uint8_t storage[N] = {0}; -}; - -#endif /* configSUPPORT_STATIC_ALLOCATION */ - -} // namespace FreeRTOS - -#endif // FREERTOS_MESSAGEBUFFER_HPP \ No newline at end of file diff --git a/source/shoh/src/FreeRTOSCPP/Mutex.hpp b/source/shoh/src/FreeRTOSCPP/Mutex.hpp deleted file mode 100644 index e045324..0000000 --- a/source/shoh/src/FreeRTOSCPP/Mutex.hpp +++ /dev/null @@ -1,495 +0,0 @@ -/* - * FreeRTOS-Cpp - * Copyright (C) 2021 Jon Enz. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * https://github.com/jonenz/FreeRTOS-Cpp - */ - -#ifndef FREERTOS_MUTEX_HPP -#define FREERTOS_MUTEX_HPP - -#include "FreeRTOS.h" -#include "semphr.h" - -namespace FreeRTOS { - -/** - * @class MutexBase Mutex.hpp - * - * @brief Base class that provides the standard mutex interface to - * FreeRTOS::Mutex, FreeRTOS::StaticMutex, FreeRTOS::RecursiveMutex, and - * FreeRTOS::StaticRecursiveMutex. - * - * @note This class is not intended to be instantiated by the user. Use - * FreeRTOS::Mutex, FreeRTOS::StaticMutex, FreeRTOS::RecursiveMutex, and - * FreeRTOS::StaticRecursiveMutex. - */ -class MutexBase { - public: - friend class Mutex; - friend class StaticMutex; - friend class RecursiveMutexBase; - friend class RecursiveMutex; - friend class StaticRecursiveMutex; - - MutexBase(const MutexBase&) = delete; - MutexBase& operator=(const MutexBase&) = delete; - - static void* operator new(size_t, void* ptr) { return ptr; } - static void* operator new[](size_t, void* ptr) { return ptr; } - static void* operator new(size_t) = delete; - static void* operator new[](size_t) = delete; - - /** - * Mutex.hpp - * - * @brief Function that checks if the underlying semaphore handle is not NULL. - * This should be used to ensure a semaphore has been created correctly. - * - * @retval true the handle is not NULL. - * @retval false the handle is NULL. - */ - inline bool isValid() const { return (handle != NULL); } - - /** - * Mutex.hpp - * - * @brief Function that calls xSemaphoreTake( SemaphoreHandle_t - * xSemaphore, TickType_t xTicksToWait ) - * - * @see - * - * @param ticksToWait The time in ticks to wait for the mutex to become - * available. The macro portTICK_PERIOD_MS can be used to convert this to a - * real time. A block time of zero can be used to poll the mutex. - * @retval true If the mutex was locked. - * @retval false If ticksToWait expired without the mutex becoming available. - * - * Example Usage - * @include Mutex/lock.cpp - */ - inline bool lock(const TickType_t ticksToWait = portMAX_DELAY) const { - return (xSemaphoreTake(handle, ticksToWait) == pdTRUE); - } - - /** - * Mutex.hpp - * - * @brief Function that calls xSemaphoreTakeFromISR ( SemaphoreHandle_t - * xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @param higherPriorityTaskWoken It is possible (although unlikely, and - * dependent on the semaphore type) that a mutex will have one or more tasks - * blocked on it waiting to give the mutex. Calling lockFromISR() will make a - * task that was blocked waiting to give the mutex leave the Blocked state. If - * calling the API function causes a task to leave the Blocked state, and the - * unblocked task has a priority equal to or higher than the currently - * executing task (the task that was interrupted), then, internally, the API - * function will set higherPriorityTaskWoken to true. - * @return true If the mutex was successfully locked. - * @return false If the mutex was not successfully locked because it was not - * available. - */ - inline bool lockFromISR(bool& higherPriorityTaskWoken) const { - BaseType_t taskWoken = pdFALSE; - bool result = (xSemaphoreTakeFromISR(handle, &taskWoken) == pdTRUE); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * Mutex.hpp - * - * @brief Function that calls xSemaphoreTakeFromISR ( SemaphoreHandle_t - * xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline bool lockFromISR() const { - return (xSemaphoreTakeFromISR(handle, NULL) == pdTRUE); - } - - /** - * Mutex.hpp - * - * @brief Function that calls xSemaphoreGive( SemaphoreHandle_t xSemaphore - * ) - * - * @see - * - * @warning This must not be used from an ISR. - * - * @return true If the mutex was unlocked. - * @return false If an error occurred. Mutexes (semaphores) are implemented - * using queues. An error can occur if there is no space on the queue to post - * a message indicating that the mutex was not first locked correctly. - * - * Example Usage - * @include Mutex/unlock.cpp - */ - inline bool unlock() const { return (xSemaphoreGive(handle) == pdTRUE); } - - private: - MutexBase() = default; - - /** - * Mutex.hpp - * - * @brief Destroy the MutexBase object by calling void vSemaphoreDelete( - * SemaphoreHandle_t xSemaphore ) - * - * @see - * - * @note Do not delete a mutex that has tasks blocked on it (tasks that are in - * the Blocked state waiting for the mutex to become available). - */ - ~MutexBase() { vSemaphoreDelete(this->handle); } - - MutexBase(MutexBase&&) noexcept = default; - MutexBase& operator=(MutexBase&&) noexcept = default; - - /** - * @brief Handle used to refer to the semaphore when using the FreeRTOS - * interface. - */ - SemaphoreHandle_t handle = NULL; -}; - -/** - * @class RecursiveMutexBase Mutex.hpp - * - * @brief Base class that provides the recursive mutex interface to - * FreeRTOS::RecursiveMutex and FreeRTOS::StaticRecursiveMutex. This class - * exists to override the lock() and unlock() functions which require different - * underlying functions from what is used in FreeRTOS::MutexBase. - * - * @note This class is not intended to be instantiated by the user. Use - * FreeRTOS::RecursiveMutex or FreeRTOS::StaticRecursiveMutex. - */ -class RecursiveMutexBase : public MutexBase { - public: - friend class RecursiveMutex; - friend class StaticRecursiveMutex; - - RecursiveMutexBase(const RecursiveMutexBase&) = delete; - RecursiveMutexBase& operator=(const RecursiveMutexBase&) = delete; - - static void* operator new(size_t, void*); - static void* operator new[](size_t, void*); - static void* operator new(size_t) = delete; - static void* operator new[](size_t) = delete; - - /** - * Mutex.hpp - * - * @brief Function that calls xSemaphoreTakeRecursive( SemaphoreHandle_t - * xMutex, TickType_t xTicksToWait ) - * - * @see - * - * @param ticksToWait The time in ticks to wait for the mutex to become - * available. The macro portTICK_PERIOD_MS can be used to convert this to a - * real time. A block time of zero can be used to poll the mutex. If the task - * already owns the mutex then take() will return immediately no matter what - * the value of ticksToWait. - * @retval true If the mutex was locked. - * @retval false If ticksToWait expired without the mutex becoming available. - * - * Example Usage - * @include Mutex/recursiveLock.cpp - */ - inline bool lock(const TickType_t ticksToWait = portMAX_DELAY) const { - return (xSemaphoreTakeRecursive(handle, ticksToWait) == pdTRUE); - } - - /** - * Mutex.hpp - * - * @brief Function that calls xSemaphoreGiveRecursive( SemaphoreHandle_t - * xSemaphore ) - * - * @see - * - * A mutex used recursively can be locked repeatedly by the owner. The mutex - * doesn't become available again until the owner has called unlock() for each - * successful lock request. For example, if a task successfully locks the - * same mutex 5 times then the mutex will not be available to any other task - * until it has also unlocked the mutex back exactly five times. - * - * @return true If the mutex was unlocked. - * @return false Otherwise. - * - * Example Usage - * @include Mutex/recursiveLock.cpp - */ - inline bool unlock() const { - return (xSemaphoreGiveRecursive(handle) == pdTRUE); - } - - private: - RecursiveMutexBase() = default; - ~RecursiveMutexBase() = default; - - RecursiveMutexBase(RecursiveMutexBase&&) noexcept = default; - RecursiveMutexBase& operator=(RecursiveMutexBase&&) noexcept = default; -}; - -#if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - -/** - * @class Mutex Mutex.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS mutex. - * - * Each mutex require a small amount of RAM that is used to hold the mutex's - * state. If a mutex is created using FreeRTOS::Mutex then the required RAM is - * automatically allocated from the FreeRTOS heap. If a mutex is created using - * FreeRTOS::StaticMutex then the RAM is provided by the application writer and - * allows the RAM to be statically allocated at compile time. See the Static Vs - * Dynamic allocation page for more information. - * - * Mutexes and binary semaphores are very similar but have some subtle - * differences: Mutexes include a priority inheritance mechanism, binary - * semaphores do not. This makes binary semaphores the better choice for - * implementing synchronisation (between tasks or between tasks and an - * interrupt), and mutexes the better choice for implementing simple mutual - * exclusion. - * - * The priority of a task that locks a mutex will be temporarily raised if - * another task of higher priority attempts to obtain the same mutex. The task - * that owns the mutex 'inherits' the priority of the task attempting to lock - * the same mutex. This means the mutex must always be unlocked back otherwise - * the higher priority task will never be able to lock the mutex, and the lower - * priority task will never 'disinherit' the priority. - */ -class Mutex : public MutexBase { - public: - /** - * Mutex.hpp - * - * @brief Construct a new Mutex object by calling SemaphoreHandle_t - * xSemaphoreCreateMutex( void ) - * - * @see - * - * @warning The user should call isValid() on this object to verify that the - * mutex was created successfully in case the memory required to create the - * queue could not be allocated. - * - * Example Usage - * @include Mutex/mutex.cpp - */ - Mutex() { this->handle = xSemaphoreCreateMutex(); } - ~Mutex() = default; - - Mutex(const Mutex&) = delete; - Mutex& operator=(const Mutex&) = delete; - - Mutex(Mutex&&) noexcept = default; - Mutex& operator=(Mutex&&) noexcept = default; -}; - -/** - * @class RecursiveMutex Mutex.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS recursive - * mutex. - * - * Each recursive mutex require a small amount of RAM that is used to hold the - * recursive mutex's state. If a mutex is created using FreeRTOS::RecursiveMutex - * then the required RAM is automatically allocated from the FreeRTOS heap. If a - * recursive mutex is created using FreeRTOS::StaticRecursiveMutex then the RAM - * is provided by the application writer, which requires an additional - * parameter, but allows the RAM to be statically allocated at compile time. See - * the Static Vs Dynamic allocation page for more information. - * - * Contrary to non-recursive mutexes, a task can lock a recursive mutex multiple - * times, and the recursive mutex will only be returned after the holding task - * has unlocked the mutex the same number of times it locked the mutex. - * - * Like non-recursive mutexes, recursive mutexes implement a priority - * inheritance algorithm. The priority of a task that locks a mutex will be - * temporarily raised if another task of higher priority attempts to obtain the - * same mutex. The task that owns the mutex 'inherits' the priority of the task - * attempting to lock the same mutex. This means the mutex must always be - * unlocked otherwise the higher priority task will never be able to obtain the - * mutex, and the lower priority task will never 'disinherit' the priority. - */ -class RecursiveMutex : public RecursiveMutexBase { - public: - /** - * Mutex.hpp - * - * @brief Construct a new RecursiveMutex object by calling - * SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void ) - * - * @see - * - * @warning The user should call isValid() on this object to verify that the - * recursive mutex was created successfully in case the memory required to - * create the queue could not be allocated. - * - * Example Usage - * @include Mutex/recursiveMutex.cpp - */ - RecursiveMutex() { this->handle = xSemaphoreCreateRecursiveMutex(); } - ~RecursiveMutex() = default; - - RecursiveMutex(const RecursiveMutex&) = delete; - RecursiveMutex& operator=(const RecursiveMutex&) = delete; - - RecursiveMutex(RecursiveMutex&&) noexcept = default; - RecursiveMutex& operator=(RecursiveMutex&&) noexcept = default; -}; - -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - -#if (configSUPPORT_STATIC_ALLOCATION == 1) - -/** - * @class StaticMutex Mutex.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS mutex. - * - * Each mutex require a small amount of RAM that is used to hold the mutex's - * state. If a mutex is created using FreeRTOS::Mutex then the required RAM is - * automatically allocated from the FreeRTOS heap. If a mutex is created using - * FreeRTOS::StaticMutex then the RAM is provided by the application writer and - * allows the RAM to be statically allocated at compile time. See the Static Vs - * Dynamic allocation page for more information. - * - * Mutexes and binary semaphores are very similar but have some subtle - * differences: Mutexes include a priority inheritance mechanism, binary - * semaphores do not. This makes binary semaphores the better choice for - * implementing synchronisation (between tasks or between tasks and an - * interrupt), and mutexes the better choice for implementing simple mutual - * exclusion. - * - * The priority of a task that locks a mutex will be temporarily raised if - * another task of higher priority attempts to obtain the same mutex. The task - * that owns the mutex 'inherits' the priority of the task attempting to lock - * the same mutex. This means the mutex must always be unlocked back otherwise - * the higher priority task will never be able to lock the mutex, and the lower - * priority task will never 'disinherit' the priority. - */ -class StaticMutex : public MutexBase { - public: - /** - * Mutex.hpp - * - * @brief Construct a new StaticMutex object by calling - * SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t - * *pxMutexBuffer ) - * - * @see - * - * @warning This class contains the storage buffer for the mutex, so the user - * should create this object as a global object or with the static storage - * specifier so that the object instance is not on the stack. - * - * Example Usage - * @include Mutex/staticMutex.cpp - */ - StaticMutex() { this->handle = xSemaphoreCreateMutexStatic(&staticMutex); } - ~StaticMutex() = default; - - StaticMutex(const StaticMutex&) = delete; - StaticMutex& operator=(const StaticMutex&) = delete; - - StaticMutex(StaticMutex&&) noexcept = default; - StaticMutex& operator=(StaticMutex&&) noexcept = default; - - private: - StaticSemaphore_t staticMutex; -}; - -/** - * @class StaticRecursiveMutex Mutex.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS recursive - * mutex. - * - * Each recursive mutex require a small amount of RAM that is used to hold the - * recursive mutex's state. If a mutex is created using FreeRTOS::RecursiveMutex - * then the required RAM is automatically allocated from the FreeRTOS heap. If a - * recursive mutex is created using FreeRTOS::StaticRecursiveMutex then the RAM - * is provided by the application writer, which requires an additional - * parameter, but allows the RAM to be statically allocated at compile time. See - * the Static Vs Dynamic allocation page for more information. - * - * Contrary to non-recursive mutexes, a task can lock a recursive mutex multiple - * times, and the recursive mutex will only be returned after the holding task - * has unlocked the mutex the same number of times it locked the mutex. - * - * Like non-recursive mutexes, recursive mutexes implement a priority - * inheritance algorithm. The priority of a task that locks a mutex will be - * temporarily raised if another task of higher priority attempts to obtain the - * same mutex. The task that owns the mutex 'inherits' the priority of the task - * attempting to lock the same mutex. This means the mutex must always be - * unlocked otherwise the higher priority task will never be able to obtain the - * mutex, and the lower priority task will never 'disinherit' the priority. - */ -class StaticRecursiveMutex : public RecursiveMutexBase { - public: - /** - * Mutex.hpp - * - * @brief Construct a new StaticRecursiveMutex object by calling - * SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( - * StaticSemaphore_t *pxMutexBuffer ) - * - * @see - * - * @warning This class contains the storage buffer for the recursive mutex, so - * the user should create this object as a global object or with the static - * storage specifier so that the object instance is not on the stack. - * - * Example Usage - * @include Mutex/staticRecursiveMutex.cpp - */ - StaticRecursiveMutex() { - this->handle = xSemaphoreCreateRecursiveMutexStatic(&staticRecursiveMutex); - } - ~StaticRecursiveMutex() = default; - - StaticRecursiveMutex(const StaticRecursiveMutex&) = delete; - StaticRecursiveMutex& operator=(const StaticRecursiveMutex&) = delete; - - StaticRecursiveMutex(StaticRecursiveMutex&&) noexcept = default; - StaticRecursiveMutex& operator=(StaticRecursiveMutex&&) noexcept = default; - - private: - StaticSemaphore_t staticRecursiveMutex; -}; - -#endif /* configSUPPORT_STATIC_ALLOCATION */ - -} // namespace FreeRTOS - -#endif // FREERTOS_MUTEX_HPP diff --git a/source/shoh/src/FreeRTOSCPP/Queue.hpp b/source/shoh/src/FreeRTOSCPP/Queue.hpp deleted file mode 100644 index fe6cc31..0000000 --- a/source/shoh/src/FreeRTOSCPP/Queue.hpp +++ /dev/null @@ -1,737 +0,0 @@ -/* - * FreeRTOS-Cpp - * Copyright (C) 2021 Jon Enz. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * https://github.com/jonenz/FreeRTOS-Cpp - */ - -#ifndef FREERTOS_QUEUE_HPP -#define FREERTOS_QUEUE_HPP - -#include - -#include "FreeRTOS.h" -#include "queue.h" - -namespace FreeRTOS { - -/** - * @class QueueBase Queue.hpp - * - * @brief Base class that provides the standard queue interface to - * FreeRTOS::Queue and FreeRTOS::StaticQueue. - * - * @note This class is not intended to be instantiated by the user. Use - * FreeRTOS::Queue or FreeRTOS::StaticQueue. - * - * @tparam T Type to be stored in the queue. - */ -template -class QueueBase { - public: - template - friend class Queue; - - template - friend class StaticQueue; - - QueueBase(const QueueBase&) = delete; - QueueBase& operator=(const QueueBase&) = delete; - - static void* operator new(size_t, void* ptr) { return ptr; } - static void* operator new[](size_t, void* ptr) { return ptr; } - static void* operator new(size_t) = delete; - static void* operator new[](size_t) = delete; - - /** - * Queue.hpp - * - * @brief Function that checks if the underlying queue handle is not NULL. - * This should be used to ensure a queue has been created correctly. - * - * @retval true the handle is not NULL. - * @retval false the handle is NULL. - */ - inline bool isValid() const { return (handle != NULL); } - - /** - * Queue.hpp - * - * @brief Function that calls xQueueSendToBack( xQueue, pvItemToQueue, - * xTicksToWait ) - * - * @see - * - * Post an item to the back of a queue. The item is queued by copy, not by - * reference. This function must not be called from an interrupt service - * routine. See FreeRTOS::Queue::sendToBackFromISR() for an alternative which - * may be used in an ISR. - * - * @param item A reference to the item that is to be placed on the queue. - * @param ticksToWait The maximum amount of time the task should block waiting - * for space to become available on the queue, should it already be full. The - * call will return immediately if this is set to 0 and the queue is full. The - * time is defined in tick periods so the constant portTICK_PERIOD_MS should - * be used to convert to real time if this is required. - * @retval true if the item was successfully posted. - * @retval false otherwise. - * - * Example Usage - * @include Queue/sendToBack.cpp - */ - inline bool sendToBack(const T& item, - const TickType_t ticksToWait = portMAX_DELAY) const { - return (xQueueSendToBack(handle, &item, ticksToWait) == pdTRUE); - } - - /** - * Queue.hpp - * - * @brief Function that calls xQueueSendToBackFromISR( xQueue, - * pvItemToQueue, pxHigherPriorityTaskWoken ) - * - * @see - * - * @param higherPriorityTaskWoken A reference that will be set to true if - * sending to the queue caused a task to unblock, and the unblocked task has a - * priority higher than the currently running task. - * @param item A reference to the item that is to be placed on the queue. - * @retval true if the item was successfully posted - * @retval false otherwise. - * - * Example Usage - * @include Queue/sendToBackFromISR.cpp - */ - inline bool sendToBackFromISR(bool& higherPriorityTaskWoken, - const T& item) const { - BaseType_t taskWoken = pdFALSE; - bool result = - (xQueueSendToBackFromISR(handle, &item, &taskWoken) == pdPASS); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * Queue.hpp - * - * @brief Function that calls xQueueSendToBackFromISR( xQueue, - * pvItemToQueue, pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline bool sendToBackFromISR(const T& item) const { - return (xQueueSendToBackFromISR(handle, &item, NULL) == pdPASS); - } - - /** - * Queue.hpp - * - * @brief Function that calls xQueueSendToFront( xQueue, pvItemToQueue, - * xTicksToWait ) - * - * @see - * - * @param item A reference to the item that is to be placed on the queue. - * @param ticksToWait The maximum amount of time the task should block waiting - * for space to become available on the queue, should it already be full. The - * call will return immediately if this is set to 0 and the queue is full. The - * time is defined in tick periods so the constant portTICK_PERIOD_MS should - * be used to convert to real time if this is required. - * @retval true if the item was successfully posted. - * @retval false otherwise. - * - * Example Usage - * @include Queue/sendToFront.cpp - */ - inline bool sendToFront(const T& item, - const TickType_t ticksToWait = portMAX_DELAY) const { - return (xQueueSendToFront(handle, &item, ticksToWait) == pdTRUE); - } - - /** - * Queue.hpp - * - * @brief Function that calls xQueueSendToFrontFromISR( xQueue, - * pvItemToQueue, pxHigherPriorityTaskWoken ) - * - * @see - * - * @param higherPriorityTaskWoken A reference that will be set to true if - * sending to the queue caused a task to unblock, and the unblocked task has a - * priority higher than the currently running task. - * @param item A reference to the item that is to be placed on the queue. - * @retval true if the item was successfully posted - * @retval false otherwise. - * - * Example Usage - * @include Queue/sendToFrontFromISR.cpp - */ - inline bool sendToFrontFromISR(bool& higherPriorityTaskWoken, - const T& item) const { - BaseType_t taskWoken = pdFALSE; - bool result = - (xQueueSendToFrontFromISR(handle, &item, &taskWoken) == pdPASS); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * Queue.hpp - * - * @brief Function that calls xQueueSendToFrontFromISR( xQueue, - * pvItemToQueue, pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline bool sendToFrontFromISR(const T& item) const { - return (xQueueSendToFrontFromISR(handle, &item, NULL) == pdPASS); - } - - /** - * Queue.hpp - * - * @brief Function that calls BaseType_t xQueueReceive( QueueHandle_t - * xQueue, void *pvBuffer, TickType_t xTicksToWait ) - * - * @see - * - * Receive an item from a queue. This function must not be used in an - * interrupt service routine. See receiveFromISR() for an alternative that - * can. - * - * @param ticksToWait The maximum amount of time the task should block waiting - * for an item to receive should the queue be empty at the time of the call. - * Setting ticksToWait to 0 will cause the function to return immediately if - * the queue is empty. The time is defined in tick periods so the constant - * portTICK_PERIOD_MS should be used to convert to real time if this is - * required. - * @return std::optional Object from the queue. User should check that the - * value is present. - * - * Example Usage - * @include Queue/receive.cpp - */ - inline std::optional receive( - const TickType_t ticksToWait = portMAX_DELAY) const { - T buffer; - return (xQueueReceive(handle, &buffer, ticksToWait) == pdTRUE) - ? std::optional(buffer) - : std::nullopt; - } - - /** - * Queue.hpp - * - * @brief Function that calls BaseType_t xQueueReceiveFromISR( - * QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken - * ) - * - * @see - * - * Receive an item from a queue. It is safe to use this function from within - * an interrupt service routine. - * - * @param higherPriorityTaskWoken A reference that will be set to true if - * sending to the queue caused a task to unblock, and the unblocked task has a - * priority higher than the currently running task. - * @return std::optional Object from the queue. User should check that the - * value is present. - * - * Example Usage - * @include Queue/receiveFromISR.cpp - */ - inline std::optional receiveFromISR(bool& higherPriorityTaskWoken) const { - T buffer; - BaseType_t taskWoken = pdFALSE; - bool result = (xQueueReceiveFromISR(handle, &buffer, &taskWoken) == pdTRUE); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result ? std::optional(buffer) : std::nullopt; - } - - /** - * Queue.hpp - * - * @brief Function that calls BaseType_t xQueueReceiveFromISR( - * QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken - * ) - * - * @see - * - * @overload - */ - inline std::optional receiveFromISR() const { - T buffer; - return (xQueueReceiveFromISR(handle, &buffer, NULL) == pdTRUE) - ? std::optional(buffer) - : std::nullopt; - } - - /** - * Queue.hpp - * - * @brief Function that calls UBaseType_t uxQueueMessagesWaiting( - * QueueHandle_t xQueue ) - * - * @see - * - * Return the number of messages stored in a queue. - * - * @retval UBaseType_t The number of messages available in the queue. - */ - inline UBaseType_t messagesWaiting() const { - return uxQueueMessagesWaiting(handle); - } - - /** - * Queue.hpp - * - * @brief Function that calls UBaseType_t uxQueueMessagesWaitingFromISR( - * QueueHandle_t xQueue ) - * - * @see - * - * A version of messagesWaiting() that can be called from an ISR. Return the - * number of messages stored in a queue. - * - * @retval UBaseType_t The number of messages available in the queue. - */ - inline UBaseType_t messagesWaitingFromISR() const { - return uxQueueMessagesWaitingFromISR(handle); - } - - /** - * Queue.hpp - * - * @brief Function that calls UBaseType_t uxQueueSpacesAvailable( - * QueueHandle_t xQueue ) - * - * @see - * - * Return the number of free spaces in a queue. - * - * @retval UBaseType_t The number of free spaces available in the queue. - */ - inline UBaseType_t spacesAvailable() const { - return uxQueueSpacesAvailable(handle); - } - - /** - * Queue.hpp - * - * @brief Function that calls BaseType_t xQueueReset( QueueHandle_t xQueue - * ) - * - * @see - * - * Resets a queue to its original empty state. - */ - inline void reset() const { xQueueReset(handle); } - - /** - * Queue.hpp - * - * @brief Function that calls BaseType_t xQueueOverwrite( QueueHandle_t - * xQueue, const void * pvItemToQueue ) - * - * @see - * - * Only for use with queues that have a length of one - so the queue is either - * empty or full. - * - * Post an item on a queue. If the queue is already full then overwrite the - * value held in the queue. The item is queued by copy, not by reference. - * - * This function must not be called from an interrupt service routine. See - * overwriteFromISR() for an alternative which may be used in an ISR. - * - * @param item A reference to the item that is to be placed on the queue. - * - * Example Usage - * @include Queue/overwrite.cpp - */ - inline void overwrite(const T& item) const { xQueueOverwrite(handle, &item); } - - /** - * Queue.hpp - * - * @brief Function that calls BaseType_t xQueueOverwriteFromISR( - * QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t - * *pxHigherPriorityTaskWoken ) - * - * @see - * - * A version of overwrite() that can be used in an interrupt service routine - * (ISR). - * - * Only for use with queues that can hold a single item - so the queue is - * either empty or full. - * - * Post an item on a queue. If the queue is already full then overwrite the - * value held in the queue. The item is queued by copy, not by reference. - * - * @param higherPriorityTaskWoken A reference that will be set to true if - * sending to the queue caused a task to unblock, and the unblocked task has a - * priority higher than the currently running task. - * @param item A reference to the item that is to be placed on the queue. - * - * Example Usage - * @include Queue/overwriteFromISR.cpp - */ - inline void overwriteFromISR(bool& higherPriorityTaskWoken, - const T& item) const { - BaseType_t taskWoken = pdFALSE; - xQueueOverwriteFromISR(handle, &item, &taskWoken); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - } - - /** - * Queue.hpp - * - * @brief Function that calls BaseType_t xQueueOverwriteFromISR( - * QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t - * *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline void overwriteFromISR(const T& item) const { - xQueueOverwriteFromISR(handle, &item, NULL); - } - - /** - * Queue.hpp - * - * @brief Function that calls BaseType_t xQueuePeek( QueueHandle_t xQueue, - * void * const pvBuffer, TickType_t xTicksToWait ) - * - * @see - * - * Receive an item from a queue without removing the item from the queue. - * - * Successfully received items remain on the queue so will be returned again - * by the next call, or a call to receive(). - * - * This function must not be used in an interrupt service routine. See - * peekFromISR() for an alternative that can be called from an interrupt - * service routine. - * - * @param ticksToWait The maximum amount of time the task should block waiting - * for an item to receive should the queue be empty at the time of the call. - * Setting ticksToWait to 0 will cause the function to return immediately if - * the queue is empty. The time is defined in tick periods so the constant - * portTICK_PERIOD_MS should be used to convert to real time if this is - * required. - * @return std::optional Object from the queue. User should check that the - * value is present. - * - * Example Usage - * @include Queue/peek.cpp - */ - inline std::optional peek( - const TickType_t ticksToWait = portMAX_DELAY) const { - T buffer; - return (xQueuePeek(handle, &buffer, ticksToWait) == pdTRUE) - ? std::optional(buffer) - : std::nullopt; - } - - /** - * Queue.hpp - * - * @brief Function that calls BaseType_t xQueuePeekFromISR( QueueHandle_t - * xQueue, void *pvBuffer ) - * - * @see - * - * A version of peek() that can be called from an interrupt service routine - * (ISR). - * - * Receive an item from a queue without removing the item from the queue. - * - * Successfully received items remain on the queue so will be returned again - * by the next call, or a call to receive(). - * - * @return std::optional Object from the queue. User should check that the - * value is present. - */ - inline std::optional peekFromISR() const { - T buffer; - return (xQueuePeekFromISR(handle, &buffer) == pdTRUE) - ? std::optional(buffer) - : std::nullopt; - } - - /** - * Queue.hpp - * - * @brief Function that calls void vQueueAddToRegistry( QueueHandle_t - * xQueue, char *pcQueueName ) - * - * @see - * - * The registry is provided as a means for kernel aware debuggers to locate - * queues, semaphores and mutexes. Call addToRegistry() add a queue, - * semaphore or mutex handle to the registry if you want the handle to be - * available to a kernel aware debugger. If you are not using a kernel aware - * debugger then this function can be ignored. - * - * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the - * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 within - * FreeRTOSConfig.h for the registry to be available. Its value does not - * effect the number of queues, semaphores and mutexes that can be created - - * just the number that the registry can hold. - * - * If addToRegistry() is called more than once for the same queue, the - * registry will store the name parameter from the most recent call to - * addToRegistry(). - * - * @param name The name to be associated with the handle. This is the name - * that the kernel aware debugger will display. The queue registry only - * stores a pointer to the string - so the string must be persistent (global - * or preferably in ROM/Flash), not on the stack. - */ - inline void addToRegistry(const char* name) const { - vQueueAddToRegistry(handle, name); - } - - /** - * Queue.hpp - * - * @brief Function that calls void vQueueUnregisterQueue( QueueHandle_t - * xQueue ) - * - * @see - * - * The registry is provided as a means for kernel aware debuggers to locate - * queues, semaphores and mutexes. Call addToRegistry() add a queue, - * semaphore or mutex handle to the registry if you want the handle to be - * available to a kernel aware debugger, and unregister() to remove the queue, - * semaphore or mutex from the register. If you are not using a kernel aware - * debugger then this function can be ignored. - */ - inline void unregister() const { vQueueUnregisterQueue(handle); } - - /** - * Queue.hpp - * - * @brief Function that calls const char *pcQueueGetName( QueueHandle_t - * xQueue ) - * - * @see - * - * The queue registry is provided as a means for kernel aware debuggers to - * locate queues, semaphores and mutexes. Call getName() to look up and return - * the name of a queue in the queue registry from the queue's handle. - * - * @return If the queue referenced by the queue is in the queue registry, then - * the text name of the queue is returned, otherwise NULL is returned. - */ - inline const char* getName() const { return pcQueueGetName(handle); } - - /** - * Queue.hpp - * - * @brief Function that calls BaseType_t xQueueIsQueueFullFromISR( const - * QueueHandle_t xQueue ) - * - * @see - * - * Queries a queue to determine if the queue is empty. This function should - * only be used in an ISR. - * - * @return true if the queue is full. - * @return false if the queue is not full. - */ - inline bool isFullFromISR() const { - return (xQueueIsQueueFullFromISR(handle) == pdTRUE); - } - - /** - * Queue.hpp - * - * @brief Function that calls BaseType_t xQueueIsQueueEmptyFromISR( const - * QueueHandle_t xQueue ) - * - * @see - * - * Queries a queue to determine if the queue is empty. This function should - * only be used in an ISR. - * - * @retval true if the queue is empty. - * @retval false if the queue is not empty. - */ - inline bool isEmptyFromISR() const { - return (xQueueIsQueueEmptyFromISR(handle) == pdTRUE); - } - - private: - /** - * Queue.hpp - * - * @brief Construct a new QueueBase object. - * - * @note Default constructor is deliberately private as this class is not - * intended to be instantiated or derived from by the user. Use - * FreeRTOS::Queue or FreeRTOS::StaticQueue. - */ - QueueBase() = default; - - /** - * Queue.hpp - * - * @brief Destroy the QueueBase object by calling void vQueueDelete( - * QueueHandle_t xQueue ) - * - * @see - * - * Delete a queue - freeing all the memory allocated for storing of items - * placed on the queue. - */ - ~QueueBase() { vQueueDelete(this->handle); } - - QueueBase(QueueBase&&) noexcept = default; - QueueBase& operator=(QueueBase&&) noexcept = default; - - /** - * @brief Handle used to refer to the queue when using the FreeRTOS interface. - */ - QueueHandle_t handle = NULL; -}; - -#if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - -/** - * @class Queue Queue.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS queue. - * - * Each queue requires RAM that is used to hold the queue state, and to hold the - * items that are contained in the queue (the queue storage area). If a queue is - * created using this class then the required RAM is automatically allocated - * from the FreeRTOS heap. - * - * @tparam T Type to be stored in the queue. - */ -template -class Queue : public QueueBase { - public: - /** - * Queue.hpp - * - * @brief Construct a new Queue object by calling QueueHandle_t - * xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize ) - * - * @see - * - * @warning The user should call isValid() on this object to verify that the - * queue was created successfully in case the memory required to create the - * queue could not be allocated. - * - * @param length The maximum number of items the queue can hold at any one - * time. - * - * Example Usage - * @include Queue/queue.cpp - */ - explicit Queue(const UBaseType_t length) { - this->handle = xQueueCreate(length, sizeof(T)); - } - ~Queue() = default; - - Queue(const Queue&) = delete; - Queue& operator=(const Queue&) = delete; - - Queue(Queue&&) noexcept = default; - Queue& operator=(Queue&&) noexcept = default; -}; - -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - -#if (configSUPPORT_STATIC_ALLOCATION == 1) - -/** - * @class StaticQueue Queue.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS queue. - * - * If a queue is created using this class then the RAM is provided by the - * application writer as part of the object instance and allows the RAM to be - * statically allocated at compile time. - * - * @tparam T Type to be stored in the queue. - * @tparam N The maximum number of items the queue can hold at any one time. - */ -template -class StaticQueue : public QueueBase { - public: - /** - * Queue.hpp - * - * @brief Construct a new StaticQueue object by calling - * QueueHandle_t xQueueCreateStatic( UBaseType_t uxQueueLength, - * UBaseType_t uxItemSize, uint8_t *pucQueueStorageBuffer, StaticQueue_t - * *pxQueueBuffer ) - * - * @see - * - * @warning This class contains the storage buffer for the queue, so the user - * should create this object as a global object or with the static storage - * specifier so that the object instance is not on the stack. - * - * Example Usage - * @include Queue/staticQueue.cpp - */ - StaticQueue() { - this->handle = xQueueCreateStatic(N, sizeof(T), storage, &staticQueue); - } - ~StaticQueue() = default; - - StaticQueue(const StaticQueue&) = delete; - StaticQueue& operator=(const StaticQueue&) = delete; - - StaticQueue(StaticQueue&&) noexcept = default; - StaticQueue& operator=(StaticQueue&&) noexcept = default; - - private: - StaticQueue_t staticQueue; - uint8_t storage[N * sizeof(T)]; -}; - -#endif /* configSUPPORT_STATIC_ALLOCATION */ - -} // namespace FreeRTOS - -#endif // FREERTOS_QUEUE_HPP diff --git a/source/shoh/src/FreeRTOSCPP/Semaphore.hpp b/source/shoh/src/FreeRTOSCPP/Semaphore.hpp deleted file mode 100644 index 63d7bfa..0000000 --- a/source/shoh/src/FreeRTOSCPP/Semaphore.hpp +++ /dev/null @@ -1,523 +0,0 @@ -/* - * FreeRTOS-Cpp - * Copyright (C) 2021 Jon Enz. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * https://github.com/jonenz/FreeRTOS-Cpp - */ - -#ifndef FREERTOS_SEMAPHORE_HPP -#define FREERTOS_SEMAPHORE_HPP - -#include "FreeRTOS.h" -#include "semphr.h" - -namespace FreeRTOS { - -/** - * @class SemaphoreBase Semaphore.hpp - * - * @brief Base class that provides the standard semaphore interface to - * FreeRTOS::BinarySemaphore, FreeRTOS::StaticBinarySemaphore, - * FreeRTOS::CountingSemaphore, and FreeRTOS::StaticCountingSemaphore. - * - * @note This class is not intended to be instantiated by the user. Use - * FreeRTOS::BinarySemaphore, FreeRTOS::StaticBinarySemaphore, - * FreeRTOS::CountingSemaphore, or FreeRTOS::StaticCountingSemaphore. - */ -class SemaphoreBase { - public: - friend class BinarySemaphore; - friend class StaticBinarySemaphore; - friend class CountingSemaphore; - friend class StaticCountingSemaphore; - - SemaphoreBase(const SemaphoreBase&) = delete; - SemaphoreBase& operator=(const SemaphoreBase&) = delete; - - static void* operator new(size_t, void* ptr) { return ptr; } - static void* operator new[](size_t, void* ptr) { return ptr; } - static void* operator new(size_t) = delete; - static void* operator new[](size_t) = delete; - - /** - * Semaphore.hpp - * - * @brief Function that checks if the underlying semaphore handle is not NULL. - * This should be used to ensure a semaphore has been created correctly. - * - * @retval true the handle is not NULL. - * @retval false the handle is NULL. - */ - inline bool isValid() const { return (handle != NULL); } - - /** - * Semaphore.hpp - * - * @brief Function that calls UBaseType_t uxSemaphoreGetCount( - * SemaphoreHandle_t xSemaphore ) - * - * @see - * - * Returns the count of a semaphore. - * - * @return UBaseType_t If the semaphore is a counting semaphore then the - * semaphores current count value is returned. If the semaphore is a binary - * semaphore then 1 is returned if the semaphore is available, and 0 is - * returned if the semaphore is not available. - */ - inline UBaseType_t getCount() const { return uxSemaphoreGetCount(handle); } - - /** - * Semaphore.hpp - * - * @brief Function that calls xSemaphoreTake( SemaphoreHandle_t - * xSemaphore, TickType_t xTicksToWait ) - * - * @see - * - * Function to obtain a semaphore. - * - * This macro must not be called from an ISR. takeFromISR() can be used to - * take a semaphore from within an interrupt if required, although this would - * not be a normal operation. Semaphores use queues as their underlying - * mechanism, so functions are to some extent interoperable. - * - * @param ticksToWait The time in ticks to wait for the semaphore to become - * available. The macro portTICK_PERIOD_MS can be used to convert this to a - * real time. A block time of zero can be used to poll the semaphore. - * @retval true If the semaphore was obtained. - * @retval false If xTicksToWait expired without the semaphore becoming - * available. - * - * Example Usage - * @include Semaphore/take.cpp - */ - inline bool take(const TickType_t ticksToWait = portMAX_DELAY) const { - return (xSemaphoreTake(handle, ticksToWait) == pdTRUE); - } - - /** - * Semaphore.hpp - * - * @brief Function that calls xSemaphoreTakeFromISR( SemaphoreHandle_t - * xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken) - * - * @see - * - * A version of take() that can be called from an ISR. Unlike take(), - * takeFromISR() does not permit a block time to be specified. - * - * @param higherPriorityTaskWoken It is possible (although unlikely, and - * dependent on the semaphore type) that a semaphore will have one or more - * tasks blocked on it waiting to give the semaphore. Calling takeFromISR() - * will make a task that was blocked waiting to give the semaphore leave the - * Blocked state. If calling the API function causes a task to leave the - * Blocked state, and the unblocked task has a priority equal to or higher - * than the currently executing task (the task that was interrupted), then, - * internally, the API function will set higherPriorityTaskWoken to true. If - * takeFromISR() sets higherPriorityTaskWoken to true, then a context switch - * should be performed before the interrupt is exited. This will ensure that - * the interrupt returns directly to the highest priority Ready state task. - * The mechanism is identical to that used in the FreeRTOS::receiveFromISR() - * function, and readers are referred to the FreeRTOS::receiveFromISR() - * documentation for further explanation. - * @retval true If the semaphore was successfully taken. - * @retval false If the semaphore was not successfully taken because it was - * not available. - */ - inline bool takeFromISR(bool& higherPriorityTaskWoken) const { - BaseType_t taskWoken = pdFALSE; - bool result = (xSemaphoreTakeFromISR(handle, &taskWoken) == pdTRUE); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * Semaphore.hpp - * - * @brief Function that calls xSemaphoreTakeFromISR( SemaphoreHandle_t - * xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken) - * - * @see - * - * @overload - */ - inline bool takeFromISR() const { - return (xSemaphoreTakeFromISR(handle, NULL) == pdTRUE); - } - - /** - * Semaphore.hpp - * - * @brief Function that calls xSemaphoreGive( SemaphoreHandle_t xSemaphore - * ) - * - * @see - * - * Function to release a semaphore. - * - * This must not be used from an ISR. See giveFromISR() for an alternative - * which can be used from an ISR. - * - * @retval true If the semaphore was released. - * @retval false If an error occurred. Semaphores are implemented using - * queues. An error can occur if there is no space on the queue to post a - * message indicating that the semaphore was not first obtained correctly. - * - * Example Usage - * @include Semaphore/give.cpp - */ - inline bool give() const { return (xSemaphoreGive(handle) == pdTRUE); } - - /** - * Semaphore.hpp - * - * @brief Function that calls xSemaphoreGiveFromISR( SemaphoreHandle_t - * xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * Function to release a semaphore. - * - * This macro can be used from an ISR. - * - * @param higherPriorityTaskWoken giveFromISR() will set - * higherPriorityTaskWoken to true if giving the semaphore caused a task to - * unblock, and the unblocked task has a priority higher than the currently - * running task. If giveFromISR() sets this value to true then a context - * switch should be requested before the interrupt is exited. - * @retval true If the semaphore was successfully given. - * @retval false Otherwise. - * - * Example Usage - * @include Semaphore/giveFromISR.cpp - */ - inline bool giveFromISR(bool& higherPriorityTaskWoken) const { - BaseType_t taskWoken = pdFALSE; - bool result = (xSemaphoreGiveFromISR(handle, &taskWoken) == pdTRUE); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * Semaphore.hpp - * - * @brief Function that calls xSemaphoreGiveFromISR( SemaphoreHandle_t - * xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline bool giveFromISR() const { - return (xSemaphoreGiveFromISR(handle, NULL) == pdTRUE); - } - - private: - SemaphoreBase() = default; - - /** - * Semaphore.hpp - * - * @brief Destroy the SemaphoreBase object by calling void - * vSemaphoreDelete( SemaphoreHandle_t xSemaphore ) - * - * @see - * - * @note Do not delete a semaphore that has tasks blocked on it (tasks that - * are in the Blocked state waiting for the semaphore to become available). - */ - ~SemaphoreBase() { vSemaphoreDelete(this->handle); } - - SemaphoreBase(SemaphoreBase&&) noexcept = default; - SemaphoreBase& operator=(SemaphoreBase&&) noexcept = default; - - /** - * @brief Handle used to refer to the semaphore when using the FreeRTOS - * interface. - */ - SemaphoreHandle_t handle = NULL; -}; - -#if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - -/** - * @class BinarySemaphore Semaphore.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS binary - * semaphore. - * - * Each binary semaphore require a small amount of RAM that is used to hold the - * semaphore's state. If a binary semaphore is created using - * FreeRTOS::BinarySemaphore then the required RAM is automatically allocated - * from the FreeRTOS heap. If a binary semaphore is created using - * FreeRTOS::StaticBinarySemaphore then the RAM is provided by the application - * writer as part of the class and allows the RAM to be statically allocated at - * compile time. See the Static Vs Dynamic allocation page for more information. - * - * The semaphore is created in the 'empty' state, meaning the semaphore must - * first be given using the give() API function before it can subsequently be - * taken (obtained) using the take() function. - * - * Binary semaphores and mutexes are very similar but have some subtle - * differences: Mutexes include a priority inheritance mechanism, binary - * semaphores do not. This makes binary semaphores the better choice for - * implementing synchronisation (between tasks or between tasks and an - * interrupt), and mutexes the better choice for implementing simple mutual - * exclusion. - * - * A binary semaphore need not be given back once obtained, so task - * synchronisation can be implemented by one task/interrupt continuously - * 'giving' the semaphore while another continuously 'takes' the semaphore. This - * is demonstrated by the sample code on the giveFromISR() documentation page. - * Note the same functionality can often be achieved in a more efficient way - * using a direct to task notification. - * - * The priority of a task that 'takes' a mutex can potentially be raised if - * another task of higher priority attempts to obtain the same mutex. The task - * that owns the mutex 'inherits' the priority of the task attempting to 'take' - * the same mutex. This means the mutex must always be 'given' back - otherwise - * the higher priority task will never be able to obtain the mutex, and the - * lower priority task will never 'disinherit' the priority. An example of a - * mutex being used to implement mutual exclusion is provided on the take() - * documentation page. - */ -class BinarySemaphore : public SemaphoreBase { - public: - /** - * Semaphore.hpp - * - * @brief Construct a new BinarySemaphore object by calling - * SemaphoreHandle_t xSemaphoreCreateBinary( void ) - * - * @see - * - * @warning The user should call isValid() on this object to verify that the - * binary semaphore was created successfully in case the memory required to - * create the queue could not be allocated. - * - * Example Usage - * @include Semaphore/binarySemaphore.cpp - */ - BinarySemaphore() { this->handle = xSemaphoreCreateBinary(); } - ~BinarySemaphore() = default; - - BinarySemaphore(const BinarySemaphore&) = delete; - BinarySemaphore& operator=(const BinarySemaphore&) = delete; - - BinarySemaphore(BinarySemaphore&&) noexcept = default; - BinarySemaphore& operator=(BinarySemaphore&&) noexcept = default; -}; - -/** - * @class CountingSemaphore Semaphore.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS counting - * semaphore. - * - * Each counting semaphore require a small amount of RAM that is used to hold - * the semaphore's state. If a counting semaphore is created using - * FreeRTOS::CountingSemaphore then the required RAM is automatically allocated - * from the FreeRTOS heap. If a counting semaphore is created using - * FreeRTOS::StaticCountingSemaphore then the RAM is provided by the application - * writer as part of the class and allows the RAM to be statically allocated at - * compile time. See the Static Vs Dynamic allocation page for more information. - * - * Counting semaphores are typically used for two things: - * 1. Counting Events: - * In this usage scenario an event handler will 'give' a semaphore each time an - * event occurs (incrementing the semaphore count value), and a handler task - * will 'take' a semaphore each time it processes an event (decrementing the - * semaphore count value). The count value is therefore the difference between - * the number of events that have occurred and the number that have been - * processed. In this case it is desirable for the initial count value to be - * zero. Note the same functionality can often be achieved in a more efficient - * way using a direct to task notification. - * - * 2. Resource Management: - * In this usage scenario the count value indicates the number of resources - * available. To obtain control of a resource a task must first obtain a - * semaphore - decrementing the semaphore count value. When the count value - * reaches zero there are no free resources. When a task finishes with the - * resource it 'gives' the semaphore back - incrementing the semaphore count - * value. In this case it is desirable for the initial count value to be equal - * to the maximum count value, indicating that all resources are free. - */ -class CountingSemaphore : public SemaphoreBase { - public: - /** - * Semaphore.hpp - * - * @brief Construct a new CountingSemaphore by calling - * SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, - * UBaseType_t uxInitialCount) - * - * @warning The user should call isValid() on this object to verify that the - * binary semaphore was created successfully in case the memory required to - * create the queue could not be allocated. - * - * @param maxCount The maximum count value that can be reached. When the - * semaphore reaches this value it can no longer be 'given'. - * @param initialCount The count value assigned to the semaphore when - * it is created. - */ - explicit CountingSemaphore(const UBaseType_t maxCount, - const UBaseType_t initialCount = 0) { - this->handle = xSemaphoreCreateCounting(maxCount, initialCount); - } - ~CountingSemaphore() = default; - - CountingSemaphore(const CountingSemaphore&) = delete; - CountingSemaphore& operator=(const CountingSemaphore&) = delete; - - CountingSemaphore(CountingSemaphore&&) noexcept = default; - CountingSemaphore& operator=(CountingSemaphore&&) noexcept = default; -}; - -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - -#if (configSUPPORT_STATIC_ALLOCATION == 1) - -/** - * @class StaticBinarySemaphore Semaphore.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS binary - * semaphore. - * - * Each binary semaphore require a small amount of RAM that is used to hold the - * semaphore's state. If a binary semaphore is created using - * FreeRTOS::BinarySemaphore then the required RAM is automatically allocated - * from the FreeRTOS heap. If a binary semaphore is created using - * FreeRTOS::StaticBinarySemaphore then the RAM is provided by the application - * writer as part of the class and allows the RAM to be statically allocated at - * compile time. See the Static Vs Dynamic allocation page for more information. - * - * The semaphore is created in the 'empty' state, meaning the semaphore must - * first be given using the give() API function before it can subsequently be - * taken (obtained) using the take() function. - * - * Binary semaphores and mutexes are very similar but have some subtle - * differences: Mutexes include a priority inheritance mechanism, binary - * semaphores do not. This makes binary semaphores the better choice for - * implementing synchronisation (between tasks or between tasks and an - * interrupt), and mutexes the better choice for implementing simple mutual - * exclusion. - * - * A binary semaphore need not be given back once obtained, so task - * synchronisation can be implemented by one task/interrupt continuously - * 'giving' the semaphore while another continuously 'takes' the semaphore. This - * is demonstrated by the sample code on the giveFromISR() documentation page. - * Note the same functionality can often be achieved in a more efficient way - * using a direct to task notification. - * - * The priority of a task that 'takes' a mutex can potentially be raised if - * another task of higher priority attempts to obtain the same mutex. The task - * that owns the mutex 'inherits' the priority of the task attempting to 'take' - * the same mutex. This means the mutex must always be 'given' back - otherwise - * the higher priority task will never be able to obtain the mutex, and the - * lower priority task will never 'disinherit' the priority. An example of a - * mutex being used to implement mutual exclusion is provided on the take() - * documentation page. - */ -class StaticBinarySemaphore : public SemaphoreBase { - public: - /** - * Semaphore.hpp - * - * @brief Construct a new StaticBinarySemaphore object by calling - * SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t - * *pxSemaphoreBuffer ) - * - * @see - * - * @warning This class contains the storage buffer for the binary semaphore, - * so the user should create this object as a global object or with the static - * storage specifier so that the object instance is not on the stack. - * - * Example Usage - * @include Semaphore/staticBinarySemaphore.cpp - */ - StaticBinarySemaphore() { - this->handle = xSemaphoreCreateBinaryStatic(&staticBinarySemaphore); - } - ~StaticBinarySemaphore() = default; - - StaticBinarySemaphore(const StaticBinarySemaphore&) = delete; - StaticBinarySemaphore& operator=(const StaticBinarySemaphore&) = delete; - - StaticBinarySemaphore(StaticBinarySemaphore&&) noexcept = default; - StaticBinarySemaphore& operator=(StaticBinarySemaphore&&) noexcept = default; - - private: - StaticSemaphore_t staticBinarySemaphore; -}; - -class StaticCountingSemaphore : public SemaphoreBase { - public: - /** - * @brief Construct a new StaticCountingSemaphore object by calling - * SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t - * uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t - * *pxSemaphoreBuffer ) - * - * @see - * - * @warning This class contains the storage buffer for the counting semaphore, - * so the user should create this object as a global object or with the static - * storage specifier so that the object instance is not on the stack. - * - * @param maxCount The maximum count value that can be reached. When the - * semaphore reaches this value it can no longer be 'given'. - * @param initialCount The count value assigned to the semaphore when it is - * created. - * - * Example Usage - * @include Semaphore/staticCountingSemaphore.cpp - */ - explicit StaticCountingSemaphore(const UBaseType_t maxCount, - const UBaseType_t initialCount = 0) { - this->handle = xSemaphoreCreateCountingStatic(maxCount, initialCount, - &staticCountingSemaphore); - } - ~StaticCountingSemaphore() = default; - - StaticCountingSemaphore(const StaticCountingSemaphore&) = delete; - StaticCountingSemaphore& operator=(const StaticCountingSemaphore&) = delete; - - StaticCountingSemaphore(StaticCountingSemaphore&&) noexcept = default; - StaticCountingSemaphore& operator=(StaticCountingSemaphore&&) noexcept = - default; - - private: - StaticSemaphore_t staticCountingSemaphore; -}; - -#endif /* configSUPPORT_STATIC_ALLOCATION */ - -} // namespace FreeRTOS - -#endif // FREERTOS_SEMAPHORE_HPP \ No newline at end of file diff --git a/source/shoh/src/FreeRTOSCPP/StreamBuffer.hpp b/source/shoh/src/FreeRTOSCPP/StreamBuffer.hpp deleted file mode 100644 index c87a734..0000000 --- a/source/shoh/src/FreeRTOSCPP/StreamBuffer.hpp +++ /dev/null @@ -1,566 +0,0 @@ -/* - * FreeRTOS-Cpp - * Copyright (C) 2021 Jon Enz. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * https://github.com/jonenz/FreeRTOS-Cpp - */ - -#ifndef FREERTOS_STREAMBUFFER_HPP -#define FREERTOS_STREAMBUFFER_HPP - -#include "FreeRTOS.h" -#include "stream_buffer.h" - -namespace FreeRTOS { - -/** - * @class StreamBufferBase StreamBuffer.hpp - * - * @brief Base class that provides the standard stream buffer interface to - * FreeRTOS::StreamBuffer and FreeRTOS::StaticStreamBuffer. - * - * @note This class is not intended to be instantiated by the user. Use - * FreeRTOS::StreamBuffer or FreeRTOS::StaticStreamBuffer. - * - * @warning Uniquely among FreeRTOS objects, the stream buffer implementation - * (so also the message buffer implementation, as message buffers are built on - * top of stream buffers) assumes there is only one task or interrupt that will - * write to the buffer (the writer), and only one task or interrupt that will - * read from the buffer (the reader). It is safe for the writer and reader to - * be different tasks or interrupts, but, unlike other FreeRTOS objects, it is - * not safe to have multiple different writers or multiple different readers. If - * there are to be multiple different writers then the application writer must - * place each call to a writing API function (such as send()) inside a critical - * section and set the send block time to 0. Likewise, if there are to be - * multiple different readers then the application writer must place each call - * to a reading API function (such as read()) inside a critical section and set - * the receive block time to 0. - */ -class StreamBufferBase { - public: - friend class StreamBuffer; - template - friend class StaticStreamBuffer; - - StreamBufferBase(const StreamBufferBase&) = delete; - StreamBufferBase& operator=(const StreamBufferBase&) = delete; - - static void* operator new(size_t, void* ptr) { return ptr; } - static void* operator new[](size_t, void* ptr) { return ptr; } - static void* operator new(size_t) = delete; - static void* operator new[](size_t) = delete; - - /** - * StreamBuffer.hpp - * - * @brief Function that checks if the underlying stream buffer handle is not - * NULL. This should be used to ensure a stream buffer has been created - * correctly. - * - * @retval true If the handle is not NULL. - * @retval false If the handle is NULL. - */ - inline bool isValid() const { return (handle != NULL); } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls size_t xStreamBufferSend( - * StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t - * xDataLengthBytes, TickType_t xTicksToWait ) - * - * @see - * - * Sends bytes to a stream buffer. The bytes are copied into the stream - * buffer. - * - * Use send() to write to a stream buffer from a task. Use sendFromISR() to - * write to a stream buffer from an interrupt service routine (ISR). - * - * @param data A pointer to the buffer that holds the bytes to be copied into - * the stream buffer. - * @param length The maximum number of bytes to copy from data into the stream - * buffer. - * @param ticksToWait The maximum amount of time the task should remain in the - * Blocked state to wait for enough space to become available in the stream - * buffer, should the stream buffer contain too little space to hold the - * another length bytes. The block time is specified in tick periods, so the - * absolute time it represents is dependent on the tick frequency. The macro - * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds - * into a time specified in ticks. Setting ticksToWait to portMAX_DELAY will - * cause the task to wait indefinitely (without timing out), provided - * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out - * before it can write all length into the buffer it will still write as many - * bytes as possible. A task does not use any CPU time when it is in the - * blocked state. - * @return size_t The number of bytes written to the stream buffer. If a task - * times out before it can write all length into the buffer it will still - * write as many bytes as possible. - * - * Example Usage - * @include StreamBuffer/send.cpp - */ - inline size_t send(const void* data, const size_t length, - const TickType_t ticksToWait = portMAX_DELAY) const { - return xStreamBufferSend(handle, data, length, ticksToWait); - } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls size_t xStreamBufferSendFromISR( - * StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t - * xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * Interrupt safe version of the API function that sends a stream of bytes to - * the stream buffer. - * - * Use send() to write to a stream buffer from a task. Use sendFromISR() to - * write to a stream buffer from an interrupt service routine (ISR). - * - * @param higherPriorityTaskWoken It is possible that a stream buffer will - * have a task blocked on it waiting for data. Calling sendFromISR() can make - * data available, and so cause a task that was waiting for data to leave the - * Blocked state. If calling sendFromISR() causes a task to leave the Blocked - * state, and the unblocked task has a priority higher than the currently - * executing task (the task that was interrupted), then, internally, - * sendFromISR() will set higherPriorityTaskWoken to true. If sendFromISR() - * sets this value to true, then normally a context switch should be performed - * before the interrupt is exited. This will ensure that the interrupt - * returns directly to the highest priority Ready state task. - * higherPriorityTaskWoken should be set to false before it is passed into the - * function. See the example code below for an example. - * @param data A pointer to the buffer that holds the bytes to be copied into - * the stream buffer. - * @param length The maximum number of bytes to copy from data into the stream - * buffer. - * @return size_t The number of bytes written to the stream buffer. If a task - * times out before it can write all length into the buffer it will still - * write as many bytes as possible. - * - * Example Usage - * @include StreamBuffer/sendFromISR.cpp - */ - inline size_t sendFromISR(bool& higherPriorityTaskWoken, const void* data, - const size_t length) const { - BaseType_t taskWoken = pdFALSE; - size_t result = xStreamBufferSendFromISR(handle, data, length, &taskWoken); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls size_t xStreamBufferSendFromISR( - * StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t - * xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline size_t sendFromISR(const void* data, const size_t length) const { - return xStreamBufferSendFromISR(handle, data, length, NULL); - } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls size_t xStreamBufferReceive( - * StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t - * xBufferLengthBytes, TickType_t xTicksToWait ) - * - * @see - * - * Receives bytes from a stream buffer. - * - * Use receive() to read from a stream buffer from a task. Use - * receiveFromISR() to read from a stream buffer from an interrupt service - * routine (ISR). - * - * @param buffer A pointer to the buffer into which the received bytes will be - * copied. - * @param bufferLength The length of the buffer pointed to by the data - * parameter. This sets the maximum number of bytes to receive in one call. - * receive() will return as many bytes as possible up to a maximum set by - * length. - * @param ticksToWait The maximum amount of time the task should remain in the - * Blocked state to wait for data to become available if the stream buffer is - * empty. receive() will return immediately if ticksToWait is zero. The block - * time is specified in tick periods, so the absolute time it represents is - * dependent on the tick frequency. The macro pdMS_TO_TICKS() can be used to - * convert a time specified in milliseconds into a time specified in ticks. - * Setting ticksToWait to portMAX_DELAY will cause the task to wait - * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to - * 1 in FreeRTOSConfig.h. A task does not use any CPU time when it is in the - * Blocked state. - * @return size_t The number of bytes read from the stream buffer. This will - * be the number of bytes available up to a maximum of length. - * - * Example Usage - * @include StreamBuffer/receive.cpp - */ - inline size_t receive(void* buffer, const size_t bufferLength, - const TickType_t ticksToWait = portMAX_DELAY) const { - return xStreamBufferReceive(handle, buffer, bufferLength, ticksToWait); - } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls size_t xStreamBufferReceiveFromISR( - * StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t - * xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * An interrupt safe version of the API function that receives bytes from a - * stream buffer. - * - * Use receive() to read from a stream buffer from a task. Use - * receiveFromISR() to read from a stream buffer from an interrupt service - * routine (ISR). - * - * @param higherPriorityTaskWoken It is possible that a stream buffer will - * have a task blocked on it waiting for space to become available. Calling - * receiveFromISR() can make space available, and so cause a task that is - * waiting for space to leave the Blocked state. If calling receiveFromISR() - * causes a task to leave the Blocked state, and the unblocked task has a - * priority higher than the currently executing task (the task that was - * interrupted), then, internally, receiveFromISR() will set - * higherPriorityTaskWoken to true. If receiveFromISR() sets this value to - * true, then normally a context switch should be performed before the - * interrupt is exited. That will ensure the interrupt returns directly to the - * highest priority Ready state task. higherPriorityTaskWoken should be set to - * false before it is passed into the function. See the code example below for - * an example. - * @param buffer A pointer to the buffer into which the received bytes will be - * copied. - * @param bufferLength The length of the buffer pointed to by the buffer - * parameter. This sets the maximum number of bytes to receive in one call. - * receive() will return as many bytes as possible up to a maximum set by - * length. - * @return size_t The number of bytes read from the stream buffer, if any. - * - * Example Usage - * @include StreamBuffer/receiveFromISR.cpp - */ - inline size_t receiveFromISR(bool& higherPriorityTaskWoken, void* buffer, - const size_t bufferLength) const { - BaseType_t taskWoken = pdFALSE; - size_t result = - xStreamBufferReceiveFromISR(handle, buffer, bufferLength, &taskWoken); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls size_t xStreamBufferReceiveFromISR( - * StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t - * xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline size_t receiveFromISR(void* buffer, const size_t bufferLength) const { - return xStreamBufferReceiveFromISR(handle, buffer, bufferLength, NULL); - } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls size_t xStreamBufferBytesAvailable( - * StreamBufferHandle_t xStreamBuffer ) - * - * @see - * - * Queries the stream buffer to see how much data it contains, which is equal - * to the number of bytes that can be read from the stream buffer before the - * stream buffer would be empty. - * - * @return size_t The number of bytes that can be read from the stream buffer - * before the stream buffer would be empty. - */ - inline size_t bytesAvailable() const { - return xStreamBufferBytesAvailable(handle); - } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls size_t xStreamBufferSpacesAvailable( - * StreamBufferHandle_t xStreamBuffer ) - * - * @see - * - * Queries a stream buffer to see how much free space it contains, which is - * equal to the amount of data that can be sent to the stream buffer before it - * is full. - * - * @return size_t The number of bytes that can be written to the stream buffer - * before the stream buffer would be full. - */ - inline size_t spacesAvailable() const { - return xStreamBufferSpacesAvailable(handle); - } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls BaseType_t xStreamBufferSetTriggerLevel( - * StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) - * - * @see - * - * A stream buffer's trigger level is the number of bytes that must be in the - * stream buffer before a task that is blocked on the stream buffer to wait - * for data is moved out of the blocked state. For example, if a task is - * blocked on a read of an empty stream buffer that has a trigger level of 1 - * then the task will be unblocked when a single byte is written to the buffer - * or the task's block time expires. As another example, if a task is blocked - * on a read of an empty stream buffer that has a trigger level of 10 then the - * task will not be unblocked until the stream buffer contains at least 10 - * bytes or the task's block time expires. If a reading task's block time - * expires before the trigger level is reached then the task will still - * receive however many bytes are actually available. Setting a trigger level - * of 0 will result in a trigger level of 1 being used. It is not valid to - * specify a trigger level that is greater than the buffer size. - * - * @param triggerLevel The new trigger level for the stream buffer. - * @retval true If triggerLevel was less than or equal to the stream buffer's - * length then the trigger level was updated. - * @retval false Otherwise. - */ - inline bool setTriggerLevel(const size_t triggerLevel = 0) const { - return (xStreamBufferSetTriggerLevel(handle, triggerLevel) == pdTRUE); - } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls BaseType_t xStreamBufferReset( - * StreamBufferHandle_t xStreamBuffer ) - * - * @see - * - * Resets a stream buffer to its initial, empty, state. Any data that was in - * the stream buffer is discarded. A stream buffer can only be reset if there - * are no tasks blocked waiting to either send to or receive from the stream - * buffer. - * - * @return true If the stream buffer is reset. - * @return false If there was a task blocked waiting to send to or read from - * the stream buffer then the stream buffer was not reset. - */ - inline bool reset() const { return (xStreamBufferReset(handle) == pdPASS); } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls BaseType_t xStreamBufferIsEmpty( - * StreamBufferHandle_t xStreamBuffer ) - * - * @see - * - * Queries a stream buffer to see if it is empty. A stream buffer is empty if - * it does not contain any data. - * - * @return true If the stream buffer is empty. - * @return false Otherwise. - */ - inline bool isEmpty() const { - return (xStreamBufferIsEmpty(handle) == pdTRUE); - } - - /** - * StreamBuffer.hpp - * - * @brief Function that calls BaseType_t xStreamBufferIsFull( - * StreamBufferHandle_t xStreamBuffer ) - * - * @see - * - * Queries a stream buffer to see if it is full. A stream buffer is full if it - * does not have any free space, and therefore cannot accept any more data. - * - * @return true If the stream buffer is full. - * @return false Otherwise. - */ - inline bool isFull() const { return (xStreamBufferIsFull(handle) == pdTRUE); } - - private: - StreamBufferBase() = default; - - /** - * StreamBuffer.hpp - * - * @brief Destroy the StreamBufferBase object by calling - * void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) - * - * @see - * - * Deletes a stream buffer and free the allocated memory. - */ - ~StreamBufferBase() { vStreamBufferDelete(this->handle); } - - StreamBufferBase(StreamBufferBase&&) noexcept = default; - StreamBufferBase& operator=(StreamBufferBase&&) noexcept = default; - - StreamBufferHandle_t handle = NULL; -}; - -#if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - -/** - * @class StreamBuffer StreamBuffer.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS stream buffer. - * - * A stream buffer using dynamically allocated memory from the FreeRTOS heap. - * See FreeRTOS::StaticStreamBuffer for a version that uses statically allocated - * memory (memory that is allocated at compile time). - */ -class StreamBuffer : public StreamBufferBase { - public: - /** - * StreamBuffer.hpp - * - * @brief Construct a new StreamBuffer object by calling - * StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, - * size_t xTriggerLevelBytes ) - * - * @see - * - * @warning The user should call isValid() on this object to verify that the - * stream buffer was created successfully in case the memory required to - * create the message buffer could not be allocated. - * - * @param size The total number of bytes the stream buffer will be able to - * hold at any one time. - * @param triggerLevel The number of bytes that must be in the stream - * buffer before a task that is blocked on the stream buffer to wait for data - * is moved out of the blocked state. For example, if a task is blocked on a - * read of an empty stream buffer that has a trigger level of 1 then the task - * will be unblocked when a single byte is written to the buffer or the task's - * block time expires. As another example, if a task is blocked on a read of - * an empty stream buffer that has a trigger level of 10 then the task will - * not be unblocked until the stream buffer contains at least 10 bytes or the - * task's block time expires. If a reading task's block time expires before - * the trigger level is reached then the task will still receive however many - * bytes are actually available. Setting a trigger level of 0 will result in a - * trigger level of 1 being used. It is not valid to specify a trigger level - * that is greater than the buffer size. - * - * Example Usage - * @include StreamBuffer/streamBuffer.cpp - */ - explicit StreamBuffer(const size_t size, const size_t triggerLevel = 0) { - this->handle = xStreamBufferCreate(size, triggerLevel); - } - ~StreamBuffer() = default; - - StreamBuffer(const StreamBuffer&) = delete; - StreamBuffer& operator=(const StreamBuffer&) = delete; - - StreamBuffer(StreamBuffer&&) noexcept = default; - StreamBuffer& operator=(StreamBuffer&&) noexcept = default; -}; - -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - -#if (configSUPPORT_STATIC_ALLOCATION == 1) - -/** - * @class StaticStreamBuffer StreamBuffer.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS stream buffer. - * - * If a stream buffer is created using this class then the RAM is provided by - * the application writer as part of the object instance and allows the RAM to - * be statically allocated at compile time. - * - * @tparam N The size, in bytes, of the storage buffer for the stream buffer. - */ -template -class StaticStreamBuffer : public StreamBufferBase { - public: - /** - * StreamBuffer.hpp - * - * @brief Construct a new StaticStreamBuffer object by calling - * StreamBufferHandle_t xStreamBufferCreateStatic( size_t - * xBufferSizeBytes, size_t xTriggerLevelBytes, uint8_t - * *pucStreamBufferStorageArea, StaticStreamBuffer_t *pxStaticStreamBuffer - * ) - * - * @see - * - * @param triggerLevel The number of bytes that must be in the stream - * buffer before a task that is blocked on the stream buffer to wait for data - * is moved out of the blocked state. For example, if a task is blocked on a - * read of an empty stream buffer that has a trigger level of 1 then the task - * will be unblocked when a single byte is written to the buffer or the task's - * block time expires. As another example, if a task is blocked on a read of - * an empty stream buffer that has a trigger level of 10 then the task will - * not be unblocked until the stream buffer contains at least 10 bytes or the - * task's block time expires. If a reading task's block time expires before - * the trigger level is reached then the task will still receive however many - * bytes are actually available. Setting a trigger level of 0 will result in a - * trigger level of 1 being used. It is not valid to specify a trigger level - * that is greater than the buffer size. - * - * Example Usage - * @include StreamBuffer/staticStreamBuffer.cpp - */ - explicit StaticStreamBuffer(const size_t triggerLevel = 0) { - this->handle = xStreamBufferCreateStatic(sizeof(storage), triggerLevel, - storage, &staticStreamBuffer); - } - ~StaticStreamBuffer() = default; - - StaticStreamBuffer(const StaticStreamBuffer&) = delete; - StaticStreamBuffer& operator=(const StaticStreamBuffer&) = delete; - - StaticStreamBuffer(StaticStreamBuffer&&) noexcept = default; - StaticStreamBuffer& operator=(StaticStreamBuffer&&) noexcept = default; - - private: - StaticStreamBuffer_t staticStreamBuffer; - uint8_t storage[N]; -}; - -#endif /* configSUPPORT_STATIC_ALLOCATION */ - -} // namespace FreeRTOS - -#endif // FREERTOS_STREAMBUFFER_HPP \ No newline at end of file diff --git a/source/shoh/src/FreeRTOSCPP/Task.hpp b/source/shoh/src/FreeRTOSCPP/Task.hpp deleted file mode 100644 index 7da36ab..0000000 --- a/source/shoh/src/FreeRTOSCPP/Task.hpp +++ /dev/null @@ -1,1480 +0,0 @@ -/* - * FreeRTOS-Cpp - * Copyright (C) 2021 Jon Enz. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * https://github.com/jonenz/FreeRTOS-Cpp - */ - -#ifndef FREERTOS_TASK_HPP -#define FREERTOS_TASK_HPP - -#include -#include - -#include "FreeRTOS.h" -#include "task.h" -#include "../FreeRTOSCPP/Kernel.hpp" - -/** - * @brief C function that is used to interface this class with the FreeRTOS - * kernel. - * - * @note This function should not be called or referenced by the user. - * - * @param task Pointer to an instance of FreeRTOS::TaskBase. - */ -void callTaskFunction(void* task); - -namespace FreeRTOS { - -/** - * @class TaskBase Task.hpp - * - * @brief Base class that provides the standard task interface to FreeRTOS::Task - * and FreeRTOS::StaticTask. - * - * @note This class is not intended to be instantiated or derived from by the - * user. Use FreeRTOS::Task or FreeRTOS::StaticTask as a base class for a user - * implemented task. - */ -class TaskBase { - public: - friend class Task; - template - friend class StaticTask; - - TaskBase(const TaskBase&) = delete; - TaskBase& operator=(const TaskBase&) = delete; - - static void* operator new(size_t, void* ptr) { return ptr; } - static void* operator new[](size_t, void* ptr) { return ptr; } - static void* operator new(size_t) = delete; - static void* operator new[](size_t) = delete; - - enum class State { - Running = eRunning, - Ready = eReady, - Blocked = eBlocked, - Suspended = eSuspended, - Deleted = eDeleted, - Invalid = eInvalid, - }; - - enum class NotifyAction { - NoAction = eNoAction, - SetBits = eSetBits, - Increment = eIncrement, - SetValueWithOverwrite = eSetValueWithOverwrite, - SetValueWithoutOverwrite = eSetValueWithoutOverwrite, - }; - - // NOLINTNEXTLINE - using NotificationBits = std::bitset<32>; - - /** - * Task.hpp - * - * @brief Function that acts as the entry point of the task instance. This - * function initializes the previous wake time of the task and calls the user - * implemented taskFunction(). - * - * @note This function is only public so that it can be accessed by the C - * interface function callTaskFunction() and should not be called or - * referenced by the user. - */ - virtual inline void taskEntry() final { - previousWakeTime = FreeRTOS::Kernel::getTickCount(); - taskFunction(); - }; - -#if (INCLUDE_uxTaskPriorityGet == 1) - /** - * Task.hpp - * - * @brief Function that calls UBaseType_t uxTaskPriorityGet( TaskHandle_t - * xTask ) - * - * @see - * - * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be - * available. See the RTOS Configuration documentation for more information. - * - * Obtain the priority of any task. - * - * @return UBaseType_t The priority of the task. - * - * Example Usage - * @include Task/getPriority.cpp - */ - inline UBaseType_t getPriority() const { return uxTaskPriorityGet(handle); } -#endif /* INCLUDE_uxTaskPriorityGet */ - -#if (INCLUDE_vTaskPrioritySet == 1) - /** - * Task.hpp - * - * @brief Function that calls void vTaskPrioritySet( TaskHandle_t xTask, - * UBaseType_t uxNewPriority ) - * - * @see - * - * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be - * available. See the configuration section for more information. - * - * Set the priority of the task. - * - * A context switch will occur before the function returns if the priority - * being set is higher than the currently executing task. - * - * @param newPriority The priority to which the task will be set. - * - * Example Usage - * @include Task/setPriority.cpp - */ - inline void setPriority(const UBaseType_t newPriority) const { - vTaskPrioritySet(handle, newPriority); - } -#endif /* INCLUDE_vTaskPrioritySet */ - -#if (INCLUDE_vTaskSuspend == 1) - /** - * Task.hpp - * - * @brief Function that calls void vTaskSuspend( TaskHandle_t - * xTaskToSuspend ) - * - * @see - * - * INCLUDE_vTaskSuspend must be defined as 1 for this function to be - * available. See the RTOS Configuration documentation for more information. - * - * Suspend a task. When suspended a task will never get any microcontroller - * processing time, no matter what its priority. - * - * Calls to suspend() are not accumulative - i.e. calling suspend() twice on - * the same task still only requires one call to resume() to ready the - * suspended task. - * - * Example Usage - * @include Task/suspend.cpp - */ - inline void suspend() const { vTaskSuspend(handle); } - - /** - * Task.hpp - * - * @brief Function that calls void vTaskResume( TaskHandle_t xTaskToResume - * ) - * - * @see - * - * INCLUDE_vTaskSuspend must be defined as 1 for this function to be - * available. See the RTOS Configuration documentation for more information. - * - * Resumes a suspended task. - * - * A task that has been suspended by one or more calls to suspend() will be - * made available for running again by a single call to resume(). - * - * Example Usage - * @include Task/resume.cpp - */ - inline void resume() const { vTaskResume(handle); } - -#if (INCLUDE_xTaskResumeFromISR == 1) - /** - * Task.hpp - * - * @brief Function that calls BaseType_t xTaskResumeFromISR( TaskHandle_t - * xTaskToResume ) - * - * @see - * - * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be - * available. See the configuration section for more information. - * - * An implementation of resume() that can be called from within an ISR. - * - * A task that has been suspended by one or more calls to suspend() will be - * made available for running again by a single call to resumeFromISR(). - * - * resumeFromISR() should not be used to synchronize a task with an interrupt - * if there is a chance that the interrupt could arrive prior to the task - * being suspended - as this can lead to interrupts being missed. Use of a - * semaphore as a synchronisation mechanism would avoid this eventuality. - * - * @retval true If resuming the task should result in a context switch. This - * is used by the ISR to determine if a context switch may be required - * following the ISR. - * @retval false Otherwise. - * - * Example Usage - * @include Task/resumeFromISR.cpp - */ - inline bool resumeFromISR() const { - return (xTaskResumeFromISR(handle) == pdTRUE); - } -#endif /* INCLUDE_xTaskResumeFromISR */ -#endif /* INCLUDE_vTaskSuspend */ - -#if (INCLUDE_xTaskAbortDelay == 1) - /** - * Task.hpp - * - * @brief Function that calls BaseType_t xTaskAbortDelay( TaskHandle_t - * xTask ) - * - * @see - * - * INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this - * function to be available. - * - * A task will enter the Blocked state when it is waiting for an event. The - * event it is waiting for can be a temporal event (waiting for a time), such - * as when delay() is called, or an event on an object, such as when - * FreeRTOS::Queue::receive() or notifyTake() is called. If the handle of a - * task that is in the Blocked state is used in a call to abortDelay() then - * the task will leave the Blocked state, and return from whichever function - * call placed the task into the Blocked state. - * - * There is no 'FromISR' version of this function as an interrupt would need - * to know which object a task was blocked on in order to know which actions - * to take. For example, if the task was blocked on a queue the interrupt - * handler would then need to know if the queue was locked. - * - * @retval true Otherwise. - * @retval false If the task was not in the Blocked state. - */ - inline bool abortDelay() const { return (xTaskAbortDelay(handle) == pdPASS); } -#endif /* INCLUDE_xTaskAbortDelay */ - -#if (INCLUDE_xTaskGetIdleTaskHandle == 1) - /** - * Task.hpp - * - * @brief Function that calls TaskHandle_t xTaskGetIdleTaskHandle( void - * ) - * - * @see - * - * getIdleTaskHandle() is only available if INCLUDE_xTaskGetIdleTaskHandle is - * set to 1 in FreeRTOSConfig.h. - * - * Simply returns the handle of the idle task. It is not valid to call - * getIdleTaskHandle() before the scheduler has been started. - * - * @return TaskHandle_t The task handle associated with the Idle task. The - * Idle task is created automatically when the RTOS scheduler is started. - */ - inline static TaskHandle_t getIdleHandle() { - return xTaskGetIdleTaskHandle(); - } -#endif /* INCLUDE_xTaskGetIdleTaskHandle */ - -#if (INCLUDE_uxTaskGetStackHighWaterMark == 1) - /** - * Task.hpp - * - * @brief Function that calls UBaseType_t uxTaskGetStackHighWaterMark( - * TaskHandle_t xTask ) - * - * @see - * - * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h - * for this function to be available. - * - * Returns the high water mark of the stack. That is, the minimum free stack - * space there has been (in words, so on a 32 bit machine a value of 1 means 4 - * bytes) since the task started. The smaller the returned number the closer - * the task has come to overflowing its stack. - * - * getStackHighWaterMark() and getStackHighWaterMark2() are the same except - * for their return type. Using configSTACK_DEPTH_TYPE allows the user to - * determine the return type. It gets around the problem of the value - * overflowing on 8-bit types without breaking backward compatibility for - * applications that expect an 8-bit return type. - * - * @return BaseType_t The smallest amount of free stack space there has been - * (in words, so actual spaces on the stack rather than bytes) since the task - * was created. - */ - inline UBaseType_t getStackHighWaterMark() const { - return uxTaskGetStackHighWaterMark(handle); - } - - /** - * Task.hpp - * - * @brief Function that calls UBaseType_t uxTaskGetStackHighWaterMark2( - * TaskHandle_t xTask ) - * - * @see - * - * Returns the high water mark of the stack. That is, the minimum free stack - * space there has been (in words, so on a 32 bit machine a value of 1 means 4 - * bytes) since the task started. The smaller the returned number the closer - * the task has come to overflowing its stack. - * - * getStackHighWaterMark() and getStackHighWaterMark2() are the same except - * for their return type. Using configSTACK_DEPTH_TYPE allows the user to - * determine the return type. It gets around the problem of the value - * overflowing on 8-bit types without breaking backward compatibility for - * applications that expect an 8-bit return type. - * - * @return configSTACK_DEPTH_TYPE The smallest amount of free stack space - * there has been (in words, so actual spaces on the stack rather than bytes) - * since the task was created. - */ - inline configSTACK_DEPTH_TYPE getStackHighWaterMark2() const { - return uxTaskGetStackHighWaterMark2(handle); - } -#endif /* INCLUDE_uxTaskGetStackHighWaterMark */ - -#if (INCLUDE_eTaskGetState == 1) - /** - * Task.hpp - * - * @brief Function that calls UBaseType_t uxTaskGetStackHighWaterMark2( - * TaskHandle_t xTask ) - * - * @see - * - * @see getInfo() - * - * INCLUDE_eTaskGetState must be defined as 1 for this function to be - * available. See the configuration section for more information. - * - * Obtain the state of any task. States are encoded by the - * FreeRTOS::Task::State enumerated class type. - * - * @return State The state of the task at the time the function was called. - * Note the state of the task might change between the function being called, - * and the functions return value being tested by the calling task. - */ - inline State getState() const { - return static_cast(eTaskGetState(handle)); - } -#endif /* INCLUDE_eTaskGetState */ - - /** - * Task.hpp - * - * @brief Function that calls char *pcTaskGetName( TaskHandle_t - * xTaskToQuery ) - * - * @see - * - * Looks up the name of a task. - * - * @return const char* The text (human readable) name of the task. A pointer - * to the subject task's name, which is a standard NULL terminated C string. - */ - inline const char* getName() const { return pcTaskGetName(handle); } - -#if (INCLUDE_xTaskGetHandle == 1) - /** - * Task.hpp - * - * @brief Function that calls TaskHandle_t xTaskGetHandle( const char - * *pcNameToQuery ) - * - * @see - * - * @note This function takes a relatively long time to complete and should be - * used sparingly. - * - * @param name The text name (as a standard C NULL terminated string) of the - * task for which the handle will be returned. - * @return TaskHandle_t The handle of the task that has the human readable - * name. NULL is returned if no matching name is found. - * INCLUDE_xTaskGetHandle must be set to 1 in FreeRTOSConfig.h for getHandle() - * to be available. - */ - inline static TaskHandle_t getHandle(const char* name) { - return xTaskGetHandle(name); - } -#endif /* INCLUDE_xTaskGetHandle */ - -#if (configUSE_TASK_NOTIFICATIONS == 1) - /** - * Task.hpp - * - * @brief Function that calls BaseType_t xTaskNotifyGiveIndexed( - * TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify ) - * - * @see - * - * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these - * functions to be available. - * - * Each task has a private array of "notification values" (or - * 'notifications'), each of which is a 32-bit unsigned integer (uint32_t). - * The constant configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of - * indexes in the array, and (for backward compatibility) defaults to 1 if - * left undefined. Prior to FreeRTOS V10.4.0 there was only one notification - * value per task. - * - * Events can be sent to a task using an intermediary object. Examples of - * such objects are queues, semaphores, mutexes and event groups. Task - * notifications are a method of sending an event directly to a task without - * the need for such an intermediary object. - * - * A notification sent to a task can optionally perform an action, such as - * update, overwrite or increment one of the task's notification values. In - * that way task notifications can be used to send data to a task, or be used - * as light weight and fast binary or counting semaphores. - * - * notifyGive() indicies is are intended for use when task notifications are - * used as light weight and faster binary or counting semaphore equivalents. - * Actual FreeRTOS semaphores are given using the FreeRTOS::Semaphore API, the - * equivalent action that instead uses a task notification is notifyGive(). - * - * When task notifications are being used as a binary or counting semaphore - * equivalent then the task being notified should wait for the notification - * using the notificationTake() API function rather than the - * notifyWaitIndexed() API function. - * - * @note Each notification within the array operates independently - a task - * can only block on one notification within the array at a time and will not - * be unblocked by a notification sent to any other array index. - * - * @param index The index within the target task's array of notification - * values to which the notification is to be sent. index must be less than - * configTASK_NOTIFICATION_ARRAY_ENTRIES. - * - * Example Usage - * @include Task/notifyGive.cpp - */ - inline void notifyGive(const UBaseType_t index = 0) const { - xTaskNotifyGiveIndexed(handle, index); - } - - /** - * Task.hpp - * - * @brief Function that calls void vTaskNotifyGiveIndexedFromISR( - * TaskHandle_t xTaskHandle, UBaseType_t uxIndexToNotify, BaseType_t - * *pxHigherPriorityTaskWoken ) - * - * @see - * - * Version of notifyGive() that can be used from an interrupt service routine - * (ISR). See the documentation page for the notifyGive() API function for a - * description of their operation and the necessary configuration parameters. - * - * @param higherPriorityTaskWoken A reference that will be set to true if - * sending the notification caused a task to unblock, and the unblocked task - * has a priority higher than the currently running task. If - * higherPriorityTaskWoken is set to true, then a context switch should be - * requested before the interrupt is exited. - * @param index The index within the target task's array of notification - * values to which the notification is to be sent. index must be less than - * configTASK_NOTIFICATION_ARRAY_ENTRIES. - * - * Example Usage - * @include Task/notifyGiveFromISR.cpp - */ - inline void notifyGiveFromISR(bool& higherPriorityTaskWoken, - const UBaseType_t index = 0) const { - BaseType_t taskWoken = pdFALSE; - vTaskNotifyGiveIndexedFromISR(handle, index, &taskWoken); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - } - - /** - * Task.hpp - * - * @brief Function that calls void vTaskNotifyGiveIndexedFromISR( - * TaskHandle_t xTaskHandle, UBaseType_t uxIndexToNotify, BaseType_t - * *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline void notifyGiveFromISR(const UBaseType_t index = 0) const { - vTaskNotifyGiveIndexedFromISR(handle, index, NULL); - } - - /** - * Task.hpp - * - * @brief Function that calls BaseType_t xTaskNotifyIndexed( TaskHandle_t - * xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction - * eAction ) - * - * @see - * - * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these - * functions to be available. - * - * Each task has a private array of "notification values" (or - * 'notifications'), each of which is a 32-bit unsigned integer (uint32_t). - * The constant configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of - * indexes in the array, and (for backward compatibility) defaults to 1 if - * left undefined. Prior to FreeRTOS V10.4.0 there was only one notification - * value per task. - * - * Events can be sent to a task using an intermediary object. Examples of - * such objects are queues, semaphores, mutexes and event groups. Task - * notifications are a method of sending an event directly to a task without - * the need for such an intermediary object. - * - * A notification sent to a task can optionally perform an action, such as - * update, overwrite or increment one of the task's notification values. In - * that way task notifications can be used to send data to a task, or be used - * as light weight and fast binary or counting semaphores. - * - * A task can use notifyWait() or notifyTake() to [optionally] block to wait - * for a notification to be pending. The task does not consume any CPU time - * while it is in the Blocked state. - * - * A notification sent to a task will remain pending until it is cleared by - * the task calling notifyWait() or notifyTake(). If the task was already in - * the Blocked state to wait for a notification when the notification arrives - * then the task will automatically be removed from the Blocked state - * (unblocked) and the notification cleared. - * - * @note Each notification within the array operates independently - a task - * can only block on one notification within the array at a time and will not - * be unblocked by a notification sent to any other array index. - * - * @param action Specifies how the notification updates the task's - * notification value, if at all. Valid values for action are as follows: - *
NotifyAction Setting Action Performed - *
NoAction The target task receives the event, - * but its notification value is not updated. In this case value is not used. - *
SetBits The notification value of the target - * task will be bitwise ORed with value. For example, if value is set to 0x01, - * then bit 0 will get set within the target task's notification value. - * Likewise if value is 0x04 then bit 2 will get set in the target task's - * notification value. In this way the RTOS task notification mechanism can be - * used as a light weight alternative to an event group.
Increment - * The notification value of the target task will be incremented by one, - * making the call to notify() equivalent to a call to notifyGive(). In this - * case value is not used.
SetValueWithOverwrite The - * notification value of the target task is unconditionally set to value. In - * this way the RTOS task notification mechanism is being used as a light - * weight alternative to FreeRTOS::Queue::Overwrite(). - *
SetValueWithoutOverwrite If the target task does not already - * have a notification pending then its notification value will be set to - * value. If the target task already has a notification pending then its - * notification value is not updated as to do so would overwrite the previous - * value before it was used. In this case the call to notify() fails and false - * is returned. In this way the RTOS task notification mechanism is being - * used as a light weight alternative to FreeRTOS::Queue::send() on a queue of - * length 1. - * @param value Data that can be sent with the notification. How the data is - * used depends on the value of the action parameter. - * @param index The index within the target task's array of notification - * values to which the notification is to be sent. index must be less than - * configTASK_NOTIFICATION_ARRAY_ENTRIES. - * - * @return false If action is set to SetValueWithoutOverwrite and the task's - * notification value cannot be updated because the target task already had a - * notification pending. - * @return true Otherwise. - * - * Example Usage - * @include Task/notify.cpp - */ - inline bool notify(const NotifyAction action, - const NotificationBits value = 0, - const UBaseType_t index = 0) const { - return (xTaskNotifyIndexed(handle, index, value.to_ulong(), - static_cast(action)) == pdPASS); - } - - /** - * Task.hpp - * - * @brief Function that calls BaseType_t xTaskNotifyAndQueryIndexed( - * TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, - * eNotifyAction eAction, uint32_t *pulPreviousNotifyValue ) - * - * @see - * - * notifyAndQuery() performs the same operation as notify() with the addition - * that it also returns the target task's prior notification value (the - * notification value at the time the function is called rather than when the - * function returns). - * - * @param action An enumerated type that can take one of the values documented - * in the table below in order to perform the associated action. - *
NotifyAction Setting Action Performed - *
NoAction The target task receives the event, - * but its notification value is not updated. In this case value is not used. - *
SetBits The notification value of the target - * task will be bitwise ORed with value. For example, if value is set to 0x01, - * then bit 0 will get set within the target task's notification value. - * Likewise if value is 0x04 then bit 2 will get set in the target task's - * notification value. In this way the RTOS task notification mechanism can be - * used as a light weight alternative to an event group.
Increment - * The notification value of the target task will be incremented by one, - * making the call to notify() equivalent to a call to notifyGive(). In this - * case value is not used.
SetValueWithOverwrite The - * notification value of the target task is unconditionally set to value. In - * this way the RTOS task notification mechanism is being used as a light - * weight alternative to FreeRTOS::Queue::Overwrite(). - *
SetValueWithoutOverwrite If the target task does not already - * have a notification pending then its notification value will be set to - * value. If the target task already has a notification pending then its - * notification value is not updated as to do so would overwrite the previous - * value before it was used. In this case the call to notify() fails and false - * is returned. In this way the RTOS task notification mechanism is being - * used as a light weight alternative to FreeRTOS::Queue::send() on a queue of - * length 1. - * @param value Used to update the notification value of the task. See the - * description of the action parameter below. - * @param index The index within the target task's array of notification - * values to which the notification is to be sent. index must be less than - * configTASK_NOTIFICATION_ARRAY_ENTRIES. - * - * @return false If action is set to SetValueWithoutOverwrite and the task's - * notification value cannot be updated because the target task already had a - * notification pending. - * @return true Otherwise. - * - * Example Usage - * @include Task/notifyAndQuery.cpp - */ - inline std::pair notifyAndQuery( - const NotifyAction action, const NotificationBits value = 0, - const UBaseType_t index = 0) const { - uint32_t pulNotificationValue; - bool result = - (xTaskNotifyAndQueryIndexed(handle, index, value.to_ulong(), - static_cast(action), - &pulNotificationValue) == pdPASS); - - return std::make_pair(result, NotificationBits(pulNotificationValue)); - } - - /** - * Task.hpp - * - * @brief Function that calls BaseType_t - xTaskNotifyAndQueryIndexedFromISR( TaskHandle_t xTaskToNotify, - * UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, - uint32_t *pulPreviousNotifyValue, - * BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * notifyAndQueryFromISR() performs the same operation as notifyFromISR() with - the addition that it also returns the - * target task's prior notification value (the notification value at the time - the function is called rather than at - * the time the function returns). - - * @param higherPriorityTaskWoken A reference that will be set to true if - sending the notification caused a task to - * unblock, and the unblocked task has a priority higher than the currently - running task. If higherPriorityTaskWoken - * is set to true, then a context switch should be requested before the - interrupt is exited. - * @param action An enumerated type that can take one of the values documented - in the table below in order to perform - * the associated action. - *
NotifyAction Setting Action Performed - *
NoAction The target task receives the event, - but its notification value is not updated. - * In this case value is not used. - *
SetBits The notification value of the target - task will be bitwise ORed with value. For - * example, if value is set to 0x01, then bit 0 will get set within the target - task's notification value. Likewise if - * value is 0x04 then bit 2 will get set in the target task's notification - value. In this way the RTOS task - * notification mechanism can be used as a light weight alternative to an - event group. - *
Increment The notification value of the target - task will be incremented by one, making - * the call to notify() equivalent to a call to notifyGive(). In this case - value is not used. - *
SetValueWithOverwrite The notification value of the target - task is unconditionally set to value. In - * this way the RTOS task notification mechanism is being used as a light - weight alternative to - * FreeRTOS::Queue::Overwrite(). - *
SetValueWithoutOverwrite If the target task does not already - have a notification pending then its - * notification value will be set to value. If the target task already has a - notification pending then its - * notification value is not updated as to do so would overwrite the previous - value before it was used. In this case - * the call to notify() fails and false is returned. In this way the RTOS - task notification mechanism is being used - * as a light weight alternative to FreeRTOS::Queue::send() on a queue of - length 1. - * @param value Used to update the notification value of the task. See the - description of the action parameter below. - * @param index The index within the target task's array of notification - values to which the notification is to be - * sent. index must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. - * - * @retval false If action is set to SetValueWithoutOverwrite and the task's - notification value cannot be updated - * because the target task already had a notification pending. - * @retval true Otherwise. - * @return NotificationBits The task's notification value before any bits are - modified. - * - * Example Usage - * @include Task/notifyAndQueryFromISR.cpp - */ - inline std::pair notifyAndQueryFromISR( - bool& higherPriorityTaskWoken, const NotifyAction action, - const NotificationBits value = 0, const UBaseType_t index = 0) const { - BaseType_t taskWoken = pdFALSE; - uint32_t pulNotificationValue; - bool result = (xTaskNotifyAndQueryIndexedFromISR( - handle, index, value.to_ulong(), - static_cast(action), - &pulNotificationValue, &taskWoken) == pdPASS); - - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - - return std::make_pair(result, NotificationBits(pulNotificationValue)); - } - - /** - * Task.hpp - * - * @brief Function that calls BaseType_t - xTaskNotifyAndQueryIndexedFromISR( TaskHandle_t xTaskToNotify, - * UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, - uint32_t *pulPreviousNotifyValue, - * BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline std::pair notifyAndQueryFromISR( - const NotifyAction action, const NotificationBits value = 0, - const UBaseType_t index = 0) const { - uint32_t pulNotificationValue; - bool result = (xTaskNotifyAndQueryIndexedFromISR( - handle, index, value.to_ulong(), - static_cast(action), - &pulNotificationValue, NULL) == pdPASS); - - return std::make_pair(result, NotificationBits(pulNotificationValue)); - } - - /** - * Task.hpp - * - * @brief Function that calls BaseType_t xTaskNotifyIndexedFromISR( - * TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, - * eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * Version of notify() that can be used from an interrupt service routine - * (ISR). See the documentation page for the notify() API function for a - * description of their operation and the necessary configuration parameters, - * as well as backward compatibility information. - * - * @param higherPriorityTaskWoken A reference that will be set to true if - * sending the notification caused a task to unblock, and the unblocked task - * has a priority higher than the currently running task. If - * higherPriorityTaskWoken is set to true, then a context switch should be - * requested before the interrupt is exited. - * @param action An enumerated type that can take one of the values documented - * in the table below in order to perform the associated action. - *
NotifyAction Setting Action Performed - *
NoAction The target task receives the event, - * but its notification value is not updated. In this case value is not used. - *
SetBits The notification value of the target - * task will be bitwise ORed with value. For example, if value is set to 0x01, - * then bit 0 will get set within the target task's notification value. - * Likewise if value is 0x04 then bit 2 will get set in the target task's - * notification value. In this way the RTOS task notification mechanism can be - * used as a light weight alternative to an event group.
Increment - * The notification value of the target task will be incremented by one, - * making the call to notify() equivalent to a call to notifyGive(). In this - * case value is not used.
SetValueWithOverwrite The - * notification value of the target task is unconditionally set to value. In - * this way the RTOS task notification mechanism is being used as a light - * weight alternative to FreeRTOS::Queue::Overwrite(). - *
SetValueWithoutOverwrite If the target task does not already - * have a notification pending then its notification value will be set to - * value. If the target task already has a notification pending then its - * notification value is not updated as to do so would overwrite the previous - * value before it was used. In this case the call to notify() fails and false - * is returned. In this way the RTOS task notification mechanism is being - * used as a light weight alternative to FreeRTOS::Queue::send() on a queue of - * length 1. - * @param value Used to update the notification value of the task. See the - * description of the action parameter below. - * @param index The index within the target task's array of notification - * values to which the notification is to be sent. index must be less than - * configTASK_NOTIFICATION_ARRAY_ENTRIES. - * - * @retval false If action is set to SetValueWithoutOverwrite and the task's - * notification value cannot be updated because the target task already had a - * notification pending. - * @retval true Otherwise. - * - * Example Usage - * This example demonstrates how to use notifyFromISR() with the SetBits - * action. See the notify() API documentation page for examples showing how to - * use the NoAction, SetValueWithOverwrite and SetValueWithoutOverwrite - * actions. - * @include Task/notifyFromISR.cpp - */ - inline bool notifyFromISR(bool& higherPriorityTaskWoken, - const NotifyAction action, - const NotificationBits value = 0, - const UBaseType_t index = 0) const { - BaseType_t taskWoken = pdFALSE; - bool result = (xTaskNotifyIndexedFromISR(handle, index, value.to_ulong(), - static_cast(action), - &taskWoken) == pdPASS); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * Task.hpp - * - * @brief Function that calls BaseType_t xTaskNotifyIndexedFromISR( - * TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, - * eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline bool notifyFromISR(const NotifyAction action, - const NotificationBits value = 0, - const UBaseType_t index = 0) const { - return (xTaskNotifyIndexedFromISR(handle, index, value.to_ulong(), - static_cast(action), - NULL) == pdPASS); - } - - /** - * Task.hpp - * - * @brief Function that calls BaseType_t xTaskNotifyWaitIndexed( - * UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t - * ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t - * xTicksToWait ) - * - * @see - * - * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these - * functions to be available. - * - * Each task has an array of 'task notifications' (or just 'notifications'), - * each of which has a state and a 32-bit value. A direct to task notification - * is an event sent directly to a task that can unblock the receiving task, - * and optionally update one of the receiving task’s notification values in a - * number of different ways. For example, a notification may overwrite one of - * the receiving task’s notification values, or just set one or more bits in - * one of the receiving task’s notification values. - * - * notifyWait() waits, with an optional timeout, for the calling task to - * receive a notification. If the receiving RTOS task was already Blocked - * waiting for a notification when the notification it is waiting for arrives - * the receiving RTOS task will be removed from the Blocked state and the - * notification cleared. - * - * @note Each notification within the array operates independently - a task - * can only block on one notification within the array at a time and will not - * be unblocked by a notification sent to any other array index. - * - * notifyGive() must not be called from an interrupt service routine. Use - * notifyGiveFromISR() instead. - * - * @param ticksToWait The maximum time to wait in the Blocked state for a - * notification to be received if a notification is not already pending when - * notifyWait() is called. - * - * The RTOS task does not consume any CPU time when it is in the Blocked - * state. - * - * The time is specified in RTOS tick periods. The pdMS_TO_TICKS() macro can - * be used to convert a time specified in milliseconds into a time specified - * in ticks. - * - * @param bitsToClearOnEntry Any bits set in bitsToClearOnEntry will be - * cleared in the calling RTOS task's notification value on entry to the - * notifyWait() function (before the task waits for a new notification) - * provided a notification is not already pending when notifyWait() is called. - * - * For example, if bitsToClearOnEntry is 0x01, then bit 0 of the task's - * notification value will be cleared on entry to the function. - * - * Setting bitsToClearOnEntry to 0xffffffff (ULONG_MAX) will clear all the - * bits in the task's notification value, effectively clearing the value to 0. - * - * @param bitsToClearOnExit Any bits set in bitsToClearOnExit will be cleared - * in the calling RTOS task's notification value before notifyWait() function - * exits if a notification was received. - * - * The bits are cleared after the RTOS task's notification value are returned. - * - * For example, if bitsToClearOnExit is 0x03, then bit 0 and bit 1 of the - * task's notification value will be cleared before the function exits. - * - * Setting bitsToClearOnExit to 0xffffffff (ULONG_MAX) will clear all the bits - * in the task's notification value, effectively clearing the value to 0. - * - * @param index The index within the calling task's array of notification - * values on which the calling task will wait for a notification to be - * received. index must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. - * - * @retval true If a notification was received, or a notification was already - * pending when notifyWait() was called. - * @retval false If the call to notifyWait() timed out before a notification - * was received. - * @return The RTOS task's notification value as it was before any bits were - * cleared due to the bitsToClearOnExit setting. - * - * Example Usage - * @include Task/notifyWait.cpp - */ - inline static std::pair notifyWait( - const TickType_t ticksToWait = portMAX_DELAY, - const NotificationBits bitsToClearOnEntry = 0, - const NotificationBits bitsToClearOnExit = 0, - const UBaseType_t index = 0) { - uint32_t pulNotificationValue; - bool result = - (xTaskNotifyWaitIndexed(index, bitsToClearOnEntry.to_ulong(), - bitsToClearOnExit.to_ulong(), - &pulNotificationValue, ticksToWait) == pdTRUE); - return std::make_pair(result, NotificationBits(pulNotificationValue)); - } - - /** - * Task.hpp - * - * @brief Function that calls BaseType_t xTaskNotifyStateClearIndexed( - * TaskHandle_t xTask, UBaseType_t uxIndexToClear ) - * - * @see - * - * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these - * functions to be available. - * - * Each RTOS task has an array of task notifications. Each task notification - * has a notification state that can be either ‘pending’ or ‘not pending’, and - * a 32-bit notification value. - * - * If a notification is sent to an index within the array of notifications - * then the notification at that index is said to be 'pending' until the task - * reads its notification value or explicitly clears the notification state to - * 'not pending' by calling notifyStateClear(). - * - * @param index The index within the target task's array of notification - * values to act upon. For example, setting index to 1 will clear the state of - * the notification at index 1 within the array. - * - * index must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. - * - * notifyStateClear() does not have this parameter and always acts on the - * notification at index 0. - * - * @retval true If the task had a notification pending, and the notification - * was cleared. - * @retval false If the task didn't have a notification pending. - * - * Example Usage - * @include Task/notifyStateClear.cpp - */ - inline bool notifyStateClear(const UBaseType_t index = 0) const { - return (xTaskNotifyStateClearIndexed(handle, index) == pdTRUE); - } - - /** - * Task.hpp - * - * @brief Function that calls uint32_t ulTaskNotifyValueClearIndexed( - * TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear - * ) - * - * @see - * - * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these - * functions to be available. - * - * Each RTOS task has an array of task notifications. Each task notification - * has a notification state that can be either ‘pending’ or ‘not pending’, and - * a 32-bit notification value. - * - * notifyValueClear() clears the bits specified by the bitsToClear bit mask in - * the notification value at array index index of the task. - * - * @param bitsToClear Bit mask of the bits to clear in the notification value - * of the task. Set a bit to 1 to clear the corresponding bits in the task's - * notification value. Set bitsToClear to 0xffffffff (UINT_MAX on 32-bit - * architectures) to clear the notification value to 0. Set bitsToClear to 0 - * to query the task's notification value without clearing any bits. - * @param index The index within the target task's array of notification - * values in which to clear the bits. index must be less than - * configTASK_NOTIFICATION_ARRAY_ENTRIES. - * @return NotificationBits The value of the target task's notification value - * before the bits specified by bitsToClear were cleared. - * - * Example Usage - * @include Task/notifyValueClear.cpp - */ - inline NotificationBits notifyValueClear( - const NotificationBits bitsToClear = 0, - const UBaseType_t index = 0) const { - return NotificationBits( - ulTaskNotifyValueClearIndexed(handle, index, bitsToClear.to_ulong())); - } -#endif /* configUSE_TASK_NOTIFICATIONS */ - - protected: - /** - * Task.hpp - * - * @brief Abstraction function that acts as the entry point of the task for - * the user. - */ - virtual void taskFunction() = 0; - -#if (INCLUDE_vTaskDelay == 1) - /** - * Task.hpp - * - * @brief Function that calls void vTaskDelay( const TickType_t - * xTicksToDelay ) - * - * @see - * - * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. - * See the configuration section for more information. - * - * Delay a task for a given number of ticks. The actual time that the task - * remains blocked depends on the tick rate. The constant portTICK_PERIOD_MS - * can be used to calculate real time from the tick rate - with the resolution - * of one tick period. - * - * delay() specifies a time at which the task wishes to unblock relative to - * the time at which delay() is called. For example, specifying a block - * period of 100 ticks will cause the task to unblock 100 ticks after delay() - * is called. delay() does not therefore provide a good method of controlling - * the frequency of a periodic task as the path taken through the code, as - * well as other task and interrupt activity, will affect the frequency at - * which delay() gets called and therefore the time at which the task next - * executes. See delayUntil() for an alternative API function designed to - * facilitate fixed frequency execution. It does this by specifying an - * absolute time (rather than a relative time) at which the calling task - * should unblock. - * - * @param ticksToDelay The amount of time, in tick periods, that the task - * should block. - * - * Example Usage - * @include Task/delay.cpp - */ - inline static void delay(const TickType_t ticksToDelay = 0) { - vTaskDelay(ticksToDelay); - } -#endif /* INCLUDE_vTaskDelay */ - -#if (INCLUDE_xTaskDelayUntil == 1) - /** - * Task.hpp - * - * @brief Function that calls BaseType_t xTaskDelayUntil( TickType_t - * *pxPreviousWakeTime, const TickType_t xTimeIncrement ) - * - * @see - * - * INCLUDE_xTaskDelayUntil must be defined as 1 for this function to be - * available. See the configuration section for more information. - * - * Delay a task until a specified time. This function can be used by periodic - * tasks to ensure a constant execution frequency. - * - * This function differs from delay() in one important aspect: delay() will - * cause a task to block for the specified number of ticks from the time delay - * () is called. It is therefore difficult to use delay() by itself to - * generate a fixed execution frequency as the time between a task starting to - * execute and that task calling delay() may not be fixed [the task may take a - * different path though the code between calls, or may get interrupted or - * preempted a different number of times each time it executes]. - * - * Whereas delay() specifies a wake time relative to the time at which the - * function is called, delayUntil() specifies the absolute (exact) time at - * which it wishes to unblock. - * - * The function pdMS_TO_TICKS() can be used to calculate the number of ticks - * from a time specified in milliseconds with a resolution of one tick period. - * - * @param timeIncrement The cycle time period. The task will be unblocked at - * time (previousWakeTime + timeIncrement). Calling delayUntil() with the same - * timeIncrement parameter value will cause the task to execute with a fixed - * interval period. - * @return true If the task way delayed. - * @return false Otherwise. A task will not be delayed if the next expected - * wake time is in the past. - * - * Example Usage - * @include Task/delayUntil.cpp - */ - inline bool delayUntil(const TickType_t timeIncrement = 0) { - return (xTaskDelayUntil(&previousWakeTime, timeIncrement) == pdTRUE); - } -#endif /* INCLUDE_xTaskDelayUntil */ - - /** - * Task.hpp - * - * @brief Function that calls uint32_t ulTaskNotifyTakeIndexed( - * UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t - * xTicksToWait ) - * - * @see - * - * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these - * functions to be available. - * - * Each task has a private array of "notification values" (or - * 'notifications'), each of which is a 32-bit unsigned integer (uint32_t). - * The constant configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of - * indexes in the array, and (for backward compatibility) defaults to 1 if - * left undefined. Prior to FreeRTOS V10.4.0 there was only one notification - * value per task. - * - * Events can be sent to a task using an intermediary object. Examples of - * such objects are queues, semaphores, mutexes and event groups. Task - * notifications are a method of sending an event directly to a task without - * the need for such an intermediary object. - * - * A notification sent to a task can optionally perform an action, such as - * update, overwrite or increment one of the task's notification values. In - * that way task notifications can be used to send data to a task, or be used - * as light weight and fast binary or counting semaphores. - * - * notifyTake() is intended for use when a task notification is used as a - * faster and lighter weight binary or counting semaphore alternative. Actual - * FreeRTOS semaphores are taken using the FreeRTOS::Semaphore::take() API - * function, the equivalent action that instead uses a task notification is - * notifyTake(). - * - * When task notifications are being used as a binary or counting semaphore - * equivalent then the task being notified should wait for the notification - * using the notificationTake() API function rather than the notifyWait() API - * function. - * - * notifyTake() can either clear the task's notification value at the array - * index specified by the indexToWaitOn parameter to zero on exit, in which - * case the notification value acts like a binary semaphore, or decrement the - * notification value on exit, in which case the notification value acts like - * a counting semaphore. - * - * A task can use notifyTake() to [optionally] block to wait for a - * notification. The task does not consume any CPU time while it is in the - * Blocked state. - * - * Where as notifyWait() will return when a notification is pending, - * notifyTake() will return when the task's notification value is not zero. - * - * @note Each notification within the array operates independently - a task - * can only block on one notification within the array at a time and will not - * be unblocked by a notification sent to any other array index. - * - * @param ticksToWait The maximum time to wait in the Blocked state for a - * notification to be received if a notification is not already pending when - * notifyTake() is called. The RTOS task does not consume any CPU time when - * it is in the Blocked state. The time is specified in RTOS tick periods. - * The pdMS_TO_TICKS() macro can be used to convert a time specified in - * milliseconds into a time specified in ticks. - * - * @param clearCountOnExit If an RTOS task notification is received and - * clearCountOnExit is set to false then the RTOS task's notification value is - * decremented before notifyTake() exits. This is equivalent to the value of a - * counting semaphore being decremented by a successful call to - * FreeRTOS::Semaphore::Take(). If an RTOS task notification is received and - * clearCountOnExit is set to true then the RTOS task's notification value is - * reset to 0 before notifyTake() exits. This is equivalent to the value of a - * binary semaphore being left at zero (or empty, or 'not available') after a - * successful call to FreeRTOS::Semaphore::Take(). - * - * @param index The index within the calling task's array of notification - * values on which the calling task will wait for a notification to be - * non-zero. index must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. - * - * @return NotificationBits The value of the task's notification value before - * it is decremented or cleared (see the description of clearCountOnExit) - * - * Example Usage - * @include Task/notifyTake.cpp - */ - inline static NotificationBits notifyTake( - const TickType_t ticksToWait = portMAX_DELAY, - const bool clearCountOnExit = true, const UBaseType_t index = 0) { - return NotificationBits( - ulTaskNotifyTakeIndexed(index, clearCountOnExit, ticksToWait)); - } - - private: - /** - * @brief Construct a new TaskBase object. This default constructor is - * deliberately private as this class is not intended to be instantiated or - * derived from by the user. Use FreeRTOS::Task or FreeRTOS::StaticTask as a - * base class for creating a task. - */ - TaskBase() = default; - - TaskBase(TaskBase&&) noexcept = default; - TaskBase& operator=(TaskBase&&) noexcept = default; - - /** - * Task.hpp - * - * @brief Destroy the Task object. - * - * @see - * - * If INCLUDE_vTaskDelete is defined as 1 and the task handle is not NULL, - * then the destructor will call void vTaskDelete( TaskHandle_t xTask - * ) See the RTOS Configuration documentation for more information. - * - * Calling void vTaskDelete( TaskHandle_t xTask ) will remove a task - * from the RTOS kernels management. The task being deleted will be removed - * from all ready, blocked, suspended and event lists. - * - * @note The idle task is responsible for freeing the RTOS kernel allocated - * memory from tasks that have been deleted. It is therefore important that - * the idle task is not starved of microcontroller processing time if your - * application makes any calls to void vTaskDelete( TaskHandle_t xTask - * ) Memory allocated by the task code is not automatically freed, and - * should be freed before the task is deleted. - * - * Example Usage - * @include Task/task.cpp - */ - ~TaskBase() { -#if (INCLUDE_vTaskDelete == 1) - - if (handle != NULL) { - vTaskDelete(handle); - } - -#endif /* INCLUDE_vTaskDelete */ - } - - /** - * @brief Handle used to refer to the task when using the FreeRTOS interface. - */ - TaskHandle_t handle = NULL; - - /** - * @brief Variable that holds the time at which the task was last unblocked. - */ - TickType_t previousWakeTime = 0; -}; - -#if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - -/** - * Task Task.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS task. - * - * Each task requires RAM that is used to hold the task state, and used by the - * task as its stack. If a task is created using this class then the required - * RAM is automatically allocated from the FreeRTOS heap. If a task is created - * using FreeRTOS::StaticTask() then the RAM is included in the object, so it - * can be statically allocated at compile time. See the Static Vs Dynamic - * allocation page for more information. - * - * @note This class is not intended to be instantiated by the user. The user - * should create a class that derives from this class and implement - * taskFunction(). - */ -class Task : public TaskBase { - public: - Task(const Task&) = delete; - Task& operator=(const Task&) = delete; - - /** - * @brief Function that checks the return value of the call to xTaskCreate in - * the constructor. This function should be called to ensure the task was - * created successfully before starting the scheduler. - * - * @return true If the task was created successfully. - * @return false If the task was not created successfully due to insufficient - * memory. - */ - bool isValid() const { return taskCreatedSuccessfully; } - - protected: - /** - * Task.hpp - * - * @brief Construct a new Task object by calling BaseType_t xTaskCreate( - * TaskFunction_t pvTaskCode, const char * const pcName, - * configSTACK_DEPTH_TYPE usStackDepth, void *pvParameters, BaseType_t - * uxPriority, TaskHandle_t *pxCreatedTask ) - * - * @see - * - * @warning The user should call isValid() on this object to verify that the - * task was created successfully in case the memory required to create the - * task could not be allocated. - * - * @note When calling xTaskCreate the constructor passes the - * this pointer as the task function argument. This pointer is used - * so that the interface function callTaskFunction() can invoke taskEntry() - * for this instance of the class. - * - * @param priority The priority at which the created task will execute. - * Priorities are asserted to be less than configMAX_PRIORITIES. If - * configASSERT is undefined, priorities are silently capped at - * (configMAX_PRIORITIES - 1). - * @param stackDepth The number of words (not bytes!) to allocate for use as - * the task's stack. For example, if the stack is 16-bits wide and stackDepth - * is 100, then 200 bytes will be allocated for use as the task's stack. As - * another example, if the stack is 32-bits wide and stackDepth is 400 then - * 1600 bytes will be allocated for use as the task's stack. The stack depth - * multiplied by the stack width must not exceed the maximum value that can be - * contained in a variable of type size_t. - * @param name A descriptive name for the task. This is mainly used to - * facilitate debugging, but can also be used to obtain a task handle. The - * maximum length of a task's name is defined by configMAX_TASK_NAME_LEN in - * FreeRTOSConfig.h. - * - * Example Usage - * @include Task/task.cpp - */ - explicit Task( - const UBaseType_t priority = tskIDLE_PRIORITY, - const configSTACK_DEPTH_TYPE stackDepth = configMINIMAL_STACK_SIZE, - const char* name = "") { - taskCreatedSuccessfully = (xTaskCreate(callTaskFunction, name, stackDepth, - this, priority, &handle) == pdPASS); - } - - ~Task() = default; - - Task(Task&&) noexcept = default; - Task& operator=(Task&&) noexcept = default; - - private: - bool taskCreatedSuccessfully = false; -}; - -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - -#if (configSUPPORT_STATIC_ALLOCATION == 1) - -/** - * StaticTask Task.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS task. - * - * Each task requires RAM that is used to hold the task state, and used by the - * task as its stack. If a task is created using this class then the RAM is - * included in the object. If a task is created using FreeRTOS::Task() then the - * required RAM is automatically allocated from the FreeRTOS heap. See the - * Static Vs Dynamic allocation page for more information. - * - * @note This class is not intended to be instantiated by the user. The user - * should create a class that derives from this class and implement - * taskFunction(). - * - * @warning This class contains the task's data structures (TCB) and the array - * used to store the task's stack, so any instace of this class or class derived - * from this class must be persistent (not declared on the stack of another - * function). - * - * @tparam N The number of indexes in the array of StackType_t used to - * store the stack for this task. - */ -template -class StaticTask : public TaskBase { - public: - StaticTask(const StaticTask&) = delete; - StaticTask& operator=(const StaticTask&) = delete; - - protected: - /** - * Task.hpp - * - * @brief Construct a new Task object by calling TaskHandle_t - * xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, - * const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t - * uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const - * pxTaskBuffer ) - * - * @see - * - * @note When calling xTaskCreateStatic the constructor passes the - * this pointer as the task function argument. This pointer is used - * so that the interface function callTaskFunction() can invoke taskEntry() - * for this instance of the class. - * - * @param priority The priority at which the created task will execute. - * Priorities are asserted to be less than configMAX_PRIORITIES. If - * configASSERT is undefined, priorities are silently capped at - * (configMAX_PRIORITIES - 1). - * @param name A descriptive name for the task. This is mainly used to - * facilitate debugging, but can also be used to obtain a task handle. The - * maximum length of a task's name is defined by configMAX_TASK_NAME_LEN in - * FreeRTOSConfig.h. - * - * Example Usage - * @include Task/staticTask.cpp - */ - explicit StaticTask(const UBaseType_t priority = tskIDLE_PRIORITY, - const char* name = "") { - handle = xTaskCreateStatic(callTaskFunction, name, N, this, priority, stack, - &taskBuffer); - } - ~StaticTask() = default; - - StaticTask(StaticTask&&) noexcept = default; - StaticTask& operator=(StaticTask&&) noexcept = default; - - private: - StaticTask_t taskBuffer; - StackType_t stack[N]; -}; - -#endif /* configSUPPORT_STATIC_ALLOCATION */ - -} // namespace FreeRTOS - -inline void callTaskFunction(void* task) { - static_cast(task)->taskEntry(); -} - -#endif // FREERTOS_TASK_HPP diff --git a/source/shoh/src/FreeRTOSCPP/Timer.hpp b/source/shoh/src/FreeRTOSCPP/Timer.hpp deleted file mode 100644 index 6bc67fe..0000000 --- a/source/shoh/src/FreeRTOSCPP/Timer.hpp +++ /dev/null @@ -1,928 +0,0 @@ -/* - * FreeRTOS-Cpp - * Copyright (C) 2021 Jon Enz. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * https://github.com/jonenz/FreeRTOS-Cpp - */ - -#ifndef FREERTOS_TIMER_HPP -#define FREERTOS_TIMER_HPP - -#include "FreeRTOS.h" -#include "timers.h" - -/** - * @brief C function that is used to interface this class with the FreeRTOS - * kernel. - * - * @note This function should not be called or referenced by the user. - * - * @param task Pointer to an instance of FreeRTOS::TimerBase. - */ -void callTimerFunction(TimerHandle_t timer); - -namespace FreeRTOS { - -/** - * @class TimerBase Timer.hpp - * - * @brief Base class that provides the standard task interface to - * FreeRTOS::Timer and FreeRTOS::StaticTimer. - * - * @note This class is not intended to be instantiated or derived from by the - * user. Use FreeRTOS::Timer or FreeRTOS::StaticTimer as a base class for a user - * implemented task. - */ -class TimerBase { - public: - friend class Timer; - friend class StaticTimer; - - TimerBase(const TimerBase&) = delete; - TimerBase& operator=(const TimerBase&) = delete; - - static void* operator new(size_t, void* ptr) { return ptr; } - static void* operator new[](size_t, void* ptr) { return ptr; } - static void* operator new(size_t) = delete; - static void* operator new[](size_t) = delete; - - /** - * Timer.hpp - * - * @brief Function that acts as the entry point of the timer instance. - * - * @note This function is only public so that it can be accessed by the C - * interface function callTimerFunction() and should not be called or - * referenced by the user. - */ - virtual inline void timerEntry() final { timerFunction(); } - - /** - * Timer.hpp - * - * @brief Function that checks the value of the timer handle. This function - * should be called to ensure the timer was created successfully. - * - * @return true If the timer was created successfully. - * @return false If the timer was not created successfully due to insufficient - * memory. - */ - inline bool isValid() const { return (handle != NULL); } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerIsTimerActive( - * TimerHandle_t xTimer ) - * - * @see - * - * Queries a software timer to see if it is active or dormant. - * - * A timer will be dormant if: - * -# It has been created but not started, or - * -# It is an expired one-shot timer that has not been restarted. - * - * @note Timers are created in the dormant state. The start(), reset(), - * startFromISR(), resetFromISR(), changePeriod() and changePeriodFromISR() - * API functions can all be used to transition a timer into the active state. - * - * @return false If the timer is dormant. - * @return true Otherwise. - * - * Example Usage - * @include Timer/isActive.cpp - */ - inline bool isActive() const { - return (xTimerIsTimerActive(handle) != pdFALSE); - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerStart( TimerHandle_t - * xTimer, TickType_t xBlockTime ) - * - * @see - * - * start() starts a timer. If the timer had already been started and was - * already in the active state, then start() has equivalent functionality to - * the reset() API function. - * - * Starting a timer ensures the timer is in the active state. If the timer is - * not stopped, deleted, or reset in the mean time, timerFunction() will get - * called 'n 'ticks after start() was called, where 'n' is the timers defined - * period. - * - * It is valid to call start() before the RTOS scheduler has been started, but - * when this is done the timer will not actually start until the RTOS - * scheduler is started, and the timers expiry time will be relative to when - * the RTOS scheduler is started, not relative to when start() was called. - * - * @param blockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the start command to be - * successfully sent to the timer command queue, should the queue already be - * full when start() was called. blockTime is ignored if start() is called - * before the RTOS scheduler is started. - * @return true If the command was successfully sent to the timer command - * queue. When the command is actually processed will depend on the priority - * of the timer service/daemon task relative to other tasks in the system, - * although the timers expiry time is relative to when start() is actually - * called. The timer service/daemon task priority is set by the - * configTIMER_TASK_PRIORITY configuration constant. - * @return false If the start command could not be sent to the timer command - * queue even after blockTime ticks had passed. - * - * Example Usage - * @include Timer/timer.cpp - */ - inline bool start(const TickType_t blockTime = 0) const { - return (xTimerStart(handle, blockTime) == pdPASS); - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerStartFromISR( TimerHandle_t - * xTimer, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * A version of start() that can be called from an interrupt service routine. - * - * @param higherPriorityTaskWoken The timer service/daemon task spends most of - * its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling startFromISR() writes a message to the timer command - * queue, so has the potential to transition the timer service/daemon task out - * of the Blocked state. If calling startFromISR() causes the timer - * service/daemon task to leave the Blocked state, and the timer service/ - * daemon task has a priority equal to or greater than the currently executing - * task (the task that was interrupted), then higherPriorityTaskWoken will get - * set to true internally within the startFromISR() function. If - * startFromISR() sets this value to true, then a context switch should be - * performed before the interrupt exits. - * @return true If the command was successfully sent to the timer command - * queue. When the command is actually processed will depend on the priority - * of the timer service/daemon task relative to other tasks in the system, - * although the timers expiry time is relative to when startFromISR() is - * actually called. The timer service/daemon task priority is set by the - * configTIMER_TASK_PRIORITY configuration constant. - * @return false If the start command could not be sent to the timer command - * queue. - * - * Example Usage - * @include Timer/startFromISR.cpp - */ - inline bool startFromISR(bool& higherPriorityTaskWoken) const { - BaseType_t taskWoken = pdFALSE; - bool result = (xTimerStartFromISR(handle, &taskWoken) == pdPASS); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerStartFromISR( TimerHandle_t - * xTimer, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline bool startFromISR() const { - return (xTimerStartFromISR(handle, NULL) == pdPASS); - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerStop( TimerHandle_t xTimer, - * TickType_t xBlockTime ) - * - * @see - * - * stop() stops a timer that was previously started using either of the - * start(), reset(), startFromISR(), resetFromISR(), changePeriod() and - * changePeriodFromISR() API functions. - * - * Stopping a timer ensures the timer is not in the active state. - * - * @param blockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the stop command to be - * successfully sent to the timer command queue, should the queue already be - * full when stop() was called. blockTime is ignored if stop() is called - * before the RTOS scheduler is started. - * @return true If the command was successfully sent to the timer command - * queue. When the command is actually processed will depend on the priority - * of the timer service/daemon task relative to other tasks in the system. The - * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * @return false If the stop command could not be sent to the timer command - * queue even after blockTime ticks had passed. - * - * Example Usage - * @include Timer/timer.cpp - */ - inline bool stop(const TickType_t blockTime = 0) const { - return (xTimerStop(handle, blockTime) == pdPASS); - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerStopFromISR( TimerHandle_t - * xTimer, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * A version of stop() that can be called from an interrupt service routine. - * - * @param higherPriorityTaskWoken The timer service/daemon task spends most of - * its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling stopFromISR() writes a message to the timer command - * queue, so has the potential to transition the timer service/daemon task out - * of the Blocked state. If calling stopFromISR() causes the timer - * service/daemon task to leave the Blocked state, and the timer service/ - * daemon task has a priority equal to or greater than the currently executing - * task (the task that was interrupted), then higherPriorityTaskWoken will get - * set to true internally within the stopFromISR() function. If stopFromISR() - * sets this value to true, then a context switch should be performed before - * the interrupt exits. - * @return true If the command was successfully sent to the timer command - * queue. When the command is actually processed will depend on the priority - * of the timer service/daemon task relative to other tasks in the system. The - * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * @return false If the start command could not be sent to the timer command - * queue. - * - * Example Usage - * @include Timer/stopFromISR.cpp - */ - inline bool stopFromISR(bool& higherPriorityTaskWoken) const { - BaseType_t taskWoken = pdFALSE; - bool result = (xTimerStopFromISR(handle, &taskWoken) == pdPASS); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerStopFromISR( TimerHandle_t - * xTimer, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline bool stopFromISR() const { - return (xTimerStopFromISR(handle, NULL) == pdPASS); - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerChangePeriod( TimerHandle_t - * xTimer, TickType_t xNewPeriod, TickType_t xBlockTime ) - * - * @see - * - * changePeriod() changes the period of a timer. - * - * changePeriod() can be called to change the period of an active or dormant - * state timer. Changing the period of a dormant timers will also start the - * timer. - * - * @param newPeriod The new period for timer. Timer periods are specified in - * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a - * time that has been specified in milliseconds. For example, if the timer - * must expire after 100 ticks, then newPeriod should be set to 100. - * Alternatively, if the timer must expire after 500ms, then newPeriod can be - * set to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less - * than or equal to 1000. - * @param blockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the change period command to be - * successfully sent to the timer command queue, should the queue already be - * full when changePeriod() was called. blockTime is ignored if changePeriod() - * is called before the RTOS scheduler is started. - * @return true If the command was successfully sent to the timer command - * queue. When the command is actually processed will depend on the priority - * of the timer service/daemon task relative to other tasks in the system. The - * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * @return false If the change period command could not be sent to the timer - * command queue even after blockTime ticks had passed. - * - * Example Usage - * @include Timer/changePeriod.cpp - */ - inline bool changePeriod(const TickType_t newPeriod, - const TickType_t blockTime = 0) const { - return (xTimerChangePeriod(handle, newPeriod, blockTime) == pdPASS); - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerChangePeriodFromISR( - * TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t - * *pxHigherPriorityTaskWoken ) - * - * @see - * - * - * A version of changePeriod() that can be called from an interrupt service - * routine. - * - * @param newPeriod The new period for timer. Timer periods are specified in - * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a - * time that has been specified in milliseconds. For example, if the timer - * must expire after 100 ticks, then newPeriod should be set to 100. - * Alternatively, if the timer must expire after 500ms, then newPeriod can be - * set to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less - * than or equal to 1000. - * @param higherPriorityTaskWoken The timer service/daemon task spends most of - * its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling changePeriodFromISR() writes a message to the timer - * command queue, so has the potential to transition the timer service/ daemon - * task out of the Blocked state. If calling changePeriodFromISR() causes the - * timer service/daemon task to leave the Blocked state, and the timer - * service/daemon task has a priority equal to or greater than the currently - * executing task (the task that was interrupted), then - * higherPriorityTaskWoken will get set to true internally within the - * changePeriodFromISR() function. If changePeriodFromISR() sets this value to - * true, then a context switch should be performed before the interrupt exits. - * @return true If the command was successfully sent to the timer command - * queue. When the command is actually processed will depend on the priority - * of the timer service/daemon task relative to other tasks in the system. The - * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * @return false If the change period command could not be sent to the timer - * command queue. - * - * Example Usage - * @include Timer/changePeriodFromISR.cpp - */ - inline bool changePeriodFromISR(bool& higherPriorityTaskWoken, - const TickType_t newPeriod) const { - BaseType_t taskWoken = pdFALSE; - bool result = - (xTimerChangePeriodFromISR(handle, newPeriod, &taskWoken) == pdPASS); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerChangePeriodFromISR( - * TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t - * *pxHigherPriorityTaskWoken ) - * - * @see - * - * - * @overload - */ - inline bool changePeriodFromISR(const TickType_t newPeriod) const { - return (xTimerChangePeriodFromISR(handle, newPeriod, NULL) == pdPASS); - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerDelete( TimerHandle_t - * xTimer, TickType_t xBlockTime ) - * - * @see - * - * deleteTimer() deletes a timer from the FreeRTOS timer task. - * - * @note This function is also called in the destructor of the timer using the - * deleteBlockTime specified when the object was created. This function - * should be used when the user wants to delete the timer from the FreeRTOS - * timer task without destroying the timer object or with a different block - * time than what was specified in the constructor. - * - * @param blockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the delete command to be - * successfully sent to the timer command queue, should the queue already be - * full when deleteTimer() was called. blockTime is ignored if deleteTimer() - * is called before the RTOS scheduler is started. - * @return true If the command was successfully sent to the timer command - * queue. When the command is actually processed will depend on the priority - * of the timer service/daemon task relative to other tasks in the system. The - * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * @return false If the delete command could not be sent to the timer command - * queue even after blockTime ticks had passed. - * - * Example Usage - * @include Timer/changePeriod.cpp - */ - inline bool deleteTimer(const TickType_t blockTime = 0) { - if (xTimerDelete(handle, blockTime) == pdPASS) { - handle = NULL; - return true; - } - return false; - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerReset( TimerHandle_t - * xTimer, TickType_t xBlockTime ) - * - * @see - * - * reset() re-starts a timer. If the timer had already been started and was - * already in the active state, then reset() will cause the timer to - * re-evaluate its expiry time so that it is relative to when reset() was - * called. If the timer was in the dormant state then reset() has equivalent - * functionality to the start() API function. - * - * Resetting a timer ensures the timer is in the active state. If the timer - * is not stopped, deleted, or reset in the mean time, the callback function - * associated with the timer will get called 'n' ticks after reset() was - * called, where 'n' is the timers defined period. - * - * It is valid to call reset() before the RTOS scheduler has been started, but - * when this is done the timer will not actually start until the RTOS - * scheduler is started, and the timers expiry time will be relative to when - * the RTOS scheduler is started, not relative to when reset() was called. - * - * @param blockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the reset command to be - * successfully sent to the timer command queue, should the queue already be - * full when reset() was called. blockTime is ignored if reset() is called - * before the RTOS scheduler is started. - * @return true If the command was successfully sent to the timer command - * queue. When the command is actually processed will depend on the priority - * of the timer service/daemon task relative to other tasks in the system, - * although the timers expiry time is relative to when reset() is actually - * called. The timer service/daemon task priority is set by the - * configTIMER_TASK_PRIORITY configuration constant. - * @return false If the reset command could not be sent to the timer command - * queue even after blockTime ticks had passed. - * - * Example Usage - * @include Timer/reset.cpp - */ - inline bool reset(const TickType_t blockTime = 0) const { - return (xTimerReset(handle, blockTime) == pdPASS); - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerResetFromISR( TimerHandle_t - * xTimer, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * A version of reset() that can be called from an interrupt service routine. - * - * @param higherPriorityTaskWoken The timer service/daemon task spends most of - * its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling resetFromISR() writes a message to the timer command - * queue, so has the potential to transition the timer service/daemon task out - * of the Blocked state. If calling resetFromISR() causes the timer - * service/daemon task to leave the Blocked state, and the timer - * service/daemon task has a priority equal to or greater than the currently - * executing task (the task that was interrupted), then - * higherPriorityTaskWoken will get set to true internally within the - * resetFromISR() function. If resetFromISR() sets this value to true, then a - * context switch should be performed before the interrupt exits. - * @return true If the command was successfully sent to the timer command - * queue. When the command is actually processed will depend on the priority - * of the timer service/daemon task relative to other tasks in the system, - * although the timers expiry time is relative to when resetFromISR() is - * actually called. The timer service/daemon task priority is set by the - * configTIMER_TASK_PRIORITY configuration constant. - * @return false If the change period command could not be sent to the timer - * command queue. - * - * Example Usage - * @include Timer/resetFromISR.cpp - */ - inline bool resetFromISR(bool& higherPriorityTaskWoken) const { - BaseType_t taskWoken = pdFALSE; - bool result = (xTimerResetFromISR(handle, &taskWoken) == pdPASS); - if (taskWoken == pdTRUE) { - higherPriorityTaskWoken = true; - } - return result; - } - - /** - * Timer.hpp - * - * @brief Function that calls BaseType_t xTimerResetFromISR( TimerHandle_t - * xTimer, BaseType_t *pxHigherPriorityTaskWoken ) - * - * @see - * - * @overload - */ - inline bool resetFromISR() const { - return (xTimerResetFromISR(handle, NULL) == pdPASS); - } - - /** - * Timer.hpp - * - * @brief Function that calls void vTimerSetReloadMode( TimerHandle_t - * xTimer, const UBaseType_t uxAutoReload ) - * - * @see - * - * Updates the 'mode' of a software timer to be either an auto reload timer or - * a one-shot timer. - * - * An auto reload timer resets itself each time it expires, causing the timer - * to expire (and therefore execute its callback) periodically. - * - * A one shot timer does not automatically reset itself, so will only expire - * (and therefore execute its callback) once unless it is manually restarted. - * - * @param autoReload Set autoReload to true to set the timer into auto reload - * mode, or false to set the timer into one shot mode. - */ - inline void setReloadMode(const bool autoReload) const { - vTimerSetReloadMode(handle, (autoReload ? pdTRUE : pdFALSE)); - } - - /** - * Timer.hpp - * - * @brief Function that calls const char * pcTimerGetName( TimerHandle_t - * xTimer ) - * - * @see - * - * Returns the human readable text name of a software timer. - * - * Text names are assigned to timers in the constructor. - * - * @return const char* A pointer to the text name of the timer as a standard - * NULL terminated C string. - * - * Example Usage - * @include Timer/getName.cpp - */ - inline const char* getName() const { return pcTimerGetName(handle); } - - /** - * Timer.hpp - * - * @brief Function that calls TickType_t xTimerGetPeriod( TimerHandle_t - * xTimer ) - * - * @see - * - * Returns the period of a software timer. The period is specified in ticks. - * - * The period of a timer is initially set using the period parameter of the - * constructor. It can then be changed using the changePeriod() and - * changePeriodFromISR() API functions. - * - * @return TickType_t The period of the timer, in ticks. - * - * Example Usage - * @include Timer/getPeriod.cpp - */ - inline TickType_t getPeriod() const { return xTimerGetPeriod(handle); } - - /** - * Timer.hpp - * - * @brief Function that calls TickType_t xTimerGetExpiryTime( - * TimerHandle_t xTimer ) - * - * @see - * - * Returns the time at which the software timer will expire, which is the time - * at which the timer's callback function will execute. - * - * If the value returned by getExpiryTime() is less than the current time then - * the timer will expire after the tick count has overflowed and wrapped back - * to 0. Overflows are handled in the RTOS implementation itself, so a timer's - * callback function will execute at the correct time whether it is before or - * after the tick count overflows. - * - * @return TickType_t If the timer is active, then the time at which the timer - * will next expire is returned (which may be after the current tick count has - * overflowed, see the notes above). If the timer is not active then the - * return value is undefined. - * - * Example Usage - * @include Timer/getExpiryTime.cpp - */ - inline TickType_t getExpiryTime() const { - return xTimerGetExpiryTime(handle); - } - - /** - * Timer.hpp - * - * @brief Function that calls UBaseType_t uxTimerGetReloadMode( - * TimerHandle_t xTimer ) - * - * @see - * - * Queries the 'mode' of the software timer. - * - * The mode can be either an auto-reloaded timer, which automatically resets - * itself each time it expires, or a one-shot timer, which will expire only - * once unless it is manually restarted. - * - * @return true If the timer is an auto-reload timer. - * @return false Otherwise. - */ - inline bool getReloadMode() const { - return (uxTimerGetReloadMode(handle) == pdTRUE); - } - - /** - * Timer.hpp - * - * @brief Set the delete block time. This value is used when the destructor - * calls deleteTimer(). - * - * @param deleteBlockTime Delete block time to be set in ticks. - */ - inline void setDeleteBlockTime(const TickType_t deleteBlockTime = 0) { - this->deleteBlockTime = deleteBlockTime; - } - - /** - * Timer.hpp - * - * @brief Set the delete block time. This value is used when the destructor - * calls deleteTimer(). - * - * @return TickType_t Delete block time in ticks. - */ - inline TickType_t getDeleteBlockTime() const { return deleteBlockTime; } - - protected: - /** - * Timer.hpp - * - * @brief Abstraction function that acts as the entry point of the timer - * callback for the user. - */ - virtual void timerFunction() = 0; - - private: - /** - * Timer.hpp - * - * @brief Construct a new TimerBase object. This default constructor is - * deliberately private as this class is not intended to be instantiated or - * derived from by the user. Use FreeRTOS::Timer or FreeRTOS::StaticTimer as - * a base class for creating a task. - * - * @param deleteBlockTime Set the delete block time. This value is used when - * the destructor calls deleteTimer(). - */ - explicit TimerBase(const TickType_t deleteBlockTime = 0) - : deleteBlockTime(deleteBlockTime) {} - - /** - * Timer.hpp - * - * @brief Destroy the TimerBase object. - * - * @note This destructor will check that the timer is still valid and has not - * already been deleted by deleteTimer() before calling the function. If the - * timer is still valid the destructor will call deleteTimer() and block for - * up to the amount of time specified by deleteBlockTime. - */ - ~TimerBase() { - if (isValid()) { - deleteTimer(getDeleteBlockTime()); - } - } - - TimerBase(TimerBase&&) noexcept = default; - TimerBase& operator=(TimerBase&&) noexcept = default; - - TimerHandle_t handle = NULL; - TickType_t deleteBlockTime; -}; - -#if (configSUPPORT_DYNAMIC_ALLOCATION == 1) - -/** - * Timer Timer.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS timer. - * - * Each software timer requires a small amount of RAM that is used to hold the - * timer's state. If a timer is created using this class then this RAM is - * automatically allocated from the FreeRTOS heap. If a software timer is - * created using FreeRTOS::StaticTimer() then the RAM is included in the object - * so it can be statically allocated at compile time. See the Static Vs Dynamic - * allocation page for more information. - * - * @note This class is not intended to be instantiated by the user. The user - * should create a class that derives from this class and implement - * timerFunction(). - */ -class Timer : public TimerBase { - public: - Timer(const Timer&) = delete; - Timer& operator=(const Timer&) = delete; - - protected: - /** - * Timer.hpp - * - * @brief Construct a new Timer object by calling TimerHandle_t - * xTimerCreate( const char * const pcTimerName, const TickType_t - * xTimerPeriod, const UBaseType_t uxAutoReload, void * const pvTimerID, - * TimerCallbackFunction_t pxCallbackFunction ) - * - * @see - * - * @warning The user should call isValid() on this object to verify that the - * timer was created successfully in case the memory required to create the - * timer could not be allocated. - * - * @note Timers are created in the dormant state. The start(), reset(), - * startFromISR(), resetFromISR(), changePeriod() and changePeriodFromISR() - * API functions can all be used to transition a timer into the active state. - * - * @note When calling xTimerCreate the constructor passes the - * this pointer as the pvTimerID argument. This pointer is used so - * that the interface function callTimerFunction() can invoke timerFunction() - * for this instance of the class. - * - * @param period The period of the timer. The period is specified in ticks, - * and the macro pdMS_TO_TICKS() can be used to convert a time specified in - * milliseconds to a time specified in ticks. For example, if the timer must - * expire after 100 ticks, then simply set period to 100. Alternatively, if - * the timer must expire after 500ms, then set period to pdMS_TO_TICKS( 500 ). - * pdMS_TO_TICKS() can only be used if configTICK_RATE_HZ is less than or - * equal to 1000. The timer period must be greater than 0. - * @param autoReload If autoReload is set to true, then the timer will expire - * repeatedly with a frequency set by the period parameter. If autoReload is - * set to false, then the timer will be a one-shot and enter the dormant state - * after it expires. - * @param name A human readable text name that is assigned to the timer. This - * is done purely to assist debugging. The RTOS kernel itself only ever - * references a timer by its handle, and never by its name. - * @param deleteBlockTime Specifies the time, in ticks, that the calling task - * should be held in the Blocked state to wait for the delete command to be - * successfully sent to the timer command queue, should the queue already be - * full when the destructor is called. deleteBlockTime is ignored if the - * destructor is called before the RTOS scheduler is started or if the timer - * has already been deleted by deleteTimer() before the destructor is called. - * This value can be updated by calling setDeleteBlockTime(). - * - * Example Usage - * @include Timer/timer.cpp - */ - explicit Timer(const TickType_t period, const bool autoReload = false, - const char* name = "", const TickType_t deleteBlockTime = 0) - : TimerBase(deleteBlockTime) { - this->handle = xTimerCreate(name, period, (autoReload ? pdTRUE : pdFALSE), - this, callTimerFunction); - } - ~Timer() = default; - - Timer(Timer&&) noexcept = default; - Timer& operator=(Timer&&) noexcept = default; -}; - -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ - -#if (configSUPPORT_STATIC_ALLOCATION == 1) - -/** - * Timer Timer.hpp - * - * @brief Class that encapsulates the functionality of a FreeRTOS timer. - * - * Each software timer requires a small amount of RAM that is used to hold the - * timer's state. If a timer is created using FreeRTOS::Timer() then this RAM is - * automatically allocated from the FreeRTOS heap. If a software timer is - * created this class then the RAM is included in the object so it can be - * statically allocated at compile time. See the Static Vs Dynamic allocation - * page for more information. - * - * @note This class is not intended to be instantiated by the user. The user - * should create a class that derives from this class and implement - * timerFunction(). - * - * @warning This class contains the timer data structure, so any instance of - * this class or class derived from this class should be persistent (not - * declared on the stack of another function). - */ -class StaticTimer : public TimerBase { - public: - StaticTimer(const StaticTimer&) = delete; - StaticTimer& operator=(const StaticTimer&) = delete; - - protected: - /** - * Timer.hpp - * - * @brief Construct a new StaticTimer object by calling TimerHandle_t - * xTimerCreateStatic( const char * const pcTimerName, const TickType_t - * xTimerPeriod, const UBaseType_t uxAutoReload, void * const pvTimerID, - * TimerCallbackFunction_t pxCallbackFunction StaticTimer_t *pxTimerBuffer - * ) - * - * @see - * - * @note When calling xTimerCreateStatic the constructor passes the - * this pointer as the pvTimerID argument. This pointer is used so - * that the interface function callTimerFunction() can invoke timerFunction() - * for this instance of the class. - * - * @note Timers are created in the dormant state. The start(), reset(), - * startFromISR(), resetFromISR(), changePeriod() and changePeriodFromISR() - * API functions can all be used to transition a timer into the active state. - * - * @param period The period of the timer. The period is specified in ticks, - * and the macro pdMS_TO_TICKS() can be used to convert a time specified in - * milliseconds to a time specified in ticks. For example, if the timer must - * expire after 100 ticks, then simply set period to 100. Alternatively, if - * the timer must expire after 500ms, then set period to pdMS_TO_TICKS( 500 ). - * pdMS_TO_TICKS() can only be used if configTICK_RATE_HZ is less than or - * equal to 1000. The timer period must be greater than 0. - * @param autoReload If autoReload is set to true, then the timer will expire - * repeatedly with a frequency set by the period parameter. If autoReload is - * set to false, then the timer will be a one-shot and enter the dormant state - * after it expires. - * @param name A human readable text name that is assigned to the timer. This - * is done purely to assist debugging. The RTOS kernel itself only ever - * references a timer by its handle, and never by its name. - * @param deleteBlockTime Specifies the time, in ticks, that the calling task - * should be held in the Blocked state to wait for the delete command to be - * successfully sent to the timer command queue, should the queue already be - * full when the destructor is called. deleteBlockTime is ignored if the - * destructor is called before the RTOS scheduler is started or if the timer - * has already been deleted by deleteTimer() before the destructor is called. - * This value can be updated by calling setDeleteBlockTime(). - * - * Example Usage - * @include Timer/staticTimer.cpp - */ - explicit StaticTimer(const TickType_t period, const bool autoReload = false, - const char* name = "", - const TickType_t deleteBlockTime = 0) - : TimerBase(deleteBlockTime) { - this->handle = - xTimerCreateStatic(name, period, (autoReload ? pdTRUE : pdFALSE), this, - callTimerFunction, &staticTimer); - } - ~StaticTimer() = default; - - StaticTimer(StaticTimer&&) noexcept = default; - StaticTimer& operator=(StaticTimer&&) noexcept = default; - - private: - StaticTimer_t staticTimer; -}; - -#endif /* configSUPPORT_STATIC_ALLOCATION */ - -} // namespace FreeRTOS - -inline void callTimerFunction(TimerHandle_t timer) { - static_cast(pvTimerGetTimerID(timer))->timerEntry(); -} - -#endif // FREERTOS_TIMER_HPP diff --git a/source/shoh/src/main.cpp b/source/shoh/src/main.cpp index fb5ea66..81ea5a8 100644 --- a/source/shoh/src/main.cpp +++ b/source/shoh/src/main.cpp @@ -3,18 +3,21 @@ #include "FreeRTOS.h" #include "task.h" #include -#include "Kernel.hpp" +#include "common/ThreadCommon.h" #include "Master.h" + int main(void) { SystemCoreClockUpdate(); Board_Init(); - // Create a task before starting the kernel. - Master master; - + ThreadCommon::ThreadManager manager; + manager.createTask(master_thread, "master", + configMINIMAL_STACK_SIZE * 10,tskIDLE_PRIORITY + 1UL, + nullptr); // Start the real time kernel with preemption. - FreeRTOS::Kernel::startScheduler(); + //FreeRTOS::Kernel::startScheduler(); + vTaskStartScheduler (); return 1; } diff --git a/source/shoh/src/threads/common/ThreadCommon.h b/source/shoh/src/threads/common/ThreadCommon.h index 634b627..d8fe51f 100644 --- a/source/shoh/src/threads/common/ThreadCommon.h +++ b/source/shoh/src/threads/common/ThreadCommon.h @@ -4,7 +4,16 @@ * Created on: 13 Apr 2023 * Author: tylen */ + +#ifndef __THREAD_COMMON_H_ +#define __THREAD_COMMON_H_ + #include "board.h" +#include "FreeRTOS.h" +#include +#include "queue.h" +#include "task.h" +#include namespace ThreadCommon { @@ -38,4 +47,26 @@ namespace ThreadCommon ThreadCommon::EventType _type; uint8_t _data; }; + + class ThreadManager + { + public: + ThreadManager(); + ~ThreadManager() = default; + bool createTask(void (*task_func)(void*), + std::string name, + size_t stack_size, + size_t priority, + void* parameters); + private: + }; + + /* global variables */ + /* 'receiver'_'what'_'sender'_q */ + extern QueueHandle_t master_event_all_q; + extern QueueHandle_t relay_event_master_q; + extern QueueHandle_t manager_event_master_q; + extern QueueHandle_t ui_event_manager_q; } + +#endif /*__THREAD_COMMON_H_*/ diff --git a/source/shoh/src/threads/common/ThreadManager.cpp b/source/shoh/src/threads/common/ThreadManager.cpp new file mode 100644 index 0000000..2ac2803 --- /dev/null +++ b/source/shoh/src/threads/common/ThreadManager.cpp @@ -0,0 +1,21 @@ +#include "ThreadCommon.h" + + +ThreadCommon::ThreadManager::ThreadManager(){} + +bool ThreadCommon::ThreadManager::createTask(void (*task_func)(void*), + std::string name, + size_t stack_size, + size_t priority, + void* parameters) +{ + const char * t_name = name.c_str(); + BaseType_t taskCreated = xTaskCreate(task_func, + t_name, + stack_size, + parameters, + priority, + NULL); + assert(taskCreated == pdPASS); + return (taskCreated == pdPASS); +} diff --git a/source/shoh/src/threads/master/Master.cpp b/source/shoh/src/threads/master/Master.cpp index 62e4e0a..1ef3bc0 100644 --- a/source/shoh/src/threads/master/Master.cpp +++ b/source/shoh/src/threads/master/Master.cpp @@ -8,6 +8,7 @@ #include "Master.h" void Master::taskFunction() { + int led = 0; bool LedState = true; for (;;) { Board_LED_Set(led, LedState); @@ -20,3 +21,8 @@ void Master::taskFunction() { } } + +void master_thread(void* pvParams) { + Master m; + m.taskFunction(); +} \ No newline at end of file diff --git a/source/shoh/src/threads/master/Master.h b/source/shoh/src/threads/master/Master.h index ef81d73..bcc173d 100644 --- a/source/shoh/src/threads/master/Master.h +++ b/source/shoh/src/threads/master/Master.h @@ -10,27 +10,23 @@ #include "chip.h" #include "board.h" -#include "FreeRTOSCPP/Task.hpp" -#include "FreeRTOSCPP/Kernel.hpp" #include "threads/common/ThreadCommon.h" #include "task.h" +#include - -class Master : public FreeRTOS::Task { +class Master { public: - Master(): FreeRTOS::Task((tskIDLE_PRIORITY + 1UL), - configMINIMAL_STACK_SIZE * 10, - "master"){}; + Master(){}; virtual ~Master() = default; - - Master(Master&&) noexcept = default; - Master& operator=(Master&&) noexcept = default; - void taskFunction(); + + //Master(Master&&) noexcept = default; + //Master& operator=(Master&&) noexcept = default; private: - int led; - //std::shared_ptr message; + ThreadCommon::Event* message; }; +void master_thread(void* pvParams); + #endif /* THREADS_MASTER_MASTER_H_ */