counting semaph implementation finished

This commit is contained in:
Robin Müller 2020-05-27 22:12:52 +02:00
parent 95bf5c1071
commit 63dbf99592
8 changed files with 154 additions and 87 deletions

View File

@ -1,7 +1,6 @@
#include <framework/osal/FreeRTOS/BinSemaphUsingTask.h>
#include <framework/osal/FreeRTOS/TaskManagement.h>
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, &notificationValue,
@ -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) {

View File

@ -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_ */

View File

@ -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;
}
}

View File

@ -2,7 +2,7 @@
#include <framework/osal/FreeRTOS/TaskManagement.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
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, &notificationValue);
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, &notificationValue,
&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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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);