diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index 9c2afe10..84b0b488 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.cpp +++ b/osal/FreeRTOS/BinSemaphUsingTask.cpp @@ -1,12 +1,22 @@ #include #include +#include BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() { handle = TaskManagement::getCurrentTaskHandle(); + if(handle == nullptr) { + sif::error << "Could not retrieve task handle. Please ensure the" + "constructor was called inside a task." << std::endl; + } xTaskNotifyGive(handle); locked = false; } +BinarySemaphoreUsingTask::~BinarySemaphoreUsingTask() { + // Clear notification value on destruction. + xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite, nullptr); +} + ReturnValue_t BinarySemaphoreUsingTask::acquire(uint32_t timeoutMs) { TickType_t timeout = SemaphoreIF::NO_TIMEOUT; if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { diff --git a/osal/FreeRTOS/BinSemaphUsingTask.h b/osal/FreeRTOS/BinSemaphUsingTask.h index cb6f6287..cad42783 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.h +++ b/osal/FreeRTOS/BinSemaphUsingTask.h @@ -10,7 +10,9 @@ extern "C" { } /** - * @brief Binary Semaphore implementation using Task Notifications + * @brief Binary Semaphore implementation using the task notification value. + * The notification value should therefore not be used + * for other purposes. * @details * Additional information: https://www.freertos.org/RTOS-task-notifications.html * and general semaphore documentation. @@ -22,6 +24,8 @@ public: //! @brief Default ctor BinarySemaphoreUsingTask(); + //! @brief Default dtor + virtual~ BinarySemaphoreUsingTask(); ReturnValue_t acquire(uint32_t timeoutMs = SemaphoreIF::NO_TIMEOUT) override; diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.cpp b/osal/FreeRTOS/CountingSemaphUsingTask.cpp index 9beca310..c29f5258 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.cpp +++ b/osal/FreeRTOS/CountingSemaphUsingTask.cpp @@ -9,13 +9,35 @@ CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t maxCount, "intial cout. Setting initial count to max count." << std::endl; initCount = maxCount; } + handle = TaskManagement::getCurrentTaskHandle(); + if(handle == nullptr) { + sif::error << "Could not retrieve task handle. Please ensure the" + "constructor was called inside a task." << std::endl; + } + + uint32_t oldNotificationValue; + xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite, + &oldNotificationValue); + if(oldNotificationValue != 0) { + sif::warning << "Semaphore initiated but current notification value" + " is not 0. Please ensure the notification value is not used" + "for other purposes!" << std::endl; + } + while(currentCount != initCount) { xTaskNotifyGive(handle); currentCount++; } } +CountingSemaphoreUsingTask::~CountingSemaphoreUsingTask() { + // Clear notification value on destruction. + // If this is not desired, don't call the destructor + // (or implement a boolea which disables the reset) + xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite, nullptr); +} + ReturnValue_t CountingSemaphoreUsingTask::acquire(uint32_t timeoutMs) { TickType_t timeout = SemaphoreIF::NO_TIMEOUT; if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { @@ -24,22 +46,16 @@ ReturnValue_t CountingSemaphoreUsingTask::acquire(uint32_t timeoutMs) { else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){ timeout = pdMS_TO_TICKS(timeoutMs); } + return acquireWithTickTimeout(timeout); - BaseType_t returncode = ulTaskNotifyTake(pdFALSE, timeout); - if (returncode == pdPASS) { - currentCount--; - return HasReturnvaluesIF::RETURN_OK; - } - else { - return SemaphoreIF::SEMAPHORE_TIMEOUT; - } } ReturnValue_t CountingSemaphoreUsingTask::acquireWithTickTimeout( TickType_t timeoutTicks) { - BaseType_t returncode = ulTaskNotifyTake(pdFALSE, timeoutTicks); - if (returncode == pdPASS) { - currentCount--; + // Decrement notfication value without resetting it. + BaseType_t oldCount = ulTaskNotifyTake(pdFALSE, timeoutTicks); + if (getSemaphoreCounter() == oldCount - 1) { + currentCount --; return HasReturnvaluesIF::RETURN_OK; } else { @@ -63,7 +79,7 @@ ReturnValue_t CountingSemaphoreUsingTask::release() { } uint8_t CountingSemaphoreUsingTask::getSemaphoreCounter() const { - uint32_t notificationValue; + uint32_t notificationValue = 0; xTaskNotifyAndQuery(handle, 0, eNoAction, ¬ificationValue); return notificationValue; } diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.h b/osal/FreeRTOS/CountingSemaphUsingTask.h index ac0425b5..2c54b31b 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.h +++ b/osal/FreeRTOS/CountingSemaphUsingTask.h @@ -9,9 +9,18 @@ extern "C" { #include } +/** + * @brief Couting Semaphore implementation which uses the notification value + * of the task. The notification value should therefore not be used + * for other purposes + * @details + * Additional information: https://www.freertos.org/RTOS-task-notifications.html + * and general semaphore documentation. + */ class CountingSemaphoreUsingTask: public SemaphoreIF { public: CountingSemaphoreUsingTask(const uint8_t maxCount, uint8_t initCount); + virtual ~CountingSemaphoreUsingTask(); ReturnValue_t acquire(uint32_t timeoutMs = SemaphoreIF::NO_TIMEOUT) override; ReturnValue_t release() override;