1
0
forked from fsfw/fsfw

Merge remote-tracking branch 'upstream/master' into mueller_binSemaphoreInit

This commit is contained in:
2020-08-27 16:28:50 +02:00
391 changed files with 4372 additions and 2300 deletions

View File

@ -1,6 +1,6 @@
#include <framework/timemanager/Clock.h>
#include <framework/globalfunctions/timevalOperations.h>
#include <framework/osal/FreeRTOS/Timekeeper.h>
#include "../../timemanager/Clock.h"
#include "../../globalfunctions/timevalOperations.h"
#include "Timekeeper.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
@ -155,7 +155,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
if (checkOrCreateClockMutex() != HasReturnvaluesIF::RETURN_OK) {
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT);
ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
@ -170,7 +170,7 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
if (timeMutex == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT);
ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}

View File

@ -1,15 +1,16 @@
#include "FixedTimeslotTask.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "../../serviceinterface/ServiceInterfaceStream.h"
uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE;
FixedTimeslotTask::FixedTimeslotTask(const char *name, TaskPriority setPriority,
FixedTimeslotTask::FixedTimeslotTask(TaskName name, TaskPriority setPriority,
TaskStackSize setStack, TaskPeriod overallPeriod,
void (*setDeadlineMissedFunc)()) :
started(false), handle(NULL), pst(overallPeriod * 1000) {
xTaskCreate(taskEntryPoint, name, setStack, this, setPriority, &handle);
configSTACK_DEPTH_TYPE stackSize = setStack / sizeof(configSTACK_DEPTH_TYPE);
xTaskCreate(taskEntryPoint, name, stackSize, this, setPriority, &handle);
// All additional attributes are applied to the object.
this->deadlineMissedFunc = setDeadlineMissedFunc;
}
@ -82,7 +83,7 @@ ReturnValue_t FixedTimeslotTask::checkSequence() const {
void FixedTimeslotTask::taskFunctionality() {
// A local iterator for the Polling Sequence Table is created to find the
// start time for the first entry.
FixedSlotSequence::SlotListIter slotListIter = pst.current;
auto slotListIter = pst.current;
//The start time for the first entry is read.
uint32_t intervalMs = slotListIter->pollingTimeMs;
@ -125,19 +126,18 @@ void FixedTimeslotTask::checkMissedDeadline(const TickType_t xLastWakeTime,
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Tick count has overflown
if(currentTickCount < xLastWakeTime) {
// Time to wake has overflown as well. If the tick count
// is larger than the time to wake, a deadline was missed.
if(timeToWake < xLastWakeTime and
currentTickCount > timeToWake) {
// Time to wake has not overflown.
if(timeToWake > xLastWakeTime) {
/* If the current time has overflown exclusively or the current
* tick count is simply larger than the time to wake, a deadline was
* missed */
if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
// No tick count overflow. If the timeToWake has not overflown
// and the current tick count is larger than the time to wake,
// a deadline was missed.
else if(timeToWake > xLastWakeTime and currentTickCount > timeToWake) {
/* Time to wake has overflown. A deadline was missed if the current time
* is larger than the time to wake */
else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
@ -156,3 +156,7 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
vTaskDelay(pdMS_TO_TICKS(ms));
return HasReturnvaluesIF::RETURN_OK;
}
TaskHandle_t FixedTimeslotTask::getTaskHandle() {
return handle;
}

View File

@ -1,14 +1,16 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_
#define FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_
#include <framework/devicehandlers/FixedSlotSequence.h>
#include <framework/tasks/FixedTimeslotTaskIF.h>
#include <framework/tasks/Typedef.h>
#include "FreeRTOSTaskIF.h"
#include "../../devicehandlers/FixedSlotSequence.h"
#include "../../tasks/FixedTimeslotTaskIF.h"
#include "../../tasks/Typedef.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
class FixedTimeslotTask: public FixedTimeslotTaskIF {
class FixedTimeslotTask: public FixedTimeslotTaskIF, public FreeRTOSTaskIF {
public:
/**
@ -23,7 +25,7 @@ public:
* @param setDeadlineMissedFunc Callback if a deadline was missed.
* @return Pointer to the newly created task.
*/
FixedTimeslotTask(const char *name, TaskPriority setPriority,
FixedTimeslotTask(TaskName name, TaskPriority setPriority,
TaskStackSize setStack, TaskPeriod overallPeriod,
void (*setDeadlineMissedFunc)());
@ -57,6 +59,8 @@ public:
ReturnValue_t sleepFor(uint32_t ms) override;
TaskHandle_t getTaskHandle() override;
protected:
bool started;
TaskHandle_t handle;

View File

@ -0,0 +1,13 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_
#define FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
class FreeRTOSTaskIF {
public:
virtual~ FreeRTOSTaskIF() {}
virtual TaskHandle_t getTaskHandle() = 0;
};
#endif /* FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_ */

View File

@ -1,6 +1,6 @@
#include "MessageQueue.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "../../serviceinterface/ServiceInterfaceStream.h"
// TODO I guess we should have a way of checking if we are in an ISR and then use the "fromISR" versions of all calls

View File

@ -1,9 +1,9 @@
#ifndef MESSAGEQUEUE_H_
#define MESSAGEQUEUE_H_
#include <framework/internalError/InternalErrorReporterIF.h>
#include <framework/ipc/MessageQueueIF.h>
#include <framework/ipc/MessageQueueMessage.h>
#include "../../internalError/InternalErrorReporterIF.h"
#include "../../ipc/MessageQueueIF.h"
#include "../../ipc/MessageQueueMessage.h"
#include <FreeRTOS.h>
#include <queue.h>

View File

@ -1,28 +1,32 @@
#include "Mutex.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h>
const uint32_t MutexIF::NO_TIMEOUT = 0;
#include "../../serviceinterface/ServiceInterfaceStream.h"
Mutex::Mutex() {
handle = xSemaphoreCreateMutex();
//TODO print error
if(handle == nullptr) {
sif::error << "Mutex::Mutex(FreeRTOS): Creation failure" << std::endl;
}
}
Mutex::~Mutex() {
if (handle != 0) {
if (handle != nullptr) {
vSemaphoreDelete(handle);
}
}
ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) {
if (handle == 0) {
//TODO Does not exist
return HasReturnvaluesIF::RETURN_FAILED;
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType,
uint32_t timeoutMs) {
if (handle == nullptr) {
return MutexIF::MUTEX_NOT_FOUND;
}
TickType_t timeout = portMAX_DELAY;
if (timeoutMs != NO_TIMEOUT) {
// If the timeout type is BLOCKING, this will be the correct value.
uint32_t timeout = portMAX_DELAY;
if(timeoutType == TimeoutType::POLLING) {
timeout = 0;
}
else if(timeoutType == TimeoutType::WAITING){
timeout = pdMS_TO_TICKS(timeoutMs);
}
@ -30,21 +34,18 @@ ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) {
if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK;
} else {
//TODO could not be acquired/timeout
return HasReturnvaluesIF::RETURN_FAILED;
return MutexIF::MUTEX_TIMEOUT;
}
}
ReturnValue_t Mutex::unlockMutex() {
if (handle == 0) {
//TODO Does not exist
return HasReturnvaluesIF::RETURN_FAILED;
if (handle == nullptr) {
return MutexIF::MUTEX_NOT_FOUND;
}
BaseType_t returncode = xSemaphoreGive(handle);
if (returncode == pdPASS) {
return HasReturnvaluesIF::RETURN_OK;
} else {
//TODO is not owner
return HasReturnvaluesIF::RETURN_FAILED;
return MutexIF::CURR_THREAD_DOES_NOT_OWN_MUTEX;
}
}

View File

@ -1,22 +1,29 @@
#ifndef OS_RTEMS_MUTEX_H_
#define OS_RTEMS_MUTEX_H_
#include <framework/ipc/MutexIF.h>
#include <FreeRTOS.h>
#include "semphr.h"
#ifndef FRAMEWORK_FREERTOS_MUTEX_H_
#define FRAMEWORK_FREERTOS_MUTEX_H_
#include "../../ipc/MutexIF.h"
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
/**
* @brief OS component to implement MUTual EXclusion
*
* @details
* Mutexes are binary semaphores which include a priority inheritance mechanism.
* Documentation: https://www.freertos.org/Real-time-embedded-RTOS-mutexes.html
* @ingroup osal
*/
class Mutex : public MutexIF {
public:
Mutex();
~Mutex();
ReturnValue_t lockMutex(uint32_t timeoutMs);
ReturnValue_t unlockMutex();
ReturnValue_t lockMutex(TimeoutType timeoutType,
uint32_t timeoutMs) override;
ReturnValue_t unlockMutex() override;
private:
SemaphoreHandle_t handle;
};
#endif /* OS_RTEMS_MUTEX_H_ */
#endif /* FRAMEWORK_FREERTOS_MUTEX_H_ */

View File

@ -1,4 +1,4 @@
#include <framework/ipc/MutexFactory.h>
#include "../../ipc/MutexFactory.h"
#include "../FreeRTOS/Mutex.h"

View File

@ -1,17 +1,20 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/tasks/ExecutableObjectIF.h>
#include "PeriodicTask.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../tasks/ExecutableObjectIF.h"
PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority,
TaskStackSize setStack, TaskPeriod setPeriod,
void (*setDeadlineMissedFunc)()) :
TaskDeadlineMissedFunction deadlineMissedFunc) :
started(false), handle(NULL), period(setPeriod), deadlineMissedFunc(
setDeadlineMissedFunc) {
BaseType_t status = xTaskCreate(taskEntryPoint, name, setStack, this, setPriority, &handle);
deadlineMissedFunc)
{
configSTACK_DEPTH_TYPE stackSize = setStack / sizeof(configSTACK_DEPTH_TYPE);
BaseType_t status = xTaskCreate(taskEntryPoint, name,
stackSize, this, setPriority, &handle);
if(status != pdPASS){
sif::debug << "PeriodicTask Insufficient heap memory remaining. Status: "
<< status << std::endl;
sif::debug << "PeriodicTask Insufficient heap memory remaining. "
"Status: " << status << std::endl;
}
}
@ -21,16 +24,19 @@ PeriodicTask::~PeriodicTask(void) {
}
void PeriodicTask::taskEntryPoint(void* argument) {
//The argument is re-interpreted as PeriodicTask. The Task object is global, so it is found from any place.
// The argument is re-interpreted as PeriodicTask. The Task object is
// global, so it is found from any place.
PeriodicTask *originalTask(reinterpret_cast<PeriodicTask*>(argument));
// Task should not start until explicitly requested
// in FreeRTOS, tasks start as soon as they are created if the scheduler is running
// but not if the scheduler is not running.
// to be able to accommodate both cases we check a member which is set in #startTask()
// if it is not set and we get here, the scheduler was started before #startTask() was called and we need to suspend
// if it is set, the scheduler was not running before #startTask() was called and we can continue
/* Task should not start until explicitly requested,
* but in FreeRTOS, tasks start as soon as they are created if the scheduler
* is running but not if the scheduler is not running.
* To be able to accommodate both cases we check a member which is set in
* #startTask(). If it is not set and we get here, the scheduler was started
* before #startTask() was called and we need to suspend if it is set,
* the scheduler was not running before #startTask() was called and we
* can continue */
if (!originalTask->started) {
if (not originalTask->started) {
vTaskSuspend(NULL);
}
@ -59,31 +65,74 @@ void PeriodicTask::taskFunctionality() {
TickType_t xLastWakeTime;
const TickType_t xPeriod = pdMS_TO_TICKS(this->period * 1000.);
/* The xLastWakeTime variable needs to be initialized with the current tick
count. Note that this is the only time the variable is written to explicitly.
After this assignment, xLastWakeTime is updated automatically internally within
vTaskDelayUntil(). */
count. Note that this is the only time the variable is written to
explicitly. After this assignment, xLastWakeTime is updated automatically
internally within vTaskDelayUntil(). */
xLastWakeTime = xTaskGetTickCount();
/* Enter the loop that defines the task behavior. */
for (;;) {
for (ObjectList::iterator it = objectList.begin();
it != objectList.end(); ++it) {
(*it)->performOperation();
for (auto const& object: objectList) {
object->performOperation();
}
//TODO deadline missed check
checkMissedDeadline(xLastWakeTime, xPeriod);
vTaskDelayUntil(&xLastWakeTime, xPeriod);
}
}
ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
object);
if (newObject == NULL) {
if (newObject == nullptr) {
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
"it implement ExecutableObjectIF" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
objectList.push_back(newObject);
newObject->setTaskIF(this);
return HasReturnvaluesIF::RETURN_OK;
}
uint32_t PeriodicTask::getPeriodMs() const {
return period * 1000;
}
void PeriodicTask::checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Time to wake has not overflown.
if(timeToWake > xLastWakeTime) {
/* If the current time has overflown exclusively or the current
* tick count is simply larger than the time to wake, a deadline was
* missed */
if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
/* Time to wake has overflown. A deadline was missed if the current time
* is larger than the time to wake */
else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) {
handleMissedDeadline();
}
}
TaskHandle_t PeriodicTask::getTaskHandle() {
return handle;
}
void PeriodicTask::handleMissedDeadline() {
#ifdef DEBUG
sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) <<
" missed deadline!\n" << std::flush;
#endif
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
}
}

View File

@ -1,48 +1,51 @@
#ifndef MULTIOBJECTTASK_H_
#define MULTIOBJECTTASK_H_
#ifndef FRAMEWORK_OSAL_FREERTOS_PERIODICTASK_H_
#define FRAMEWORK_OSAL_FREERTOS_PERIODICTASK_H_
#include <framework/objectmanager/ObjectManagerIF.h>
#include <framework/tasks/PeriodicTaskIF.h>
#include <framework/tasks/Typedef.h>
#include "../../objectmanager/ObjectManagerIF.h"
#include "../../tasks/PeriodicTaskIF.h"
#include "../../tasks/Typedef.h"
#include "FreeRTOSTaskIF.h"
#include <FreeRTOS.h>
#include "task.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <vector>
class ExecutableObjectIF;
/**
* @brief This class represents a specialized task for periodic activities of multiple objects.
*
* @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute
* multiple objects that implement the ExecutableObjectIF interface. The objects must be
* added prior to starting the task.
*
* @brief This class represents a specialized task for
* periodic activities of multiple objects.
* @ingroup task_handling
*/
class PeriodicTask: public PeriodicTaskIF {
class PeriodicTask: public PeriodicTaskIF, public FreeRTOSTaskIF {
public:
/**
* @brief Standard constructor of the class.
* @details The class is initialized without allocated objects. These need to be added
* with #addObject.
* In the underlying TaskBase class, a new operating system task is created.
* In addition to the TaskBase parameters, the period, the pointer to the
* aforementioned initialization function and an optional "deadline-missed"
* function pointer is passed.
* @param priority Sets the priority of a task. Values range from a low 0 to a high 99.
* @param stack_size The stack size reserved by the operating system for the task.
* @param setPeriod The length of the period with which the task's functionality will be
* executed. It is expressed in clock ticks.
* @param setDeadlineMissedFunc The function pointer to the deadline missed function
* that shall be assigned.
* Keep in Mind that you need to call before this vTaskStartScheduler()!
* A lot of task parameters are set in "FreeRTOSConfig.h".
* TODO: why does this need to be called before vTaskStartScheduler?
* @details
* The class is initialized without allocated objects.
* These need to be added with #addComponent.
* @param priority
* Sets the priority of a task. Values depend on freeRTOS configuration,
* high number means high priority.
* @param stack_size
* The stack size reserved by the operating system for the task.
* @param setPeriod
* The length of the period with which the task's
* functionality will be executed. It is expressed in clock ticks.
* @param setDeadlineMissedFunc
* The function pointer to the deadline missed function that shall
* be assigned.
*/
PeriodicTask(const char *name, TaskPriority setPriority, TaskStackSize setStack, TaskPeriod setPeriod,
void (*setDeadlineMissedFunc)());
PeriodicTask(TaskName name, TaskPriority setPriority,
TaskStackSize setStack, TaskPeriod setPeriod,
TaskDeadlineMissedFunction deadlineMissedFunc);
/**
* @brief Currently, the executed object's lifetime is not coupled with the task object's
* lifetime, so the destructor is empty.
* @brief Currently, the executed object's lifetime is not coupled with
* the task object's lifetime, so the destructor is empty.
*/
virtual ~PeriodicTask(void);
@ -53,58 +56,73 @@ public:
* The address of the task object is passed as an argument
* to the system call.
*/
ReturnValue_t startTask(void);
ReturnValue_t startTask() override;
/**
* Adds an object to the list of objects to be executed.
* The objects are executed in the order added.
* @param object Id of the object to add.
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
* @return
* -@c RETURN_OK on success
* -@c RETURN_FAILED if the object could not be added.
*/
ReturnValue_t addComponent(object_id_t object);
ReturnValue_t addComponent(object_id_t object) override;
uint32_t getPeriodMs() const;
uint32_t getPeriodMs() const override;
ReturnValue_t sleepFor(uint32_t ms);
ReturnValue_t sleepFor(uint32_t ms) override;
TaskHandle_t getTaskHandle() override;
protected:
bool started;
TaskHandle_t handle;
typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects.
//! Typedef for the List of objects.
typedef std::vector<ExecutableObjectIF*> ObjectList;
/**
* @brief This attribute holds a list of objects to be executed.
*/
ObjectList objectList;
/**
* @brief The period of the task.
* @details The period determines the frequency of the task's execution. It is expressed in clock ticks.
* @details
* The period determines the frequency of the task's execution.
* It is expressed in clock ticks.
*/
TaskPeriod period;
/**
* @brief The pointer to the deadline-missed function.
* @details This pointer stores the function that is executed if the task's deadline is missed.
* So, each may react individually on a timing failure. The pointer may be NULL,
* then nothing happens on missing the deadline. The deadline is equal to the next execution
* of the periodic task.
* @details
* This pointer stores the function that is executed if the task's deadline
* is missed so each may react individually on a timing failure.
* The pointer may be NULL, then nothing happens on missing the deadline.
* The deadline is equal to the next execution of the periodic task.
*/
void (*deadlineMissedFunc)(void);
/**
* @brief This is the function executed in the new task's context.
* @details It converts the argument back to the thread object type and copies the class instance
* to the task context. The taskFunctionality method is called afterwards.
* @details
* It converts the argument back to the thread object type and copies the
* class instance to the task context. The taskFunctionality method is
* called afterwards.
* @param A pointer to the task object itself is passed as argument.
*/
static void taskEntryPoint(void* argument);
/**
* @brief The function containing the actual functionality of the task.
* @details The method sets and starts
* the task's period, then enters a loop that is repeated as long as the isRunning
* attribute is true. Within the loop, all performOperation methods of the added
* objects are called. Afterwards the checkAndRestartPeriod system call blocks the task
* until the next period.
* On missing the deadline, the deadlineMissedFunction is executed.
* @details
* The method sets and starts the task's period, then enters a loop that is
* repeated as long as the isRunning attribute is true. Within the loop,
* all performOperation methods of the added objects are called.
* Afterwards the checkAndRestartPeriod system call blocks the task until
* the next period.
* On missing the deadline, the deadlineMissedFunction is executed.
*/
void taskFunctionality(void);
void checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval);
void handleMissedDeadline();
};
#endif /* MULTIOBJECTTASK_H_ */
#endif /* PERIODICTASK_H_ */

View File

@ -1,6 +1,6 @@
#include <framework/ipc/QueueFactory.h>
#include "../../ipc/QueueFactory.h"
#include <framework/osal/FreeRTOS/MessageQueue.h>
#include "MessageQueue.h"
QueueFactory* QueueFactory::factoryInstance = NULL;

View File

@ -1,5 +1,5 @@
#include <framework/tasks/TaskFactory.h>
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include "../../tasks/TaskFactory.h"
#include "../../returnvalues/HasReturnvaluesIF.h"
#include "PeriodicTask.h"
#include "FixedTimeslotTask.h"

View File

@ -1,4 +1,4 @@
#include <framework/osal/FreeRTOS/Timekeeper.h>
#include "Timekeeper.h"
#include "FreeRTOSConfig.h"

View File

@ -1,7 +1,7 @@
#ifndef FRAMEWORK_OSAL_FREERTOS_TIMEKEEPER_H_
#define FRAMEWORK_OSAL_FREERTOS_TIMEKEEPER_H_
#include <framework/timemanager/Clock.h>
#include "../../timemanager/Clock.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>

View File

@ -1,7 +1,7 @@
#ifndef INTERNALERRORCODES_H_
#define INTERNALERRORCODES_H_
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include "../returnvalues/HasReturnvaluesIF.h"
class InternalErrorCodes {
public:

View File

@ -1,5 +1,5 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/timemanager/Clock.h>
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../timemanager/Clock.h"
#include <sys/time.h>
#include <sys/sysinfo.h>
@ -179,7 +179,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT);
ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
@ -194,7 +194,7 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
if(timeMutex==NULL){
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT);
ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}

View File

@ -1,5 +1,5 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/osal/linux/FixedTimeslotTask.h>
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "FixedTimeslotTask.h"
#include <limits.h>

View File

@ -1,9 +1,9 @@
#ifndef FRAMEWORK_OSAL_LINUX_FIXEDTIMESLOTTASK_H_
#define FRAMEWORK_OSAL_LINUX_FIXEDTIMESLOTTASK_H_
#include <framework/tasks/FixedTimeslotTaskIF.h>
#include <framework/devicehandlers/FixedSlotSequence.h>
#include <framework/osal/linux/PosixThread.h>
#include "../../tasks/FixedTimeslotTaskIF.h"
#include "../../devicehandlers/FixedSlotSequence.h"
#include "PosixThread.h"
#include <pthread.h>
class FixedTimeslotTask: public FixedTimeslotTaskIF, public PosixThread {

View File

@ -1,4 +1,4 @@
#include <framework/osal/InternalErrorCodes.h>
#include "../../osal/InternalErrorCodes.h"
ReturnValue_t InternalErrorCodes::translate(uint8_t code) {
//TODO This class can be removed

View File

@ -1,5 +1,5 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/osal/linux/MessageQueue.h>
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "MessageQueue.h"
#include <fstream>

View File

@ -1,9 +1,9 @@
#ifndef MESSAGEQUEUE_H_
#define MESSAGEQUEUE_H_
#include <framework/internalError/InternalErrorReporterIF.h>
#include <framework/ipc/MessageQueueIF.h>
#include <framework/ipc/MessageQueueMessage.h>
#include "../../internalError/InternalErrorReporterIF.h"
#include "../../ipc/MessageQueueIF.h"
#include "../../ipc/MessageQueueMessage.h"
#include <mqueue.h>
/**

View File

@ -1,8 +1,7 @@
#include <framework/osal/linux/Mutex.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/timemanager/Clock.h>
#include "Mutex.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../timemanager/Clock.h"
const uint32_t MutexIF::NO_TIMEOUT = 0;
uint8_t Mutex::count = 0;
@ -25,7 +24,9 @@ Mutex::Mutex() {
sif::error << "Mutex: creation with name, id " << mutex.__data.__count
<< ", " << " failed with " << strerror(status) << std::endl;
}
//After a mutex attributes object has been used to initialize one or more mutexes, any function affecting the attributes object (including destruction) shall not affect any previously initialized mutexes.
// After a mutex attributes object has been used to initialize one or more
// mutexes, any function affecting the attributes object
// (including destruction) shall not affect any previously initialized mutexes.
status = pthread_mutexattr_destroy(&mutexAttr);
if (status != 0) {
sif::error << "Mutex: Attribute destroy failed with " << strerror(status) << std::endl;
@ -37,9 +38,13 @@ Mutex::~Mutex() {
pthread_mutex_destroy(&mutex);
}
ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) {
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
int status = 0;
if (timeoutMs != MutexIF::NO_TIMEOUT) {
if(timeoutType == TimeoutType::POLLING) {
status = pthread_mutex_trylock(&mutex);
}
else if (timeoutType == TimeoutType::WAITING) {
timespec timeOut;
clock_gettime(CLOCK_REALTIME, &timeOut);
uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec;
@ -47,27 +52,35 @@ ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) {
timeOut.tv_sec = nseconds / 1000000000;
timeOut.tv_nsec = nseconds - timeOut.tv_sec * 1000000000;
status = pthread_mutex_timedlock(&mutex, &timeOut);
} else {
}
else if(timeoutType == TimeoutType::BLOCKING) {
status = pthread_mutex_lock(&mutex);
}
switch (status) {
case EINVAL:
//The mutex was created with the protocol attribute having the value PTHREAD_PRIO_PROTECT and the calling thread's priority is higher than the mutex's current priority ceiling.
// The mutex was created with the protocol attribute having the value
// PTHREAD_PRIO_PROTECT and the calling thread's priority is higher
// than the mutex's current priority ceiling.
return WRONG_ATTRIBUTE_SETTING;
//The process or thread would have blocked, and the abs_timeout parameter specified a nanoseconds field value less than zero or greater than or equal to 1000 million.
//The value specified by mutex does not refer to an initialized mutex object.
// The process or thread would have blocked, and the abs_timeout
// parameter specified a nanoseconds field value less than zero or
// greater than or equal to 1000 million.
// The value specified by mutex does not refer to an initialized mutex object.
//return MUTEX_NOT_FOUND;
case EBUSY:
//The mutex could not be acquired because it was already locked.
// The mutex could not be acquired because it was already locked.
return MUTEX_ALREADY_LOCKED;
case ETIMEDOUT:
//The mutex could not be locked before the specified timeout expired.
// The mutex could not be locked before the specified timeout expired.
return MUTEX_TIMEOUT;
case EAGAIN:
//The mutex could not be acquired because the maximum number of recursive locks for mutex has been exceeded.
// The mutex could not be acquired because the maximum number of
// recursive locks for mutex has been exceeded.
return MUTEX_MAX_LOCKS;
case EDEADLK:
//A deadlock condition was detected or the current thread already owns the mutex.
// A deadlock condition was detected or the current thread
// already owns the mutex.
return CURR_THREAD_ALREADY_OWNS_MUTEX;
case 0:
//Success

View File

@ -1,14 +1,15 @@
#ifndef OS_RTEMS_MUTEX_H_
#define OS_RTEMS_MUTEX_H_
#ifndef OS_LINUX_MUTEX_H_
#define OS_LINUX_MUTEX_H_
#include <framework/ipc/MutexIF.h>
#include "../../ipc/MutexIF.h"
#include <pthread.h>
class Mutex : public MutexIF {
public:
Mutex();
virtual ~Mutex();
virtual ReturnValue_t lockMutex(uint32_t timeoutMs);
virtual ReturnValue_t lockMutex(TimeoutType timeoutType, uint32_t timeoutMs);
virtual ReturnValue_t unlockMutex();
private:
pthread_mutex_t mutex;

View File

@ -1,5 +1,5 @@
#include <framework/ipc/MutexFactory.h>
#include <framework/osal/linux/Mutex.h>
#include "../../ipc/MutexFactory.h"
#include "Mutex.h"
//TODO: Different variant than the lazy loading in QueueFactory. What's better and why?
MutexFactory* MutexFactory::factoryInstance = new MutexFactory();

View File

@ -1,7 +1,7 @@
#include <framework/tasks/ExecutableObjectIF.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "../../tasks/ExecutableObjectIF.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include <errno.h>
#include <framework/osal/linux/PeriodicPosixTask.h>
#include "PeriodicPosixTask.h"
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_,
size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()):
@ -24,10 +24,12 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) {
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
object);
if (newObject == NULL) {
if (newObject == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
objectList.push_back(newObject);
newObject->setTaskIF(this);
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,10 +1,10 @@
#ifndef FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_
#define FRAMEWORK_OSAL_LINUX_PERIODICPOSIXTASK_H_
#include <framework/tasks/PeriodicTaskIF.h>
#include <framework/objectmanager/ObjectManagerIF.h>
#include <framework/osal/linux/PosixThread.h>
#include <framework/tasks/ExecutableObjectIF.h>
#include "../../tasks/PeriodicTaskIF.h"
#include "../../objectmanager/ObjectManagerIF.h"
#include "PosixThread.h"
#include "../../tasks/ExecutableObjectIF.h"
#include <vector>
class PeriodicPosixTask: public PosixThread, public PeriodicTaskIF {
@ -39,11 +39,11 @@ public:
* @param object Id of the object to add.
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
*/
ReturnValue_t addComponent(object_id_t object);
ReturnValue_t addComponent(object_id_t object) override;
uint32_t getPeriodMs() const;
uint32_t getPeriodMs() const override;
ReturnValue_t sleepFor(uint32_t ms);
ReturnValue_t sleepFor(uint32_t ms) override;
private:
typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects.

View File

@ -1,5 +1,5 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/osal/linux/PosixThread.h>
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "PosixThread.h"
#include <cstring>
#include <errno.h>

View File

@ -1,7 +1,7 @@
#ifndef FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_
#define FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <pthread.h>
#include <signal.h>
#include <cstdlib>

View File

@ -1,8 +1,8 @@
#include <framework/ipc/QueueFactory.h>
#include "../../ipc/QueueFactory.h"
#include <mqueue.h>
#include <errno.h>
#include <framework/osal/linux/MessageQueue.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "MessageQueue.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include <cstring>
QueueFactory* QueueFactory::factoryInstance = nullptr;

View File

@ -1,7 +1,7 @@
#include <framework/osal/linux/FixedTimeslotTask.h>
#include <framework/osal/linux/PeriodicPosixTask.h>
#include <framework/tasks/TaskFactory.h>
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include "FixedTimeslotTask.h"
#include "PeriodicPosixTask.h"
#include "../../tasks/TaskFactory.h"
#include "../../returnvalues/HasReturnvaluesIF.h"
//TODO: Different variant than the lazy loading in QueueFactory. What's better and why?
TaskFactory* TaskFactory::factoryInstance = new TaskFactory();

View File

@ -1,6 +1,6 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include <errno.h>
#include <framework/osal/linux/Timer.h>
#include "Timer.h"
Timer::Timer() {
sigevent sigEvent;

View File

@ -1,4 +1,4 @@
#include <framework/timemanager/Clock.h>
#include "../../timemanager/Clock.h"
#include "RtemsBasic.h"
#include <rtems/score/todimpl.h>

View File

@ -1,6 +1,6 @@
#include "CpuUsage.h"
#include <framework/serialize/SerialArrayListAdapter.h>
#include <framework/serialize/SerializeAdapter.h>
#include "../../serialize/SerialArrayListAdapter.h"
#include "../../serialize/SerializeAdapter.h"
#include <string.h>
extern "C" {

View File

@ -1,8 +1,8 @@
#ifndef CPUUSAGE_H_
#define CPUUSAGE_H_
#include <framework/container/FixedArrayList.h>
#include <framework/serialize/SerializeIF.h>
#include "../../container/FixedArrayList.h"
#include "../../serialize/SerializeIF.h"
#include <stdarg.h>
class CpuUsage : public SerializeIF {

View File

@ -1,4 +1,4 @@
#include <framework/osal/InternalErrorCodes.h>
#include "../../osal/InternalErrorCodes.h"
#include <rtems/score/interr.h>
ReturnValue_t InternalErrorCodes::translate(uint8_t code) {

View File

@ -1,7 +1,7 @@
#ifndef OS_RTEMS_INTERRUPT_H_
#define OS_RTEMS_INTERRUPT_H_
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <cstring>
#include <rtems.h>

View File

@ -1,4 +1,4 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "MessageQueue.h"
#include "RtemsBasic.h"
#include <cstring>

View File

@ -10,9 +10,9 @@
#ifndef MESSAGEQUEUE_H_
#define MESSAGEQUEUE_H_
#include <framework/internalError/InternalErrorReporterIF.h>
#include <framework/ipc/MessageQueueIF.h>
#include <framework/ipc/MessageQueueMessage.h>
#include "../../internalError/InternalErrorReporterIF.h"
#include "../../ipc/MessageQueueIF.h"
#include "../../ipc/MessageQueueMessage.h"
#include "RtemsBasic.h"
/**

View File

@ -5,8 +5,8 @@
* @author baetz
*/
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/tasks/ExecutableObjectIF.h>
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../tasks/ExecutableObjectIF.h"
#include "MultiObjectTask.h"
MultiObjectTask::MultiObjectTask(const char *name, rtems_task_priority setPriority,
@ -78,6 +78,8 @@ ReturnValue_t MultiObjectTask::addComponent(object_id_t object) {
return HasReturnvaluesIF::RETURN_FAILED;
}
objectList.push_back(newObject);
newObject->setTaskIF(this);
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,14 +1,8 @@
/**
* @file MultiObjectTask.h
* @brief This file defines the MultiObjectTask class.
* @date 30.01.2014
* @author baetz
*/
#ifndef MULTIOBJECTTASK_H_
#define MULTIOBJECTTASK_H_
#ifndef FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_
#define FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_
#include <framework/objectmanager/ObjectManagerIF.h>
#include <framework/tasks/PeriodicTaskIF.h>
#include "../../objectmanager/ObjectManagerIF.h"
#include "../../tasks/PeriodicTaskIF.h"
#include "TaskBase.h"
#include <vector>
@ -21,7 +15,7 @@ class ExecutableObjectIF;
* @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute
* multiple objects that implement the ExecutableObjectIF interface. The objects must be
* added prior to starting the task.
*
* @author baetz
* @ingroup task_handling
*/
class MultiObjectTask: public TaskBase, public PeriodicTaskIF {
@ -63,11 +57,11 @@ public:
* @param object Id of the object to add.
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added.
*/
ReturnValue_t addComponent(object_id_t object);
ReturnValue_t addComponent(object_id_t object) override;
uint32_t getPeriodMs() const;
uint32_t getPeriodMs() const override;
ReturnValue_t sleepFor(uint32_t ms);
ReturnValue_t sleepFor(uint32_t ms) override;
protected:
typedef std::vector<ExecutableObjectIF*> ObjectList; //!< Typedef for the List of objects.
/**
@ -110,4 +104,4 @@ protected:
void taskFunctionality(void);
};
#endif /* MULTIOBJECTTASK_H_ */
#endif /* FSFW_OSAL_RTEMS_MULTIOBJECTTASK_H_ */

View File

@ -1,7 +1,6 @@
#include "Mutex.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "../../serviceinterface/ServiceInterfaceStream.h"
const uint32_t MutexIF::NO_TIMEOUT = RTEMS_NO_TIMEOUT;
uint8_t Mutex::count = 0;
Mutex::Mutex() :
@ -24,8 +23,22 @@ Mutex::~Mutex() {
}
}
ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) {
rtems_status_code status = rtems_semaphore_obtain(mutexId, RTEMS_WAIT, timeoutMs);
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType =
TimeoutType::BLOCKING, uint32_t timeoutMs) {
if(timeoutMs == MutexIF::TimeoutType::BLOCKING) {
rtems_status_code status = rtems_semaphore_obtain(mutexId,
RTEMS_WAIT, RTEMS_NO_TIMEOUT);
}
else if(timeoutMs == MutexIF::TimeoutType::POLLING) {
timeoutMs = RTEMS_NO_TIMEOUT;
rtems_status_code status = rtems_semaphore_obtain(mutexId,
RTEMS_NO_WAIT, 0);
}
else {
rtems_status_code status = rtems_semaphore_obtain(mutexId,
RTEMS_WAIT, timeoutMs);
}
switch(status){
case RTEMS_SUCCESSFUL:
//semaphore obtained successfully

View File

@ -1,14 +1,14 @@
#ifndef OS_RTEMS_MUTEX_H_
#define OS_RTEMS_MUTEX_H_
#ifndef FRAMEWORK_OSAL_RTEMS_MUTEX_H_
#define FRAMEWORK_OSAL_RTEMS_MUTEX_H_
#include <framework/ipc/MutexIF.h>
#include "../../ipc/MutexIF.h"
#include "RtemsBasic.h"
class Mutex : public MutexIF {
public:
Mutex();
~Mutex();
ReturnValue_t lockMutex(uint32_t timeoutMs);
ReturnValue_t lockMutex(TimeoutType timeoutType, uint32_t timeoutMs = 0);
ReturnValue_t unlockMutex();
private:
rtems_id mutexId;

View File

@ -1,4 +1,4 @@
#include <framework/ipc/MutexFactory.h>
#include "../../ipc/MutexFactory.h"
#include "Mutex.h"
#include "RtemsBasic.h"

View File

@ -1,9 +1,9 @@
#include <framework/devicehandlers/FixedSequenceSlot.h>
#include <framework/objectmanager/SystemObjectIF.h>
#include <framework/osal/rtems/PollingTask.h>
#include <framework/osal/rtems/RtemsBasic.h>
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "../../devicehandlers/FixedSequenceSlot.h"
#include "../../objectmanager/SystemObjectIF.h"
#include "PollingTask.h"
#include "RtemsBasic.h"
#include "../../returnvalues/HasReturnvaluesIF.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include <rtems/bspIo.h>
#include <rtems/rtems/ratemon.h>
#include <rtems/rtems/status.h>

View File

@ -1,8 +1,8 @@
#ifndef POLLINGTASK_H_
#define POLLINGTASK_H_
#include <framework/devicehandlers/FixedSlotSequence.h>
#include <framework/tasks/FixedTimeslotTaskIF.h>
#include "../../devicehandlers/FixedSlotSequence.h"
#include "../../tasks/FixedTimeslotTaskIF.h"
#include "TaskBase.h"
class PollingTask: public TaskBase, public FixedTimeslotTaskIF {

View File

@ -1,4 +1,4 @@
#include <framework/ipc/QueueFactory.h>
#include "../../ipc/QueueFactory.h"
#include "MessageQueue.h"
#include "RtemsBasic.h"

View File

@ -1,7 +1,7 @@
#ifndef OS_RTEMS_RTEMSBASIC_H_
#define OS_RTEMS_RTEMSBASIC_H_
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <rtems.h>
#include <rtems/libio.h>
#include <rtems/error.h>

View File

@ -1,4 +1,4 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "TaskBase.h"
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE=RTEMS_MINIMUM_STACK_SIZE;

View File

@ -2,7 +2,7 @@
#define TASKBASE_H_
#include "RtemsBasic.h"
#include <framework/tasks/PeriodicTaskIF.h>
#include "../../tasks/PeriodicTaskIF.h"
/**
* @brief This is the basic task handling class for rtems.

View File

@ -1,9 +1,9 @@
#include <framework/tasks/TaskFactory.h>
#include "../../tasks/TaskFactory.h"
#include "MultiObjectTask.h"
#include "PollingTask.h"
#include "InitTask.h"
#include "RtemsBasic.h"
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include "../../returnvalues/HasReturnvaluesIF.h"
//TODO: Different variant than the lazy loading in QueueFactory. What's better and why?
TaskFactory* TaskFactory::factoryInstance = new TaskFactory();