sempahore wrapper extended

This commit is contained in:
Robin Müller 2020-02-25 17:04:21 +01:00
parent 685c18dc4e
commit 083cc7c50a
9 changed files with 204 additions and 25 deletions

View File

@ -3,6 +3,13 @@
#include <framework/returnvalues/HasReturnvaluesIF.h>
/**
* @brief Common interface for OS Mutex objects which provide MUTual EXclusion.
*
* @details https://en.wikipedia.org/wiki/Lock_(computer_science)
* @ingroup osal
* @ingroup interface
*/
class MutexIF {
public:
static const uint32_t NO_TIMEOUT; //!< Needs to be defined in implementation.

View File

@ -3,7 +3,93 @@
*
* @date 25.02.2020
*/
#include <framework/osal/FreeRTOS/BinarySemaphore.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "portmacro.h"
#include "task.h"
BinarySemaphore::BinarySemaphore() {
vSemaphoreCreateBinary(handle);
if(handle == NULL) {
error << "Binary semaphore creation failure" << std::endl;
}
}
BinarySemaphore::~BinarySemaphore() {
vSemaphoreDelete(handle);
}
ReturnValue_t BinarySemaphore::takeBinarySemaphore(uint32_t timeoutMs) {
if(handle == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
TickType_t timeout = portMAX_DELAY;
if(timeoutMs != 0) {
timeout = pdMS_TO_TICKS(timeoutMs);
}
BaseType_t returncode = xSemaphoreTake(handle, timeout);
if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK;
} else {
return SEMAPHORE_NOT_FOUND;
}
}
ReturnValue_t BinarySemaphore::takeBinarySemaphoreTickTimeout(TickType_t timeoutTicks) {
if(handle == NULL) {
return SEMAPHORE_NOT_FOUND;
}
BaseType_t returncode = xSemaphoreTake(handle, timeoutTicks);
if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK;
} else {
return SEMAPHORE_TIMEOUT;
}
}
ReturnValue_t BinarySemaphore::giveBinarySemaphore() {
if (handle == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
BaseType_t returncode = xSemaphoreGive(handle);
if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK;
} else {
return SEMAPHORE_NOT_OWNED;
}
}
SemaphoreHandle_t BinarySemaphore::getSemaphore() {
return handle;
}
ReturnValue_t giveBinarySemaphore(SemaphoreHandle_t semaphore) {
if (semaphore == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
BaseType_t returncode = xSemaphoreGive(semaphore);
if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t giveBinarySemaphoreFromISR(SemaphoreHandle_t semaphore,
BaseType_t * higherPriorityTaskWoken) {
if (semaphore == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
BaseType_t returncode = xSemaphoreGiveFromISR(semaphore, higherPriorityTaskWoken);
if (returncode == pdPASS) {
if(*higherPriorityTaskWoken == pdPASS) {
// Request context switch
portYIELD_FROM_ISR();
}
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}

View File

@ -0,0 +1,94 @@
/**
* @file BinarySempahore.h
*
* @date 25.02.2020
*/
#ifndef FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_
#define FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include <FreeRTOS.h>
#include "semphr.h"
/**
* @brief OS Tool to achieve synchronization of between tasks or between task and ISR
* @details
* Documentation: https://www.freertos.org/Embedded-RTOS-Binary-Semaphores.html
* @ingroup osal
*/
class BinarySemaphore: public HasReturnvaluesIF {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF;
/** Semaphore object not found */
static const ReturnValue_t SEMAPHORE_NOT_FOUND = MAKE_RETURN_CODE(1);
/** Semaphore timeout */
static const ReturnValue_t SEMAPHORE_TIMEOUT = MAKE_RETURN_CODE(2);
/** The current semaphore can not be given, because it is not owned */
static const ReturnValue_t SEMAPHORE_NOT_OWNED = MAKE_RETURN_CODE(3);
/**
* Create a binary semaphore
*/
BinarySemaphore();
/**
* Delete the binary semaphore to prevent a memory leak
*/
~BinarySemaphore();
/**
* 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);
/**
* 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);
/**
* 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
*/
SemaphoreHandle_t getSemaphore();
private:
SemaphoreHandle_t handle;
};
/**
* Wrapper function to give back semaphore from handle
* @param semaphore
* @return -@c RETURN_OK on success
* -@c RETURN_FAILED on failure
*/
ReturnValue_t giveBinarySemaphore(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
*/
ReturnValue_t giveBinarySemaphoreFromISR(SemaphoreHandle_t semaphore,
BaseType_t * higherPriorityTaskWoken);
#endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */

View File

@ -1,14 +0,0 @@
/**
* @file BinarySempahore.h
*
* @date 25.02.2020
*/
#ifndef FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_
#define FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_
#endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */

View File

@ -1,5 +1,4 @@
#include "MessageQueue.h"
#include "task.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h>
@ -24,6 +23,12 @@ void MessageQueue::switchSystemContext(SystemContext callContext) {
this->callContext = callContext;
}
void MessageQueue::requestContextSwitch(SystemContext callContext) {
if(callContext == SystemContext::isr_context) {
portYIELD_FROM_ISR();
}
}
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo,
MessageQueueMessage* message, bool ignoreFault) {
return sendMessageFrom(sendTo, message, this->getId(), ignoreFault);
@ -72,11 +77,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
return handleSendResult(result, ignoreFault);
}
void MessageQueue::requestContextSwitch(SystemContext callContext) {
if(callContext == SystemContext::isr_context) {
portYIELD_FROM_ISR();
}
}
ReturnValue_t MessageQueue::handleSendResult(BaseType_t result, bool ignoreFault) {
if (result != pdPASS) {

View File

@ -8,6 +8,7 @@
#include <FreeRTOS.h>
#include "queue.h"
#include "portmacro.h"
#include "task.h"
//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 to have something checking or even an always working solution
// https://scaryreasoner.wordpress.com/2009/02/28/checking-sizeof-at-compile-time/

View File

@ -37,8 +37,7 @@ ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) {
ReturnValue_t Mutex::unlockMutex() {
if (handle == 0) {
//TODO Does not exist
return HasReturnvaluesIF::RETURN_FAILED;
return MutexIF::MUTEX_NOT_FOUND;
}
BaseType_t returncode = xSemaphoreGive(handle);
if (returncode == pdPASS) {

View File

@ -1,5 +1,5 @@
#ifndef OS_RTEMS_MUTEX_H_
#define OS_RTEMS_MUTEX_H_
#ifndef FRAMEWORK_FREERTOS_MUTEX_H_
#define FRAMEWORK_FREERTOS_MUTEX_H_
#include <framework/ipc/MutexIF.h>
@ -8,7 +8,11 @@
#include "semphr.h"
/**
* @brief OS component to implement MUTual EXclusion
*
* @details
* Mutexes are binary semaphores which include a priority inheritance mechanism.
* Documentation: https://www.freertos.org/Real-time-embedded-RTOS-mutexes.html
* @ingroup osal
*/
class Mutex : public MutexIF {
@ -21,4 +25,4 @@ private:
SemaphoreHandle_t handle;
};
#endif /* OS_RTEMS_MUTEX_H_ */
#endif /* FRAMEWORK_FREERTOS_MUTEX_H_ */

View File

@ -60,6 +60,7 @@ enum {
SGP4PROPAGATOR_CLASS, //SGP4 53
MUTEX_IF, //MUX 54
MESSAGE_QUEUE_IF,//MQI 55
SEMAPHORE_IF, //SPH 56
FW_CLASS_ID_COUNT //is actually count + 1 !
};