diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index 2a5ca3bd..9c2afe10 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.cpp +++ b/osal/FreeRTOS/BinSemaphUsingTask.cpp @@ -1,7 +1,6 @@ #include #include - BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() { handle = TaskManagement::getCurrentTaskHandle(); xTaskNotifyGive(handle); @@ -9,44 +8,29 @@ BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() { } ReturnValue_t BinarySemaphoreUsingTask::acquire(uint32_t timeoutMs) { - return takeBinarySemaphore(timeoutMs); -} - -ReturnValue_t BinarySemaphoreUsingTask::release() { - return giveBinarySemaphore(); -} - -ReturnValue_t BinarySemaphoreUsingTask::takeBinarySemaphore(uint32_t timeoutMs) { TickType_t timeout = SemaphoreIF::NO_TIMEOUT; if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { - timeout = SemaphoreIF::MAX_TIMEOUT; + timeout = SemaphoreIF::MAX_TIMEOUT; } else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){ - timeout = pdMS_TO_TICKS(timeoutMs); - } - - BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeout); - if (returncode == pdPASS) { - locked = true; - return HasReturnvaluesIF::RETURN_OK; - } - else { - return SemaphoreIF::SEMAPHORE_TIMEOUT; + timeout = pdMS_TO_TICKS(timeoutMs); } + return acquireWithTickTimeout(timeout); } -ReturnValue_t BinarySemaphoreUsingTask::takeBinarySemaphoreTickTimeout( +ReturnValue_t BinarySemaphoreUsingTask::acquireWithTickTimeout( TickType_t timeoutTicks) { BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeoutTicks); if (returncode == pdPASS) { locked = true; return HasReturnvaluesIF::RETURN_OK; - } else { - return SEMAPHORE_TIMEOUT; + } + else { + return SemaphoreIF::SEMAPHORE_TIMEOUT; } } -ReturnValue_t BinarySemaphoreUsingTask::giveBinarySemaphore() { +ReturnValue_t BinarySemaphoreUsingTask::release() { if(not locked) { return SemaphoreIF::SEMAPHORE_NOT_OWNED; } @@ -69,7 +53,9 @@ uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter() const { return notificationValue; } -uint8_t BinarySemaphoreUsingTask::getSemaphoreCounterFromISR(TaskHandle_t taskHandle) { + +uint8_t BinarySemaphoreUsingTask::getSemaphoreCounterFromISR( + TaskHandle_t taskHandle) { uint32_t notificationValue; BaseType_t higherPriorityTaskWoken; xTaskNotifyAndQueryFromISR(taskHandle, 0, eNoAction, ¬ificationValue, @@ -80,8 +66,8 @@ uint8_t BinarySemaphoreUsingTask::getSemaphoreCounterFromISR(TaskHandle_t taskHa return notificationValue; } - -ReturnValue_t BinarySemaphoreUsingTask::giveBinarySemaphore(TaskHandle_t taskHandle) { +ReturnValue_t BinarySemaphoreUsingTask::release( + TaskHandle_t taskHandle) { BaseType_t returncode = xTaskNotifyGive(taskHandle); if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; @@ -93,7 +79,7 @@ ReturnValue_t BinarySemaphoreUsingTask::giveBinarySemaphore(TaskHandle_t taskHan } // Be careful with the stack size here. This is called from an ISR! -ReturnValue_t BinarySemaphoreUsingTask::giveBinarySemaphoreFromISR( +ReturnValue_t BinarySemaphoreUsingTask::releaseFromISR( TaskHandle_t taskHandle, BaseType_t * higherPriorityTaskWoken) { vTaskNotifyGiveFromISR(taskHandle, higherPriorityTaskWoken); if(*higherPriorityTaskWoken == pdPASS) { diff --git a/osal/FreeRTOS/BinSemaphUsingTask.h b/osal/FreeRTOS/BinSemaphUsingTask.h index b65d4d80..cb6f6287 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.h +++ b/osal/FreeRTOS/BinSemaphUsingTask.h @@ -27,35 +27,17 @@ public: SemaphoreIF::NO_TIMEOUT) override; ReturnValue_t release() override; uint8_t getSemaphoreCounter() const override; + static uint8_t getSemaphoreCounterFromISR(TaskHandle_t taskHandle); /** - * Take the binary semaphore. - * If the semaphore has already been taken, the task will be blocked - * for a maximum of #timeoutMs or until the semaphore is given back, - * for example by an ISR or another task. - * @param timeoutMs - * @return -@c RETURN_OK on success - * -@c RETURN_FAILED on failure - */ - ReturnValue_t takeBinarySemaphore(uint32_t timeoutMs = - SemaphoreIF::NO_TIMEOUT); - - /** - * Same as lockBinarySemaphore() with timeout in FreeRTOS ticks. + * Same as acquire() with timeout in FreeRTOS ticks. * @param timeoutTicks * @return - @c RETURN_OK on success * - @c RETURN_FAILED on failure */ - ReturnValue_t takeBinarySemaphoreTickTimeout(TickType_t timeoutTicks = + ReturnValue_t acquireWithTickTimeout(TickType_t timeoutTicks = SemaphoreIF::NO_TIMEOUT); - /** - * Give back the binary semaphore - * @return - @c RETURN_OK on success - * - @c RETURN_FAILED on failure - */ - ReturnValue_t giveBinarySemaphore(); - /** * Get handle to the task related to the semaphore. * @return @@ -68,7 +50,7 @@ public: * @return - @c RETURN_OK on success * - @c RETURN_FAILED on failure */ - static ReturnValue_t giveBinarySemaphore(TaskHandle_t taskToNotify); + static ReturnValue_t release(TaskHandle_t taskToNotify); /** * Wrapper function to give back semaphore from handle when called from an ISR @@ -78,11 +60,9 @@ public: * @return - @c RETURN_OK on success * - @c RETURN_FAILED on failure */ - static ReturnValue_t giveBinarySemaphoreFromISR(TaskHandle_t taskToNotify, + static ReturnValue_t releaseFromISR(TaskHandle_t taskToNotify, BaseType_t * higherPriorityTaskWoken); - static uint8_t getSemaphoreCounterFromISR(TaskHandle_t taskHandle); - protected: TaskHandle_t handle; // This boolean is required to track whether the semaphore is locked @@ -90,6 +70,4 @@ protected: bool locked; }; - - #endif /* FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */ diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index 0d8d415c..8891b755 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -43,21 +43,13 @@ ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { timeout = SemaphoreIF::MAX_TIMEOUT; } - else if(timeoutMs > BinarySemaphore::NO_TIMEOUT){ + else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){ timeout = pdMS_TO_TICKS(timeoutMs); } - - BaseType_t returncode = xSemaphoreTake(handle, timeout); - if (returncode == pdPASS) { - return HasReturnvaluesIF::RETURN_OK; - } - else { - return SemaphoreIF::SEMAPHORE_TIMEOUT; - } + return acquireWithTickTimeout(timeout); } -ReturnValue_t BinarySemaphore::acquireWithTickTimeout( - TickType_t timeoutTicks) { +ReturnValue_t BinarySemaphore::acquireWithTickTimeout(TickType_t timeoutTicks) { if(handle == nullptr) { return SemaphoreIF::SEMAPHORE_NULLPOINTER; } @@ -65,20 +57,22 @@ ReturnValue_t BinarySemaphore::acquireWithTickTimeout( BaseType_t returncode = xSemaphoreTake(handle, timeoutTicks); if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; - } else { + } + else { return SemaphoreIF::SEMAPHORE_TIMEOUT; } } ReturnValue_t BinarySemaphore::release() { if (handle == nullptr) { - return SEMAPHORE_NULLPOINTER; + return SemaphoreIF::SEMAPHORE_NULLPOINTER; } BaseType_t returncode = xSemaphoreGive(handle); if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; - } else { - return SEMAPHORE_NOT_OWNED; + } + else { + return SemaphoreIF::SEMAPHORE_NOT_OWNED; } } diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.cpp b/osal/FreeRTOS/CountingSemaphUsingTask.cpp index d08a549e..9beca310 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.cpp +++ b/osal/FreeRTOS/CountingSemaphUsingTask.cpp @@ -2,7 +2,7 @@ #include #include -CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(uint8_t maxCount, +CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t maxCount, uint8_t initCount): maxCount(maxCount) { if(initCount > maxCount) { sif::error << "CountingSemaphoreUsingTask: Max count bigger than " @@ -17,13 +17,93 @@ CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(uint8_t maxCount, } ReturnValue_t CountingSemaphoreUsingTask::acquire(uint32_t timeoutMs) { - return HasReturnvaluesIF::RETURN_OK; + TickType_t timeout = SemaphoreIF::NO_TIMEOUT; + if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { + timeout = SemaphoreIF::MAX_TIMEOUT; + } + else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){ + timeout = pdMS_TO_TICKS(timeoutMs); + } + + 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--; + return HasReturnvaluesIF::RETURN_OK; + } + else { + return SemaphoreIF::SEMAPHORE_TIMEOUT; + } } ReturnValue_t CountingSemaphoreUsingTask::release() { - return HasReturnvaluesIF::RETURN_OK; + if(currentCount == maxCount) { + return SemaphoreIF::SEMAPHORE_NOT_OWNED; + } + BaseType_t returncode = xTaskNotifyGive(handle); + if (returncode == pdPASS) { + currentCount++; + return HasReturnvaluesIF::RETURN_OK; + } + else { + // This should never happen + return HasReturnvaluesIF::RETURN_FAILED; + } } uint8_t CountingSemaphoreUsingTask::getSemaphoreCounter() const { - return 0; + uint32_t notificationValue; + xTaskNotifyAndQuery(handle, 0, eNoAction, ¬ificationValue); + return notificationValue; +} + +TaskHandle_t CountingSemaphoreUsingTask::getTaskHandle() { + return handle; +} + + +uint8_t CountingSemaphoreUsingTask::getSemaphoreCounterFromISR( + TaskHandle_t task) { + uint32_t notificationValue; + BaseType_t higherPriorityTaskWoken = 0; + xTaskNotifyAndQueryFromISR(task, 0, eNoAction, ¬ificationValue, + &higherPriorityTaskWoken); + if(higherPriorityTaskWoken == pdTRUE) { + TaskManagement::requestContextSwitch(CallContext::isr); + } + return notificationValue; +} + +ReturnValue_t CountingSemaphoreUsingTask::release( + TaskHandle_t taskToNotify) { + BaseType_t returncode = xTaskNotifyGive(taskToNotify); + if (returncode == pdPASS) { + return HasReturnvaluesIF::RETURN_OK; + } + else { + // This should never happen. + return HasReturnvaluesIF::RETURN_FAILED; + } +} + +ReturnValue_t CountingSemaphoreUsingTask::releaseFromISR( + TaskHandle_t taskToNotify, BaseType_t* higherPriorityTaskWoken) { + vTaskNotifyGiveFromISR(taskToNotify, higherPriorityTaskWoken); + if(*higherPriorityTaskWoken == pdPASS) { + // Request context switch because unblocking the semaphore + // caused a high priority task unblock. + TaskManagement::requestContextSwitch(CallContext::isr); + } + return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.h b/osal/FreeRTOS/CountingSemaphUsingTask.h index 877a975e..ac0425b5 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.h +++ b/osal/FreeRTOS/CountingSemaphUsingTask.h @@ -11,11 +11,39 @@ extern "C" { class CountingSemaphoreUsingTask: public SemaphoreIF { public: - CountingSemaphoreUsingTask(uint8_t maxCount, uint8_t initCount); + CountingSemaphoreUsingTask(const uint8_t maxCount, uint8_t initCount); - ReturnValue_t acquire(uint32_t timeoutMs) override; + ReturnValue_t acquire(uint32_t timeoutMs = SemaphoreIF::NO_TIMEOUT) override; ReturnValue_t release() override; uint8_t getSemaphoreCounter() const override; + static uint8_t getSemaphoreCounterFromISR(TaskHandle_t task); + /** + * Acquire, using a timeout value in ticks + * @param timeoutTicks + * @return + */ + ReturnValue_t acquireWithTickTimeout( + TickType_t timeoutTicks= SemaphoreIF::NO_TIMEOUT); + + /** + * Get handle to the task related to the semaphore. + * @return + */ + TaskHandle_t getTaskHandle(); + + /** + * Release semaphore of task by supplying task handle + * @param taskToNotify + * @return + */ + static ReturnValue_t release(TaskHandle_t taskToNotify); + /** + * Release seamphore of a task from an ISR. + * @param taskToNotify + * @return + */ + static ReturnValue_t releaseFromISR(TaskHandle_t taskToNotify, + BaseType_t* higherPriorityTaskWoken); private: TaskHandle_t handle; diff --git a/osal/FreeRTOS/CountingSemaphore.cpp b/osal/FreeRTOS/CountingSemaphore.cpp index 2f0dfd76..a23f32a0 100644 --- a/osal/FreeRTOS/CountingSemaphore.cpp +++ b/osal/FreeRTOS/CountingSemaphore.cpp @@ -8,16 +8,17 @@ extern "C" { // Make sure #define configUSE_COUNTING_SEMAPHORES 1 is set in // free FreeRTOSConfig.h file. -CountingSemaphore::CountingSemaphore(uint8_t count, uint8_t initCount): - count(count), initCount(initCount) { - handle = xSemaphoreCreateCounting(count, initCount); +CountingSemaphore::CountingSemaphore(const uint8_t maxCount, uint8_t initCount): + maxCount(maxCount), initCount(initCount) { + handle = xSemaphoreCreateCounting(maxCount, initCount); if(handle == nullptr) { sif::error << "CountingSemaphore: Creation failure" << std::endl; } } -CountingSemaphore::CountingSemaphore(CountingSemaphore&& other) { - handle = xSemaphoreCreateCounting(other.count, other.initCount); +CountingSemaphore::CountingSemaphore(CountingSemaphore&& other): + maxCount(other.maxCount), initCount(other.initCount) { + handle = xSemaphoreCreateCounting(other.maxCount, other.initCount); if(handle == nullptr) { sif::error << "CountingSemaphore: Creation failure" << std::endl; } @@ -25,7 +26,7 @@ CountingSemaphore::CountingSemaphore(CountingSemaphore&& other) { CountingSemaphore& CountingSemaphore::operator =( CountingSemaphore&& other) { - handle = xSemaphoreCreateCounting(other.count, other.initCount); + handle = xSemaphoreCreateCounting(other.maxCount, other.initCount); if(handle == nullptr) { sif::error << "CountingSemaphore: Creation failure" << std::endl; } diff --git a/osal/FreeRTOS/CountingSemaphore.h b/osal/FreeRTOS/CountingSemaphore.h index a33a0fa5..77050f90 100644 --- a/osal/FreeRTOS/CountingSemaphore.h +++ b/osal/FreeRTOS/CountingSemaphore.h @@ -12,7 +12,7 @@ */ class CountingSemaphore: public BinarySemaphore { public: - CountingSemaphore(uint8_t count, uint8_t initCount); + CountingSemaphore(const uint8_t maxCount, uint8_t initCount); //! @brief Copy ctor, disabled CountingSemaphore(const CountingSemaphore&) = delete; //! @brief Copy assignment, disabled @@ -22,7 +22,7 @@ public: //! @brief Move assignment CountingSemaphore & operator=(CountingSemaphore &&); private: - uint8_t count = 0; + const uint8_t maxCount; uint8_t initCount = 0; }; diff --git a/tasks/SemaphoreFactory.h b/tasks/SemaphoreFactory.h index 75bbe25d..3e21be36 100644 --- a/tasks/SemaphoreFactory.h +++ b/tasks/SemaphoreFactory.h @@ -23,7 +23,7 @@ public: * @param argument Can be used to pass implementation specific information. * @return Pointer to newly created semaphore class instance. */ - SemaphoreIF* createBinarySemaphore(uint32_t argument = 0); + SemaphoreIF* createBinarySemaphore(uint32_t arguments = 0); /** * Create a counting semaphore. * Creator functons for a counting semaphore which may be acquired multiple @@ -33,8 +33,8 @@ public: * @param argument Can be used to pass implementation specific information. * @return */ - SemaphoreIF* createCountingSemaphore(uint8_t maxCount, uint8_t initCount, - uint32_t argument = 0); + SemaphoreIF* createCountingSemaphore(const uint8_t maxCount, + uint8_t initCount, uint32_t arguments = 0); void deleteSemaphore(SemaphoreIF* mutex);