From 968d7fad815877213c154845bc058140e47ee91b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 17:07:35 +0200 Subject: [PATCH 01/33] replaced some timeout values --- osal/FreeRTOS/BinarySemaphore.cpp | 9 ++++----- osal/FreeRTOS/BinarySemaphore.h | 20 ++++++-------------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index 026704d63..98911ad19 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -1,6 +1,5 @@ #include #include - #include BinarySemaphore::BinarySemaphore() { @@ -39,11 +38,11 @@ ReturnValue_t BinarySemaphore::takeBinarySemaphore(uint32_t timeoutMs) { if(handle == nullptr) { return SEMAPHORE_NULLPOINTER; } - TickType_t timeout = BinarySemaphore::NO_BLOCK_TICKS; - if(timeoutMs == BinarySemaphore::BLOCK_TIMEOUT) { - timeout = BinarySemaphore::BLOCK_TIMEOUT_TICKS; + TickType_t timeout = SemaphoreIF::NO_TIMEOUT; + if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { + timeout = SemaphoreIF::MAX_TIMEOUT; } - else if(timeoutMs > BinarySemaphore::NO_BLOCK_TIMEOUT){ + else if(timeoutMs > BinarySemaphore::NO_TIMEOUT){ timeout = pdMS_TO_TICKS(timeoutMs); } diff --git a/osal/FreeRTOS/BinarySemaphore.h b/osal/FreeRTOS/BinarySemaphore.h index 5f69dc90b..7079e91f8 100644 --- a/osal/FreeRTOS/BinarySemaphore.h +++ b/osal/FreeRTOS/BinarySemaphore.h @@ -3,13 +3,14 @@ #include #include + extern "C" { #include #include } -// TODO: Counting semaphores and implement the new (better) -// task notifications. However, those use task notifications require +// TODO: Implement the new (better) task notifications. +// However, those task notifications require // the task handle. Maybe it would be better to make a separate class // and switch between the classes with #ifdefs. // Task Notifications require FreeRTOS V8.2 something.. @@ -27,15 +28,6 @@ class BinarySemaphore: public SemaphoreIF, public HasReturnvaluesIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; - - //! No block time, poll the semaphore. Can also be used as tick type. - //! Can be passed as tick type and ms value. - static constexpr uint32_t NO_BLOCK_TIMEOUT = 0; - static constexpr TickType_t NO_BLOCK_TICKS = 0; - //! No block time, poll the semaphore. - //! Can be passed as tick type and ms value. - static constexpr TickType_t BLOCK_TIMEOUT_TICKS = portMAX_DELAY; - static constexpr uint32_t BLOCK_TIMEOUT = portMAX_DELAY; //! @brief Default ctor BinarySemaphore(); @@ -51,7 +43,7 @@ public: virtual ~BinarySemaphore(); ReturnValue_t acquire(uint32_t timeoutMs = - BinarySemaphore::NO_BLOCK_TIMEOUT) override; + SemaphoreIF::NO_TIMEOUT) override; ReturnValue_t release() override; uint8_t getSemaphoreCounter() override; @@ -65,7 +57,7 @@ public: * -@c RETURN_FAILED on failure */ ReturnValue_t takeBinarySemaphore(uint32_t timeoutMs = - BinarySemaphore::NO_BLOCK_TIMEOUT); + SemaphoreIF::NO_TIMEOUT); /** * Same as lockBinarySemaphore() with timeout in FreeRTOS ticks. @@ -74,7 +66,7 @@ public: * - @c RETURN_FAILED on failure */ ReturnValue_t takeBinarySemaphoreTickTimeout(TickType_t timeoutTicks = - BinarySemaphore::NO_BLOCK_TICKS); + BinarySemaphore::NO_TIMEOUT); /** * Give back the binary semaphore From 2d33274c2306fd51b4ea512d5d399502755f20fa Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 17:42:18 +0200 Subject: [PATCH 02/33] implementing new task notifications --- osal/FreeRTOS/BinarySemaphore.cpp | 69 +++++++++++++++++++--- osal/FreeRTOS/BinarySemaphore.h | 95 +++++++++++++++++++++++++++---- 2 files changed, 145 insertions(+), 19 deletions(-) diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index 98911ad19..f7e879830 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -2,6 +2,8 @@ #include #include +#if ( configUSE_OLD_SEMAPHORES == 1 ) + BinarySemaphore::BinarySemaphore() { handle = xSemaphoreCreateBinary(); if(handle == nullptr) { @@ -51,7 +53,7 @@ ReturnValue_t BinarySemaphore::takeBinarySemaphore(uint32_t timeoutMs) { return HasReturnvaluesIF::RETURN_OK; } else { - return SEMAPHORE_TIMEOUT; + return SemaphoreIF::SEMAPHORE_TIMEOUT; } } @@ -96,14 +98,6 @@ ReturnValue_t BinarySemaphore::giveBinarySemaphore(SemaphoreHandle_t semaphore) return HasReturnvaluesIF::RETURN_FAILED; } } - -void BinarySemaphore::resetSemaphore() { - if(handle != nullptr) { - vSemaphoreDelete(handle); - handle = xSemaphoreCreateBinary(); - xSemaphoreGive(handle); - } -} ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { return takeBinarySemaphore(timeoutMs); @@ -135,3 +129,60 @@ ReturnValue_t BinarySemaphore::giveBinarySemaphoreFromISR(SemaphoreHandle_t sema return SEMAPHORE_NOT_OWNED; } } + + +#else + +BinarySemaphore::BinarySemaphore() { + handle = TaskManagement::getCurrentTaskHandle(); +} + +ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { + return takeBinarySemaphore(timeoutMs); +} + +ReturnValue_t BinarySemaphore::release() { + return giveBinarySemaphore(); +} + +ReturnValue_t BinarySemaphore::takeBinarySemaphore(uint32_t timeoutMs) { + TickType_t timeout = SemaphoreIF::NO_TIMEOUT; + if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { + timeout = SemaphoreIF::MAX_TIMEOUT; + } + else if(timeoutMs > BinarySemaphore::NO_TIMEOUT){ + timeout = pdMS_TO_TICKS(timeoutMs); + } + + BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeout); + if (returncode == pdPASS) { + return HasReturnvaluesIF::RETURN_OK; + } + else { + return SemaphoreIF::SEMAPHORE_TIMEOUT; + } +} + +ReturnValue_t BinarySemaphore::takeBinarySemaphoreTickTimeout( + TickType_t timeoutTicks) { + BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeoutTicks); + if (returncode == pdPASS) { + return HasReturnvaluesIF::RETURN_OK; + } else { + return SEMAPHORE_TIMEOUT; + } +} + +ReturnValue_t BinarySemaphore::giveBinarySemaphore() { + if (handle == nullptr) { + return SEMAPHORE_NULLPOINTER; + } + BaseType_t returncode = xTaskNotifyGive(handle); + if (returncode == pdPASS) { + return HasReturnvaluesIF::RETURN_OK; + } else { + return SEMAPHORE_NOT_OWNED; + } +} + +#endif diff --git a/osal/FreeRTOS/BinarySemaphore.h b/osal/FreeRTOS/BinarySemaphore.h index 7079e91f8..4d95fc27c 100644 --- a/osal/FreeRTOS/BinarySemaphore.h +++ b/osal/FreeRTOS/BinarySemaphore.h @@ -6,7 +6,11 @@ extern "C" { #include +#if ( configUSE_OLD_SEMAPHORES == 1 ) #include +#else +#include +#endif } // TODO: Implement the new (better) task notifications. @@ -24,11 +28,13 @@ extern "C" { * @author R. Mueller * @ingroup osal */ +#if ( configUSE_OLD_SEMAPHORES == 1 ) + class BinarySemaphore: public SemaphoreIF, - public HasReturnvaluesIF { + public HasReturnvaluesIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; - + //! @brief Default ctor BinarySemaphore(); //! @brief Copy ctor, deleted explicitely. @@ -46,7 +52,7 @@ public: SemaphoreIF::NO_TIMEOUT) override; ReturnValue_t release() override; uint8_t getSemaphoreCounter() override; - + /** * Take the binary semaphore. * If the semaphore has already been taken, the task will be blocked @@ -81,11 +87,6 @@ public: */ SemaphoreHandle_t getSemaphore(); - /** - * Reset the semaphore. - */ - void resetSemaphore(); - /** * Wrapper function to give back semaphore from handle * @param semaphore @@ -104,9 +105,83 @@ public: */ static ReturnValue_t giveBinarySemaphoreFromISR(SemaphoreHandle_t semaphore, BaseType_t * higherPriorityTaskWoken); - -protected: + +protected: SemaphoreHandle_t handle; }; + +#else + +class BinarySemaphore: public SemaphoreIF, + public HasReturnvaluesIF { +public: + static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; + + //! @brief Default ctor + BinarySemaphore(); + + ReturnValue_t acquire(uint32_t timeoutMs = + SemaphoreIF::NO_TIMEOUT) override; + ReturnValue_t release() override; + uint8_t getSemaphoreCounter() override; + + /** + * 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. + * @param timeoutTicks + * @return - @c RETURN_OK on success + * - @c RETURN_FAILED on failure + */ + ReturnValue_t takeBinarySemaphoreTickTimeout(TickType_t timeoutTicks = + BinarySemaphore::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 semaphore. + * @return + */ + TaskHandle_t getTaskHandle(); + + /** + * Wrapper function to give back semaphore from handle + * @param semaphore + * @return - @c RETURN_OK on success + * - @c RETURN_FAILED on failure + */ + static ReturnValue_t giveBinarySemaphore(TaskHandle_t taskToNotify); + + /** + * 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 + * @return - @c RETURN_OK on success + * - @c RETURN_FAILED on failure + */ + static ReturnValue_t giveBinarySemaphoreFromISR(TaskHandle_t taskToNotify, + BaseType_t * higherPriorityTaskWoken); + +protected: + TaskHandle_t handle; +}; +#endif + #endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */ From 8a1e0dab0370c5b454fcb9e95de0f1349000b380 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 19:03:46 +0200 Subject: [PATCH 03/33] continued with task notifications --- osal/FreeRTOS/BinarySemaphore.cpp | 48 ++++++++++++++++++++++++++--- osal/FreeRTOS/BinarySemaphore.h | 8 +++-- osal/FreeRTOS/CountingSemaphore.cpp | 4 +++ 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index f7e879830..150f8c993 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -2,7 +2,7 @@ #include #include -#if ( configUSE_OLD_SEMAPHORES == 1 ) +#if ( configUSE_TASK_NOTIFICATIONS == 0 ) BinarySemaphore::BinarySemaphore() { handle = xSemaphoreCreateBinary(); @@ -174,9 +174,6 @@ ReturnValue_t BinarySemaphore::takeBinarySemaphoreTickTimeout( } ReturnValue_t BinarySemaphore::giveBinarySemaphore() { - if (handle == nullptr) { - return SEMAPHORE_NULLPOINTER; - } BaseType_t returncode = xTaskNotifyGive(handle); if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; @@ -185,4 +182,47 @@ ReturnValue_t BinarySemaphore::giveBinarySemaphore() { } } +TaskHandle_t BinarySemaphore::getTaskHandle() { + return handle; +} + +uint8_t BinarySemaphore::getSemaphoreCounter() { + uint32_t notificationValue; + xTaskNotifyAndQuery(handle, 0, eNoAction, ¬ificationValue); + return notificationValue; +} + +uint8_t BinarySemaphore::getSemaphoreCounterFromISR(TaskHandle_t taskHandle) { + uint32_t notificationValue; + BaseType_t higherPriorityTaskWoken; + xTaskNotifyAndQueryFromISR(taskHandle, 0, eNoAction, ¬ificationValue, + &higherPriorityTaskWoken); + if(higherPriorityTaskWoken) { + TaskManagement::requestContextSwitch(CallContext::isr); + } + return notificationValue; +} + + +ReturnValue_t BinarySemaphore::giveBinarySemaphore(TaskHandle_t taskHandle) { + BaseType_t returncode = xTaskNotifyGive(taskHandle); + if (returncode == pdPASS) { + return HasReturnvaluesIF::RETURN_OK; + } else { + return SEMAPHORE_NOT_OWNED; + } +} + +// Be careful with the stack size here. This is called from an ISR! +ReturnValue_t BinarySemaphore::giveBinarySemaphoreFromISR( + 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); + } + return HasReturnvaluesIF::RETURN_OK; +} + #endif diff --git a/osal/FreeRTOS/BinarySemaphore.h b/osal/FreeRTOS/BinarySemaphore.h index 4d95fc27c..2ee102267 100644 --- a/osal/FreeRTOS/BinarySemaphore.h +++ b/osal/FreeRTOS/BinarySemaphore.h @@ -6,7 +6,7 @@ extern "C" { #include -#if ( configUSE_OLD_SEMAPHORES == 1 ) +#if ( configUSE_TASK_NOTIFICATIONS == 0 ) #include #else #include @@ -28,7 +28,7 @@ extern "C" { * @author R. Mueller * @ingroup osal */ -#if ( configUSE_OLD_SEMAPHORES == 1 ) +#if ( configUSE_TASK_NOTIFICATIONS == 0 ) class BinarySemaphore: public SemaphoreIF, public HasReturnvaluesIF { @@ -155,7 +155,7 @@ public: ReturnValue_t giveBinarySemaphore(); /** - * Get Handle to the semaphore. + * Get handle to the task related to the semaphore. * @return */ TaskHandle_t getTaskHandle(); @@ -179,6 +179,8 @@ public: static ReturnValue_t giveBinarySemaphoreFromISR(TaskHandle_t taskToNotify, BaseType_t * higherPriorityTaskWoken); + static uint8_t getSemaphoreCounterFromISR(TaskHandle_t taskHandle); + protected: TaskHandle_t handle; }; diff --git a/osal/FreeRTOS/CountingSemaphore.cpp b/osal/FreeRTOS/CountingSemaphore.cpp index 2b81848a2..e04d3defd 100644 --- a/osal/FreeRTOS/CountingSemaphore.cpp +++ b/osal/FreeRTOS/CountingSemaphore.cpp @@ -1,6 +1,10 @@ #include #include +extern "C" { +#include +} + // Make sure #define configUSE_COUNTING_SEMAPHORES 1 is set in // free FreeRTOSConfig.h file. CountingSemaphore::CountingSemaphore(uint8_t count, uint8_t initCount): From b4065c776437b39613542d9beff87ba06e6242ad Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 19:46:56 +0200 Subject: [PATCH 04/33] seperation of semaph implementations finished --- osal/FreeRTOS/BinSemaphUsingTask.cpp | 95 ++++++++++++++++++++++ osal/FreeRTOS/BinSemaphUsingTask.h | 86 ++++++++++++++++++++ osal/FreeRTOS/BinarySemaphore.cpp | 99 ----------------------- osal/FreeRTOS/BinarySemaphore.h | 93 ++------------------- osal/FreeRTOS/CountingSemaphUsingTask.cpp | 8 ++ osal/FreeRTOS/CountingSemaphUsingTask.h | 25 ++++++ osal/FreeRTOS/CountingSemaphore.cpp | 2 + osal/FreeRTOS/SemaphoreFactory.cpp | 6 +- tasks/SemaphoreFactory.h | 10 ++- 9 files changed, 232 insertions(+), 192 deletions(-) create mode 100644 osal/FreeRTOS/BinSemaphUsingTask.cpp create mode 100644 osal/FreeRTOS/BinSemaphUsingTask.h create mode 100644 osal/FreeRTOS/CountingSemaphUsingTask.cpp create mode 100644 osal/FreeRTOS/CountingSemaphUsingTask.h diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp new file mode 100644 index 000000000..0d7320545 --- /dev/null +++ b/osal/FreeRTOS/BinSemaphUsingTask.cpp @@ -0,0 +1,95 @@ +#include +#include + + +BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() { + handle = TaskManagement::getCurrentTaskHandle(); +} + +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; + } + else if(timeoutMs > BinarySemaphoreUsingTask::NO_TIMEOUT){ + timeout = pdMS_TO_TICKS(timeoutMs); + } + + BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeout); + if (returncode == pdPASS) { + return HasReturnvaluesIF::RETURN_OK; + } + else { + return SemaphoreIF::SEMAPHORE_TIMEOUT; + } +} + +ReturnValue_t BinarySemaphoreUsingTask::takeBinarySemaphoreTickTimeout( + TickType_t timeoutTicks) { + BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeoutTicks); + if (returncode == pdPASS) { + return HasReturnvaluesIF::RETURN_OK; + } else { + return SEMAPHORE_TIMEOUT; + } +} + +ReturnValue_t BinarySemaphoreUsingTask::giveBinarySemaphore() { + BaseType_t returncode = xTaskNotifyGive(handle); + if (returncode == pdPASS) { + return HasReturnvaluesIF::RETURN_OK; + } else { + return SEMAPHORE_NOT_OWNED; + } +} + +TaskHandle_t BinarySemaphoreUsingTask::getTaskHandle() { + return handle; +} + +uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter() { + 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; +} + + +ReturnValue_t BinarySemaphoreUsingTask::giveBinarySemaphore(TaskHandle_t taskHandle) { + BaseType_t returncode = xTaskNotifyGive(taskHandle); + if (returncode == pdPASS) { + return HasReturnvaluesIF::RETURN_OK; + } else { + return SEMAPHORE_NOT_OWNED; + } +} + +// Be careful with the stack size here. This is called from an ISR! +ReturnValue_t BinarySemaphoreUsingTask::giveBinarySemaphoreFromISR( + 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); + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/osal/FreeRTOS/BinSemaphUsingTask.h b/osal/FreeRTOS/BinSemaphUsingTask.h new file mode 100644 index 000000000..2736b1db6 --- /dev/null +++ b/osal/FreeRTOS/BinSemaphUsingTask.h @@ -0,0 +1,86 @@ +#ifndef FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ +#define FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ + +#include +#include + +extern "C" { +#include +#include +} + +class BinarySemaphoreUsingTask: public SemaphoreIF, + public HasReturnvaluesIF { +public: + static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; + + //! @brief Default ctor + BinarySemaphoreUsingTask(); + + ReturnValue_t acquire(uint32_t timeoutMs = + SemaphoreIF::NO_TIMEOUT) override; + ReturnValue_t release() override; + uint8_t getSemaphoreCounter() override; + + /** + * 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. + * @param timeoutTicks + * @return - @c RETURN_OK on success + * - @c RETURN_FAILED on failure + */ + ReturnValue_t takeBinarySemaphoreTickTimeout(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 + */ + TaskHandle_t getTaskHandle(); + + /** + * Wrapper function to give back semaphore from handle + * @param semaphore + * @return - @c RETURN_OK on success + * - @c RETURN_FAILED on failure + */ + static ReturnValue_t giveBinarySemaphore(TaskHandle_t taskToNotify); + + /** + * 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 + * @return - @c RETURN_OK on success + * - @c RETURN_FAILED on failure + */ + static ReturnValue_t giveBinarySemaphoreFromISR(TaskHandle_t taskToNotify, + BaseType_t * higherPriorityTaskWoken); + + static uint8_t getSemaphoreCounterFromISR(TaskHandle_t taskHandle); + +protected: + TaskHandle_t handle; +}; + + + +#endif /* FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */ diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index 150f8c993..d56be763d 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -2,8 +2,6 @@ #include #include -#if ( configUSE_TASK_NOTIFICATIONS == 0 ) - BinarySemaphore::BinarySemaphore() { handle = xSemaphoreCreateBinary(); if(handle == nullptr) { @@ -129,100 +127,3 @@ ReturnValue_t BinarySemaphore::giveBinarySemaphoreFromISR(SemaphoreHandle_t sema return SEMAPHORE_NOT_OWNED; } } - - -#else - -BinarySemaphore::BinarySemaphore() { - handle = TaskManagement::getCurrentTaskHandle(); -} - -ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { - return takeBinarySemaphore(timeoutMs); -} - -ReturnValue_t BinarySemaphore::release() { - return giveBinarySemaphore(); -} - -ReturnValue_t BinarySemaphore::takeBinarySemaphore(uint32_t timeoutMs) { - TickType_t timeout = SemaphoreIF::NO_TIMEOUT; - if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { - timeout = SemaphoreIF::MAX_TIMEOUT; - } - else if(timeoutMs > BinarySemaphore::NO_TIMEOUT){ - timeout = pdMS_TO_TICKS(timeoutMs); - } - - BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeout); - if (returncode == pdPASS) { - return HasReturnvaluesIF::RETURN_OK; - } - else { - return SemaphoreIF::SEMAPHORE_TIMEOUT; - } -} - -ReturnValue_t BinarySemaphore::takeBinarySemaphoreTickTimeout( - TickType_t timeoutTicks) { - BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeoutTicks); - if (returncode == pdPASS) { - return HasReturnvaluesIF::RETURN_OK; - } else { - return SEMAPHORE_TIMEOUT; - } -} - -ReturnValue_t BinarySemaphore::giveBinarySemaphore() { - BaseType_t returncode = xTaskNotifyGive(handle); - if (returncode == pdPASS) { - return HasReturnvaluesIF::RETURN_OK; - } else { - return SEMAPHORE_NOT_OWNED; - } -} - -TaskHandle_t BinarySemaphore::getTaskHandle() { - return handle; -} - -uint8_t BinarySemaphore::getSemaphoreCounter() { - uint32_t notificationValue; - xTaskNotifyAndQuery(handle, 0, eNoAction, ¬ificationValue); - return notificationValue; -} - -uint8_t BinarySemaphore::getSemaphoreCounterFromISR(TaskHandle_t taskHandle) { - uint32_t notificationValue; - BaseType_t higherPriorityTaskWoken; - xTaskNotifyAndQueryFromISR(taskHandle, 0, eNoAction, ¬ificationValue, - &higherPriorityTaskWoken); - if(higherPriorityTaskWoken) { - TaskManagement::requestContextSwitch(CallContext::isr); - } - return notificationValue; -} - - -ReturnValue_t BinarySemaphore::giveBinarySemaphore(TaskHandle_t taskHandle) { - BaseType_t returncode = xTaskNotifyGive(taskHandle); - if (returncode == pdPASS) { - return HasReturnvaluesIF::RETURN_OK; - } else { - return SEMAPHORE_NOT_OWNED; - } -} - -// Be careful with the stack size here. This is called from an ISR! -ReturnValue_t BinarySemaphore::giveBinarySemaphoreFromISR( - 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); - } - return HasReturnvaluesIF::RETURN_OK; -} - -#endif diff --git a/osal/FreeRTOS/BinarySemaphore.h b/osal/FreeRTOS/BinarySemaphore.h index 2ee102267..e5c0ce4b5 100644 --- a/osal/FreeRTOS/BinarySemaphore.h +++ b/osal/FreeRTOS/BinarySemaphore.h @@ -6,18 +6,9 @@ extern "C" { #include -#if ( configUSE_TASK_NOTIFICATIONS == 0 ) #include -#else -#include -#endif } -// TODO: Implement the new (better) task notifications. -// However, those task notifications require -// the task handle. Maybe it would be better to make a separate class -// and switch between the classes with #ifdefs. -// Task Notifications require FreeRTOS V8.2 something.. /** * @brief OS Tool to achieve synchronization of between tasks or between * task and ISR. The default semaphore implementation creates a @@ -25,11 +16,15 @@ extern "C" { * @details * Documentation: https://www.freertos.org/Embedded-RTOS-Binary-Semaphores.html * + * Please note that if the semaphore implementation is only related to + * the synchronization of one task, the new task notifications can be used, + * also see the BinSemaphUsingTask and CountingSemaphUsingTask classes. + * These use the task notification value instead of a queue and are + * faster and more efficient. + * * @author R. Mueller * @ingroup osal */ -#if ( configUSE_TASK_NOTIFICATIONS == 0 ) - class BinarySemaphore: public SemaphoreIF, public HasReturnvaluesIF { public: @@ -110,80 +105,4 @@ protected: SemaphoreHandle_t handle; }; - -#else - -class BinarySemaphore: public SemaphoreIF, - public HasReturnvaluesIF { -public: - static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; - - //! @brief Default ctor - BinarySemaphore(); - - ReturnValue_t acquire(uint32_t timeoutMs = - SemaphoreIF::NO_TIMEOUT) override; - ReturnValue_t release() override; - uint8_t getSemaphoreCounter() override; - - /** - * 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. - * @param timeoutTicks - * @return - @c RETURN_OK on success - * - @c RETURN_FAILED on failure - */ - ReturnValue_t takeBinarySemaphoreTickTimeout(TickType_t timeoutTicks = - BinarySemaphore::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 - */ - TaskHandle_t getTaskHandle(); - - /** - * Wrapper function to give back semaphore from handle - * @param semaphore - * @return - @c RETURN_OK on success - * - @c RETURN_FAILED on failure - */ - static ReturnValue_t giveBinarySemaphore(TaskHandle_t taskToNotify); - - /** - * 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 - * @return - @c RETURN_OK on success - * - @c RETURN_FAILED on failure - */ - static ReturnValue_t giveBinarySemaphoreFromISR(TaskHandle_t taskToNotify, - BaseType_t * higherPriorityTaskWoken); - - static uint8_t getSemaphoreCounterFromISR(TaskHandle_t taskHandle); - -protected: - TaskHandle_t handle; -}; -#endif - #endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */ diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.cpp b/osal/FreeRTOS/CountingSemaphUsingTask.cpp new file mode 100644 index 000000000..6c5d45c7c --- /dev/null +++ b/osal/FreeRTOS/CountingSemaphUsingTask.cpp @@ -0,0 +1,8 @@ +#include +#include + +CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(uint8_t count, + uint8_t initCount): + count(count), initCount(initCount) { + handle = TaskManagement::getCurrentTaskHandle(); +} diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.h b/osal/FreeRTOS/CountingSemaphUsingTask.h new file mode 100644 index 000000000..c4bfb61ab --- /dev/null +++ b/osal/FreeRTOS/CountingSemaphUsingTask.h @@ -0,0 +1,25 @@ +#ifndef FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ +#define FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ + +#include +#include + +extern "C" { +#include +#include +} + +class CountingSemaphoreUsingTask: public SemaphoreIF { +public: + CountingSemaphoreUsingTask(uint8_t count, uint8_t initCount); + + ReturnValue_t acquire(uint32_t timeoutMs); + ReturnValue_t release(); + +private: + TaskHandle_t handle; + uint8_t count = 0; + uint8_t initCount = 0; +}; + +#endif /* FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ */ diff --git a/osal/FreeRTOS/CountingSemaphore.cpp b/osal/FreeRTOS/CountingSemaphore.cpp index e04d3defd..2f0dfd764 100644 --- a/osal/FreeRTOS/CountingSemaphore.cpp +++ b/osal/FreeRTOS/CountingSemaphore.cpp @@ -1,5 +1,6 @@ #include #include +#include extern "C" { #include @@ -30,3 +31,4 @@ CountingSemaphore& CountingSemaphore::operator =( } return * this; } + diff --git a/osal/FreeRTOS/SemaphoreFactory.cpp b/osal/FreeRTOS/SemaphoreFactory.cpp index 7bd71dd7a..1eee1bacc 100644 --- a/osal/FreeRTOS/SemaphoreFactory.cpp +++ b/osal/FreeRTOS/SemaphoreFactory.cpp @@ -21,15 +21,15 @@ SemaphoreFactory* SemaphoreFactory::instance() { return SemaphoreFactory::factoryInstance; } -SemaphoreIF* SemaphoreFactory::createBinarySemaphore() { +SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t argument) { return new BinarySemaphore(); } SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t count, - uint8_t initCount) { + uint8_t initCount, uint32_t argument) { return new CountingSemaphore(count, initCount); } -void SemaphoreFactory::deleteMutex(SemaphoreIF* semaphore) { +void SemaphoreFactory::deleteSemaphore(SemaphoreIF* semaphore) { delete semaphore; } diff --git a/tasks/SemaphoreFactory.h b/tasks/SemaphoreFactory.h index fa95399a1..971e97fa3 100644 --- a/tasks/SemaphoreFactory.h +++ b/tasks/SemaphoreFactory.h @@ -20,19 +20,23 @@ public: /** * Create a binary semaphore. * Creator function for a binary semaphore which may only be acquired once + * @param argument Can be used to pass implementation specific information. * @return Pointer to newly created semaphore class instance. */ - SemaphoreIF* createBinarySemaphore(); + SemaphoreIF* createBinarySemaphore(uint32_t argument = 0); /** * Create a counting semaphore. * Creator functons for a counting semaphore which may be acquired multiple * times. * @param count Semaphore can be taken count times. * @param initCount Initial count value. + * @param argument Can be used to pass implementation specific information. * @return */ - SemaphoreIF* createCountingSemaphore(uint8_t count, uint8_t initCount); - void deleteMutex(SemaphoreIF* mutex); + SemaphoreIF* createCountingSemaphore(uint8_t count, uint8_t initCount, + uint32_t argument = 0); + + void deleteSemaphore(SemaphoreIF* mutex); private: /** From eabee85ba9f1dd014abc66d13e212427dc328242 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 19:56:02 +0200 Subject: [PATCH 05/33] tweaked factory to have configurability --- osal/FreeRTOS/CountingSemaphUsingTask.cpp | 13 ++++++++++ osal/FreeRTOS/CountingSemaphUsingTask.h | 5 ++-- osal/FreeRTOS/SemaphoreFactory.cpp | 30 +++++++++++++++++++++-- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.cpp b/osal/FreeRTOS/CountingSemaphUsingTask.cpp index 6c5d45c7c..10365d7e1 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.cpp +++ b/osal/FreeRTOS/CountingSemaphUsingTask.cpp @@ -6,3 +6,16 @@ CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(uint8_t count, count(count), initCount(initCount) { handle = TaskManagement::getCurrentTaskHandle(); } + +ReturnValue_t CountingSemaphoreUsingTask::acquire( + uint32_t timeoutMs) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t CountingSemaphoreUsingTask::release() { + return HasReturnvaluesIF::RETURN_OK; +} + +uint8_t CountingSemaphoreUsingTask::getSemaphoreCounter() { + return 0; +} diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.h b/osal/FreeRTOS/CountingSemaphUsingTask.h index c4bfb61ab..7fc98e937 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.h +++ b/osal/FreeRTOS/CountingSemaphUsingTask.h @@ -13,8 +13,9 @@ class CountingSemaphoreUsingTask: public SemaphoreIF { public: CountingSemaphoreUsingTask(uint8_t count, uint8_t initCount); - ReturnValue_t acquire(uint32_t timeoutMs); - ReturnValue_t release(); + ReturnValue_t acquire(uint32_t timeoutMs) override; + ReturnValue_t release() override; + uint8_t getSemaphoreCounter() override; private: TaskHandle_t handle; diff --git a/osal/FreeRTOS/SemaphoreFactory.cpp b/osal/FreeRTOS/SemaphoreFactory.cpp index 1eee1bacc..6acdc7b73 100644 --- a/osal/FreeRTOS/SemaphoreFactory.cpp +++ b/osal/FreeRTOS/SemaphoreFactory.cpp @@ -1,5 +1,7 @@ #include +#include #include +#include #include #include @@ -7,6 +9,9 @@ SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr; const uint32_t SemaphoreIF::NO_TIMEOUT = 0; const uint32_t SemaphoreIF::MAX_TIMEOUT = portMAX_DELAY; +static const uint32_t USE_REGULAR_SEMAPHORES = 0; +static const uint32_t USE_TASK_NOTIFICATIONS = 1; + SemaphoreFactory::SemaphoreFactory() { } @@ -22,12 +27,33 @@ SemaphoreFactory* SemaphoreFactory::instance() { } SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t argument) { - return new BinarySemaphore(); + if(argument == USE_REGULAR_SEMAPHORES) { + return new BinarySemaphore(); + } + else if(argument == USE_TASK_NOTIFICATIONS) { + return new BinarySemaphoreUsingTask(); + } + else { + sif::warning << "SemaphoreFactory: Invalid argument, return regular" + "binary semaphore" << std::endl; + return new BinarySemaphore(); + } } SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t count, uint8_t initCount, uint32_t argument) { - return new CountingSemaphore(count, initCount); + if(argument == USE_REGULAR_SEMAPHORES) { + return new CountingSemaphore(count, initCount); + } + else if(argument == USE_TASK_NOTIFICATIONS) { + return new CountingSemaphoreUsingTask(count, initCount); + } + else { + sif::warning << "SemaphoreFactory: Invalid argument, return regular" + "binary semaphore" << std::endl; + return new CountingSemaphore(count, initCount); + } + } void SemaphoreFactory::deleteSemaphore(SemaphoreIF* semaphore) { From 7145982b4ade5f3da12e8dd05161b11e45512998 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 19:59:59 +0200 Subject: [PATCH 06/33] improved documentation --- osal/FreeRTOS/BinSemaphUsingTask.cpp | 2 +- osal/FreeRTOS/BinSemaphUsingTask.h | 6 ++++++ tasks/SemaphoreIF.h | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index 0d7320545..d6bc02bc0 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.cpp +++ b/osal/FreeRTOS/BinSemaphUsingTask.cpp @@ -19,7 +19,7 @@ ReturnValue_t BinarySemaphoreUsingTask::takeBinarySemaphore(uint32_t timeoutMs) if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { timeout = SemaphoreIF::MAX_TIMEOUT; } - else if(timeoutMs > BinarySemaphoreUsingTask::NO_TIMEOUT){ + else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){ timeout = pdMS_TO_TICKS(timeoutMs); } diff --git a/osal/FreeRTOS/BinSemaphUsingTask.h b/osal/FreeRTOS/BinSemaphUsingTask.h index 2736b1db6..8b8a77735 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.h +++ b/osal/FreeRTOS/BinSemaphUsingTask.h @@ -9,6 +9,12 @@ extern "C" { #include } +/** + * @brief Binary Semaphore implementation using Task Notifications + * @details + * Additional information: https://www.freertos.org/RTOS-task-notifications.html + * and general semaphore documentation. + */ class BinarySemaphoreUsingTask: public SemaphoreIF, public HasReturnvaluesIF { public: diff --git a/tasks/SemaphoreIF.h b/tasks/SemaphoreIF.h index b2b113f17..fb181ccaa 100644 --- a/tasks/SemaphoreIF.h +++ b/tasks/SemaphoreIF.h @@ -12,7 +12,8 @@ * A semaphore is a synchronization primitive. * See: https://en.wikipedia.org/wiki/Semaphore_(programming) * A semaphore can be used to achieve task synchonization and track the - * availability of resources. + * availability of resources by using either the binary or the counting + * semaphore types. * * If mutual exlcusion of a resource is desired, a mutex should be used, * which is a special form of a semaphore and has an own interface. From 88e3dc15b2604de0c337f2bf4911ee5e4780588f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 21:27:31 +0200 Subject: [PATCH 07/33] replaced old semaph api --- osal/FreeRTOS/BinSemaphUsingTask.cpp | 16 +++++++++++++--- osal/FreeRTOS/BinSemaphUsingTask.h | 3 +++ osal/FreeRTOS/BinarySemaphore.cpp | 22 ++++++++-------------- osal/FreeRTOS/BinarySemaphore.h | 11 ++++------- osal/FreeRTOS/CountingSemaphUsingTask.cpp | 15 ++++++++++++--- osal/FreeRTOS/CountingSemaphUsingTask.h | 6 +++--- osal/FreeRTOS/SemaphoreFactory.cpp | 8 ++++---- tasks/SemaphoreFactory.h | 2 +- 8 files changed, 48 insertions(+), 35 deletions(-) diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index d6bc02bc0..8cdcbc333 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.cpp +++ b/osal/FreeRTOS/BinSemaphUsingTask.cpp @@ -4,6 +4,8 @@ BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() { handle = TaskManagement::getCurrentTaskHandle(); + xTaskNotifyGive(handle); + locked = false; } ReturnValue_t BinarySemaphoreUsingTask::acquire(uint32_t timeoutMs) { @@ -25,6 +27,7 @@ ReturnValue_t BinarySemaphoreUsingTask::takeBinarySemaphore(uint32_t timeoutMs) BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeout); if (returncode == pdPASS) { + locked = true; return HasReturnvaluesIF::RETURN_OK; } else { @@ -36,6 +39,7 @@ ReturnValue_t BinarySemaphoreUsingTask::takeBinarySemaphoreTickTimeout( TickType_t timeoutTicks) { BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeoutTicks); if (returncode == pdPASS) { + locked = true; return HasReturnvaluesIF::RETURN_OK; } else { return SEMAPHORE_TIMEOUT; @@ -43,11 +47,15 @@ ReturnValue_t BinarySemaphoreUsingTask::takeBinarySemaphoreTickTimeout( } ReturnValue_t BinarySemaphoreUsingTask::giveBinarySemaphore() { + if(not locked) { + return SemaphoreIF::SEMAPHORE_NOT_OWNED; + } BaseType_t returncode = xTaskNotifyGive(handle); if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; } else { - return SEMAPHORE_NOT_OWNED; + // This should never happen + return HasReturnvaluesIF::RETURN_FAILED; } } @@ -77,8 +85,10 @@ ReturnValue_t BinarySemaphoreUsingTask::giveBinarySemaphore(TaskHandle_t taskHan BaseType_t returncode = xTaskNotifyGive(taskHandle); if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; - } else { - return SEMAPHORE_NOT_OWNED; + } + else { + // This should never happen. + return HasReturnvaluesIF::RETURN_FAILED; } } diff --git a/osal/FreeRTOS/BinSemaphUsingTask.h b/osal/FreeRTOS/BinSemaphUsingTask.h index 8b8a77735..e44b838c1 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.h +++ b/osal/FreeRTOS/BinSemaphUsingTask.h @@ -85,6 +85,9 @@ public: protected: TaskHandle_t handle; + // This boolean is required to track whether the semaphore is locked + // or unlocked. + bool locked; }; diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index d56be763d..fa54b71f8 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -7,6 +7,7 @@ BinarySemaphore::BinarySemaphore() { if(handle == nullptr) { sif::error << "Semaphore: Binary semaph creation failure" << std::endl; } + // Initiated semaphore must be given before it can be taken. xSemaphoreGive(handle); } @@ -34,7 +35,7 @@ BinarySemaphore& BinarySemaphore::operator =( return *this; } -ReturnValue_t BinarySemaphore::takeBinarySemaphore(uint32_t timeoutMs) { +ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { if(handle == nullptr) { return SEMAPHORE_NULLPOINTER; } @@ -55,7 +56,7 @@ ReturnValue_t BinarySemaphore::takeBinarySemaphore(uint32_t timeoutMs) { } } -ReturnValue_t BinarySemaphore::takeBinarySemaphoreTickTimeout( +ReturnValue_t BinarySemaphore::acquireWithTickTimeout( TickType_t timeoutTicks) { if(handle == nullptr) { return SEMAPHORE_NULLPOINTER; @@ -69,7 +70,7 @@ ReturnValue_t BinarySemaphore::takeBinarySemaphoreTickTimeout( } } -ReturnValue_t BinarySemaphore::giveBinarySemaphore() { +ReturnValue_t BinarySemaphore::release() { if (handle == nullptr) { return SEMAPHORE_NULLPOINTER; } @@ -96,26 +97,19 @@ ReturnValue_t BinarySemaphore::giveBinarySemaphore(SemaphoreHandle_t semaphore) return HasReturnvaluesIF::RETURN_FAILED; } } - -ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { - return takeBinarySemaphore(timeoutMs); -} - -ReturnValue_t BinarySemaphore::release() { - return giveBinarySemaphore(); -} uint8_t BinarySemaphore::getSemaphoreCounter() { return uxSemaphoreGetCount(handle); } // Be careful with the stack size here. This is called from an ISR! -ReturnValue_t BinarySemaphore::giveBinarySemaphoreFromISR(SemaphoreHandle_t semaphore, - BaseType_t * higherPriorityTaskWoken) { +ReturnValue_t BinarySemaphore::giveBinarySemaphoreFromISR( + SemaphoreHandle_t semaphore, BaseType_t * higherPriorityTaskWoken) { if (semaphore == nullptr) { return SEMAPHORE_NULLPOINTER; } - BaseType_t returncode = xSemaphoreGiveFromISR(semaphore, higherPriorityTaskWoken); + BaseType_t returncode = xSemaphoreGiveFromISR(semaphore, + higherPriorityTaskWoken); if (returncode == pdPASS) { if(*higherPriorityTaskWoken == pdPASS) { // Request context switch because unblocking the semaphore diff --git a/osal/FreeRTOS/BinarySemaphore.h b/osal/FreeRTOS/BinarySemaphore.h index e5c0ce4b5..0c2fe3bff 100644 --- a/osal/FreeRTOS/BinarySemaphore.h +++ b/osal/FreeRTOS/BinarySemaphore.h @@ -43,9 +43,6 @@ public: //! @brief Destructor virtual ~BinarySemaphore(); - ReturnValue_t acquire(uint32_t timeoutMs = - SemaphoreIF::NO_TIMEOUT) override; - ReturnValue_t release() override; uint8_t getSemaphoreCounter() override; /** @@ -57,8 +54,8 @@ public: * @return -@c RETURN_OK on success * -@c RETURN_FAILED on failure */ - ReturnValue_t takeBinarySemaphore(uint32_t timeoutMs = - SemaphoreIF::NO_TIMEOUT); + ReturnValue_t acquire(uint32_t timeoutMs = + SemaphoreIF::NO_TIMEOUT) override; /** * Same as lockBinarySemaphore() with timeout in FreeRTOS ticks. @@ -66,7 +63,7 @@ public: * @return - @c RETURN_OK on success * - @c RETURN_FAILED on failure */ - ReturnValue_t takeBinarySemaphoreTickTimeout(TickType_t timeoutTicks = + ReturnValue_t acquireWithTickTimeout(TickType_t timeoutTicks = BinarySemaphore::NO_TIMEOUT); /** @@ -74,7 +71,7 @@ public: * @return - @c RETURN_OK on success * - @c RETURN_FAILED on failure */ - ReturnValue_t giveBinarySemaphore(); + ReturnValue_t release() override; /** * Get Handle to the semaphore. diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.cpp b/osal/FreeRTOS/CountingSemaphUsingTask.cpp index 10365d7e1..eecd986b4 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.cpp +++ b/osal/FreeRTOS/CountingSemaphUsingTask.cpp @@ -1,10 +1,19 @@ #include #include +#include -CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(uint8_t count, - uint8_t initCount): - count(count), initCount(initCount) { +CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(uint8_t maxCount, + uint8_t initCount): maxCount(maxCount) { + if(initCount > maxCount) { + sif::error << "CountingSemaphoreUsingTask: Max count bigger than " + "intial cout. Setting initial count to max count." << std::endl; + initCount = maxCount; + } handle = TaskManagement::getCurrentTaskHandle(); + while(currentCount != initCount) { + xTaskNotifyGive(handle); + currentCount++; + } } ReturnValue_t CountingSemaphoreUsingTask::acquire( diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.h b/osal/FreeRTOS/CountingSemaphUsingTask.h index 7fc98e937..8c881d690 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.h +++ b/osal/FreeRTOS/CountingSemaphUsingTask.h @@ -11,7 +11,7 @@ extern "C" { class CountingSemaphoreUsingTask: public SemaphoreIF { public: - CountingSemaphoreUsingTask(uint8_t count, uint8_t initCount); + CountingSemaphoreUsingTask(uint8_t maxCount, uint8_t initCount); ReturnValue_t acquire(uint32_t timeoutMs) override; ReturnValue_t release() override; @@ -19,8 +19,8 @@ public: private: TaskHandle_t handle; - uint8_t count = 0; - uint8_t initCount = 0; + const uint8_t maxCount; + uint8_t currentCount = 0; }; #endif /* FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ */ diff --git a/osal/FreeRTOS/SemaphoreFactory.cpp b/osal/FreeRTOS/SemaphoreFactory.cpp index 6acdc7b73..05a898cd1 100644 --- a/osal/FreeRTOS/SemaphoreFactory.cpp +++ b/osal/FreeRTOS/SemaphoreFactory.cpp @@ -40,18 +40,18 @@ SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t argument) { } } -SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t count, +SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t maxCount, uint8_t initCount, uint32_t argument) { if(argument == USE_REGULAR_SEMAPHORES) { - return new CountingSemaphore(count, initCount); + return new CountingSemaphore(maxCount, initCount); } else if(argument == USE_TASK_NOTIFICATIONS) { - return new CountingSemaphoreUsingTask(count, initCount); + return new CountingSemaphoreUsingTask(maxCount, initCount); } else { sif::warning << "SemaphoreFactory: Invalid argument, return regular" "binary semaphore" << std::endl; - return new CountingSemaphore(count, initCount); + return new CountingSemaphore(maxCount, initCount); } } diff --git a/tasks/SemaphoreFactory.h b/tasks/SemaphoreFactory.h index 971e97fa3..75bbe25dc 100644 --- a/tasks/SemaphoreFactory.h +++ b/tasks/SemaphoreFactory.h @@ -33,7 +33,7 @@ public: * @param argument Can be used to pass implementation specific information. * @return */ - SemaphoreIF* createCountingSemaphore(uint8_t count, uint8_t initCount, + SemaphoreIF* createCountingSemaphore(uint8_t maxCount, uint8_t initCount, uint32_t argument = 0); void deleteSemaphore(SemaphoreIF* mutex); From c4e60946d3282c497714cb9345918069afb11047 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 21:30:20 +0200 Subject: [PATCH 08/33] improved bin semaph implementation --- osal/FreeRTOS/BinarySemaphore.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index fa54b71f8..e6bb8dcab 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 SEMAPHORE_NULLPOINTER; + return SemaphoreIF::SEMAPHORE_NULLPOINTER; } TickType_t timeout = SemaphoreIF::NO_TIMEOUT; if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { @@ -59,14 +59,14 @@ ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { ReturnValue_t BinarySemaphore::acquireWithTickTimeout( TickType_t timeoutTicks) { if(handle == nullptr) { - return SEMAPHORE_NULLPOINTER; + return SemaphoreIF::SEMAPHORE_NULLPOINTER; } BaseType_t returncode = xSemaphoreTake(handle, timeoutTicks); if (returncode == pdPASS) { return HasReturnvaluesIF::RETURN_OK; } else { - return SEMAPHORE_TIMEOUT; + return SemaphoreIF::SEMAPHORE_TIMEOUT; } } @@ -82,13 +82,17 @@ ReturnValue_t BinarySemaphore::release() { } } +uint8_t BinarySemaphore::getSemaphoreCounter() { + return uxSemaphoreGetCount(handle); +} + SemaphoreHandle_t BinarySemaphore::getSemaphore() { return handle; } ReturnValue_t BinarySemaphore::giveBinarySemaphore(SemaphoreHandle_t semaphore) { if (semaphore == nullptr) { - return SEMAPHORE_NULLPOINTER; + return SemaphoreIF::SEMAPHORE_NULLPOINTER; } BaseType_t returncode = xSemaphoreGive(semaphore); if (returncode == pdPASS) { @@ -96,17 +100,13 @@ ReturnValue_t BinarySemaphore::giveBinarySemaphore(SemaphoreHandle_t semaphore) } else { return HasReturnvaluesIF::RETURN_FAILED; } -} - -uint8_t BinarySemaphore::getSemaphoreCounter() { - return uxSemaphoreGetCount(handle); } // Be careful with the stack size here. This is called from an ISR! ReturnValue_t BinarySemaphore::giveBinarySemaphoreFromISR( SemaphoreHandle_t semaphore, BaseType_t * higherPriorityTaskWoken) { if (semaphore == nullptr) { - return SEMAPHORE_NULLPOINTER; + return SemaphoreIF::SEMAPHORE_NULLPOINTER; } BaseType_t returncode = xSemaphoreGiveFromISR(semaphore, higherPriorityTaskWoken); @@ -117,7 +117,8 @@ ReturnValue_t BinarySemaphore::giveBinarySemaphoreFromISR( TaskManagement::requestContextSwitch(CallContext::isr); } return HasReturnvaluesIF::RETURN_OK; - } else { - return SEMAPHORE_NOT_OWNED; + } + else { + return SemaphoreIF::SEMAPHORE_NOT_OWNED; } } From 95bf5c1071a84696cc0e15abf9a01102764caaca Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 21:33:34 +0200 Subject: [PATCH 09/33] improved const correctness --- osal/FreeRTOS/BinSemaphUsingTask.cpp | 2 +- osal/FreeRTOS/BinSemaphUsingTask.h | 2 +- osal/FreeRTOS/BinarySemaphore.cpp | 2 +- osal/FreeRTOS/BinarySemaphore.h | 2 +- osal/FreeRTOS/CountingSemaphUsingTask.cpp | 5 ++--- osal/FreeRTOS/CountingSemaphUsingTask.h | 2 +- tasks/SemaphoreIF.h | 2 +- 7 files changed, 8 insertions(+), 9 deletions(-) diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index 8cdcbc333..2a5ca3bd5 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.cpp +++ b/osal/FreeRTOS/BinSemaphUsingTask.cpp @@ -63,7 +63,7 @@ TaskHandle_t BinarySemaphoreUsingTask::getTaskHandle() { return handle; } -uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter() { +uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter() const { uint32_t notificationValue; xTaskNotifyAndQuery(handle, 0, eNoAction, ¬ificationValue); return notificationValue; diff --git a/osal/FreeRTOS/BinSemaphUsingTask.h b/osal/FreeRTOS/BinSemaphUsingTask.h index e44b838c1..b65d4d802 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.h +++ b/osal/FreeRTOS/BinSemaphUsingTask.h @@ -26,7 +26,7 @@ public: ReturnValue_t acquire(uint32_t timeoutMs = SemaphoreIF::NO_TIMEOUT) override; ReturnValue_t release() override; - uint8_t getSemaphoreCounter() override; + uint8_t getSemaphoreCounter() const override; /** * Take the binary semaphore. diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index e6bb8dcab..0d8d415cd 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -82,7 +82,7 @@ ReturnValue_t BinarySemaphore::release() { } } -uint8_t BinarySemaphore::getSemaphoreCounter() { +uint8_t BinarySemaphore::getSemaphoreCounter() const { return uxSemaphoreGetCount(handle); } diff --git a/osal/FreeRTOS/BinarySemaphore.h b/osal/FreeRTOS/BinarySemaphore.h index 0c2fe3bff..b883f8017 100644 --- a/osal/FreeRTOS/BinarySemaphore.h +++ b/osal/FreeRTOS/BinarySemaphore.h @@ -43,7 +43,7 @@ public: //! @brief Destructor virtual ~BinarySemaphore(); - uint8_t getSemaphoreCounter() override; + uint8_t getSemaphoreCounter() const override; /** * Take the binary semaphore. diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.cpp b/osal/FreeRTOS/CountingSemaphUsingTask.cpp index eecd986b4..d08a549ea 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.cpp +++ b/osal/FreeRTOS/CountingSemaphUsingTask.cpp @@ -16,8 +16,7 @@ CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(uint8_t maxCount, } } -ReturnValue_t CountingSemaphoreUsingTask::acquire( - uint32_t timeoutMs) { +ReturnValue_t CountingSemaphoreUsingTask::acquire(uint32_t timeoutMs) { return HasReturnvaluesIF::RETURN_OK; } @@ -25,6 +24,6 @@ ReturnValue_t CountingSemaphoreUsingTask::release() { return HasReturnvaluesIF::RETURN_OK; } -uint8_t CountingSemaphoreUsingTask::getSemaphoreCounter() { +uint8_t CountingSemaphoreUsingTask::getSemaphoreCounter() const { return 0; } diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.h b/osal/FreeRTOS/CountingSemaphUsingTask.h index 8c881d690..877a975e9 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.h +++ b/osal/FreeRTOS/CountingSemaphUsingTask.h @@ -15,7 +15,7 @@ public: ReturnValue_t acquire(uint32_t timeoutMs) override; ReturnValue_t release() override; - uint8_t getSemaphoreCounter() override; + uint8_t getSemaphoreCounter() const override; private: TaskHandle_t handle; diff --git a/tasks/SemaphoreIF.h b/tasks/SemaphoreIF.h index fb181ccaa..044e03a8d 100644 --- a/tasks/SemaphoreIF.h +++ b/tasks/SemaphoreIF.h @@ -55,7 +55,7 @@ public: * is returned if the semaphore is available, and 0 is returned if the * semaphore is not available. */ - virtual uint8_t getSemaphoreCounter() = 0; + virtual uint8_t getSemaphoreCounter() const = 0; }; #endif /* FRAMEWORK_TASKS_SEMAPHOREIF_H_ */ From 63dbf995925f181f406173ba380d36b8faadb393 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 22:12:52 +0200 Subject: [PATCH 10/33] counting semaph implementation finished --- osal/FreeRTOS/BinSemaphUsingTask.cpp | 42 ++++------- osal/FreeRTOS/BinSemaphUsingTask.h | 32 ++------- osal/FreeRTOS/BinarySemaphore.cpp | 24 +++---- osal/FreeRTOS/CountingSemaphUsingTask.cpp | 88 +++++++++++++++++++++-- osal/FreeRTOS/CountingSemaphUsingTask.h | 32 ++++++++- osal/FreeRTOS/CountingSemaphore.cpp | 13 ++-- osal/FreeRTOS/CountingSemaphore.h | 4 +- tasks/SemaphoreFactory.h | 6 +- 8 files changed, 154 insertions(+), 87 deletions(-) diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index 2a5ca3bd5..9c2afe10c 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 b65d4d802..cb6f6287a 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 0d8d415cd..8891b755b 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 d08a549ea..9beca310d 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 877a975e9..ac0425b50 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 2f0dfd764..a23f32a03 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 a33a0fa5a..77050f900 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 75bbe25dc..3e21be368 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); From 7ce505fdf9234630298dc6560b625cc44f41770a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 23:29:06 +0200 Subject: [PATCH 11/33] some safety updates and fixes --- osal/FreeRTOS/BinSemaphUsingTask.cpp | 10 ++++++ osal/FreeRTOS/BinSemaphUsingTask.h | 6 +++- osal/FreeRTOS/CountingSemaphUsingTask.cpp | 40 ++++++++++++++++------- osal/FreeRTOS/CountingSemaphUsingTask.h | 9 +++++ 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index 9c2afe10c..84b0b488e 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 cb6f6287a..cad427831 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 9beca310d..c29f52589 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 ac0425b50..2c54b31ba 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; From 08ffe89682e72c70876d3dbfd0555161e16608e9 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 23:41:59 +0200 Subject: [PATCH 12/33] doc and api improvements --- osal/FreeRTOS/BinarySemaphore.cpp | 4 +-- osal/FreeRTOS/BinarySemaphore.h | 27 ++++++++++--------- osal/FreeRTOS/CountingSemaphUsingTask.h | 36 ++++++++++++++++++++----- osal/FreeRTOS/CountingSemaphore.h | 4 +++ 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index 8891b755b..7d882afff 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -84,7 +84,7 @@ SemaphoreHandle_t BinarySemaphore::getSemaphore() { return handle; } -ReturnValue_t BinarySemaphore::giveBinarySemaphore(SemaphoreHandle_t semaphore) { +ReturnValue_t BinarySemaphore::release(SemaphoreHandle_t semaphore) { if (semaphore == nullptr) { return SemaphoreIF::SEMAPHORE_NULLPOINTER; } @@ -97,7 +97,7 @@ ReturnValue_t BinarySemaphore::giveBinarySemaphore(SemaphoreHandle_t semaphore) } // Be careful with the stack size here. This is called from an ISR! -ReturnValue_t BinarySemaphore::giveBinarySemaphoreFromISR( +ReturnValue_t BinarySemaphore::releaseFromISR( SemaphoreHandle_t semaphore, BaseType_t * higherPriorityTaskWoken) { if (semaphore == nullptr) { return SemaphoreIF::SEMAPHORE_NULLPOINTER; diff --git a/osal/FreeRTOS/BinarySemaphore.h b/osal/FreeRTOS/BinarySemaphore.h index b883f8017..f3839151d 100644 --- a/osal/FreeRTOS/BinarySemaphore.h +++ b/osal/FreeRTOS/BinarySemaphore.h @@ -52,7 +52,7 @@ public: * for example by an ISR or another task. * @param timeoutMs * @return -@c RETURN_OK on success - * -@c RETURN_FAILED on failure + * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout */ ReturnValue_t acquire(uint32_t timeoutMs = SemaphoreIF::NO_TIMEOUT) override; @@ -60,16 +60,17 @@ public: /** * Same as lockBinarySemaphore() with timeout in FreeRTOS ticks. * @param timeoutTicks - * @return - @c RETURN_OK on success - * - @c RETURN_FAILED on failure + * @return -@c RETURN_OK on success + * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout */ ReturnValue_t acquireWithTickTimeout(TickType_t timeoutTicks = BinarySemaphore::NO_TIMEOUT); /** - * Give back the binary semaphore - * @return - @c RETURN_OK on success - * - @c RETURN_FAILED on failure + * Release the binary semaphore. + * @return -@c RETURN_OK on success + * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is + * already available. */ ReturnValue_t release() override; @@ -82,20 +83,22 @@ public: /** * Wrapper function to give back semaphore from handle * @param semaphore - * @return - @c RETURN_OK on success - * - @c RETURN_FAILED on failure + * @return -@c RETURN_OK on success + * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is + * already available. */ - static ReturnValue_t giveBinarySemaphore(SemaphoreHandle_t semaphore); + static ReturnValue_t release(SemaphoreHandle_t semaphore); /** * 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 - * @return - @c RETURN_OK on success - * - @c RETURN_FAILED on failure + * @return -@c RETURN_OK on success + * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is + * already available. */ - static ReturnValue_t giveBinarySemaphoreFromISR(SemaphoreHandle_t semaphore, + static ReturnValue_t releaseFromISR(SemaphoreHandle_t semaphore, BaseType_t * higherPriorityTaskWoken); protected: diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.h b/osal/FreeRTOS/CountingSemaphUsingTask.h index 2c54b31ba..73d3f987c 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.h +++ b/osal/FreeRTOS/CountingSemaphUsingTask.h @@ -12,7 +12,7 @@ extern "C" { /** * @brief Couting Semaphore implementation which uses the notification value * of the task. The notification value should therefore not be used - * for other purposes + * for other purposes. * @details * Additional information: https://www.freertos.org/RTOS-task-notifications.html * and general semaphore documentation. @@ -22,17 +22,37 @@ public: CountingSemaphoreUsingTask(const uint8_t maxCount, uint8_t initCount); virtual ~CountingSemaphoreUsingTask(); + /** + * Acquire the counting semaphore. + * If no semaphores are available, the task will be blocked + * for a maximum of #timeoutMs or until one is given back, + * for example by an ISR or another task. + * @param timeoutMs + * @return -@c RETURN_OK on success + * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout + */ ReturnValue_t acquire(uint32_t timeoutMs = SemaphoreIF::NO_TIMEOUT) override; + + /** + * Release a semaphore, increasing the number of available counting + * semaphores up to the #maxCount value. + * @return -@c RETURN_OK on success + * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if #maxCount semaphores are + * already available. + */ ReturnValue_t release() override; + uint8_t getSemaphoreCounter() const override; static uint8_t getSemaphoreCounterFromISR(TaskHandle_t task); + /** - * Acquire, using a timeout value in ticks + * Acquire with a timeout value in ticks * @param timeoutTicks - * @return + * @return -@c RETURN_OK on success + * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout */ ReturnValue_t acquireWithTickTimeout( - TickType_t timeoutTicks= SemaphoreIF::NO_TIMEOUT); + TickType_t timeoutTicks = SemaphoreIF::NO_TIMEOUT); /** * Get handle to the task related to the semaphore. @@ -43,13 +63,17 @@ public: /** * Release semaphore of task by supplying task handle * @param taskToNotify - * @return + * @return -@c RETURN_OK on success + * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if #maxCount semaphores are + * already available. */ static ReturnValue_t release(TaskHandle_t taskToNotify); /** * Release seamphore of a task from an ISR. * @param taskToNotify - * @return + * @return -@c RETURN_OK on success + * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if #maxCount semaphores are + * already available. */ static ReturnValue_t releaseFromISR(TaskHandle_t taskToNotify, BaseType_t* higherPriorityTaskWoken); diff --git a/osal/FreeRTOS/CountingSemaphore.h b/osal/FreeRTOS/CountingSemaphore.h index 77050f900..bed3c7260 100644 --- a/osal/FreeRTOS/CountingSemaphore.h +++ b/osal/FreeRTOS/CountingSemaphore.h @@ -21,6 +21,10 @@ public: CountingSemaphore (CountingSemaphore &&); //! @brief Move assignment CountingSemaphore & operator=(CountingSemaphore &&); + + /* Same API as binary semaphore otherwise. acquire() can be called + * until there are not semaphores left and release() can be called + * until maxCount is reached. */ private: const uint8_t maxCount; uint8_t initCount = 0; From 60872f936ce2c2566b388e1e40bdb24194178453 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 27 May 2020 23:43:40 +0200 Subject: [PATCH 13/33] some output improvements --- osal/FreeRTOS/CountingSemaphUsingTask.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.cpp b/osal/FreeRTOS/CountingSemaphUsingTask.cpp index c29f52589..d34c7d6a8 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.cpp +++ b/osal/FreeRTOS/CountingSemaphUsingTask.cpp @@ -12,19 +12,19 @@ CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t 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; + sif::error << "CountingSemaphoreUsingTask: 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; + sif::warning << "CountinSemaphoreUsingTask: 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++; From 8676fcd9a929b619b65c1598434c75261fdb74b1 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 00:47:54 +0200 Subject: [PATCH 14/33] yay, linux bin semaph finished --- osal/linux/BinarySemaphore.cpp | 127 ++++++++++++++++++++++++++++++++ osal/linux/BinarySemaphore.h | 68 +++++++++++++++++ osal/linux/MessageQueue.cpp | 2 +- osal/linux/Mutex.h | 4 +- osal/linux/SemaphoreFactory.cpp | 6 +- tasks/SemaphoreFactory.h | 2 +- tasks/SemaphoreIF.h | 2 +- 7 files changed, 203 insertions(+), 8 deletions(-) create mode 100644 osal/linux/BinarySemaphore.cpp create mode 100644 osal/linux/BinarySemaphore.h diff --git a/osal/linux/BinarySemaphore.cpp b/osal/linux/BinarySemaphore.cpp new file mode 100644 index 000000000..ed1045e0a --- /dev/null +++ b/osal/linux/BinarySemaphore.cpp @@ -0,0 +1,127 @@ +#include +#include + +extern "C" { +#include +#include +} + +BinarySemaphore::BinarySemaphore() { + // Using unnamed semaphores for now + initSemaphore(); +} + +BinarySemaphore::~BinarySemaphore() { + sem_destroy(&handle); +} + +BinarySemaphore::BinarySemaphore(BinarySemaphore&& s) { + initSemaphore(); +} + +BinarySemaphore& BinarySemaphore::operator =( + BinarySemaphore&& s) { + initSemaphore(); + return * this; +} + +ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { + int result = 0; + if(timeoutMs == SemaphoreIF::NO_TIMEOUT) { + result = sem_trywait(&handle); + } + if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { + result = sem_wait(&handle); + } + else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){ + timespec timeOut; + clock_gettime(CLOCK_REALTIME, &timeOut); + uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec; + nseconds += timeoutMs * 1000000; + timeOut.tv_sec = nseconds / 1000000000; + timeOut.tv_nsec = nseconds - timeOut.tv_sec * 1000000000; + result = sem_timedwait(&handle, &timeOut); + if(result != 0 and errno == EINVAL) { + sif::debug << "BinarySemaphore::acquire: Invalid time value possible" + << std::endl; + } + } + if(result == 0) { + return HasReturnvaluesIF::RETURN_OK; + } + + switch(result) { + case(EAGAIN): + // Operation could not be performed without blocking (for sem_trywait) + case(ETIMEDOUT): + // Semaphore is 0 + return SemaphoreIF::SEMAPHORE_TIMEOUT; + case(EINVAL): + // Semaphore invalid + return SemaphoreIF::SEMAPHORE_INVALID; + case(EINTR): + // Call was interrupted by signal handler + sif::debug << "BinarySemaphore::acquire: Signal handler interrupted" + << std::endl; + /* No break */ + default: + return HasReturnvaluesIF::RETURN_FAILED; + } +} + +ReturnValue_t BinarySemaphore::release() { + return release(&this->handle); +} + +ReturnValue_t BinarySemaphore::release(sem_t *handle) { + int result = sem_post(handle); + if(result == 0) { + return HasReturnvaluesIF::RETURN_OK; + } + + switch(errno) { + case(EINVAL): + // Semaphore invalid + return SemaphoreIF::SEMAPHORE_INVALID; + case(EOVERFLOW): + // SEM_MAX_VALUE overflow. This should never happen + default: + return HasReturnvaluesIF::RETURN_FAILED; + } +} + +uint8_t BinarySemaphore::getSemaphoreCounter() const { + // And another ugly cast :-D + return getSemaphoreCounter(const_cast(&this->handle)); +} + +uint8_t BinarySemaphore::getSemaphoreCounter(sem_t *handle) { + int value = 0; + int result = sem_getvalue(handle, &value); + if (result == 0) { + return value; + } + else if(result != 0 and errno == EINVAL) { + sif::debug << "BInarySemaphore::getSemaphoreCounter: Invalid" + " Semaphore." << std::endl; + return 0; + } + else { + // This should never happen. + return 0; + } +} + +void BinarySemaphore::initSemaphore() { + auto result = sem_init(&handle, true, 1); + if(result == -1) { + switch(errno) { + case(EINVAL): + // Value excees SEM_VALUE_MAX + case(ENOSYS): + // System does not support process-shared semaphores + sif::error << "BinarySemaphore: Init failed with" << strerror(errno) + << std::endl; + } + } +} diff --git a/osal/linux/BinarySemaphore.h b/osal/linux/BinarySemaphore.h new file mode 100644 index 000000000..d18b3eaa8 --- /dev/null +++ b/osal/linux/BinarySemaphore.h @@ -0,0 +1,68 @@ +#ifndef FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ +#define FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ + +#include +#include + +extern "C" { +#include +} + +/** + * @brief OS Tool to achieve synchronization of between tasks or between + * task and ISR. The default semaphore implementation creates a + * binary semaphore, which can only be taken once. + * @details + * See: http://www.man7.org/linux/man-pages/man7/sem_overview.7.html + * @author R. Mueller + * @ingroup osal + */ +class BinarySemaphore: public SemaphoreIF, + public HasReturnvaluesIF { +public: + static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; + + //! @brief Default ctor + BinarySemaphore(); + //! @brief Copy ctor, deleted explicitely. + BinarySemaphore(const BinarySemaphore&) = delete; + //! @brief Copy assignment, deleted explicitely. + BinarySemaphore& operator=(const BinarySemaphore&) = delete; + //! @brief Move ctor + BinarySemaphore (BinarySemaphore &&); + //! @brief Move assignment + BinarySemaphore & operator=(BinarySemaphore &&); + //! @brief Destructor + virtual ~BinarySemaphore(); + + void initSemaphore(); + + uint8_t getSemaphoreCounter() const override; + static uint8_t getSemaphoreCounter(sem_t* handle); + /** + * 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 SemaphoreIF::SEMAPHORE_TIMEOUT on timeout + */ + ReturnValue_t acquire(uint32_t timeoutMs = + SemaphoreIF::NO_TIMEOUT) override; + + /** + * Release the binary semaphore. + * @return -@c RETURN_OK on success + * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is + * already available. + */ + ReturnValue_t release() override; + + static ReturnValue_t release(sem_t* handle); + +protected: + sem_t handle; +}; + +#endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */ diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 96d9fb4d0..48ba29e80 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -7,7 +7,7 @@ #include -MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) : +MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): id(0), lastPartner(0), defaultDestination(NO_QUEUE) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; mq_attr attributes; diff --git a/osal/linux/Mutex.h b/osal/linux/Mutex.h index 872ac3ac4..607337aea 100644 --- a/osal/linux/Mutex.h +++ b/osal/linux/Mutex.h @@ -1,5 +1,5 @@ -#ifndef OS_RTEMS_MUTEX_H_ -#define OS_RTEMS_MUTEX_H_ +#ifndef OS_LINUX_MUTEX_H_ +#define OS_LINUX_MUTEX_H_ #include diff --git a/osal/linux/SemaphoreFactory.cpp b/osal/linux/SemaphoreFactory.cpp index b1100e750..db4bebb35 100644 --- a/osal/linux/SemaphoreFactory.cpp +++ b/osal/linux/SemaphoreFactory.cpp @@ -20,18 +20,18 @@ SemaphoreFactory* SemaphoreFactory::instance() { return SemaphoreFactory::factoryInstance; } -SemaphoreIF* SemaphoreFactory::createBinarySemaphore() { +SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) { sif::error << "Semaphore not implemented for Linux yet" << std::endl; return nullptr; } SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t count, - uint8_t initCount) { + uint8_t initCount, uint32_t arguments) { sif::error << "Counting Semaphore not implemented for " "Linux yet" << std::endl; return nullptr; } -void SemaphoreFactory::deleteMutex(SemaphoreIF* semaphore) { +void SemaphoreFactory::deleteSemaphore(SemaphoreIF* semaphore) { delete semaphore; } diff --git a/tasks/SemaphoreFactory.h b/tasks/SemaphoreFactory.h index 3e21be368..7f8edaf12 100644 --- a/tasks/SemaphoreFactory.h +++ b/tasks/SemaphoreFactory.h @@ -36,7 +36,7 @@ public: SemaphoreIF* createCountingSemaphore(const uint8_t maxCount, uint8_t initCount, uint32_t arguments = 0); - void deleteSemaphore(SemaphoreIF* mutex); + void deleteSemaphore(SemaphoreIF* semaphore); private: /** diff --git a/tasks/SemaphoreIF.h b/tasks/SemaphoreIF.h index 044e03a8d..a7c5a97b9 100644 --- a/tasks/SemaphoreIF.h +++ b/tasks/SemaphoreIF.h @@ -30,7 +30,7 @@ public: static constexpr ReturnValue_t SEMAPHORE_TIMEOUT = MAKE_RETURN_CODE(1); //! The current semaphore can not be given, because it is not owned static constexpr ReturnValue_t SEMAPHORE_NOT_OWNED = MAKE_RETURN_CODE(2); - static constexpr ReturnValue_t SEMAPHORE_NULLPOINTER = MAKE_RETURN_CODE(3); + static constexpr ReturnValue_t SEMAPHORE_INVALID = MAKE_RETURN_CODE(3); /** * Generic call to acquire a semaphore. From 56498e5bc12076330e8f1b74ce7955b16005d0aa Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 00:50:44 +0200 Subject: [PATCH 15/33] linux bin semaph unlocked --- osal/linux/SemaphoreFactory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osal/linux/SemaphoreFactory.cpp b/osal/linux/SemaphoreFactory.cpp index db4bebb35..8d29ffe39 100644 --- a/osal/linux/SemaphoreFactory.cpp +++ b/osal/linux/SemaphoreFactory.cpp @@ -1,4 +1,5 @@ #include +#include #include const uint32_t SemaphoreIF::NO_TIMEOUT = 0; @@ -21,8 +22,7 @@ SemaphoreFactory* SemaphoreFactory::instance() { } SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) { - sif::error << "Semaphore not implemented for Linux yet" << std::endl; - return nullptr; + return new BinarySemaphore(); } SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t count, From 671f298935a640e33274e1a5fd52339e790068b6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 01:41:16 +0200 Subject: [PATCH 16/33] implemented counting semaph for linux --- osal/FreeRTOS/CountingSemaphore.cpp | 10 ++++++ osal/FreeRTOS/CountingSemaphore.h | 1 + osal/linux/BinarySemaphore.cpp | 43 +++++++++++++++++------ osal/linux/BinarySemaphore.h | 23 +++++++++--- osal/linux/CountingSemaphore.cpp | 54 +++++++++++++++++++++++++++++ osal/linux/CountingSemaphore.h | 37 ++++++++++++++++++++ osal/linux/SemaphoreFactory.cpp | 7 ++-- 7 files changed, 155 insertions(+), 20 deletions(-) create mode 100644 osal/linux/CountingSemaphore.cpp create mode 100644 osal/linux/CountingSemaphore.h diff --git a/osal/FreeRTOS/CountingSemaphore.cpp b/osal/FreeRTOS/CountingSemaphore.cpp index a23f32a03..c838f3e2d 100644 --- a/osal/FreeRTOS/CountingSemaphore.cpp +++ b/osal/FreeRTOS/CountingSemaphore.cpp @@ -10,6 +10,12 @@ extern "C" { // free FreeRTOSConfig.h file. CountingSemaphore::CountingSemaphore(const uint8_t maxCount, uint8_t initCount): maxCount(maxCount), initCount(initCount) { + if(initCount > maxCount) { + sif::error << "CountingSemaphoreUsingTask: Max count bigger than " + "intial cout. Setting initial count to max count." << std::endl; + initCount = maxCount; + } + handle = xSemaphoreCreateCounting(maxCount, initCount); if(handle == nullptr) { sif::error << "CountingSemaphore: Creation failure" << std::endl; @@ -33,3 +39,7 @@ CountingSemaphore& CountingSemaphore::operator =( return * this; } + +uint8_t CountingSemaphore::getMaxCount() const { + return maxCount; +} diff --git a/osal/FreeRTOS/CountingSemaphore.h b/osal/FreeRTOS/CountingSemaphore.h index bed3c7260..dca3ab0ed 100644 --- a/osal/FreeRTOS/CountingSemaphore.h +++ b/osal/FreeRTOS/CountingSemaphore.h @@ -25,6 +25,7 @@ public: /* Same API as binary semaphore otherwise. acquire() can be called * until there are not semaphores left and release() can be called * until maxCount is reached. */ + uint8_t getMaxCount() const; private: const uint8_t maxCount; uint8_t initCount = 0; diff --git a/osal/linux/BinarySemaphore.cpp b/osal/linux/BinarySemaphore.cpp index ed1045e0a..7c76a5c4f 100644 --- a/osal/linux/BinarySemaphore.cpp +++ b/osal/linux/BinarySemaphore.cpp @@ -30,7 +30,7 @@ ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { if(timeoutMs == SemaphoreIF::NO_TIMEOUT) { result = sem_trywait(&handle); } - if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { + else if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { result = sem_wait(&handle); } else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){ @@ -50,7 +50,7 @@ ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { return HasReturnvaluesIF::RETURN_OK; } - switch(result) { + switch(errno) { case(EAGAIN): // Operation could not be performed without blocking (for sem_trywait) case(ETIMEDOUT): @@ -61,8 +61,8 @@ ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { return SemaphoreIF::SEMAPHORE_INVALID; case(EINTR): // Call was interrupted by signal handler - sif::debug << "BinarySemaphore::acquire: Signal handler interrupted" - << std::endl; + sif::debug << "BinarySemaphore::acquire: Signal handler interrupted." + "Code " << strerror(errno) << std::endl; /* No break */ default: return HasReturnvaluesIF::RETURN_FAILED; @@ -70,10 +70,15 @@ ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { } ReturnValue_t BinarySemaphore::release() { - return release(&this->handle); + return BinarySemaphore::release(&this->handle); } ReturnValue_t BinarySemaphore::release(sem_t *handle) { + ReturnValue_t countResult = checkCount(handle, 1); + if(countResult != HasReturnvaluesIF::RETURN_OK) { + return countResult; + } + int result = sem_post(handle); if(result == 0) { return HasReturnvaluesIF::RETURN_OK; @@ -102,8 +107,8 @@ uint8_t BinarySemaphore::getSemaphoreCounter(sem_t *handle) { return value; } else if(result != 0 and errno == EINVAL) { - sif::debug << "BInarySemaphore::getSemaphoreCounter: Invalid" - " Semaphore." << std::endl; + // Could be called from interrupt, use lightweight printf + printf("BinarySemaphore::getSemaphoreCounter: Invalid semaphore\n"); return 0; } else { @@ -112,16 +117,32 @@ uint8_t BinarySemaphore::getSemaphoreCounter(sem_t *handle) { } } -void BinarySemaphore::initSemaphore() { - auto result = sem_init(&handle, true, 1); +void BinarySemaphore::initSemaphore(uint8_t initCount) { + auto result = sem_init(&handle, true, initCount); if(result == -1) { switch(errno) { case(EINVAL): - // Value excees SEM_VALUE_MAX + // Value exceeds SEM_VALUE_MAX case(ENOSYS): // System does not support process-shared semaphores sif::error << "BinarySemaphore: Init failed with" << strerror(errno) - << std::endl; + << std::endl; } } } + +ReturnValue_t BinarySemaphore::checkCount(sem_t* handle, uint8_t maxCount) { + int value = getSemaphoreCounter(handle); + if(value >= maxCount) { + if(maxCount == 1 and value > 1) { + // Binary Semaphore special case. + // This is a config error use lightweight printf is this is called + // from an interrupt + printf("BinarySemaphore::release: Value of binary semaphore greater" + " than 1!\n"); + return HasReturnvaluesIF::RETURN_FAILED; + } + return SemaphoreIF::SEMAPHORE_NOT_OWNED; + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/osal/linux/BinarySemaphore.h b/osal/linux/BinarySemaphore.h index d18b3eaa8..7836cd413 100644 --- a/osal/linux/BinarySemaphore.h +++ b/osal/linux/BinarySemaphore.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ -#define FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ +#ifndef FRAMEWORK_OSAL_LINUX_BINARYSEMPAHORE_H_ +#define FRAMEWORK_OSAL_LINUX_BINARYSEMPAHORE_H_ #include #include @@ -35,10 +35,11 @@ public: //! @brief Destructor virtual ~BinarySemaphore(); - void initSemaphore(); + void initSemaphore(uint8_t initCount = 1); uint8_t getSemaphoreCounter() const override; static uint8_t getSemaphoreCounter(sem_t* handle); + /** * Take the binary semaphore. * If the semaphore has already been taken, the task will be blocked @@ -57,10 +58,22 @@ public: * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is * already available. */ - ReturnValue_t release() override; - + virtual ReturnValue_t release() override; + /** + * This static function can be used to release a semaphore by providing + * its handle. + * @param handle + * @return + */ static ReturnValue_t release(sem_t* handle); + /** Checks the validity of the semaphore count against a specified + * known maxCount + * @param handle + * @param maxCount + * @return + */ + static ReturnValue_t checkCount(sem_t* handle, uint8_t maxCount); protected: sem_t handle; }; diff --git a/osal/linux/CountingSemaphore.cpp b/osal/linux/CountingSemaphore.cpp new file mode 100644 index 000000000..dfc4d8013 --- /dev/null +++ b/osal/linux/CountingSemaphore.cpp @@ -0,0 +1,54 @@ +#include +#include + +CountingSemaphore::CountingSemaphore(const uint8_t maxCount, uint8_t initCount): + maxCount(maxCount), initCount(initCount) { + if(initCount > maxCount) { + sif::error << "CountingSemaphoreUsingTask: Max count bigger than " + "intial cout. Setting initial count to max count." << std::endl; + initCount = maxCount; + } + + initSemaphore(initCount); +} + +CountingSemaphore::CountingSemaphore(CountingSemaphore&& other): + maxCount(other.maxCount), initCount(other.initCount) { + initSemaphore(initCount); +} + +CountingSemaphore& CountingSemaphore::operator =( + CountingSemaphore&& other) { + initSemaphore(other.initCount); + return * this; +} + +ReturnValue_t CountingSemaphore::release() { + ReturnValue_t result = checkCount(&handle, maxCount); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return CountingSemaphore::release(&this->handle); +} + +ReturnValue_t CountingSemaphore::release(sem_t* handle) { + int result = sem_post(handle); + if(result == 0) { + return HasReturnvaluesIF::RETURN_OK; + } + + switch(errno) { + case(EINVAL): + // Semaphore invalid + return SemaphoreIF::SEMAPHORE_INVALID; + case(EOVERFLOW): + // SEM_MAX_VALUE overflow. This should never happen + default: + return HasReturnvaluesIF::RETURN_FAILED; + } +} + +uint8_t CountingSemaphore::getMaxCount() const { + return maxCount; +} + diff --git a/osal/linux/CountingSemaphore.h b/osal/linux/CountingSemaphore.h new file mode 100644 index 000000000..ba6065955 --- /dev/null +++ b/osal/linux/CountingSemaphore.h @@ -0,0 +1,37 @@ +#ifndef FRAMEWORK_OSAL_LINUX_COUNTINGSEMAPHORE_H_ +#define FRAMEWORK_OSAL_LINUX_COUNTINGSEMAPHORE_H_ +#include + +/** + * @brief Counting semaphores, which can be acquired more than once. + * @details + * See: https://www.freertos.org/CreateCounting.html + * API of counting semaphores is almost identical to binary semaphores, + * so we just inherit from binary semaphore and provide the respective + * constructors. + */ +class CountingSemaphore: public BinarySemaphore { +public: + CountingSemaphore(const uint8_t maxCount, uint8_t initCount); + //! @brief Copy ctor, disabled + CountingSemaphore(const CountingSemaphore&) = delete; + //! @brief Copy assignment, disabled + CountingSemaphore& operator=(const CountingSemaphore&) = delete; + //! @brief Move ctor + CountingSemaphore (CountingSemaphore &&); + //! @brief Move assignment + CountingSemaphore & operator=(CountingSemaphore &&); + + ReturnValue_t release() override; + static ReturnValue_t release(sem_t* sem); + /* Same API as binary semaphore otherwise. acquire() can be called + * until there are not semaphores left and release() can be called + * until maxCount is reached. */ + + uint8_t getMaxCount() const; +private: + const uint8_t maxCount; + uint8_t initCount = 0; +}; + +#endif /* FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_ */ diff --git a/osal/linux/SemaphoreFactory.cpp b/osal/linux/SemaphoreFactory.cpp index 8d29ffe39..5aec84eae 100644 --- a/osal/linux/SemaphoreFactory.cpp +++ b/osal/linux/SemaphoreFactory.cpp @@ -1,5 +1,6 @@ #include #include +#include #include const uint32_t SemaphoreIF::NO_TIMEOUT = 0; @@ -25,11 +26,9 @@ SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) { return new BinarySemaphore(); } -SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t count, +SemaphoreIF* SemaphoreFactory::createCountingSemaphore(const uint8_t maxCount, uint8_t initCount, uint32_t arguments) { - sif::error << "Counting Semaphore not implemented for " - "Linux yet" << std::endl; - return nullptr; + return new CountingSemaphore(maxCount, initCount); } void SemaphoreFactory::deleteSemaphore(SemaphoreIF* semaphore) { From ccf79ab5b63d5870dfd8aabde90895746f9cdc08 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 01:55:20 +0200 Subject: [PATCH 17/33] output correction for linux --- osal/linux/PeriodicPosixTask.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index 28a0b9461..f6a74901c 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -57,9 +57,11 @@ void PeriodicPosixTask::taskFunctionality(void){ char name[20] = {0}; int status = pthread_getname_np(pthread_self(),name,sizeof(name)); if(status==0){ - sif::error << "ObjectTask: " << name << " Deadline missed." << std::endl; + sif::error << "PeriodicPosixTask " << name << ": Deadline " + "missed." << std::endl; }else{ - sif::error << "ObjectTask: X Deadline missed. " << status << std::endl; + sif::error << "PeriodicPosixTask X: Deadline missed. " << + status << std::endl; } if (this->deadlineMissedFunc != NULL) { this->deadlineMissedFunc(); From 3d2935ac6917b6d8f20c68011cd77cf9d5890686 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 02:23:14 +0200 Subject: [PATCH 18/33] linux time lib improvements stop watch other function used (more precise for linux) --- osal/linux/Clock.cpp | 17 ++++++++++++++--- timemanager/Clock.h | 18 ++++++++++-------- timemanager/Stopwatch.cpp | 14 +++++--------- timemanager/Stopwatch.h | 9 ++------- 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/osal/linux/Clock.cpp b/osal/linux/Clock.cpp index e24a4fe4b..b3e5c84bf 100644 --- a/osal/linux/Clock.cpp +++ b/osal/linux/Clock.cpp @@ -1,11 +1,13 @@ -#include -#include +#include #include - +extern "C" { +#include #include #include +#include #include +} //#include uint16_t Clock::leapSeconds = 0; @@ -65,6 +67,15 @@ ReturnValue_t Clock::getClock_usecs(uint64_t* time) { return HasReturnvaluesIF::RETURN_OK; } +timeval Clock::getUptime() { + timeval uptime; + auto result = getUptime(&uptime); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Clock::getUptime: Error getting uptime" << std::endl; + } + return uptime; +} + ReturnValue_t Clock::getUptime(timeval* uptime) { //TODO This is not posix compatible and delivers only seconds precision struct sysinfo sysInfo; diff --git a/timemanager/Clock.h b/timemanager/Clock.h index 5f18de3ee..fcfacbc09 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -2,11 +2,12 @@ #define FRAMEWORK_TIMEMANAGER_CLOCK_H_ #include -#include -#include #include #include +#include +#include + typedef uint32_t millis_t; typedef float seconds_t; @@ -22,7 +23,7 @@ public: uint32_t usecond; //!< Microseconds, 0 .. 999999 } TimeOfDay_t; - /**static Clock* TimeOfDay_t(); + /** * This method returns the number of clock ticks per second. * In RTEMS, this is typically 1000. * @return The number of ticks. @@ -34,22 +35,23 @@ public: * This system call sets the system time. * To set the time, it uses a TimeOfDay_t struct. * @param time The struct with the time settings to set. - * @return \c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return -@c RETURN_OK on success. Otherwise, the OS failure code + * is returned. */ static ReturnValue_t setClock(const TimeOfDay_t* time); /** * This system call sets the system time. * To set the time, it uses a timeval struct. * @param time The struct with the time settings to set. - * @return \c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return -@c RETURN_OK on success. Otherwise, the OS failure code is returned. */ static ReturnValue_t setClock(const timeval* time); /** * This system call returns the current system clock in timeval format. - * The timval format has the fields \c tv_sec with seconds and \c tv_usec with + * The timval format has the fields @c tv_sec with seconds and @c tv_usec with * microseconds since an OS-defined epoch. * @param time A pointer to a timeval struct where the current time is stored. - * @return \c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return @c RETURN_OK on success. Otherwise, the OS failure code is returned. */ static ReturnValue_t getClock_timeval(timeval* time); @@ -57,7 +59,7 @@ public: * Get the time since boot in a timeval struct * * @param[out] time A pointer to a timeval struct where the uptime is stored. - * @return\c RETURN_OK on success. Otherwise, the OS failure code is returned. + * @return @c RETURN_OK on success. Otherwise, the OS failure code is returned. * * @deprecated, I do not think this should be able to fail, use timeval getUptime() */ diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index 1f287fb38..bc8b4149c 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -1,9 +1,3 @@ -/** - * @file Stopwatch.cpp - * - * @date 08.04.2020 - */ - #include #include #include @@ -12,11 +6,11 @@ Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode): displayOnDestruction( displayOnDestruction), displayMode(displayMode) { // Measures start time on initialization. - startTime = Clock::getUptime(); + Clock::getClock_timeval(&startTime); } void Stopwatch::start() { - startTime = Clock::getUptime(); + Clock::getClock_timeval(&startTime); } millis_t Stopwatch::stop() { @@ -57,5 +51,7 @@ StopwatchDisplayMode Stopwatch::getDisplayMode() const { } void Stopwatch::stopInternal() { - elapsedTime = Clock::getUptime() - startTime; + timeval endTime; + Clock::getClock_timeval(&endTime); + elapsedTime = endTime - startTime; } diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index f48c04eca..c57200b07 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -1,9 +1,3 @@ -/** - * @file Stopwatch.h - * - * @date 08.04.2020 - */ - #ifndef FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ #define FRAMEWORK_TIMEMANAGER_STOPWATCH_H_ #include @@ -14,12 +8,13 @@ enum class StopwatchDisplayMode { }; /** - * @brief Simple Stopwatch implementation to measure elapsed time + * @brief Simple Stopwatch implementation to measure elapsed time * @details * This class can be used to measure elapsed times. It also displays elapsed * times automatically on destruction if not explicitely deactivated in the * constructor. The default time format is the elapsed time in miliseconds * as a float. + * @author R. Mueller */ class Stopwatch { public: From da403c01d0178d814896d4c26561e092c1ac2a6e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 03:03:48 +0200 Subject: [PATCH 19/33] retval fix, unittest running again --- osal/FreeRTOS/BinSemaphUsingTask.cpp | 71 ++++++++++------------- osal/FreeRTOS/BinSemaphUsingTask.h | 9 ++- osal/FreeRTOS/BinarySemaphore.cpp | 40 ++++++------- osal/FreeRTOS/CountingSemaphUsingTask.cpp | 69 +++++++++------------- osal/FreeRTOS/CountingSemaphUsingTask.h | 17 +++++- 5 files changed, 94 insertions(+), 112 deletions(-) diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index 84b0b488e..51a3c5636 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 cad427831..316208801 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 7d882afff..7b695dee1 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 d34c7d6a8..d0f63f3f9 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 73d3f987c..797e864b5 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_ */ From 78ae109a08ec58c17b1b966944992da0b74da011 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 13:02:13 +0200 Subject: [PATCH 20/33] removed context switch request (shall be done at end of ISR, so must be performed by caller) --- osal/FreeRTOS/BinSemaphUsingTask.cpp | 9 ++++----- osal/FreeRTOS/BinSemaphUsingTask.h | 3 ++- osal/FreeRTOS/BinarySemaphore.cpp | 9 --------- osal/FreeRTOS/BinarySemaphore.h | 5 +++-- osal/FreeRTOS/MessageQueue.cpp | 2 +- osal/FreeRTOS/MessageQueue.h | 4 ++-- osal/FreeRTOS/TaskManagement.cpp | 4 ++-- osal/FreeRTOS/TaskManagement.h | 6 +++--- 8 files changed, 17 insertions(+), 25 deletions(-) diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index 51a3c5636..8f5fd4d8a 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.cpp +++ b/osal/FreeRTOS/BinSemaphUsingTask.cpp @@ -75,7 +75,7 @@ uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter( // Be careful with the stack size here. This is called from an ISR! ReturnValue_t BinarySemaphoreUsingTask::releaseFromISR( TaskHandle_t taskHandle, BaseType_t * higherPriorityTaskWoken) { - if(getSemaphoreCounterFromISR(taskHandle) == 1) { + if(getSemaphoreCounterFromISR(taskHandle, higherPriorityTaskWoken) == 1) { return SemaphoreIF::SEMAPHORE_NOT_OWNED; } vTaskNotifyGiveFromISR(taskHandle, higherPriorityTaskWoken); @@ -83,10 +83,9 @@ ReturnValue_t BinarySemaphoreUsingTask::releaseFromISR( } uint8_t BinarySemaphoreUsingTask::getSemaphoreCounterFromISR( - TaskHandle_t taskHandle) { - uint32_t notificationValue; - BaseType_t higherPriorityTaskWoken; + TaskHandle_t taskHandle, BaseType_t* higherPriorityTaskWoken) { + uint32_t notificationValue = 0; xTaskNotifyAndQueryFromISR(taskHandle, 0, eNoAction, ¬ificationValue, - &higherPriorityTaskWoken); + higherPriorityTaskWoken); return notificationValue; } diff --git a/osal/FreeRTOS/BinSemaphUsingTask.h b/osal/FreeRTOS/BinSemaphUsingTask.h index 316208801..e6cb2a074 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.h +++ b/osal/FreeRTOS/BinSemaphUsingTask.h @@ -32,7 +32,8 @@ public: ReturnValue_t release() override; uint8_t getSemaphoreCounter() const override; static uint8_t getSemaphoreCounter(TaskHandle_t taskHandle); - static uint8_t getSemaphoreCounterFromISR(TaskHandle_t taskHandle); + static uint8_t getSemaphoreCounterFromISR(TaskHandle_t taskHandle, + BaseType_t* higherPriorityTaskWoken); /** * Same as acquire() with timeout in FreeRTOS ticks. diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index 7b695dee1..b6687bb75 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -36,9 +36,6 @@ BinarySemaphore& BinarySemaphore::operator =( } ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { - if(handle == nullptr) { - return SemaphoreIF::SEMAPHORE_INVALID; - } TickType_t timeout = SemaphoreIF::NO_TIMEOUT; if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { timeout = SemaphoreIF::MAX_TIMEOUT; @@ -97,12 +94,6 @@ ReturnValue_t BinarySemaphore::releaseFromISR( } 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) { return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/FreeRTOS/BinarySemaphore.h b/osal/FreeRTOS/BinarySemaphore.h index f3839151d..de6092afd 100644 --- a/osal/FreeRTOS/BinarySemaphore.h +++ b/osal/FreeRTOS/BinarySemaphore.h @@ -92,8 +92,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 from an ISR should + * then be requested (see TaskManagement functions) * @return -@c RETURN_OK on success * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is * already available. diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index 9e4b581be..b56a62521 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -124,7 +124,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, bool ignoreFault, CallContext callContext) { message->setSender(sentFrom); BaseType_t result; - if(callContext == CallContext::task) { + if(callContext == CallContext::TASK) { result = xQueueSendToBack(reinterpret_cast(sendTo), static_cast(message->getBuffer()), 0); } diff --git a/osal/FreeRTOS/MessageQueue.h b/osal/FreeRTOS/MessageQueue.h index 988733f6b..8daab8f66 100644 --- a/osal/FreeRTOS/MessageQueue.h +++ b/osal/FreeRTOS/MessageQueue.h @@ -199,7 +199,7 @@ protected: */ static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo, MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, - bool ignoreFault=false, CallContext callContext = CallContext::task); + bool ignoreFault=false, CallContext callContext = CallContext::TASK); static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault); @@ -209,7 +209,7 @@ private: MessageQueueId_t defaultDestination = 0; MessageQueueId_t lastPartner = 0; //!< Stores the current system context - CallContext callContext = CallContext::task; + CallContext callContext = CallContext::TASK; }; #endif /* MESSAGEQUEUE_H_ */ diff --git a/osal/FreeRTOS/TaskManagement.cpp b/osal/FreeRTOS/TaskManagement.cpp index 4529b3710..7871ab2ec 100644 --- a/osal/FreeRTOS/TaskManagement.cpp +++ b/osal/FreeRTOS/TaskManagement.cpp @@ -5,8 +5,8 @@ void TaskManagement::requestContextSwitchFromTask() { } void TaskManagement::requestContextSwitch( - CallContext callContext = CallContext::task) { - if(callContext == CallContext::isr) { + CallContext callContext = CallContext::TASK) { + if(callContext == CallContext::ISR) { // This function depends on the partmacro.h definition for the specific device requestContextSwitchFromISR(); } else { diff --git a/osal/FreeRTOS/TaskManagement.h b/osal/FreeRTOS/TaskManagement.h index b9874db0c..39c24377b 100644 --- a/osal/FreeRTOS/TaskManagement.h +++ b/osal/FreeRTOS/TaskManagement.h @@ -21,9 +21,9 @@ extern "C" void requestContextSwitchFromISR(); * has different functions for handling semaphores and messages from within * an ISR and task. */ -enum CallContext { - task = 0x00,//!< task_context - isr = 0xFF //!< isr_context +enum class CallContext { + TASK = 0x00,//!< task_context + ISR = 0xFF //!< isr_context }; From 5169c09fd8d56eb041011da9062bb325578a313e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 13:07:35 +0200 Subject: [PATCH 21/33] improved includes --- osal/FreeRTOS/Clock.cpp | 9 +++++---- osal/FreeRTOS/Timekeeper.cpp | 9 +-------- osal/FreeRTOS/Timekeeper.h | 3 ++- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index 5e597f258..d1c9f97ba 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -1,13 +1,14 @@ #include #include -#include -#include "Timekeeper.h" +#include extern "C" { -#include -#include +#include +#include } +#include +#include //TODO sanitize input? //TODO much of this code can be reused for tick-only systems diff --git a/osal/FreeRTOS/Timekeeper.cpp b/osal/FreeRTOS/Timekeeper.cpp index 949e1df3c..9fd4af623 100644 --- a/osal/FreeRTOS/Timekeeper.cpp +++ b/osal/FreeRTOS/Timekeeper.cpp @@ -1,13 +1,6 @@ -/** - * @file Timekeeper.cpp - * @date - */ - #include -extern "C" { -#include -} +#include "FreeRTOSConfig.h" Timekeeper * Timekeeper::myinstance = nullptr; diff --git a/osal/FreeRTOS/Timekeeper.h b/osal/FreeRTOS/Timekeeper.h index 05f0f7011..8709e362c 100644 --- a/osal/FreeRTOS/Timekeeper.h +++ b/osal/FreeRTOS/Timekeeper.h @@ -3,7 +3,8 @@ #include extern "C" { -#include +#include +#include } From e7ae35c6592fb101ebe2fd44517a8cfc62b1096d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 13:09:47 +0200 Subject: [PATCH 22/33] improved structure a bit --- osal/FreeRTOS/Timekeeper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osal/FreeRTOS/Timekeeper.cpp b/osal/FreeRTOS/Timekeeper.cpp index 9fd4af623..643b27479 100644 --- a/osal/FreeRTOS/Timekeeper.cpp +++ b/osal/FreeRTOS/Timekeeper.cpp @@ -4,7 +4,9 @@ Timekeeper * Timekeeper::myinstance = nullptr; -Timekeeper::Timekeeper() : offset( { 0, 0 }) {} +Timekeeper::Timekeeper() : offset( { 0, 0 } ) {} + +Timekeeper::~Timekeeper() {} const timeval& Timekeeper::getOffset() const { return offset; @@ -21,8 +23,6 @@ void Timekeeper::setOffset(const timeval& offset) { this->offset = offset; } -Timekeeper::~Timekeeper() {} - timeval Timekeeper::ticksToTimeval(TickType_t ticks) { timeval uptime; uptime.tv_sec = ticks / configTICK_RATE_HZ; From d5352a9b87a604cd8535963d2a7fcc8176b2182b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 13:15:37 +0200 Subject: [PATCH 23/33] actually extern "C" is not needed it is included by freeRTOS --- osal/FreeRTOS/Clock.cpp | 6 ++---- osal/FreeRTOS/Timekeeper.h | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index d1c9f97ba..dce202657 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -2,10 +2,8 @@ #include #include -extern "C" { #include #include -} #include #include @@ -14,7 +12,7 @@ extern "C" { //TODO much of this code can be reused for tick-only systems uint16_t Clock::leapSeconds = 0; -MutexIF* Clock::timeMutex = NULL; +MutexIF* Clock::timeMutex = nullptr; uint32_t Clock::getTicksPerSecond(void) { return 1000; @@ -131,7 +129,7 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) { ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) { //SHOULDDO: works not for dates in the past (might have less leap seconds) - if (timeMutex == NULL) { + if (timeMutex == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/osal/FreeRTOS/Timekeeper.h b/osal/FreeRTOS/Timekeeper.h index 8709e362c..7d3ca22b7 100644 --- a/osal/FreeRTOS/Timekeeper.h +++ b/osal/FreeRTOS/Timekeeper.h @@ -2,10 +2,9 @@ #define FRAMEWORK_OSAL_FREERTOS_TIMEKEEPER_H_ #include -extern "C" { + #include #include -} /** From 6a3dc94108304d9cf0cdde1cc82ecc6dc62390d8 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 13:18:27 +0200 Subject: [PATCH 24/33] removed extern "C" for freertos includes --- osal/FreeRTOS/BinSemaphUsingTask.h | 2 -- osal/FreeRTOS/BinarySemaphore.h | 2 -- osal/FreeRTOS/CountingSemaphore.cpp | 2 -- osal/FreeRTOS/MessageQueue.cpp | 2 +- osal/FreeRTOS/MessageQueue.h | 7 ------- osal/FreeRTOS/Mutex.cpp | 2 +- osal/FreeRTOS/Mutex.h | 3 --- 7 files changed, 2 insertions(+), 18 deletions(-) diff --git a/osal/FreeRTOS/BinSemaphUsingTask.h b/osal/FreeRTOS/BinSemaphUsingTask.h index e6cb2a074..48c1cd12d 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.h +++ b/osal/FreeRTOS/BinSemaphUsingTask.h @@ -4,10 +4,8 @@ #include #include -extern "C" { #include #include -} /** * @brief Binary Semaphore implementation using the task notification value. diff --git a/osal/FreeRTOS/BinarySemaphore.h b/osal/FreeRTOS/BinarySemaphore.h index de6092afd..0938dee6f 100644 --- a/osal/FreeRTOS/BinarySemaphore.h +++ b/osal/FreeRTOS/BinarySemaphore.h @@ -4,10 +4,8 @@ #include #include -extern "C" { #include #include -} /** * @brief OS Tool to achieve synchronization of between tasks or between diff --git a/osal/FreeRTOS/CountingSemaphore.cpp b/osal/FreeRTOS/CountingSemaphore.cpp index c838f3e2d..957f6a319 100644 --- a/osal/FreeRTOS/CountingSemaphore.cpp +++ b/osal/FreeRTOS/CountingSemaphore.cpp @@ -2,9 +2,7 @@ #include #include -extern "C" { #include -} // Make sure #define configUSE_COUNTING_SEMAPHORES 1 is set in // free FreeRTOSConfig.h file. diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index b56a62521..0a579296b 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -1,4 +1,4 @@ -#include "MessageQueue.h" +#include #include diff --git a/osal/FreeRTOS/MessageQueue.h b/osal/FreeRTOS/MessageQueue.h index 8daab8f66..81b4c186d 100644 --- a/osal/FreeRTOS/MessageQueue.h +++ b/osal/FreeRTOS/MessageQueue.h @@ -6,11 +6,8 @@ #include #include -extern "C" { #include #include -} - // TODO: this class assumes that MessageQueueId_t is the same size as void* // (the FreeRTOS handle type), compiler will catch this but it might be nice @@ -164,11 +161,7 @@ public: MessageQueueId_t getId() const; /** -<<<<<<< HEAD - * \brief This method is a simple setter for the default destination. -======= * @brief This method is a simple setter for the default destination. ->>>>>>> mueller_BinSempahInterface */ void setDefaultDestination(MessageQueueId_t defaultDestination); /** diff --git a/osal/FreeRTOS/Mutex.cpp b/osal/FreeRTOS/Mutex.cpp index 25513a819..e304d60e9 100644 --- a/osal/FreeRTOS/Mutex.cpp +++ b/osal/FreeRTOS/Mutex.cpp @@ -1,4 +1,4 @@ -#include "Mutex.h" +#include #include diff --git a/osal/FreeRTOS/Mutex.h b/osal/FreeRTOS/Mutex.h index ef93fd344..e04cd20d2 100644 --- a/osal/FreeRTOS/Mutex.h +++ b/osal/FreeRTOS/Mutex.h @@ -3,11 +3,8 @@ #include -extern "C" { #include #include -} - /** * @brief OS component to implement MUTual EXclusion From f14bacba32e97c7d74e55405d59b9230ec4e362c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 14:15:45 +0200 Subject: [PATCH 25/33] using nullptr now added new distinction between blocking (MAX_TIMEOUT) and polling (NO_TIMEOUT) --- ipc/MutexIF.h | 2 +- osal/FreeRTOS/Mutex.cpp | 18 +++++++++++------- osal/FreeRTOS/Mutex.h | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ipc/MutexIF.h b/ipc/MutexIF.h index a4aff1cd8..dcb1cf333 100644 --- a/ipc/MutexIF.h +++ b/ipc/MutexIF.h @@ -13,7 +13,7 @@ class MutexIF { public: static const uint32_t NO_TIMEOUT; //!< Needs to be defined in implementation. - + static const uint32_t MAX_TIMEOUT; static const uint8_t INTERFACE_ID = CLASS_ID::MUTEX_IF; /** * The system lacked the necessary resources (other than memory) to initialize another mutex. diff --git a/osal/FreeRTOS/Mutex.cpp b/osal/FreeRTOS/Mutex.cpp index e304d60e9..cc2f865ff 100644 --- a/osal/FreeRTOS/Mutex.cpp +++ b/osal/FreeRTOS/Mutex.cpp @@ -3,27 +3,31 @@ #include const uint32_t MutexIF::NO_TIMEOUT = 0; +const uint32_t MutexIF::MAX_TIMEOUT = portMAX_DELAY; Mutex::Mutex() { handle = xSemaphoreCreateMutex(); - if(handle == NULL) { - sif::error << "Mutex creation failure" << std::endl; + if(handle == nullptr) { + sif::error << "Mutex: Creation failure" << std::endl; } } Mutex::~Mutex() { - if (handle != 0) { + if (handle != nullptr) { vSemaphoreDelete(handle); } } ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { - if (handle == 0) { + if (handle == nullptr) { return MutexIF::MUTEX_NOT_FOUND; } - TickType_t timeout = portMAX_DELAY; - if (timeoutMs != NO_TIMEOUT) { + TickType_t timeout = MutexIF::NO_TIMEOUT; + if(timeoutMs == MutexIF::MAX_TIMEOUT) { + timeout = MutexIF::MAX_TIMEOUT; + } + else if(timeoutMs > MutexIF::NO_TIMEOUT){ timeout = pdMS_TO_TICKS(timeoutMs); } @@ -36,7 +40,7 @@ ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { } ReturnValue_t Mutex::unlockMutex() { - if (handle == 0) { + if (handle == nullptr) { return MutexIF::MUTEX_NOT_FOUND; } BaseType_t returncode = xSemaphoreGive(handle); diff --git a/osal/FreeRTOS/Mutex.h b/osal/FreeRTOS/Mutex.h index e04cd20d2..90e824678 100644 --- a/osal/FreeRTOS/Mutex.h +++ b/osal/FreeRTOS/Mutex.h @@ -18,7 +18,7 @@ class Mutex : public MutexIF { public: Mutex(); ~Mutex(); - ReturnValue_t lockMutex(uint32_t timeoutMs) override; + ReturnValue_t lockMutex(uint32_t timeoutMs = MutexIF::MAX_TIMEOUT) override; ReturnValue_t unlockMutex() override; private: SemaphoreHandle_t handle; From b90492562ac44f576ab7c7519826ae272d5be68e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 16:40:57 +0200 Subject: [PATCH 26/33] added author tag back at class definition --- storagemanager/LocalPool.h | 1 + 1 file changed, 1 insertion(+) diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index c155f918b..2d61dea51 100644 --- a/storagemanager/LocalPool.h +++ b/storagemanager/LocalPool.h @@ -22,6 +22,7 @@ * 0xFFFF-1 bytes. * It is possible to store empty packets in the pool. * The local pool is NOT thread-safe. + * @author Bastian Baetz */ template From 5cf9e938cccf450c5a4ad5b7fb74f7cc4b3705ff Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 16:45:03 +0200 Subject: [PATCH 27/33] added include protection --- storagemanager/LocalPool.tpp | 4 ++++ storagemanager/PoolManager.tpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/storagemanager/LocalPool.tpp b/storagemanager/LocalPool.tpp index 32724bd8c..dd360a0ab 100644 --- a/storagemanager/LocalPool.tpp +++ b/storagemanager/LocalPool.tpp @@ -1,6 +1,10 @@ #ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_TPP_ #define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_TPP_ +#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ +#error Include LocalPool.h instead of LocalPool.tpp!. +#endif + template inline LocalPool::LocalPool(object_id_t setObjectId, const uint16_t element_sizes[NUMBER_OF_POOLS], diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp index 854e22daa..bdc73ec28 100644 --- a/storagemanager/PoolManager.tpp +++ b/storagemanager/PoolManager.tpp @@ -1,6 +1,10 @@ #ifndef FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ #define FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ +#ifndef FRAMEWORK_STORAGEMANAGER_POOLMANAGER_H_ +#error Include LocalPool.h instead of LocalPool.tpp!. +#endif + template inline PoolManager::PoolManager(object_id_t setObjectId, const uint16_t element_sizes[NUMBER_OF_POOLS], From 3ef939aca8cff90c0ad51418e859eb69a76a655f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 16:46:26 +0200 Subject: [PATCH 28/33] fixed inclue protection --- storagemanager/LocalPool.tpp | 2 +- storagemanager/PoolManager.tpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storagemanager/LocalPool.tpp b/storagemanager/LocalPool.tpp index dd360a0ab..b7fa0da96 100644 --- a/storagemanager/LocalPool.tpp +++ b/storagemanager/LocalPool.tpp @@ -2,7 +2,7 @@ #define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_TPP_ #ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ -#error Include LocalPool.h instead of LocalPool.tpp!. +#error Include LocalPool.h instead of LocalPool.tpp! #endif template diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp index bdc73ec28..97603246e 100644 --- a/storagemanager/PoolManager.tpp +++ b/storagemanager/PoolManager.tpp @@ -2,7 +2,7 @@ #define FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ #ifndef FRAMEWORK_STORAGEMANAGER_POOLMANAGER_H_ -#error Include LocalPool.h instead of LocalPool.tpp!. +#error Include LocalPool.h instead of LocalPool.tpp! #endif template From 6b0558d6c71a5b23b2f678d5b18e170cde60e706 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 16:49:11 +0200 Subject: [PATCH 29/33] added author tag back --- storagemanager/PoolManager.h | 1 + 1 file changed, 1 insertion(+) diff --git a/storagemanager/PoolManager.h b/storagemanager/PoolManager.h index 6e353de22..c74e95c0e 100644 --- a/storagemanager/PoolManager.h +++ b/storagemanager/PoolManager.h @@ -10,6 +10,7 @@ * a fixed pool size policy for inter-process communication. * @details Uses local pool calls but is thread safe by protecting the call * with a lock. + * @author Bastian Baetz */ template class PoolManager : public LocalPool { From f13eff79c90a174011c6d3b6c617ce25b575cc76 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 16:51:09 +0200 Subject: [PATCH 30/33] another little include guard fix --- storagemanager/LocalPool.tpp | 2 +- storagemanager/PoolManager.tpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storagemanager/LocalPool.tpp b/storagemanager/LocalPool.tpp index b7fa0da96..764bd7be4 100644 --- a/storagemanager/LocalPool.tpp +++ b/storagemanager/LocalPool.tpp @@ -2,7 +2,7 @@ #define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_TPP_ #ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ -#error Include LocalPool.h instead of LocalPool.tpp! +#error Include LocalPool.h before LocalPool.tpp! #endif template diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp index 97603246e..29b2b82a6 100644 --- a/storagemanager/PoolManager.tpp +++ b/storagemanager/PoolManager.tpp @@ -2,7 +2,7 @@ #define FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ #ifndef FRAMEWORK_STORAGEMANAGER_POOLMANAGER_H_ -#error Include LocalPool.h instead of LocalPool.tpp! +#error Include PoolManager.h before PoolManager.tpp! #endif template From 4d4ca2f3bd87efaca572378e107f92dda2c57eb2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 17:43:37 +0200 Subject: [PATCH 31/33] doc fix for stopwatch --- timemanager/Stopwatch.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index c57200b07..71580778f 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -13,7 +13,7 @@ enum class StopwatchDisplayMode { * This class can be used to measure elapsed times. It also displays elapsed * times automatically on destruction if not explicitely deactivated in the * constructor. The default time format is the elapsed time in miliseconds - * as a float. + * in seconds as a double. * @author R. Mueller */ class Stopwatch { @@ -41,6 +41,10 @@ public: * @return elapsed time in milliseconds (rounded) */ millis_t stop(); + /** + * Calculates the elapsed time since start and returns it + * @return elapsed time in seconds (double precision) + */ seconds_t stopSeconds(); /** From 914bf8b9fc1afff3cf98675b4a98707099cb4021 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 17:45:53 +0200 Subject: [PATCH 32/33] seconds_t is double now --- timemanager/Clock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/timemanager/Clock.h b/timemanager/Clock.h index fcfacbc09..19991b817 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -9,7 +9,7 @@ #include typedef uint32_t millis_t; -typedef float seconds_t; +typedef double seconds_t; class Clock { public: From 7a22d12d0f1328ff55e3e2826e58000e191ef643 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 17:48:24 +0200 Subject: [PATCH 33/33] removed extern "C", not needed --- osal/linux/Clock.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/osal/linux/Clock.cpp b/osal/linux/Clock.cpp index b3e5c84bf..630b2cf4c 100644 --- a/osal/linux/Clock.cpp +++ b/osal/linux/Clock.cpp @@ -1,13 +1,11 @@ #include #include -extern "C" { #include #include #include #include #include -} //#include uint16_t Clock::leapSeconds = 0;