counting semaph implementation finished
This commit is contained in:
parent
95bf5c1071
commit
63dbf99592
@ -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, ¬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) {
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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, ¬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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user