diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index 84b0b488..51a3c563 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.cpp +++ b/osal/FreeRTOS/BinSemaphUsingTask.cpp @@ -9,7 +9,6 @@ BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() { "constructor was called inside a task." << std::endl; } xTaskNotifyGive(handle); - locked = false; } BinarySemaphoreUsingTask::~BinarySemaphoreUsingTask() { @@ -32,7 +31,6 @@ ReturnValue_t BinarySemaphoreUsingTask::acquireWithTickTimeout( TickType_t timeoutTicks) { BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeoutTicks); if (returncode == pdPASS) { - locked = true; return HasReturnvaluesIF::RETURN_OK; } else { @@ -41,43 +39,14 @@ ReturnValue_t BinarySemaphoreUsingTask::acquireWithTickTimeout( } ReturnValue_t BinarySemaphoreUsingTask::release() { - if(not locked) { - return SemaphoreIF::SEMAPHORE_NOT_OWNED; - } - BaseType_t returncode = xTaskNotifyGive(handle); - if (returncode == pdPASS) { - return HasReturnvaluesIF::RETURN_OK; - } else { - // This should never happen - return HasReturnvaluesIF::RETURN_FAILED; - } -} - -TaskHandle_t BinarySemaphoreUsingTask::getTaskHandle() { - return handle; -} - -uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter() const { - uint32_t notificationValue; - xTaskNotifyAndQuery(handle, 0, eNoAction, ¬ificationValue); - return notificationValue; -} - - -uint8_t BinarySemaphoreUsingTask::getSemaphoreCounterFromISR( - TaskHandle_t taskHandle) { - uint32_t notificationValue; - BaseType_t higherPriorityTaskWoken; - xTaskNotifyAndQueryFromISR(taskHandle, 0, eNoAction, ¬ificationValue, - &higherPriorityTaskWoken); - if(higherPriorityTaskWoken) { - TaskManagement::requestContextSwitch(CallContext::isr); - } - return notificationValue; + return release(this->handle); } ReturnValue_t BinarySemaphoreUsingTask::release( TaskHandle_t taskHandle) { + if(getSemaphoreCounter(taskHandle) == 1) { + return SemaphoreIF::SEMAPHORE_NOT_OWNED; + } BaseType_t returncode = xTaskNotifyGive(taskHandle); if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; @@ -88,14 +57,36 @@ ReturnValue_t BinarySemaphoreUsingTask::release( } } +TaskHandle_t BinarySemaphoreUsingTask::getTaskHandle() { + return handle; +} + +uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter() const { + return getSemaphoreCounter(this->handle); +} + +uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter( + TaskHandle_t taskHandle) { + uint32_t notificationValue; + xTaskNotifyAndQuery(taskHandle, 0, eNoAction, ¬ificationValue); + return notificationValue; +} + // Be careful with the stack size here. This is called from an ISR! ReturnValue_t BinarySemaphoreUsingTask::releaseFromISR( TaskHandle_t taskHandle, BaseType_t * higherPriorityTaskWoken) { - vTaskNotifyGiveFromISR(taskHandle, higherPriorityTaskWoken); - if(*higherPriorityTaskWoken == pdPASS) { - // Request context switch because unblocking the semaphore - // caused a high priority task unblock. - TaskManagement::requestContextSwitch(CallContext::isr); + if(getSemaphoreCounterFromISR(taskHandle) == 1) { + return SemaphoreIF::SEMAPHORE_NOT_OWNED; } + vTaskNotifyGiveFromISR(taskHandle, higherPriorityTaskWoken); return HasReturnvaluesIF::RETURN_OK; } + +uint8_t BinarySemaphoreUsingTask::getSemaphoreCounterFromISR( + TaskHandle_t taskHandle) { + uint32_t notificationValue; + BaseType_t higherPriorityTaskWoken; + xTaskNotifyAndQueryFromISR(taskHandle, 0, eNoAction, ¬ificationValue, + &higherPriorityTaskWoken); + return notificationValue; +} diff --git a/osal/FreeRTOS/BinSemaphUsingTask.h b/osal/FreeRTOS/BinSemaphUsingTask.h index cad42783..31620880 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.h +++ b/osal/FreeRTOS/BinSemaphUsingTask.h @@ -31,6 +31,7 @@ public: SemaphoreIF::NO_TIMEOUT) override; ReturnValue_t release() override; uint8_t getSemaphoreCounter() const override; + static uint8_t getSemaphoreCounter(TaskHandle_t taskHandle); static uint8_t getSemaphoreCounterFromISR(TaskHandle_t taskHandle); /** @@ -59,8 +60,9 @@ public: /** * Wrapper function to give back semaphore from handle when called from an ISR * @param semaphore - * @param higherPriorityTaskWoken This will be set to pdPASS if a task with a higher priority - * was unblocked + * @param higherPriorityTaskWoken This will be set to pdPASS if a task with + * a higher priority was unblocked. A context switch should be requested + * from an ISR if this is the case (see TaskManagement functions) * @return - @c RETURN_OK on success * - @c RETURN_FAILED on failure */ @@ -69,9 +71,6 @@ public: protected: TaskHandle_t handle; - // This boolean is required to track whether the semaphore is locked - // or unlocked. - bool locked; }; #endif /* FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */ diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index 7d882aff..7b695dee 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -37,7 +37,7 @@ BinarySemaphore& BinarySemaphore::operator =( ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { if(handle == nullptr) { - return SemaphoreIF::SEMAPHORE_NULLPOINTER; + return SemaphoreIF::SEMAPHORE_INVALID; } TickType_t timeout = SemaphoreIF::NO_TIMEOUT; if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { @@ -51,7 +51,7 @@ ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { ReturnValue_t BinarySemaphore::acquireWithTickTimeout(TickType_t timeoutTicks) { if(handle == nullptr) { - return SemaphoreIF::SEMAPHORE_NULLPOINTER; + return SemaphoreIF::SEMAPHORE_INVALID; } BaseType_t returncode = xSemaphoreTake(handle, timeoutTicks); @@ -64,10 +64,14 @@ ReturnValue_t BinarySemaphore::acquireWithTickTimeout(TickType_t timeoutTicks) { } ReturnValue_t BinarySemaphore::release() { - if (handle == nullptr) { - return SemaphoreIF::SEMAPHORE_NULLPOINTER; + return release(handle); +} + +ReturnValue_t BinarySemaphore::release(SemaphoreHandle_t semaphore) { + if (semaphore == nullptr) { + return SemaphoreIF::SEMAPHORE_INVALID; } - BaseType_t returncode = xSemaphoreGive(handle); + BaseType_t returncode = xSemaphoreGive(semaphore); if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; } @@ -83,33 +87,23 @@ uint8_t BinarySemaphore::getSemaphoreCounter() const { SemaphoreHandle_t BinarySemaphore::getSemaphore() { return handle; } - -ReturnValue_t BinarySemaphore::release(SemaphoreHandle_t semaphore) { - if (semaphore == nullptr) { - return SemaphoreIF::SEMAPHORE_NULLPOINTER; - } - BaseType_t returncode = xSemaphoreGive(semaphore); - if (returncode == pdPASS) { - return HasReturnvaluesIF::RETURN_OK; - } else { - return HasReturnvaluesIF::RETURN_FAILED; - } -} + // Be careful with the stack size here. This is called from an ISR! ReturnValue_t BinarySemaphore::releaseFromISR( SemaphoreHandle_t semaphore, BaseType_t * higherPriorityTaskWoken) { if (semaphore == nullptr) { - return SemaphoreIF::SEMAPHORE_NULLPOINTER; + return SemaphoreIF::SEMAPHORE_INVALID; } BaseType_t returncode = xSemaphoreGiveFromISR(semaphore, higherPriorityTaskWoken); + // This should propably be called at the end of the (calling) ISR + //if(*higherPriorityTaskWoken == pdPASS) { + // Request context switch because unblocking the semaphore + // caused a high priority task unblock. + //TaskManagement::requestContextSwitch(CallContext::isr); + //} if (returncode == pdPASS) { - if(*higherPriorityTaskWoken == pdPASS) { - // Request context switch because unblocking the semaphore - // caused a high priority task unblock. - TaskManagement::requestContextSwitch(CallContext::isr); - } return HasReturnvaluesIF::RETURN_OK; } else { diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.cpp b/osal/FreeRTOS/CountingSemaphUsingTask.cpp index d34c7d6a..d0f63f3f 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.cpp +++ b/osal/FreeRTOS/CountingSemaphUsingTask.cpp @@ -25,16 +25,15 @@ CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t maxCount, "current notification value is not 0. Please ensure the " "notification value is not used for other purposes!" << std::endl; } - while(currentCount != initCount) { + for(int i = 0; i < initCount; i++) { 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) + // (or implement a boolean which disables the reset) xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite, nullptr); } @@ -55,7 +54,6 @@ ReturnValue_t CountingSemaphoreUsingTask::acquireWithTickTimeout( // Decrement notfication value without resetting it. BaseType_t oldCount = ulTaskNotifyTake(pdFALSE, timeoutTicks); if (getSemaphoreCounter() == oldCount - 1) { - currentCount --; return HasReturnvaluesIF::RETURN_OK; } else { @@ -64,41 +62,10 @@ ReturnValue_t CountingSemaphoreUsingTask::acquireWithTickTimeout( } ReturnValue_t CountingSemaphoreUsingTask::release() { - if(currentCount == maxCount) { + if(getSemaphoreCounter() == 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 { - uint32_t notificationValue = 0; - 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; + return release(handle); } ReturnValue_t CountingSemaphoreUsingTask::release( @@ -113,13 +80,31 @@ ReturnValue_t CountingSemaphoreUsingTask::release( } } + +uint8_t CountingSemaphoreUsingTask::getSemaphoreCounter() const { + uint32_t notificationValue = 0; + xTaskNotifyAndQuery(handle, 0, eNoAction, ¬ificationValue); + return notificationValue; +} + +TaskHandle_t CountingSemaphoreUsingTask::getTaskHandle() { + return handle; +} + 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; } + +uint8_t CountingSemaphoreUsingTask::getSemaphoreCounterFromISR( + TaskHandle_t task, BaseType_t* higherPriorityTaskWoken) { + uint32_t notificationValue; + xTaskNotifyAndQueryFromISR(task, 0, eNoAction, ¬ificationValue, + higherPriorityTaskWoken); + return notificationValue; +} + +uint8_t CountingSemaphoreUsingTask::getMaxCount() const { + return maxCount; +} diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.h b/osal/FreeRTOS/CountingSemaphUsingTask.h index 73d3f987..797e864b 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.h +++ b/osal/FreeRTOS/CountingSemaphUsingTask.h @@ -43,7 +43,16 @@ public: ReturnValue_t release() override; uint8_t getSemaphoreCounter() const override; - static uint8_t getSemaphoreCounterFromISR(TaskHandle_t task); + /** + * Get the semaphore counter from an ISR. + * @param task + * @param higherPriorityTaskWoken This will be set to pdPASS if a task with + * a higher priority was unblocked. A context switch should be requested + * from an ISR if this is the case (see TaskManagement functions) + * @return + */ + static uint8_t getSemaphoreCounterFromISR(TaskHandle_t task, + BaseType_t* higherPriorityTaskWoken); /** * Acquire with a timeout value in ticks @@ -71,6 +80,9 @@ public: /** * Release seamphore of a task from an ISR. * @param taskToNotify + * @param higherPriorityTaskWoken This will be set to pdPASS if a task with + * a higher priority was unblocked. A context switch should be requested + * from an ISR if this is the case (see TaskManagement functions) * @return -@c RETURN_OK on success * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if #maxCount semaphores are * already available. @@ -78,10 +90,11 @@ public: static ReturnValue_t releaseFromISR(TaskHandle_t taskToNotify, BaseType_t* higherPriorityTaskWoken); + uint8_t getMaxCount() const; + private: TaskHandle_t handle; const uint8_t maxCount; - uint8_t currentCount = 0; }; #endif /* FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ */