renormalized files

This commit is contained in:
Robin Müller 2020-09-18 13:15:14 +02:00
parent 42bfedd36c
commit 386f347574
23 changed files with 3811 additions and 3811 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,117 +1,117 @@
#ifndef _sgp4unit_ #ifndef _sgp4unit_
#define _sgp4unit_ #define _sgp4unit_
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* *
* sgp4unit.h * sgp4unit.h
* *
* this file contains the sgp4 procedures for analytical propagation * this file contains the sgp4 procedures for analytical propagation
* of a satellite. the code was originally released in the 1980 and 1986 * of a satellite. the code was originally released in the 1980 and 1986
* spacetrack papers. a detailed discussion of the theory and history * spacetrack papers. a detailed discussion of the theory and history
* may be found in the 2006 aiaa paper by vallado, crawford, hujsak, * may be found in the 2006 aiaa paper by vallado, crawford, hujsak,
* and kelso. * and kelso.
* *
* companion code for * companion code for
* fundamentals of astrodynamics and applications * fundamentals of astrodynamics and applications
* 2007 * 2007
* by david vallado * by david vallado
* *
* (w) 719-573-2600, email dvallado@agi.com * (w) 719-573-2600, email dvallado@agi.com
* *
* current : * current :
* 20 apr 07 david vallado * 20 apr 07 david vallado
* misc fixes for constants * misc fixes for constants
* changes : * changes :
* 11 aug 06 david vallado * 11 aug 06 david vallado
* chg lyddane choice back to strn3, constants, misc doc * chg lyddane choice back to strn3, constants, misc doc
* 15 dec 05 david vallado * 15 dec 05 david vallado
* misc fixes * misc fixes
* 26 jul 05 david vallado * 26 jul 05 david vallado
* fixes for paper * fixes for paper
* note that each fix is preceded by a * note that each fix is preceded by a
* comment with "sgp4fix" and an explanation of * comment with "sgp4fix" and an explanation of
* what was changed * what was changed
* 10 aug 04 david vallado * 10 aug 04 david vallado
* 2nd printing baseline working * 2nd printing baseline working
* 14 may 01 david vallado * 14 may 01 david vallado
* 2nd edition baseline * 2nd edition baseline
* 80 norad * 80 norad
* original baseline * original baseline
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
// -------------------------- structure declarations ---------------------------- // -------------------------- structure declarations ----------------------------
typedef enum typedef enum
{ {
wgs72old, wgs72old,
wgs72, wgs72,
wgs84 wgs84
} gravconsttype; } gravconsttype;
typedef struct elsetrec typedef struct elsetrec
{ {
long int satnum; long int satnum;
int epochyr, epochtynumrev; int epochyr, epochtynumrev;
int error; int error;
char init, method; char init, method;
/* Near Earth */ /* Near Earth */
int isimp; int isimp;
double aycof , con41 , cc1 , cc4 , cc5 , d2 , d3 , d4 , double aycof , con41 , cc1 , cc4 , cc5 , d2 , d3 , d4 ,
delmo , eta , argpdot, omgcof , sinmao , t , t2cof, t3cof , delmo , eta , argpdot, omgcof , sinmao , t , t2cof, t3cof ,
t4cof , t5cof , x1mth2 , x7thm1 , mdot , nodedot, xlcof , xmcof , t4cof , t5cof , x1mth2 , x7thm1 , mdot , nodedot, xlcof , xmcof ,
nodecf; nodecf;
/* Deep Space */ /* Deep Space */
int irez; int irez;
double d2201 , d2211 , d3210 , d3222 , d4410 , d4422 , d5220 , d5232 , double d2201 , d2211 , d3210 , d3222 , d4410 , d4422 , d5220 , d5232 ,
d5421 , d5433 , dedt , del1 , del2 , del3 , didt , dmdt , d5421 , d5433 , dedt , del1 , del2 , del3 , didt , dmdt ,
dnodt , domdt , e3 , ee2 , peo , pgho , pho , pinco , dnodt , domdt , e3 , ee2 , peo , pgho , pho , pinco ,
plo , se2 , se3 , sgh2 , sgh3 , sgh4 , sh2 , sh3 , plo , se2 , se3 , sgh2 , sgh3 , sgh4 , sh2 , sh3 ,
si2 , si3 , sl2 , sl3 , sl4 , gsto , xfact , xgh2 , si2 , si3 , sl2 , sl3 , sl4 , gsto , xfact , xgh2 ,
xgh3 , xgh4 , xh2 , xh3 , xi2 , xi3 , xl2 , xl3 , xgh3 , xgh4 , xh2 , xh3 , xi2 , xi3 , xl2 , xl3 ,
xl4 , xlamo , zmol , zmos , atime , xli , xni; xl4 , xlamo , zmol , zmos , atime , xli , xni;
double a , altp , alta , epochdays, jdsatepoch , nddot , ndot , double a , altp , alta , epochdays, jdsatepoch , nddot , ndot ,
bstar , rcse , inclo , nodeo , ecco , argpo , mo , bstar , rcse , inclo , nodeo , ecco , argpo , mo ,
no; no;
} elsetrec; } elsetrec;
// --------------------------- function declarations ---------------------------- // --------------------------- function declarations ----------------------------
int sgp4init int sgp4init
( (
gravconsttype whichconst, const int satn, const double epoch, gravconsttype whichconst, const int satn, const double epoch,
const double xbstar, const double xecco, const double xargpo, const double xbstar, const double xecco, const double xargpo,
const double xinclo, const double xmo, const double xno, const double xinclo, const double xmo, const double xno,
const double xnodeo, const double xnodeo,
elsetrec& satrec elsetrec& satrec
); );
int sgp4 int sgp4
( (
gravconsttype whichconst, gravconsttype whichconst,
elsetrec& satrec, double tsince, elsetrec& satrec, double tsince,
double r[], double v[] double r[], double v[]
); );
double gstime double gstime
( (
double double
); );
void getgravconst void getgravconst
( (
gravconsttype, gravconsttype,
double&, double&,
double&, double&,
double&, double&,
double&, double&,
double&, double&,
double&, double&,
double&, double&,
double& double&
); );
#endif #endif

View File

@ -1,99 +1,99 @@
#include "timevalOperations.h" #include "timevalOperations.h"
timeval& operator+=(timeval& lhs, const timeval& rhs) { timeval& operator+=(timeval& lhs, const timeval& rhs) {
int64_t sum = lhs.tv_sec * 1000000. + lhs.tv_usec; int64_t sum = lhs.tv_sec * 1000000. + lhs.tv_usec;
sum += rhs.tv_sec * 1000000. + rhs.tv_usec; sum += rhs.tv_sec * 1000000. + rhs.tv_usec;
lhs.tv_sec = sum / 1000000; lhs.tv_sec = sum / 1000000;
lhs.tv_usec = sum - lhs.tv_sec * 1000000; lhs.tv_usec = sum - lhs.tv_sec * 1000000;
return lhs; return lhs;
} }
timeval operator+(timeval lhs, const timeval& rhs) { timeval operator+(timeval lhs, const timeval& rhs) {
lhs += rhs; lhs += rhs;
return lhs; return lhs;
} }
timeval& operator-=(timeval& lhs, const timeval& rhs) { timeval& operator-=(timeval& lhs, const timeval& rhs) {
int64_t sum = lhs.tv_sec * 1000000. + lhs.tv_usec; int64_t sum = lhs.tv_sec * 1000000. + lhs.tv_usec;
sum -= rhs.tv_sec * 1000000. + rhs.tv_usec; sum -= rhs.tv_sec * 1000000. + rhs.tv_usec;
lhs.tv_sec = sum / 1000000; lhs.tv_sec = sum / 1000000;
lhs.tv_usec = sum - lhs.tv_sec * 1000000; lhs.tv_usec = sum - lhs.tv_sec * 1000000;
return lhs; return lhs;
} }
timeval operator-(timeval lhs, const timeval& rhs) { timeval operator-(timeval lhs, const timeval& rhs) {
lhs -= rhs; lhs -= rhs;
return lhs; return lhs;
} }
double operator/(const timeval& lhs, const timeval& rhs) { double operator/(const timeval& lhs, const timeval& rhs) {
double lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec; double lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec;
double rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec; double rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec;
return lhs64 / rhs64; return lhs64 / rhs64;
} }
timeval& operator/=(timeval& lhs, double scalar) { timeval& operator/=(timeval& lhs, double scalar) {
int64_t product = lhs.tv_sec * 1000000. + lhs.tv_usec; int64_t product = lhs.tv_sec * 1000000. + lhs.tv_usec;
product /= scalar; product /= scalar;
lhs.tv_sec = product / 1000000; lhs.tv_sec = product / 1000000;
lhs.tv_usec = product - lhs.tv_sec * 1000000; lhs.tv_usec = product - lhs.tv_sec * 1000000;
return lhs; return lhs;
} }
timeval operator/(timeval lhs, double scalar) { timeval operator/(timeval lhs, double scalar) {
lhs /= scalar; lhs /= scalar;
return lhs; return lhs;
} }
timeval& operator*=(timeval& lhs, double scalar) { timeval& operator*=(timeval& lhs, double scalar) {
int64_t product = lhs.tv_sec * 1000000. + lhs.tv_usec; int64_t product = lhs.tv_sec * 1000000. + lhs.tv_usec;
product *= scalar; product *= scalar;
lhs.tv_sec = product / 1000000; lhs.tv_sec = product / 1000000;
lhs.tv_usec = product - lhs.tv_sec * 1000000; lhs.tv_usec = product - lhs.tv_sec * 1000000;
return lhs; return lhs;
} }
timeval operator*(timeval lhs, double scalar) { timeval operator*(timeval lhs, double scalar) {
lhs *= scalar; lhs *= scalar;
return lhs; return lhs;
} }
timeval operator*(double scalar, timeval rhs) { timeval operator*(double scalar, timeval rhs) {
rhs *= scalar; rhs *= scalar;
return rhs; return rhs;
} }
bool operator==(const timeval& lhs, const timeval& rhs) { bool operator==(const timeval& lhs, const timeval& rhs) {
int64_t lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec; int64_t lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec;
int64_t rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec; int64_t rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec;
return lhs64 == rhs64; return lhs64 == rhs64;
} }
bool operator!=(const timeval& lhs, const timeval& rhs) { bool operator!=(const timeval& lhs, const timeval& rhs) {
return !operator==(lhs, rhs); return !operator==(lhs, rhs);
} }
bool operator<(const timeval& lhs, const timeval& rhs) { bool operator<(const timeval& lhs, const timeval& rhs) {
int64_t lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec; int64_t lhs64 = lhs.tv_sec * 1000000. + lhs.tv_usec;
int64_t rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec; int64_t rhs64 = rhs.tv_sec * 1000000. + rhs.tv_usec;
return lhs64 < rhs64; return lhs64 < rhs64;
} }
bool operator>(const timeval& lhs, const timeval& rhs) { bool operator>(const timeval& lhs, const timeval& rhs) {
return operator<(rhs, lhs); return operator<(rhs, lhs);
} }
bool operator<=(const timeval& lhs, const timeval& rhs) { bool operator<=(const timeval& lhs, const timeval& rhs) {
return !operator>(lhs, rhs); return !operator>(lhs, rhs);
} }
bool operator>=(const timeval& lhs, const timeval& rhs) { bool operator>=(const timeval& lhs, const timeval& rhs) {
return !operator<(lhs, rhs); return !operator<(lhs, rhs);
} }
double timevalOperations::toDouble(const timeval timeval) { double timevalOperations::toDouble(const timeval timeval) {
double result = timeval.tv_sec * 1000000. + timeval.tv_usec; double result = timeval.tv_sec * 1000000. + timeval.tv_usec;
return result / 1000000.; return result / 1000000.;
} }
timeval timevalOperations::toTimeval(const double seconds) { timeval timevalOperations::toTimeval(const double seconds) {
timeval tval; timeval tval;
tval.tv_sec = seconds; tval.tv_sec = seconds;
tval.tv_usec = seconds *(double) 1e6 - (tval.tv_sec *1e6); tval.tv_usec = seconds *(double) 1e6 - (tval.tv_sec *1e6);
return tval; return tval;
} }

View File

@ -1,95 +1,95 @@
#include "../../osal/FreeRTOS/BinSemaphUsingTask.h" #include "../../osal/FreeRTOS/BinSemaphUsingTask.h"
#include "../../osal/FreeRTOS/TaskManagement.h" #include "../../osal/FreeRTOS/TaskManagement.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() { BinarySemaphoreUsingTask::BinarySemaphoreUsingTask() {
handle = TaskManagement::getCurrentTaskHandle(); handle = TaskManagement::getCurrentTaskHandle();
if(handle == nullptr) { if(handle == nullptr) {
sif::error << "Could not retrieve task handle. Please ensure the" sif::error << "Could not retrieve task handle. Please ensure the"
"constructor was called inside a task." << std::endl; "constructor was called inside a task." << std::endl;
} }
xTaskNotifyGive(handle); xTaskNotifyGive(handle);
} }
BinarySemaphoreUsingTask::~BinarySemaphoreUsingTask() { BinarySemaphoreUsingTask::~BinarySemaphoreUsingTask() {
// Clear notification value on destruction. // Clear notification value on destruction.
xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite, nullptr); xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite, nullptr);
} }
ReturnValue_t BinarySemaphoreUsingTask::acquire(TimeoutType timeoutType, ReturnValue_t BinarySemaphoreUsingTask::acquire(TimeoutType timeoutType,
uint32_t timeoutMs) { uint32_t timeoutMs) {
TickType_t timeout = 0; TickType_t timeout = 0;
if(timeoutType == TimeoutType::POLLING) { if(timeoutType == TimeoutType::POLLING) {
timeout = 0; timeout = 0;
} }
else if(timeoutType == TimeoutType::WAITING){ else if(timeoutType == TimeoutType::WAITING){
timeout = pdMS_TO_TICKS(timeoutMs); timeout = pdMS_TO_TICKS(timeoutMs);
} }
else { else {
timeout = portMAX_DELAY; timeout = portMAX_DELAY;
} }
return acquireWithTickTimeout(timeoutType, timeout); return acquireWithTickTimeout(timeoutType, timeout);
} }
ReturnValue_t BinarySemaphoreUsingTask::acquireWithTickTimeout( ReturnValue_t BinarySemaphoreUsingTask::acquireWithTickTimeout(
TimeoutType timeoutType, TickType_t timeoutTicks) { TimeoutType timeoutType, TickType_t timeoutTicks) {
BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeoutTicks); BaseType_t returncode = ulTaskNotifyTake(pdTRUE, timeoutTicks);
if (returncode == pdPASS) { if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else { else {
return SemaphoreIF::SEMAPHORE_TIMEOUT; return SemaphoreIF::SEMAPHORE_TIMEOUT;
} }
} }
ReturnValue_t BinarySemaphoreUsingTask::release() { ReturnValue_t BinarySemaphoreUsingTask::release() {
return release(this->handle); return release(this->handle);
} }
ReturnValue_t BinarySemaphoreUsingTask::release( ReturnValue_t BinarySemaphoreUsingTask::release(
TaskHandle_t taskHandle) { TaskHandle_t taskHandle) {
if(getSemaphoreCounter(taskHandle) == 1) { if(getSemaphoreCounter(taskHandle) == 1) {
return SemaphoreIF::SEMAPHORE_NOT_OWNED; return SemaphoreIF::SEMAPHORE_NOT_OWNED;
} }
BaseType_t returncode = xTaskNotifyGive(taskHandle); BaseType_t returncode = xTaskNotifyGive(taskHandle);
if (returncode == pdPASS) { if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else { else {
// This should never happen. // This should never happen.
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
TaskHandle_t BinarySemaphoreUsingTask::getTaskHandle() { TaskHandle_t BinarySemaphoreUsingTask::getTaskHandle() {
return handle; return handle;
} }
uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter() const { uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter() const {
return getSemaphoreCounter(this->handle); return getSemaphoreCounter(this->handle);
} }
uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter( uint8_t BinarySemaphoreUsingTask::getSemaphoreCounter(
TaskHandle_t taskHandle) { TaskHandle_t taskHandle) {
uint32_t notificationValue; uint32_t notificationValue;
xTaskNotifyAndQuery(taskHandle, 0, eNoAction, &notificationValue); xTaskNotifyAndQuery(taskHandle, 0, eNoAction, &notificationValue);
return notificationValue; return notificationValue;
} }
// Be careful with the stack size here. This is called from an ISR! // Be careful with the stack size here. This is called from an ISR!
ReturnValue_t BinarySemaphoreUsingTask::releaseFromISR( ReturnValue_t BinarySemaphoreUsingTask::releaseFromISR(
TaskHandle_t taskHandle, BaseType_t * higherPriorityTaskWoken) { TaskHandle_t taskHandle, BaseType_t * higherPriorityTaskWoken) {
if(getSemaphoreCounterFromISR(taskHandle, higherPriorityTaskWoken) == 1) { if(getSemaphoreCounterFromISR(taskHandle, higherPriorityTaskWoken) == 1) {
return SemaphoreIF::SEMAPHORE_NOT_OWNED; return SemaphoreIF::SEMAPHORE_NOT_OWNED;
} }
vTaskNotifyGiveFromISR(taskHandle, higherPriorityTaskWoken); vTaskNotifyGiveFromISR(taskHandle, higherPriorityTaskWoken);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
uint8_t BinarySemaphoreUsingTask::getSemaphoreCounterFromISR( uint8_t BinarySemaphoreUsingTask::getSemaphoreCounterFromISR(
TaskHandle_t taskHandle, BaseType_t* higherPriorityTaskWoken) { TaskHandle_t taskHandle, BaseType_t* higherPriorityTaskWoken) {
uint32_t notificationValue = 0; uint32_t notificationValue = 0;
xTaskNotifyAndQueryFromISR(taskHandle, 0, eNoAction, &notificationValue, xTaskNotifyAndQueryFromISR(taskHandle, 0, eNoAction, &notificationValue,
higherPriorityTaskWoken); higherPriorityTaskWoken);
return notificationValue; return notificationValue;
} }

View File

@ -1,76 +1,76 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ #ifndef FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_
#define FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ #define FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_
#include "../../returnvalues/HasReturnvaluesIF.h" #include "../../returnvalues/HasReturnvaluesIF.h"
#include "../../tasks/SemaphoreIF.h" #include "../../tasks/SemaphoreIF.h"
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>
/** /**
* @brief Binary Semaphore implementation using the task notification value. * @brief Binary Semaphore implementation using the task notification value.
* The notification value should therefore not be used * The notification value should therefore not be used
* for other purposes. * for other purposes.
* @details * @details
* Additional information: https://www.freertos.org/RTOS-task-notifications.html * Additional information: https://www.freertos.org/RTOS-task-notifications.html
* and general semaphore documentation. * and general semaphore documentation.
*/ */
class BinarySemaphoreUsingTask: public SemaphoreIF, class BinarySemaphoreUsingTask: public SemaphoreIF,
public HasReturnvaluesIF { public HasReturnvaluesIF {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF;
//! @brief Default ctor //! @brief Default ctor
BinarySemaphoreUsingTask(); BinarySemaphoreUsingTask();
//! @brief Default dtor //! @brief Default dtor
virtual~ BinarySemaphoreUsingTask(); virtual~ BinarySemaphoreUsingTask();
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING, ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
uint32_t timeoutMs = portMAX_DELAY) override; uint32_t timeoutMs = portMAX_DELAY) override;
ReturnValue_t release() override; ReturnValue_t release() override;
uint8_t getSemaphoreCounter() const override; uint8_t getSemaphoreCounter() const override;
static uint8_t getSemaphoreCounter(TaskHandle_t taskHandle); static uint8_t getSemaphoreCounter(TaskHandle_t taskHandle);
static uint8_t getSemaphoreCounterFromISR(TaskHandle_t taskHandle, static uint8_t getSemaphoreCounterFromISR(TaskHandle_t taskHandle,
BaseType_t* higherPriorityTaskWoken); BaseType_t* higherPriorityTaskWoken);
/** /**
* Same as acquire() with timeout in FreeRTOS ticks. * Same as acquire() with timeout in FreeRTOS ticks.
* @param timeoutTicks * @param timeoutTicks
* @return - @c RETURN_OK on success * @return - @c RETURN_OK on success
* - @c RETURN_FAILED on failure * - @c RETURN_FAILED on failure
*/ */
ReturnValue_t acquireWithTickTimeout( ReturnValue_t acquireWithTickTimeout(
TimeoutType timeoutType = TimeoutType::BLOCKING, TimeoutType timeoutType = TimeoutType::BLOCKING,
TickType_t timeoutTicks = portMAX_DELAY); TickType_t timeoutTicks = portMAX_DELAY);
/** /**
* Get handle to the task related to the semaphore. * Get handle to the task related to the semaphore.
* @return * @return
*/ */
TaskHandle_t getTaskHandle(); TaskHandle_t getTaskHandle();
/** /**
* Wrapper function to give back semaphore from handle * Wrapper function to give back semaphore from handle
* @param semaphore * @param semaphore
* @return - @c RETURN_OK on success * @return - @c RETURN_OK on success
* - @c RETURN_FAILED on failure * - @c RETURN_FAILED on failure
*/ */
static ReturnValue_t release(TaskHandle_t taskToNotify); static ReturnValue_t release(TaskHandle_t taskToNotify);
/** /**
* Wrapper function to give back semaphore from handle when called from an ISR * Wrapper function to give back semaphore from handle when called from an ISR
* @param semaphore * @param semaphore
* @param higherPriorityTaskWoken This will be set to pdPASS if a task with * @param higherPriorityTaskWoken This will be set to pdPASS if a task with
* a higher priority was unblocked. A context switch should be requested * a higher priority was unblocked. A context switch should be requested
* from an ISR if this is the case (see TaskManagement functions) * from an ISR if this is the case (see TaskManagement functions)
* @return - @c RETURN_OK on success * @return - @c RETURN_OK on success
* - @c RETURN_FAILED on failure * - @c RETURN_FAILED on failure
*/ */
static ReturnValue_t releaseFromISR(TaskHandle_t taskToNotify, static ReturnValue_t releaseFromISR(TaskHandle_t taskToNotify,
BaseType_t * higherPriorityTaskWoken); BaseType_t * higherPriorityTaskWoken);
protected: protected:
TaskHandle_t handle; TaskHandle_t handle;
}; };
#endif /* FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */ #endif /* FRAMEWORK_OSAL_FREERTOS_BINSEMAPHUSINGTASK_H_ */

View File

@ -1,108 +1,108 @@
#include "../../osal/FreeRTOS/BinarySemaphore.h" #include "../../osal/FreeRTOS/BinarySemaphore.h"
#include "../../osal/FreeRTOS/TaskManagement.h" #include "../../osal/FreeRTOS/TaskManagement.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
BinarySemaphore::BinarySemaphore() { BinarySemaphore::BinarySemaphore() {
handle = xSemaphoreCreateBinary(); handle = xSemaphoreCreateBinary();
if(handle == nullptr) { if(handle == nullptr) {
sif::error << "Semaphore: Binary semaph creation failure" << std::endl; sif::error << "Semaphore: Binary semaph creation failure" << std::endl;
} }
// Initiated semaphore must be given before it can be taken. // Initiated semaphore must be given before it can be taken.
xSemaphoreGive(handle); xSemaphoreGive(handle);
} }
BinarySemaphore::~BinarySemaphore() { BinarySemaphore::~BinarySemaphore() {
vSemaphoreDelete(handle); vSemaphoreDelete(handle);
} }
BinarySemaphore::BinarySemaphore(BinarySemaphore&& s) { BinarySemaphore::BinarySemaphore(BinarySemaphore&& s) {
handle = xSemaphoreCreateBinary(); handle = xSemaphoreCreateBinary();
if(handle == nullptr) { if(handle == nullptr) {
sif::error << "Binary semaphore creation failure" << std::endl; sif::error << "Binary semaphore creation failure" << std::endl;
} }
xSemaphoreGive(handle); xSemaphoreGive(handle);
} }
BinarySemaphore& BinarySemaphore::operator =( BinarySemaphore& BinarySemaphore::operator =(
BinarySemaphore&& s) { BinarySemaphore&& s) {
if(&s != this) { if(&s != this) {
handle = xSemaphoreCreateBinary(); handle = xSemaphoreCreateBinary();
if(handle == nullptr) { if(handle == nullptr) {
sif::error << "Binary semaphore creation failure" << std::endl; sif::error << "Binary semaphore creation failure" << std::endl;
} }
xSemaphoreGive(handle); xSemaphoreGive(handle);
} }
return *this; return *this;
} }
ReturnValue_t BinarySemaphore::acquire(TimeoutType timeoutType, ReturnValue_t BinarySemaphore::acquire(TimeoutType timeoutType,
uint32_t timeoutMs) { uint32_t timeoutMs) {
TickType_t timeout = 0; TickType_t timeout = 0;
if(timeoutType == TimeoutType::POLLING) { if(timeoutType == TimeoutType::POLLING) {
timeout = 0; timeout = 0;
} }
else if(timeoutType == TimeoutType::WAITING){ else if(timeoutType == TimeoutType::WAITING){
timeout = pdMS_TO_TICKS(timeoutMs); timeout = pdMS_TO_TICKS(timeoutMs);
} }
else { else {
timeout = portMAX_DELAY; timeout = portMAX_DELAY;
} }
return acquireWithTickTimeout(timeoutType, timeout); return acquireWithTickTimeout(timeoutType, timeout);
} }
ReturnValue_t BinarySemaphore::acquireWithTickTimeout(TimeoutType timeoutType, ReturnValue_t BinarySemaphore::acquireWithTickTimeout(TimeoutType timeoutType,
TickType_t timeoutTicks) { TickType_t timeoutTicks) {
if(handle == nullptr) { if(handle == nullptr) {
return SemaphoreIF::SEMAPHORE_INVALID; return SemaphoreIF::SEMAPHORE_INVALID;
} }
BaseType_t returncode = xSemaphoreTake(handle, timeoutTicks); BaseType_t returncode = xSemaphoreTake(handle, timeoutTicks);
if (returncode == pdPASS) { if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else { else {
return SemaphoreIF::SEMAPHORE_TIMEOUT; return SemaphoreIF::SEMAPHORE_TIMEOUT;
} }
} }
ReturnValue_t BinarySemaphore::release() { ReturnValue_t BinarySemaphore::release() {
return release(handle); return release(handle);
} }
ReturnValue_t BinarySemaphore::release(SemaphoreHandle_t semaphore) { ReturnValue_t BinarySemaphore::release(SemaphoreHandle_t semaphore) {
if (semaphore == nullptr) { if (semaphore == nullptr) {
return SemaphoreIF::SEMAPHORE_INVALID; return SemaphoreIF::SEMAPHORE_INVALID;
} }
BaseType_t returncode = xSemaphoreGive(semaphore); BaseType_t returncode = xSemaphoreGive(semaphore);
if (returncode == pdPASS) { if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else { else {
return SemaphoreIF::SEMAPHORE_NOT_OWNED; return SemaphoreIF::SEMAPHORE_NOT_OWNED;
} }
} }
uint8_t BinarySemaphore::getSemaphoreCounter() const { uint8_t BinarySemaphore::getSemaphoreCounter() const {
return uxSemaphoreGetCount(handle); return uxSemaphoreGetCount(handle);
} }
SemaphoreHandle_t BinarySemaphore::getSemaphore() { SemaphoreHandle_t BinarySemaphore::getSemaphore() {
return handle; return handle;
} }
// Be careful with the stack size here. This is called from an ISR! // Be careful with the stack size here. This is called from an ISR!
ReturnValue_t BinarySemaphore::releaseFromISR( ReturnValue_t BinarySemaphore::releaseFromISR(
SemaphoreHandle_t semaphore, BaseType_t * higherPriorityTaskWoken) { SemaphoreHandle_t semaphore, BaseType_t * higherPriorityTaskWoken) {
if (semaphore == nullptr) { if (semaphore == nullptr) {
return SemaphoreIF::SEMAPHORE_INVALID; return SemaphoreIF::SEMAPHORE_INVALID;
} }
BaseType_t returncode = xSemaphoreGiveFromISR(semaphore, BaseType_t returncode = xSemaphoreGiveFromISR(semaphore,
higherPriorityTaskWoken); higherPriorityTaskWoken);
if (returncode == pdPASS) { if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else { else {
return SemaphoreIF::SEMAPHORE_NOT_OWNED; return SemaphoreIF::SEMAPHORE_NOT_OWNED;
} }
} }

View File

@ -1,107 +1,107 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ #ifndef FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_
#define FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ #define FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_
#include "../../returnvalues/HasReturnvaluesIF.h" #include "../../returnvalues/HasReturnvaluesIF.h"
#include "../../tasks/SemaphoreIF.h" #include "../../tasks/SemaphoreIF.h"
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/semphr.h> #include <freertos/semphr.h>
/** /**
* @brief OS Tool to achieve synchronization of between tasks or between * @brief OS Tool to achieve synchronization of between tasks or between
* task and ISR. The default semaphore implementation creates a * task and ISR. The default semaphore implementation creates a
* binary semaphore, which can only be taken once. * binary semaphore, which can only be taken once.
* @details * @details
* Documentation: https://www.freertos.org/Embedded-RTOS-Binary-Semaphores.html * Documentation: https://www.freertos.org/Embedded-RTOS-Binary-Semaphores.html
* *
* Please note that if the semaphore implementation is only related to * Please note that if the semaphore implementation is only related to
* the synchronization of one task, the new task notifications can be used, * the synchronization of one task, the new task notifications can be used,
* also see the BinSemaphUsingTask and CountingSemaphUsingTask classes. * also see the BinSemaphUsingTask and CountingSemaphUsingTask classes.
* These use the task notification value instead of a queue and are * These use the task notification value instead of a queue and are
* faster and more efficient. * faster and more efficient.
* *
* @author R. Mueller * @author R. Mueller
* @ingroup osal * @ingroup osal
*/ */
class BinarySemaphore: public SemaphoreIF, class BinarySemaphore: public SemaphoreIF,
public HasReturnvaluesIF { public HasReturnvaluesIF {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF;
//! @brief Default ctor //! @brief Default ctor
BinarySemaphore(); BinarySemaphore();
//! @brief Copy ctor, deleted explicitely. //! @brief Copy ctor, deleted explicitely.
BinarySemaphore(const BinarySemaphore&) = delete; BinarySemaphore(const BinarySemaphore&) = delete;
//! @brief Copy assignment, deleted explicitely. //! @brief Copy assignment, deleted explicitely.
BinarySemaphore& operator=(const BinarySemaphore&) = delete; BinarySemaphore& operator=(const BinarySemaphore&) = delete;
//! @brief Move ctor //! @brief Move ctor
BinarySemaphore (BinarySemaphore &&); BinarySemaphore (BinarySemaphore &&);
//! @brief Move assignment //! @brief Move assignment
BinarySemaphore & operator=(BinarySemaphore &&); BinarySemaphore & operator=(BinarySemaphore &&);
//! @brief Destructor //! @brief Destructor
virtual ~BinarySemaphore(); virtual ~BinarySemaphore();
uint8_t getSemaphoreCounter() const override; uint8_t getSemaphoreCounter() const override;
/** /**
* Take the binary semaphore. * Take the binary semaphore.
* If the semaphore has already been taken, the task will be blocked * 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 a maximum of #timeoutMs or until the semaphore is given back,
* for example by an ISR or another task. * for example by an ISR or another task.
* @param timeoutMs * @param timeoutMs
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
*/ */
ReturnValue_t acquire(TimeoutType timeoutType = ReturnValue_t acquire(TimeoutType timeoutType =
TimeoutType::BLOCKING, uint32_t timeoutMs = portMAX_DELAY) override; TimeoutType::BLOCKING, uint32_t timeoutMs = portMAX_DELAY) override;
/** /**
* Same as lockBinarySemaphore() with timeout in FreeRTOS ticks. * Same as lockBinarySemaphore() with timeout in FreeRTOS ticks.
* @param timeoutTicks * @param timeoutTicks
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
*/ */
ReturnValue_t acquireWithTickTimeout(TimeoutType timeoutType = ReturnValue_t acquireWithTickTimeout(TimeoutType timeoutType =
TimeoutType::BLOCKING, TickType_t timeoutTicks = portMAX_DELAY); TimeoutType::BLOCKING, TickType_t timeoutTicks = portMAX_DELAY);
/** /**
* Release the binary semaphore. * Release the binary semaphore.
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is
* already available. * already available.
*/ */
ReturnValue_t release() override; ReturnValue_t release() override;
/** /**
* Get Handle to the semaphore. * Get Handle to the semaphore.
* @return * @return
*/ */
SemaphoreHandle_t getSemaphore(); SemaphoreHandle_t getSemaphore();
/** /**
* Wrapper function to give back semaphore from handle * Wrapper function to give back semaphore from handle
* @param semaphore * @param semaphore
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is
* already available. * already available.
*/ */
static ReturnValue_t release(SemaphoreHandle_t semaphore); static ReturnValue_t release(SemaphoreHandle_t semaphore);
/** /**
* Wrapper function to give back semaphore from handle when called from an ISR * Wrapper function to give back semaphore from handle when called from an ISR
* @param semaphore * @param semaphore
* @param higherPriorityTaskWoken This will be set to pdPASS if a task with * @param higherPriorityTaskWoken This will be set to pdPASS if a task with
* a higher priority was unblocked. A context switch from an ISR should * a higher priority was unblocked. A context switch from an ISR should
* then be requested (see TaskManagement functions) * then be requested (see TaskManagement functions)
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is
* already available. * already available.
*/ */
static ReturnValue_t releaseFromISR(SemaphoreHandle_t semaphore, static ReturnValue_t releaseFromISR(SemaphoreHandle_t semaphore,
BaseType_t * higherPriorityTaskWoken); BaseType_t * higherPriorityTaskWoken);
protected: protected:
SemaphoreHandle_t handle; SemaphoreHandle_t handle;
}; };
#endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */ #endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */

View File

@ -1,114 +1,114 @@
#include "../../osal/FreeRTOS/CountingSemaphUsingTask.h" #include "../../osal/FreeRTOS/CountingSemaphUsingTask.h"
#include "../../osal/FreeRTOS/TaskManagement.h" #include "../../osal/FreeRTOS/TaskManagement.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t maxCount, CountingSemaphoreUsingTask::CountingSemaphoreUsingTask(const uint8_t maxCount,
uint8_t initCount): maxCount(maxCount) { uint8_t initCount): maxCount(maxCount) {
if(initCount > maxCount) { if(initCount > maxCount) {
sif::error << "CountingSemaphoreUsingTask: Max count bigger than " sif::error << "CountingSemaphoreUsingTask: Max count bigger than "
"intial cout. Setting initial count to max count." << std::endl; "intial cout. Setting initial count to max count." << std::endl;
initCount = maxCount; initCount = maxCount;
} }
handle = TaskManagement::getCurrentTaskHandle(); handle = TaskManagement::getCurrentTaskHandle();
if(handle == nullptr) { if(handle == nullptr) {
sif::error << "CountingSemaphoreUsingTask: Could not retrieve task " sif::error << "CountingSemaphoreUsingTask: Could not retrieve task "
"handle. Please ensure the constructor was called inside a " "handle. Please ensure the constructor was called inside a "
"task." << std::endl; "task." << std::endl;
} }
uint32_t oldNotificationValue; uint32_t oldNotificationValue;
xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite, xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite,
&oldNotificationValue); &oldNotificationValue);
if(oldNotificationValue != 0) { if(oldNotificationValue != 0) {
sif::warning << "CountinSemaphoreUsingTask: Semaphore initiated but " sif::warning << "CountinSemaphoreUsingTask: Semaphore initiated but "
"current notification value is not 0. Please ensure the " "current notification value is not 0. Please ensure the "
"notification value is not used for other purposes!" << std::endl; "notification value is not used for other purposes!" << std::endl;
} }
for(int i = 0; i < initCount; i++) { for(int i = 0; i < initCount; i++) {
xTaskNotifyGive(handle); xTaskNotifyGive(handle);
} }
} }
CountingSemaphoreUsingTask::~CountingSemaphoreUsingTask() { CountingSemaphoreUsingTask::~CountingSemaphoreUsingTask() {
// Clear notification value on destruction. // Clear notification value on destruction.
// If this is not desired, don't call the destructor // If this is not desired, don't call the destructor
// (or implement a boolean which disables the reset) // (or implement a boolean which disables the reset)
xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite, nullptr); xTaskNotifyAndQuery(handle, 0, eSetValueWithOverwrite, nullptr);
} }
ReturnValue_t CountingSemaphoreUsingTask::acquire(TimeoutType timeoutType, ReturnValue_t CountingSemaphoreUsingTask::acquire(TimeoutType timeoutType,
uint32_t timeoutMs) { uint32_t timeoutMs) {
TickType_t timeout = 0; TickType_t timeout = 0;
if(timeoutType == TimeoutType::POLLING) { if(timeoutType == TimeoutType::POLLING) {
timeout = 0; timeout = 0;
} }
else if(timeoutType == TimeoutType::WAITING){ else if(timeoutType == TimeoutType::WAITING){
timeout = pdMS_TO_TICKS(timeoutMs); timeout = pdMS_TO_TICKS(timeoutMs);
} }
else { else {
timeout = portMAX_DELAY; timeout = portMAX_DELAY;
} }
return acquireWithTickTimeout(timeoutType, timeout); return acquireWithTickTimeout(timeoutType, timeout);
} }
ReturnValue_t CountingSemaphoreUsingTask::acquireWithTickTimeout( ReturnValue_t CountingSemaphoreUsingTask::acquireWithTickTimeout(
TimeoutType timeoutType, TickType_t timeoutTicks) { TimeoutType timeoutType, TickType_t timeoutTicks) {
// Decrement notfication value without resetting it. // Decrement notfication value without resetting it.
BaseType_t oldCount = ulTaskNotifyTake(pdFALSE, timeoutTicks); BaseType_t oldCount = ulTaskNotifyTake(pdFALSE, timeoutTicks);
if (getSemaphoreCounter() == oldCount - 1) { if (getSemaphoreCounter() == oldCount - 1) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else { else {
return SemaphoreIF::SEMAPHORE_TIMEOUT; return SemaphoreIF::SEMAPHORE_TIMEOUT;
} }
} }
ReturnValue_t CountingSemaphoreUsingTask::release() { ReturnValue_t CountingSemaphoreUsingTask::release() {
if(getSemaphoreCounter() == maxCount) { if(getSemaphoreCounter() == maxCount) {
return SemaphoreIF::SEMAPHORE_NOT_OWNED; return SemaphoreIF::SEMAPHORE_NOT_OWNED;
} }
return release(handle); return release(handle);
} }
ReturnValue_t CountingSemaphoreUsingTask::release( ReturnValue_t CountingSemaphoreUsingTask::release(
TaskHandle_t taskToNotify) { TaskHandle_t taskToNotify) {
BaseType_t returncode = xTaskNotifyGive(taskToNotify); BaseType_t returncode = xTaskNotifyGive(taskToNotify);
if (returncode == pdPASS) { if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else { else {
// This should never happen. // This should never happen.
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
uint8_t CountingSemaphoreUsingTask::getSemaphoreCounter() const { uint8_t CountingSemaphoreUsingTask::getSemaphoreCounter() const {
uint32_t notificationValue = 0; uint32_t notificationValue = 0;
xTaskNotifyAndQuery(handle, 0, eNoAction, &notificationValue); xTaskNotifyAndQuery(handle, 0, eNoAction, &notificationValue);
return notificationValue; return notificationValue;
} }
TaskHandle_t CountingSemaphoreUsingTask::getTaskHandle() { TaskHandle_t CountingSemaphoreUsingTask::getTaskHandle() {
return handle; return handle;
} }
ReturnValue_t CountingSemaphoreUsingTask::releaseFromISR( ReturnValue_t CountingSemaphoreUsingTask::releaseFromISR(
TaskHandle_t taskToNotify, BaseType_t* higherPriorityTaskWoken) { TaskHandle_t taskToNotify, BaseType_t* higherPriorityTaskWoken) {
vTaskNotifyGiveFromISR(taskToNotify, higherPriorityTaskWoken); vTaskNotifyGiveFromISR(taskToNotify, higherPriorityTaskWoken);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
uint8_t CountingSemaphoreUsingTask::getSemaphoreCounterFromISR( uint8_t CountingSemaphoreUsingTask::getSemaphoreCounterFromISR(
TaskHandle_t task, BaseType_t* higherPriorityTaskWoken) { TaskHandle_t task, BaseType_t* higherPriorityTaskWoken) {
uint32_t notificationValue; uint32_t notificationValue;
xTaskNotifyAndQueryFromISR(task, 0, eNoAction, &notificationValue, xTaskNotifyAndQueryFromISR(task, 0, eNoAction, &notificationValue,
higherPriorityTaskWoken); higherPriorityTaskWoken);
return notificationValue; return notificationValue;
} }
uint8_t CountingSemaphoreUsingTask::getMaxCount() const { uint8_t CountingSemaphoreUsingTask::getMaxCount() const {
return maxCount; return maxCount;
} }

View File

@ -1,102 +1,102 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ #ifndef FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_
#define FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ #define FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_
#include "../../osal/FreeRTOS/CountingSemaphUsingTask.h" #include "../../osal/FreeRTOS/CountingSemaphUsingTask.h"
#include "../../tasks/SemaphoreIF.h" #include "../../tasks/SemaphoreIF.h"
extern "C" { extern "C" {
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>
} }
/** /**
* @brief Couting Semaphore implementation which uses the notification value * @brief Couting Semaphore implementation which uses the notification value
* of the task. The notification value should therefore not be used * of the task. The notification value should therefore not be used
* for other purposes. * for other purposes.
* @details * @details
* Additional information: https://www.freertos.org/RTOS-task-notifications.html * Additional information: https://www.freertos.org/RTOS-task-notifications.html
* and general semaphore documentation. * and general semaphore documentation.
*/ */
class CountingSemaphoreUsingTask: public SemaphoreIF { class CountingSemaphoreUsingTask: public SemaphoreIF {
public: public:
CountingSemaphoreUsingTask(const uint8_t maxCount, uint8_t initCount); CountingSemaphoreUsingTask(const uint8_t maxCount, uint8_t initCount);
virtual ~CountingSemaphoreUsingTask(); virtual ~CountingSemaphoreUsingTask();
/** /**
* Acquire the counting semaphore. * Acquire the counting semaphore.
* If no semaphores are available, the task will be blocked * If no semaphores are available, the task will be blocked
* for a maximum of #timeoutMs or until one is given back, * for a maximum of #timeoutMs or until one is given back,
* for example by an ISR or another task. * for example by an ISR or another task.
* @param timeoutMs * @param timeoutMs
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
*/ */
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING, ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
uint32_t timeoutMs = portMAX_DELAY) override; uint32_t timeoutMs = portMAX_DELAY) override;
/** /**
* Release a semaphore, increasing the number of available counting * Release a semaphore, increasing the number of available counting
* semaphores up to the #maxCount value. * semaphores up to the #maxCount value.
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if #maxCount semaphores are * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if #maxCount semaphores are
* already available. * already available.
*/ */
ReturnValue_t release() override; ReturnValue_t release() override;
uint8_t getSemaphoreCounter() const override; uint8_t getSemaphoreCounter() const override;
/** /**
* Get the semaphore counter from an ISR. * Get the semaphore counter from an ISR.
* @param task * @param task
* @param higherPriorityTaskWoken This will be set to pdPASS if a task with * @param higherPriorityTaskWoken This will be set to pdPASS if a task with
* a higher priority was unblocked. A context switch should be requested * a higher priority was unblocked. A context switch should be requested
* from an ISR if this is the case (see TaskManagement functions) * from an ISR if this is the case (see TaskManagement functions)
* @return * @return
*/ */
static uint8_t getSemaphoreCounterFromISR(TaskHandle_t task, static uint8_t getSemaphoreCounterFromISR(TaskHandle_t task,
BaseType_t* higherPriorityTaskWoken); BaseType_t* higherPriorityTaskWoken);
/** /**
* Acquire with a timeout value in ticks * Acquire with a timeout value in ticks
* @param timeoutTicks * @param timeoutTicks
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
*/ */
ReturnValue_t acquireWithTickTimeout( ReturnValue_t acquireWithTickTimeout(
TimeoutType timeoutType = TimeoutType::BLOCKING, TimeoutType timeoutType = TimeoutType::BLOCKING,
TickType_t timeoutTicks = portMAX_DELAY); TickType_t timeoutTicks = portMAX_DELAY);
/** /**
* Get handle to the task related to the semaphore. * Get handle to the task related to the semaphore.
* @return * @return
*/ */
TaskHandle_t getTaskHandle(); TaskHandle_t getTaskHandle();
/** /**
* Release semaphore of task by supplying task handle * Release semaphore of task by supplying task handle
* @param taskToNotify * @param taskToNotify
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if #maxCount semaphores are * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if #maxCount semaphores are
* already available. * already available.
*/ */
static ReturnValue_t release(TaskHandle_t taskToNotify); static ReturnValue_t release(TaskHandle_t taskToNotify);
/** /**
* Release seamphore of a task from an ISR. * Release seamphore of a task from an ISR.
* @param taskToNotify * @param taskToNotify
* @param higherPriorityTaskWoken This will be set to pdPASS if a task with * @param higherPriorityTaskWoken This will be set to pdPASS if a task with
* a higher priority was unblocked. A context switch should be requested * a higher priority was unblocked. A context switch should be requested
* from an ISR if this is the case (see TaskManagement functions) * from an ISR if this is the case (see TaskManagement functions)
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if #maxCount semaphores are * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if #maxCount semaphores are
* already available. * already available.
*/ */
static ReturnValue_t releaseFromISR(TaskHandle_t taskToNotify, static ReturnValue_t releaseFromISR(TaskHandle_t taskToNotify,
BaseType_t* higherPriorityTaskWoken); BaseType_t* higherPriorityTaskWoken);
uint8_t getMaxCount() const; uint8_t getMaxCount() const;
private: private:
TaskHandle_t handle; TaskHandle_t handle;
const uint8_t maxCount; const uint8_t maxCount;
}; };
#endif /* FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ */ #endif /* FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHUSINGTASK_H_ */

View File

@ -1,43 +1,43 @@
#include "../../osal/FreeRTOS/CountingSemaphore.h" #include "../../osal/FreeRTOS/CountingSemaphore.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../osal/FreeRTOS/TaskManagement.h" #include "../../osal/FreeRTOS/TaskManagement.h"
#include <freertos/semphr.h> #include <freertos/semphr.h>
// Make sure #define configUSE_COUNTING_SEMAPHORES 1 is set in // Make sure #define configUSE_COUNTING_SEMAPHORES 1 is set in
// free FreeRTOSConfig.h file. // free FreeRTOSConfig.h file.
CountingSemaphore::CountingSemaphore(const uint8_t maxCount, uint8_t initCount): CountingSemaphore::CountingSemaphore(const uint8_t maxCount, uint8_t initCount):
maxCount(maxCount), initCount(initCount) { maxCount(maxCount), initCount(initCount) {
if(initCount > maxCount) { if(initCount > maxCount) {
sif::error << "CountingSemaphoreUsingTask: Max count bigger than " sif::error << "CountingSemaphoreUsingTask: Max count bigger than "
"intial cout. Setting initial count to max count." << std::endl; "intial cout. Setting initial count to max count." << std::endl;
initCount = maxCount; initCount = maxCount;
} }
handle = xSemaphoreCreateCounting(maxCount, initCount); handle = xSemaphoreCreateCounting(maxCount, initCount);
if(handle == nullptr) { if(handle == nullptr) {
sif::error << "CountingSemaphore: Creation failure" << std::endl; sif::error << "CountingSemaphore: Creation failure" << std::endl;
} }
} }
CountingSemaphore::CountingSemaphore(CountingSemaphore&& other): CountingSemaphore::CountingSemaphore(CountingSemaphore&& other):
maxCount(other.maxCount), initCount(other.initCount) { maxCount(other.maxCount), initCount(other.initCount) {
handle = xSemaphoreCreateCounting(other.maxCount, other.initCount); handle = xSemaphoreCreateCounting(other.maxCount, other.initCount);
if(handle == nullptr) { if(handle == nullptr) {
sif::error << "CountingSemaphore: Creation failure" << std::endl; sif::error << "CountingSemaphore: Creation failure" << std::endl;
} }
} }
CountingSemaphore& CountingSemaphore::operator =( CountingSemaphore& CountingSemaphore::operator =(
CountingSemaphore&& other) { CountingSemaphore&& other) {
handle = xSemaphoreCreateCounting(other.maxCount, other.initCount); handle = xSemaphoreCreateCounting(other.maxCount, other.initCount);
if(handle == nullptr) { if(handle == nullptr) {
sif::error << "CountingSemaphore: Creation failure" << std::endl; sif::error << "CountingSemaphore: Creation failure" << std::endl;
} }
return * this; return * this;
} }
uint8_t CountingSemaphore::getMaxCount() const { uint8_t CountingSemaphore::getMaxCount() const {
return maxCount; return maxCount;
} }

View File

@ -1,34 +1,34 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_ #ifndef FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_
#define FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_ #define FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_
#include "../../osal/FreeRTOS/BinarySemaphore.h" #include "../../osal/FreeRTOS/BinarySemaphore.h"
/** /**
* @brief Counting semaphores, which can be acquire more than once. * @brief Counting semaphores, which can be acquire more than once.
* @details * @details
* See: https://www.freertos.org/CreateCounting.html * See: https://www.freertos.org/CreateCounting.html
* API of counting semaphores is almost identical to binary semaphores, * API of counting semaphores is almost identical to binary semaphores,
* so we just inherit from binary semaphore and provide the respective * so we just inherit from binary semaphore and provide the respective
* constructors. * constructors.
*/ */
class CountingSemaphore: public BinarySemaphore { class CountingSemaphore: public BinarySemaphore {
public: public:
CountingSemaphore(const uint8_t maxCount, uint8_t initCount); CountingSemaphore(const uint8_t maxCount, uint8_t initCount);
//! @brief Copy ctor, disabled //! @brief Copy ctor, disabled
CountingSemaphore(const CountingSemaphore&) = delete; CountingSemaphore(const CountingSemaphore&) = delete;
//! @brief Copy assignment, disabled //! @brief Copy assignment, disabled
CountingSemaphore& operator=(const CountingSemaphore&) = delete; CountingSemaphore& operator=(const CountingSemaphore&) = delete;
//! @brief Move ctor //! @brief Move ctor
CountingSemaphore (CountingSemaphore &&); CountingSemaphore (CountingSemaphore &&);
//! @brief Move assignment //! @brief Move assignment
CountingSemaphore & operator=(CountingSemaphore &&); CountingSemaphore & operator=(CountingSemaphore &&);
/* Same API as binary semaphore otherwise. acquire() can be called /* Same API as binary semaphore otherwise. acquire() can be called
* until there are not semaphores left and release() can be called * until there are not semaphores left and release() can be called
* until maxCount is reached. */ * until maxCount is reached. */
uint8_t getMaxCount() const; uint8_t getMaxCount() const;
private: private:
const uint8_t maxCount; const uint8_t maxCount;
uint8_t initCount = 0; uint8_t initCount = 0;
}; };
#endif /* FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_ */ #endif /* FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_ */

View File

@ -1,59 +1,59 @@
#include "../../osal/FreeRTOS/BinarySemaphore.h" #include "../../osal/FreeRTOS/BinarySemaphore.h"
#include "../../osal/FreeRTOS/BinSemaphUsingTask.h" #include "../../osal/FreeRTOS/BinSemaphUsingTask.h"
#include "../../osal/FreeRTOS/CountingSemaphore.h" #include "../../osal/FreeRTOS/CountingSemaphore.h"
#include "../../osal/FreeRTOS/CountingSemaphUsingTask.h" #include "../../osal/FreeRTOS/CountingSemaphUsingTask.h"
#include "../../tasks/SemaphoreFactory.h" #include "../../tasks/SemaphoreFactory.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr; SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr;
static const uint32_t USE_REGULAR_SEMAPHORES = 0; static const uint32_t USE_REGULAR_SEMAPHORES = 0;
static const uint32_t USE_TASK_NOTIFICATIONS = 1; static const uint32_t USE_TASK_NOTIFICATIONS = 1;
SemaphoreFactory::SemaphoreFactory() { SemaphoreFactory::SemaphoreFactory() {
} }
SemaphoreFactory::~SemaphoreFactory() { SemaphoreFactory::~SemaphoreFactory() {
delete factoryInstance; delete factoryInstance;
} }
SemaphoreFactory* SemaphoreFactory::instance() { SemaphoreFactory* SemaphoreFactory::instance() {
if (factoryInstance == nullptr){ if (factoryInstance == nullptr){
factoryInstance = new SemaphoreFactory(); factoryInstance = new SemaphoreFactory();
} }
return SemaphoreFactory::factoryInstance; return SemaphoreFactory::factoryInstance;
} }
SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t argument) { SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t argument) {
if(argument == USE_REGULAR_SEMAPHORES) { if(argument == USE_REGULAR_SEMAPHORES) {
return new BinarySemaphore(); return new BinarySemaphore();
} }
else if(argument == USE_TASK_NOTIFICATIONS) { else if(argument == USE_TASK_NOTIFICATIONS) {
return new BinarySemaphoreUsingTask(); return new BinarySemaphoreUsingTask();
} }
else { else {
sif::warning << "SemaphoreFactory: Invalid argument, return regular" sif::warning << "SemaphoreFactory: Invalid argument, return regular"
"binary semaphore" << std::endl; "binary semaphore" << std::endl;
return new BinarySemaphore(); return new BinarySemaphore();
} }
} }
SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t maxCount, SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t maxCount,
uint8_t initCount, uint32_t argument) { uint8_t initCount, uint32_t argument) {
if(argument == USE_REGULAR_SEMAPHORES) { if(argument == USE_REGULAR_SEMAPHORES) {
return new CountingSemaphore(maxCount, initCount); return new CountingSemaphore(maxCount, initCount);
} }
else if(argument == USE_TASK_NOTIFICATIONS) { else if(argument == USE_TASK_NOTIFICATIONS) {
return new CountingSemaphoreUsingTask(maxCount, initCount); return new CountingSemaphoreUsingTask(maxCount, initCount);
} }
else { else {
sif::warning << "SemaphoreFactory: Invalid argument, return regular" sif::warning << "SemaphoreFactory: Invalid argument, return regular"
"binary semaphore" << std::endl; "binary semaphore" << std::endl;
return new CountingSemaphore(maxCount, initCount); return new CountingSemaphore(maxCount, initCount);
} }
} }
void SemaphoreFactory::deleteSemaphore(SemaphoreIF* semaphore) { void SemaphoreFactory::deleteSemaphore(SemaphoreIF* semaphore) {
delete semaphore; delete semaphore;
} }

View File

@ -1,24 +1,24 @@
#include "../../osal/FreeRTOS/TaskManagement.h" #include "../../osal/FreeRTOS/TaskManagement.h"
void TaskManagement::vRequestContextSwitchFromTask() { void TaskManagement::vRequestContextSwitchFromTask() {
vTaskDelay(0); vTaskDelay(0);
} }
void TaskManagement::requestContextSwitch( void TaskManagement::requestContextSwitch(
CallContext callContext = CallContext::TASK) { CallContext callContext = CallContext::TASK) {
if(callContext == CallContext::ISR) { if(callContext == CallContext::ISR) {
// This function depends on the partmacro.h definition for the specific device // This function depends on the partmacro.h definition for the specific device
vRequestContextSwitchFromISR(); vRequestContextSwitchFromISR();
} else { } else {
vRequestContextSwitchFromTask(); vRequestContextSwitchFromTask();
} }
} }
TaskHandle_t TaskManagement::getCurrentTaskHandle() { TaskHandle_t TaskManagement::getCurrentTaskHandle() {
return xTaskGetCurrentTaskHandle(); return xTaskGetCurrentTaskHandle();
} }
size_t TaskManagement::getTaskStackHighWatermark( size_t TaskManagement::getTaskStackHighWatermark(
TaskHandle_t task) { TaskHandle_t task) {
return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t); return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t);
} }

View File

@ -1,64 +1,64 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_ #ifndef FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_
#define FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_ #define FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_
#include "../../returnvalues/HasReturnvaluesIF.h" #include "../../returnvalues/HasReturnvaluesIF.h"
extern "C" { extern "C" {
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>
} }
#include <cstdint> #include <cstdint>
/** /**
* Architecture dependant portmacro.h function call. * Architecture dependant portmacro.h function call.
* Should be implemented in bsp. * Should be implemented in bsp.
*/ */
extern void vRequestContextSwitchFromISR(); extern void vRequestContextSwitchFromISR();
/*! /*!
* Used by functions to tell if they are being called from * Used by functions to tell if they are being called from
* within an ISR or from a regular task. This is required because FreeRTOS * within an ISR or from a regular task. This is required because FreeRTOS
* has different functions for handling semaphores and messages from within * has different functions for handling semaphores and messages from within
* an ISR and task. * an ISR and task.
*/ */
enum class CallContext { enum class CallContext {
TASK = 0x00,//!< task_context TASK = 0x00,//!< task_context
ISR = 0xFF //!< isr_context ISR = 0xFF //!< isr_context
}; };
class TaskManagement { class TaskManagement {
public: public:
/** /**
* @brief In this function, a function dependant on the portmacro.h header * @brief In this function, a function dependant on the portmacro.h header
* function calls to request a context switch can be specified. * function calls to request a context switch can be specified.
* This can be used if sending to the queue from an ISR caused a task * This can be used if sending to the queue from an ISR caused a task
* to unblock and a context switch is required. * to unblock and a context switch is required.
*/ */
static void requestContextSwitch(CallContext callContext); static void requestContextSwitch(CallContext callContext);
/** /**
* If task preemption in FreeRTOS is disabled, a context switch * If task preemption in FreeRTOS is disabled, a context switch
* can be requested manually by calling this function. * can be requested manually by calling this function.
*/ */
static void vRequestContextSwitchFromTask(void); static void vRequestContextSwitchFromTask(void);
/** /**
* @return The current task handle * @return The current task handle
*/ */
static TaskHandle_t getCurrentTaskHandle(); static TaskHandle_t getCurrentTaskHandle();
/** /**
* Get returns the minimum amount of remaining stack space in words * Get returns the minimum amount of remaining stack space in words
* that was a available to the task since the task started executing. * that was a available to the task since the task started executing.
* Please note that the actual value in bytes depends * Please note that the actual value in bytes depends
* on the stack depth type. * on the stack depth type.
* E.g. on a 32 bit machine, a value of 200 means 800 bytes. * E.g. on a 32 bit machine, a value of 200 means 800 bytes.
* @return Smallest value of stack remaining since the task was started in * @return Smallest value of stack remaining since the task was started in
* words. * words.
*/ */
static size_t getTaskStackHighWatermark( static size_t getTaskStackHighWatermark(
TaskHandle_t task = nullptr); TaskHandle_t task = nullptr);
}; };
#endif /* FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_ */ #endif /* FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_ */

View File

@ -1,149 +1,149 @@
#include "../../osal/linux/BinarySemaphore.h" #include "../../osal/linux/BinarySemaphore.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
extern "C" { extern "C" {
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
} }
BinarySemaphore::BinarySemaphore() { BinarySemaphore::BinarySemaphore() {
// Using unnamed semaphores for now // Using unnamed semaphores for now
initSemaphore(); initSemaphore();
} }
BinarySemaphore::~BinarySemaphore() { BinarySemaphore::~BinarySemaphore() {
sem_destroy(&handle); sem_destroy(&handle);
} }
BinarySemaphore::BinarySemaphore(BinarySemaphore&& s) { BinarySemaphore::BinarySemaphore(BinarySemaphore&& s) {
initSemaphore(); initSemaphore();
} }
BinarySemaphore& BinarySemaphore::operator =( BinarySemaphore& BinarySemaphore::operator =(
BinarySemaphore&& s) { BinarySemaphore&& s) {
initSemaphore(); initSemaphore();
return * this; return * this;
} }
ReturnValue_t BinarySemaphore::acquire(TimeoutType timeoutType, ReturnValue_t BinarySemaphore::acquire(TimeoutType timeoutType,
uint32_t timeoutMs) { uint32_t timeoutMs) {
int result = 0; int result = 0;
if(timeoutType == TimeoutType::POLLING) { if(timeoutType == TimeoutType::POLLING) {
result = sem_trywait(&handle); result = sem_trywait(&handle);
} }
else if(timeoutType == TimeoutType::BLOCKING) { else if(timeoutType == TimeoutType::BLOCKING) {
result = sem_wait(&handle); result = sem_wait(&handle);
} }
else if(timeoutType == TimeoutType::WAITING){ else if(timeoutType == TimeoutType::WAITING){
timespec timeOut; timespec timeOut;
clock_gettime(CLOCK_REALTIME, &timeOut); clock_gettime(CLOCK_REALTIME, &timeOut);
uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec; uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec;
nseconds += timeoutMs * 1000000; nseconds += timeoutMs * 1000000;
timeOut.tv_sec = nseconds / 1000000000; timeOut.tv_sec = nseconds / 1000000000;
timeOut.tv_nsec = nseconds - timeOut.tv_sec * 1000000000; timeOut.tv_nsec = nseconds - timeOut.tv_sec * 1000000000;
result = sem_timedwait(&handle, &timeOut); result = sem_timedwait(&handle, &timeOut);
if(result != 0 and errno == EINVAL) { if(result != 0 and errno == EINVAL) {
sif::debug << "BinarySemaphore::acquire: Invalid time value possible" sif::debug << "BinarySemaphore::acquire: Invalid time value possible"
<< std::endl; << std::endl;
} }
} }
if(result == 0) { if(result == 0) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
switch(errno) { switch(errno) {
case(EAGAIN): case(EAGAIN):
// Operation could not be performed without blocking (for sem_trywait) // Operation could not be performed without blocking (for sem_trywait)
case(ETIMEDOUT): case(ETIMEDOUT):
// Semaphore is 0 // Semaphore is 0
return SemaphoreIF::SEMAPHORE_TIMEOUT; return SemaphoreIF::SEMAPHORE_TIMEOUT;
case(EINVAL): case(EINVAL):
// Semaphore invalid // Semaphore invalid
return SemaphoreIF::SEMAPHORE_INVALID; return SemaphoreIF::SEMAPHORE_INVALID;
case(EINTR): case(EINTR):
// Call was interrupted by signal handler // Call was interrupted by signal handler
sif::debug << "BinarySemaphore::acquire: Signal handler interrupted." sif::debug << "BinarySemaphore::acquire: Signal handler interrupted."
"Code " << strerror(errno) << std::endl; "Code " << strerror(errno) << std::endl;
/* No break */ /* No break */
default: default:
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
ReturnValue_t BinarySemaphore::release() { ReturnValue_t BinarySemaphore::release() {
return BinarySemaphore::release(&this->handle); return BinarySemaphore::release(&this->handle);
} }
ReturnValue_t BinarySemaphore::release(sem_t *handle) { ReturnValue_t BinarySemaphore::release(sem_t *handle) {
ReturnValue_t countResult = checkCount(handle, 1); ReturnValue_t countResult = checkCount(handle, 1);
if(countResult != HasReturnvaluesIF::RETURN_OK) { if(countResult != HasReturnvaluesIF::RETURN_OK) {
return countResult; return countResult;
} }
int result = sem_post(handle); int result = sem_post(handle);
if(result == 0) { if(result == 0) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
switch(errno) { switch(errno) {
case(EINVAL): case(EINVAL):
// Semaphore invalid // Semaphore invalid
return SemaphoreIF::SEMAPHORE_INVALID; return SemaphoreIF::SEMAPHORE_INVALID;
case(EOVERFLOW): case(EOVERFLOW):
// SEM_MAX_VALUE overflow. This should never happen // SEM_MAX_VALUE overflow. This should never happen
default: default:
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
uint8_t BinarySemaphore::getSemaphoreCounter() const { uint8_t BinarySemaphore::getSemaphoreCounter() const {
// And another ugly cast :-D // And another ugly cast :-D
return getSemaphoreCounter(const_cast<sem_t*>(&this->handle)); return getSemaphoreCounter(const_cast<sem_t*>(&this->handle));
} }
uint8_t BinarySemaphore::getSemaphoreCounter(sem_t *handle) { uint8_t BinarySemaphore::getSemaphoreCounter(sem_t *handle) {
int value = 0; int value = 0;
int result = sem_getvalue(handle, &value); int result = sem_getvalue(handle, &value);
if (result == 0) { if (result == 0) {
return value; return value;
} }
else if(result != 0 and errno == EINVAL) { else if(result != 0 and errno == EINVAL) {
// Could be called from interrupt, use lightweight printf // Could be called from interrupt, use lightweight printf
printf("BinarySemaphore::getSemaphoreCounter: Invalid semaphore\n"); printf("BinarySemaphore::getSemaphoreCounter: Invalid semaphore\n");
return 0; return 0;
} }
else { else {
// This should never happen. // This should never happen.
return 0; return 0;
} }
} }
void BinarySemaphore::initSemaphore(uint8_t initCount) { void BinarySemaphore::initSemaphore(uint8_t initCount) {
auto result = sem_init(&handle, true, initCount); auto result = sem_init(&handle, true, initCount);
if(result == -1) { if(result == -1) {
switch(errno) { switch(errno) {
case(EINVAL): case(EINVAL):
// Value exceeds SEM_VALUE_MAX // Value exceeds SEM_VALUE_MAX
case(ENOSYS): case(ENOSYS):
// System does not support process-shared semaphores // System does not support process-shared semaphores
sif::error << "BinarySemaphore: Init failed with" << strerror(errno) sif::error << "BinarySemaphore: Init failed with" << strerror(errno)
<< std::endl; << std::endl;
} }
} }
} }
ReturnValue_t BinarySemaphore::checkCount(sem_t* handle, uint8_t maxCount) { ReturnValue_t BinarySemaphore::checkCount(sem_t* handle, uint8_t maxCount) {
int value = getSemaphoreCounter(handle); int value = getSemaphoreCounter(handle);
if(value >= maxCount) { if(value >= maxCount) {
if(maxCount == 1 and value > 1) { if(maxCount == 1 and value > 1) {
// Binary Semaphore special case. // Binary Semaphore special case.
// This is a config error use lightweight printf is this is called // This is a config error use lightweight printf is this is called
// from an interrupt // from an interrupt
printf("BinarySemaphore::release: Value of binary semaphore greater" printf("BinarySemaphore::release: Value of binary semaphore greater"
" than 1!\n"); " than 1!\n");
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
return SemaphoreIF::SEMAPHORE_NOT_OWNED; return SemaphoreIF::SEMAPHORE_NOT_OWNED;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -1,81 +1,81 @@
#ifndef FRAMEWORK_OSAL_LINUX_BINARYSEMPAHORE_H_ #ifndef FRAMEWORK_OSAL_LINUX_BINARYSEMPAHORE_H_
#define FRAMEWORK_OSAL_LINUX_BINARYSEMPAHORE_H_ #define FRAMEWORK_OSAL_LINUX_BINARYSEMPAHORE_H_
#include "../../returnvalues/HasReturnvaluesIF.h" #include "../../returnvalues/HasReturnvaluesIF.h"
#include "../../tasks/SemaphoreIF.h" #include "../../tasks/SemaphoreIF.h"
extern "C" { extern "C" {
#include <semaphore.h> #include <semaphore.h>
} }
/** /**
* @brief OS Tool to achieve synchronization of between tasks or between * @brief OS Tool to achieve synchronization of between tasks or between
* task and ISR. The default semaphore implementation creates a * task and ISR. The default semaphore implementation creates a
* binary semaphore, which can only be taken once. * binary semaphore, which can only be taken once.
* @details * @details
* See: http://www.man7.org/linux/man-pages/man7/sem_overview.7.html * See: http://www.man7.org/linux/man-pages/man7/sem_overview.7.html
* @author R. Mueller * @author R. Mueller
* @ingroup osal * @ingroup osal
*/ */
class BinarySemaphore: public SemaphoreIF, class BinarySemaphore: public SemaphoreIF,
public HasReturnvaluesIF { public HasReturnvaluesIF {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF;
//! @brief Default ctor //! @brief Default ctor
BinarySemaphore(); BinarySemaphore();
//! @brief Copy ctor, deleted explicitely. //! @brief Copy ctor, deleted explicitely.
BinarySemaphore(const BinarySemaphore&) = delete; BinarySemaphore(const BinarySemaphore&) = delete;
//! @brief Copy assignment, deleted explicitely. //! @brief Copy assignment, deleted explicitely.
BinarySemaphore& operator=(const BinarySemaphore&) = delete; BinarySemaphore& operator=(const BinarySemaphore&) = delete;
//! @brief Move ctor //! @brief Move ctor
BinarySemaphore (BinarySemaphore &&); BinarySemaphore (BinarySemaphore &&);
//! @brief Move assignment //! @brief Move assignment
BinarySemaphore & operator=(BinarySemaphore &&); BinarySemaphore & operator=(BinarySemaphore &&);
//! @brief Destructor //! @brief Destructor
virtual ~BinarySemaphore(); virtual ~BinarySemaphore();
void initSemaphore(uint8_t initCount = 1); void initSemaphore(uint8_t initCount = 1);
uint8_t getSemaphoreCounter() const override; uint8_t getSemaphoreCounter() const override;
static uint8_t getSemaphoreCounter(sem_t* handle); static uint8_t getSemaphoreCounter(sem_t* handle);
/** /**
* Take the binary semaphore. * Take the binary semaphore.
* If the semaphore has already been taken, the task will be blocked * 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 a maximum of #timeoutMs or until the semaphore is given back,
* for example by an ISR or another task. * for example by an ISR or another task.
* @param timeoutMs * @param timeoutMs
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
*/ */
ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING, ReturnValue_t acquire(TimeoutType timeoutType = TimeoutType::BLOCKING,
uint32_t timeoutMs = 0) override; uint32_t timeoutMs = 0) override;
/** /**
* Release the binary semaphore. * Release the binary semaphore.
* @return -@c RETURN_OK on success * @return -@c RETURN_OK on success
* -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is * -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is
* already available. * already available.
*/ */
virtual ReturnValue_t release() override; virtual ReturnValue_t release() override;
/** /**
* This static function can be used to release a semaphore by providing * This static function can be used to release a semaphore by providing
* its handle. * its handle.
* @param handle * @param handle
* @return * @return
*/ */
static ReturnValue_t release(sem_t* handle); static ReturnValue_t release(sem_t* handle);
/** Checks the validity of the semaphore count against a specified /** Checks the validity of the semaphore count against a specified
* known maxCount * known maxCount
* @param handle * @param handle
* @param maxCount * @param maxCount
* @return * @return
*/ */
static ReturnValue_t checkCount(sem_t* handle, uint8_t maxCount); static ReturnValue_t checkCount(sem_t* handle, uint8_t maxCount);
protected: protected:
sem_t handle; sem_t handle;
}; };
#endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */ #endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */

View File

@ -1,54 +1,54 @@
#include "../../osal/linux/CountingSemaphore.h" #include "../../osal/linux/CountingSemaphore.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
CountingSemaphore::CountingSemaphore(const uint8_t maxCount, uint8_t initCount): CountingSemaphore::CountingSemaphore(const uint8_t maxCount, uint8_t initCount):
maxCount(maxCount), initCount(initCount) { maxCount(maxCount), initCount(initCount) {
if(initCount > maxCount) { if(initCount > maxCount) {
sif::error << "CountingSemaphoreUsingTask: Max count bigger than " sif::error << "CountingSemaphoreUsingTask: Max count bigger than "
"intial cout. Setting initial count to max count." << std::endl; "intial cout. Setting initial count to max count." << std::endl;
initCount = maxCount; initCount = maxCount;
} }
initSemaphore(initCount); initSemaphore(initCount);
} }
CountingSemaphore::CountingSemaphore(CountingSemaphore&& other): CountingSemaphore::CountingSemaphore(CountingSemaphore&& other):
maxCount(other.maxCount), initCount(other.initCount) { maxCount(other.maxCount), initCount(other.initCount) {
initSemaphore(initCount); initSemaphore(initCount);
} }
CountingSemaphore& CountingSemaphore::operator =( CountingSemaphore& CountingSemaphore::operator =(
CountingSemaphore&& other) { CountingSemaphore&& other) {
initSemaphore(other.initCount); initSemaphore(other.initCount);
return * this; return * this;
} }
ReturnValue_t CountingSemaphore::release() { ReturnValue_t CountingSemaphore::release() {
ReturnValue_t result = checkCount(&handle, maxCount); ReturnValue_t result = checkCount(&handle, maxCount);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return CountingSemaphore::release(&this->handle); return CountingSemaphore::release(&this->handle);
} }
ReturnValue_t CountingSemaphore::release(sem_t* handle) { ReturnValue_t CountingSemaphore::release(sem_t* handle) {
int result = sem_post(handle); int result = sem_post(handle);
if(result == 0) { if(result == 0) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
switch(errno) { switch(errno) {
case(EINVAL): case(EINVAL):
// Semaphore invalid // Semaphore invalid
return SemaphoreIF::SEMAPHORE_INVALID; return SemaphoreIF::SEMAPHORE_INVALID;
case(EOVERFLOW): case(EOVERFLOW):
// SEM_MAX_VALUE overflow. This should never happen // SEM_MAX_VALUE overflow. This should never happen
default: default:
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
uint8_t CountingSemaphore::getMaxCount() const { uint8_t CountingSemaphore::getMaxCount() const {
return maxCount; return maxCount;
} }

View File

@ -1,37 +1,37 @@
#ifndef FRAMEWORK_OSAL_LINUX_COUNTINGSEMAPHORE_H_ #ifndef FRAMEWORK_OSAL_LINUX_COUNTINGSEMAPHORE_H_
#define FRAMEWORK_OSAL_LINUX_COUNTINGSEMAPHORE_H_ #define FRAMEWORK_OSAL_LINUX_COUNTINGSEMAPHORE_H_
#include "../../osal/linux/BinarySemaphore.h" #include "../../osal/linux/BinarySemaphore.h"
/** /**
* @brief Counting semaphores, which can be acquired more than once. * @brief Counting semaphores, which can be acquired more than once.
* @details * @details
* See: https://www.freertos.org/CreateCounting.html * See: https://www.freertos.org/CreateCounting.html
* API of counting semaphores is almost identical to binary semaphores, * API of counting semaphores is almost identical to binary semaphores,
* so we just inherit from binary semaphore and provide the respective * so we just inherit from binary semaphore and provide the respective
* constructors. * constructors.
*/ */
class CountingSemaphore: public BinarySemaphore { class CountingSemaphore: public BinarySemaphore {
public: public:
CountingSemaphore(const uint8_t maxCount, uint8_t initCount); CountingSemaphore(const uint8_t maxCount, uint8_t initCount);
//! @brief Copy ctor, disabled //! @brief Copy ctor, disabled
CountingSemaphore(const CountingSemaphore&) = delete; CountingSemaphore(const CountingSemaphore&) = delete;
//! @brief Copy assignment, disabled //! @brief Copy assignment, disabled
CountingSemaphore& operator=(const CountingSemaphore&) = delete; CountingSemaphore& operator=(const CountingSemaphore&) = delete;
//! @brief Move ctor //! @brief Move ctor
CountingSemaphore (CountingSemaphore &&); CountingSemaphore (CountingSemaphore &&);
//! @brief Move assignment //! @brief Move assignment
CountingSemaphore & operator=(CountingSemaphore &&); CountingSemaphore & operator=(CountingSemaphore &&);
ReturnValue_t release() override; ReturnValue_t release() override;
static ReturnValue_t release(sem_t* sem); static ReturnValue_t release(sem_t* sem);
/* Same API as binary semaphore otherwise. acquire() can be called /* Same API as binary semaphore otherwise. acquire() can be called
* until there are not semaphores left and release() can be called * until there are not semaphores left and release() can be called
* until maxCount is reached. */ * until maxCount is reached. */
uint8_t getMaxCount() const; uint8_t getMaxCount() const;
private: private:
const uint8_t maxCount; const uint8_t maxCount;
uint8_t initCount = 0; uint8_t initCount = 0;
}; };
#endif /* FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_ */ #endif /* FRAMEWORK_OSAL_FREERTOS_COUNTINGSEMAPHORE_H_ */

View File

@ -1,33 +1,33 @@
#include "../../tasks/SemaphoreFactory.h" #include "../../tasks/SemaphoreFactory.h"
#include "BinarySemaphore.h" #include "BinarySemaphore.h"
#include "CountingSemaphore.h" #include "CountingSemaphore.h"
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr; SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr;
SemaphoreFactory::SemaphoreFactory() { SemaphoreFactory::SemaphoreFactory() {
} }
SemaphoreFactory::~SemaphoreFactory() { SemaphoreFactory::~SemaphoreFactory() {
delete factoryInstance; delete factoryInstance;
} }
SemaphoreFactory* SemaphoreFactory::instance() { SemaphoreFactory* SemaphoreFactory::instance() {
if (factoryInstance == nullptr){ if (factoryInstance == nullptr){
factoryInstance = new SemaphoreFactory(); factoryInstance = new SemaphoreFactory();
} }
return SemaphoreFactory::factoryInstance; return SemaphoreFactory::factoryInstance;
} }
SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) { SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) {
return new BinarySemaphore(); return new BinarySemaphore();
} }
SemaphoreIF* SemaphoreFactory::createCountingSemaphore(const uint8_t maxCount, SemaphoreIF* SemaphoreFactory::createCountingSemaphore(const uint8_t maxCount,
uint8_t initCount, uint32_t arguments) { uint8_t initCount, uint32_t arguments) {
return new CountingSemaphore(maxCount, initCount); return new CountingSemaphore(maxCount, initCount);
} }
void SemaphoreFactory::deleteSemaphore(SemaphoreIF* semaphore) { void SemaphoreFactory::deleteSemaphore(SemaphoreIF* semaphore) {
delete semaphore; delete semaphore;
} }

View File

@ -1,129 +1,129 @@
#include "../serialize/SerialBufferAdapter.h" #include "../serialize/SerialBufferAdapter.h"
#include "../serviceinterface/ServiceInterfaceStream.h" #include "../serviceinterface/ServiceInterfaceStream.h"
#include <cstring> #include <cstring>
template<typename count_t> template<typename count_t>
SerialBufferAdapter<count_t>::SerialBufferAdapter(const uint8_t* buffer, SerialBufferAdapter<count_t>::SerialBufferAdapter(const uint8_t* buffer,
count_t bufferLength, bool serializeLength) : count_t bufferLength, bool serializeLength) :
serializeLength(serializeLength), serializeLength(serializeLength),
constBuffer(buffer), buffer(nullptr), constBuffer(buffer), buffer(nullptr),
bufferLength(bufferLength) {} bufferLength(bufferLength) {}
template<typename count_t> template<typename count_t>
SerialBufferAdapter<count_t>::SerialBufferAdapter(uint8_t* buffer, SerialBufferAdapter<count_t>::SerialBufferAdapter(uint8_t* buffer,
count_t bufferLength, bool serializeLength) : count_t bufferLength, bool serializeLength) :
serializeLength(serializeLength), constBuffer(buffer), buffer(buffer), serializeLength(serializeLength), constBuffer(buffer), buffer(buffer),
bufferLength(bufferLength) {} bufferLength(bufferLength) {}
template<typename count_t> template<typename count_t>
SerialBufferAdapter<count_t>::~SerialBufferAdapter() { SerialBufferAdapter<count_t>::~SerialBufferAdapter() {
} }
template<typename count_t> template<typename count_t>
ReturnValue_t SerialBufferAdapter<count_t>::serialize(uint8_t** buffer, ReturnValue_t SerialBufferAdapter<count_t>::serialize(uint8_t** buffer,
size_t* size, size_t maxSize, Endianness streamEndianness) const { size_t* size, size_t maxSize, Endianness streamEndianness) const {
if (serializeLength) { if (serializeLength) {
ReturnValue_t result = SerializeAdapter::serialize(&bufferLength, ReturnValue_t result = SerializeAdapter::serialize(&bufferLength,
buffer, size, maxSize, streamEndianness); buffer, size, maxSize, streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
} }
if (*size + bufferLength > maxSize) { if (*size + bufferLength > maxSize) {
return BUFFER_TOO_SHORT; return BUFFER_TOO_SHORT;
} }
if (this->constBuffer != nullptr) { if (this->constBuffer != nullptr) {
std::memcpy(*buffer, this->constBuffer, bufferLength); std::memcpy(*buffer, this->constBuffer, bufferLength);
} }
else if (this->buffer != nullptr) { else if (this->buffer != nullptr) {
// This will propably be never reached, constBuffer should always be // This will propably be never reached, constBuffer should always be
// set if non-const buffer is set. // set if non-const buffer is set.
std::memcpy(*buffer, this->buffer, bufferLength); std::memcpy(*buffer, this->buffer, bufferLength);
} }
else { else {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
*size += bufferLength; *size += bufferLength;
(*buffer) += bufferLength; (*buffer) += bufferLength;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
template<typename count_t> template<typename count_t>
size_t SerialBufferAdapter<count_t>::getSerializedSize() const { size_t SerialBufferAdapter<count_t>::getSerializedSize() const {
if (serializeLength) { if (serializeLength) {
return bufferLength + SerializeAdapter::getSerializedSize(&bufferLength); return bufferLength + SerializeAdapter::getSerializedSize(&bufferLength);
} else { } else {
return bufferLength; return bufferLength;
} }
} }
template<typename count_t> template<typename count_t>
ReturnValue_t SerialBufferAdapter<count_t>::deSerialize(const uint8_t** buffer, ReturnValue_t SerialBufferAdapter<count_t>::deSerialize(const uint8_t** buffer,
size_t* size, Endianness streamEndianness) { size_t* size, Endianness streamEndianness) {
if (this->buffer == nullptr) { if (this->buffer == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
if(serializeLength){ if(serializeLength){
count_t lengthField = 0; count_t lengthField = 0;
ReturnValue_t result = SerializeAdapter::deSerialize(&lengthField, ReturnValue_t result = SerializeAdapter::deSerialize(&lengthField,
buffer, size, streamEndianness); buffer, size, streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
if(lengthField > bufferLength) { if(lengthField > bufferLength) {
return TOO_MANY_ELEMENTS; return TOO_MANY_ELEMENTS;
} }
bufferLength = lengthField; bufferLength = lengthField;
} }
if (bufferLength <= *size) { if (bufferLength <= *size) {
*size -= bufferLength; *size -= bufferLength;
std::memcpy(this->buffer, *buffer, bufferLength); std::memcpy(this->buffer, *buffer, bufferLength);
(*buffer) += bufferLength; (*buffer) += bufferLength;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else { else {
return STREAM_TOO_SHORT; return STREAM_TOO_SHORT;
} }
} }
template<typename count_t> template<typename count_t>
uint8_t * SerialBufferAdapter<count_t>::getBuffer() { uint8_t * SerialBufferAdapter<count_t>::getBuffer() {
if(buffer == nullptr) { if(buffer == nullptr) {
sif::error << "Wrong access function for stored type !" sif::error << "Wrong access function for stored type !"
" Use getConstBuffer()." << std::endl; " Use getConstBuffer()." << std::endl;
return nullptr; return nullptr;
} }
return buffer; return buffer;
} }
template<typename count_t> template<typename count_t>
const uint8_t * SerialBufferAdapter<count_t>::getConstBuffer() { const uint8_t * SerialBufferAdapter<count_t>::getConstBuffer() {
if(constBuffer == nullptr) { if(constBuffer == nullptr) {
sif::error << "SerialBufferAdapter::getConstBuffer:" sif::error << "SerialBufferAdapter::getConstBuffer:"
" Buffers are unitialized!" << std::endl; " Buffers are unitialized!" << std::endl;
return nullptr; return nullptr;
} }
return constBuffer; return constBuffer;
} }
template<typename count_t> template<typename count_t>
void SerialBufferAdapter<count_t>::setBuffer(uint8_t* buffer, void SerialBufferAdapter<count_t>::setBuffer(uint8_t* buffer,
count_t bufferLength) { count_t bufferLength) {
this->buffer = buffer; this->buffer = buffer;
this->constBuffer = buffer; this->constBuffer = buffer;
this->bufferLength = bufferLength; this->bufferLength = bufferLength;
} }
//forward Template declaration for linker //forward Template declaration for linker
template class SerialBufferAdapter<uint8_t>; template class SerialBufferAdapter<uint8_t>;
template class SerialBufferAdapter<uint16_t>; template class SerialBufferAdapter<uint16_t>;
template class SerialBufferAdapter<uint32_t>; template class SerialBufferAdapter<uint32_t>;
template class SerialBufferAdapter<uint64_t>; template class SerialBufferAdapter<uint64_t>;

View File

@ -1,78 +1,78 @@
#ifndef SERIALBUFFERADAPTER_H_ #ifndef SERIALBUFFERADAPTER_H_
#define SERIALBUFFERADAPTER_H_ #define SERIALBUFFERADAPTER_H_
#include "../serialize/SerializeIF.h" #include "../serialize/SerializeIF.h"
#include "../serialize/SerializeAdapter.h" #include "../serialize/SerializeAdapter.h"
/** /**
* This adapter provides an interface for SerializeIF to serialize or deserialize * This adapter provides an interface for SerializeIF to serialize or deserialize
* buffers with no length header but a known size. * buffers with no length header but a known size.
* *
* Additionally, the buffer length can be serialized too and will be put in * Additionally, the buffer length can be serialized too and will be put in
* front of the serialized buffer. * front of the serialized buffer.
* *
* Can be used with SerialLinkedListAdapter by declaring a SerializeElement with * Can be used with SerialLinkedListAdapter by declaring a SerializeElement with
* SerialElement<SerialBufferAdapter<bufferLengthType(will be uint8_t mostly)>>. * SerialElement<SerialBufferAdapter<bufferLengthType(will be uint8_t mostly)>>.
* Right now, the SerialBufferAdapter must always * Right now, the SerialBufferAdapter must always
* be initialized with the buffer and size ! * be initialized with the buffer and size !
* *
* \ingroup serialize * \ingroup serialize
*/ */
template<typename count_t> template<typename count_t>
class SerialBufferAdapter: public SerializeIF { class SerialBufferAdapter: public SerializeIF {
public: public:
/** /**
* Constructor for constant uint8_t buffer. Length field can be serialized optionally. * Constructor for constant uint8_t buffer. Length field can be serialized optionally.
* Type of length can be supplied as template type. * Type of length can be supplied as template type.
* @param buffer * @param buffer
* @param bufferLength * @param bufferLength
* @param serializeLength * @param serializeLength
*/ */
SerialBufferAdapter(const uint8_t* buffer, count_t bufferLength, SerialBufferAdapter(const uint8_t* buffer, count_t bufferLength,
bool serializeLength = false); bool serializeLength = false);
/** /**
* Constructor for non-constant uint8_t buffer. * Constructor for non-constant uint8_t buffer.
* Length field can be serialized optionally. * Length field can be serialized optionally.
* Type of length can be supplied as template type. * Type of length can be supplied as template type.
* @param buffer * @param buffer
* @param bufferLength * @param bufferLength
* @param serializeLength Length field will be serialized with size count_t * @param serializeLength Length field will be serialized with size count_t
*/ */
SerialBufferAdapter(uint8_t* buffer, count_t bufferLength, SerialBufferAdapter(uint8_t* buffer, count_t bufferLength,
bool serializeLength = false); bool serializeLength = false);
virtual ~SerialBufferAdapter(); virtual ~SerialBufferAdapter();
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const override; size_t maxSize, Endianness streamEndianness) const override;
virtual size_t getSerializedSize() const override; virtual size_t getSerializedSize() const override;
/** /**
* @brief This function deserializes a buffer into the member buffer. * @brief This function deserializes a buffer into the member buffer.
* @details * @details
* If a length field is present, it is ignored, as the size should have * If a length field is present, it is ignored, as the size should have
* been set in the constructor. If the size is not known beforehand, * been set in the constructor. If the size is not known beforehand,
* consider using SerialFixedArrayListAdapter instead. * consider using SerialFixedArrayListAdapter instead.
* @param buffer [out] Resulting buffer * @param buffer [out] Resulting buffer
* @param size remaining size to deserialize, should be larger than buffer * @param size remaining size to deserialize, should be larger than buffer
* + size field size * + size field size
* @param bigEndian * @param bigEndian
* @return * @return
*/ */
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) override; Endianness streamEndianness) override;
uint8_t * getBuffer(); uint8_t * getBuffer();
const uint8_t * getConstBuffer(); const uint8_t * getConstBuffer();
void setBuffer(uint8_t* buffer, count_t bufferLength); void setBuffer(uint8_t* buffer, count_t bufferLength);
private: private:
bool serializeLength = false; bool serializeLength = false;
const uint8_t *constBuffer = nullptr; const uint8_t *constBuffer = nullptr;
uint8_t *buffer = nullptr; uint8_t *buffer = nullptr;
count_t bufferLength = 0; count_t bufferLength = 0;
}; };
#endif /* SERIALBUFFERADAPTER_H_ */ #endif /* SERIALBUFFERADAPTER_H_ */

View File

@ -1,50 +1,50 @@
#ifndef FSFW_TASKS_SEMAPHOREFACTORY_H_ #ifndef FSFW_TASKS_SEMAPHOREFACTORY_H_
#define FSFW_TASKS_SEMAPHOREFACTORY_H_ #define FSFW_TASKS_SEMAPHOREFACTORY_H_
#include "../tasks/SemaphoreIF.h" #include "../tasks/SemaphoreIF.h"
/** /**
* Creates Semaphore. * Creates Semaphore.
* This class is a "singleton" interface, i.e. it provides an * This class is a "singleton" interface, i.e. it provides an
* interface, but also is the base class for a singleton. * interface, but also is the base class for a singleton.
*/ */
class SemaphoreFactory { class SemaphoreFactory {
public: public:
virtual ~SemaphoreFactory(); virtual ~SemaphoreFactory();
/** /**
* Returns the single instance of SemaphoreFactory. * Returns the single instance of SemaphoreFactory.
* The implementation of #instance is found in its subclasses. * The implementation of #instance is found in its subclasses.
* Thus, we choose link-time variability of the instance. * Thus, we choose link-time variability of the instance.
*/ */
static SemaphoreFactory* instance(); static SemaphoreFactory* instance();
/** /**
* Create a binary semaphore. * Create a binary semaphore.
* Creator function for a binary semaphore which may only be acquired once * Creator function for a binary semaphore which may only be acquired once
* @param argument Can be used to pass implementation specific information. * @param argument Can be used to pass implementation specific information.
* @return Pointer to newly created semaphore class instance. * @return Pointer to newly created semaphore class instance.
*/ */
SemaphoreIF* createBinarySemaphore(uint32_t arguments = 0); SemaphoreIF* createBinarySemaphore(uint32_t arguments = 0);
/** /**
* Create a counting semaphore. * Create a counting semaphore.
* Creator functons for a counting semaphore which may be acquired multiple * Creator functons for a counting semaphore which may be acquired multiple
* times. * times.
* @param count Semaphore can be taken count times. * @param count Semaphore can be taken count times.
* @param initCount Initial count value. * @param initCount Initial count value.
* @param argument Can be used to pass implementation specific information. * @param argument Can be used to pass implementation specific information.
* @return * @return
*/ */
SemaphoreIF* createCountingSemaphore(const uint8_t maxCount, SemaphoreIF* createCountingSemaphore(const uint8_t maxCount,
uint8_t initCount, uint32_t arguments = 0); uint8_t initCount, uint32_t arguments = 0);
void deleteSemaphore(SemaphoreIF* semaphore); void deleteSemaphore(SemaphoreIF* semaphore);
private: private:
/** /**
* External instantiation is not allowed. * External instantiation is not allowed.
*/ */
SemaphoreFactory(); SemaphoreFactory();
static SemaphoreFactory* factoryInstance; static SemaphoreFactory* factoryInstance;
}; };
#endif /* FSFW_TASKS_SEMAPHOREFACTORY_H_ */ #endif /* FSFW_TASKS_SEMAPHOREFACTORY_H_ */

View File

@ -1,68 +1,68 @@
#ifndef FRAMEWORK_TASKS_SEMAPHOREIF_H_ #ifndef FRAMEWORK_TASKS_SEMAPHOREIF_H_
#define FRAMEWORK_TASKS_SEMAPHOREIF_H_ #define FRAMEWORK_TASKS_SEMAPHOREIF_H_
#include "../returnvalues/FwClassIds.h" #include "../returnvalues/FwClassIds.h"
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
#include <cstdint> #include <cstdint>
/** /**
* @brief Generic interface for semaphores, which can be used to achieve * @brief Generic interface for semaphores, which can be used to achieve
* task synchronization. This is a generic interface which can be * task synchronization. This is a generic interface which can be
* used for both binary semaphores and counting semaphores. * used for both binary semaphores and counting semaphores.
* @details * @details
* A semaphore is a synchronization primitive. * A semaphore is a synchronization primitive.
* See: https://en.wikipedia.org/wiki/Semaphore_(programming) * See: https://en.wikipedia.org/wiki/Semaphore_(programming)
* A semaphore can be used to achieve task synchonization and track the * A semaphore can be used to achieve task synchonization and track the
* availability of resources by using either the binary or the counting * availability of resources by using either the binary or the counting
* semaphore types. * semaphore types.
* *
* If mutual exlcusion of a resource is desired, a mutex should be used, * 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. * which is a special form of a semaphore and has an own interface.
*/ */
class SemaphoreIF { class SemaphoreIF {
public: public:
/** /**
* Different types of timeout for the mutex lock. * Different types of timeout for the mutex lock.
*/ */
enum TimeoutType { enum TimeoutType {
POLLING, //!< If mutex is not available, return immediately POLLING, //!< If mutex is not available, return immediately
WAITING, //!< Wait a specified time for the mutex to become available WAITING, //!< Wait a specified time for the mutex to become available
BLOCKING //!< Block indefinitely until the mutex becomes available. BLOCKING //!< Block indefinitely until the mutex becomes available.
}; };
virtual~ SemaphoreIF() {}; virtual~ SemaphoreIF() {};
static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF;
//! Semaphore timeout //! Semaphore timeout
static constexpr ReturnValue_t SEMAPHORE_TIMEOUT = MAKE_RETURN_CODE(1); static constexpr ReturnValue_t SEMAPHORE_TIMEOUT = MAKE_RETURN_CODE(1);
//! The current semaphore can not be given, because it is not owned //! 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_NOT_OWNED = MAKE_RETURN_CODE(2);
static constexpr ReturnValue_t SEMAPHORE_INVALID = MAKE_RETURN_CODE(3); static constexpr ReturnValue_t SEMAPHORE_INVALID = MAKE_RETURN_CODE(3);
/** /**
* Generic call to acquire a semaphore. * Generic call to acquire a semaphore.
* If there are no more semaphores to be taken (for a counting semaphore, * If there are no more semaphores to be taken (for a counting semaphore,
* a semaphore may be taken more than once), the taks will block * a semaphore may be taken more than once), the taks will block
* for a maximum of timeoutMs while trying to acquire the semaphore. * for a maximum of timeoutMs while trying to acquire the semaphore.
* This can be used to achieve task synchrnization. * This can be used to achieve task synchrnization.
* @param timeoutMs * @param timeoutMs
* @return - c RETURN_OK for successfull acquisition * @return - c RETURN_OK for successfull acquisition
*/ */
virtual ReturnValue_t acquire(TimeoutType timeoutType = virtual ReturnValue_t acquire(TimeoutType timeoutType =
TimeoutType::BLOCKING, uint32_t timeoutMs = 0) = 0; TimeoutType::BLOCKING, uint32_t timeoutMs = 0) = 0;
/** /**
* Corrensponding call to release a semaphore. * Corrensponding call to release a semaphore.
* @return -@c RETURN_OK for successfull release * @return -@c RETURN_OK for successfull release
*/ */
virtual ReturnValue_t release() = 0; virtual ReturnValue_t release() = 0;
/** /**
* If the semaphore is a counting semaphore then the semaphores current * If the semaphore is a counting semaphore then the semaphores current
* count value is returned. If the semaphore is a binary semaphore then 1 * count value is returned. If the semaphore is a binary semaphore then 1
* is returned if the semaphore is available, and 0 is returned if the * is returned if the semaphore is available, and 0 is returned if the
* semaphore is not available. * semaphore is not available.
*/ */
virtual uint8_t getSemaphoreCounter() const = 0; virtual uint8_t getSemaphoreCounter() const = 0;
}; };
#endif /* FRAMEWORK_TASKS_SEMAPHOREIF_H_ */ #endif /* FRAMEWORK_TASKS_SEMAPHOREIF_H_ */