Merge pull request 'Fixes for RTEMS #173' (#262) from gaisser_rtems_fixes into master

Reviewed-on: fsfw/fsfw#262
This commit is contained in:
Steffen Gaisser 2020-11-27 20:21:08 +01:00
commit d3a7f86ea2
20 changed files with 88 additions and 234 deletions

View File

@ -4,7 +4,7 @@
#include <stdint.h> #include <stdint.h>
#include "fwSubsystemIdRanges.h" #include "fwSubsystemIdRanges.h"
//could be move to more suitable location //could be move to more suitable location
#include <subsystemIdRanges.h> #include <events/subsystemIdRanges.h>
typedef uint16_t EventId_t; typedef uint16_t EventId_t;
typedef uint8_t EventSeverity_t; typedef uint8_t EventSeverity_t;

View File

@ -3,7 +3,7 @@
#include <rtems/score/todimpl.h> #include <rtems/score/todimpl.h>
uint16_t Clock::leapSeconds = 0; uint16_t Clock::leapSeconds = 0;
MutexIF* Clock::timeMutex = NULL; MutexIF* Clock::timeMutex = nullptr;
uint32_t Clock::getTicksPerSecond(void){ uint32_t Clock::getTicksPerSecond(void){
rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second(); rtems_interval ticks_per_second = rtems_clock_get_ticks_per_second();
@ -40,7 +40,7 @@ ReturnValue_t Clock::setClock(const timeval* time) {
//SHOULDDO: Not sure if we need to protect this call somehow (by thread lock or something). //SHOULDDO: Not sure if we need to protect this call somehow (by thread lock or something).
//Uli: rtems docu says you can call this from an ISR, not sure if this means no protetion needed //Uli: rtems docu says you can call this from an ISR, not sure if this means no protetion needed
//TODO Second parameter is ISR_lock_Context //TODO Second parameter is ISR_lock_Context
_TOD_Set(&newTime,NULL); _TOD_Set(&newTime,nullptr);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -131,7 +131,7 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) { ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
//SHOULDDO: works not for dates in the past (might have less leap seconds) //SHOULDDO: works not for dates in the past (might have less leap seconds)
if (timeMutex == NULL) { if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -157,40 +157,34 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){ if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); MutexHelper helper(timeMutex);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
leapSeconds = leapSeconds_; leapSeconds = leapSeconds_;
result = timeMutex->unlockMutex();
return result; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
if(timeMutex==NULL){ if(timeMutex==nullptr){
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); MutexHelper helper(timeMutex);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
*leapSeconds_ = leapSeconds; *leapSeconds_ = leapSeconds;
result = timeMutex->unlockMutex(); return HasReturnvaluesIF::RETURN_OK;
return result;
} }
ReturnValue_t Clock::checkOrCreateClockMutex(){ ReturnValue_t Clock::checkOrCreateClockMutex(){
if(timeMutex==NULL){ if(timeMutex==nullptr){
MutexFactory* mutexFactory = MutexFactory::instance(); MutexFactory* mutexFactory = MutexFactory::instance();
if (mutexFactory == NULL) { if (mutexFactory == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
timeMutex = mutexFactory->createMutex(); timeMutex = mutexFactory->createMutex();
if (timeMutex == NULL) { if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }

View File

@ -158,7 +158,7 @@ uint32_t CpuUsage::ThreadData::getSerializedSize() const {
} }
ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer, ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer,
int32_t* size, Endianness streamEndianness) { size_t* size, Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer, ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer,
size, streamEndianness); size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {

View File

@ -12,8 +12,8 @@ ReturnValue_t InternalErrorCodes::translate(uint8_t code) {
// return INVALID_WORKSPACE_ADDRESS; // return INVALID_WORKSPACE_ADDRESS;
case INTERNAL_ERROR_TOO_LITTLE_WORKSPACE: case INTERNAL_ERROR_TOO_LITTLE_WORKSPACE:
return TOO_LITTLE_WORKSPACE; return TOO_LITTLE_WORKSPACE;
case INTERNAL_ERROR_WORKSPACE_ALLOCATION: // case INTERNAL_ERROR_WORKSPACE_ALLOCATION:
return WORKSPACE_ALLOCATION; // return WORKSPACE_ALLOCATION;
// case INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL: // case INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL:
// return INTERRUPT_STACK_TOO_SMALL; // return INTERRUPT_STACK_TOO_SMALL;
case INTERNAL_ERROR_THREAD_EXITTED: case INTERNAL_ERROR_THREAD_EXITTED:

View File

@ -1,86 +0,0 @@
#include "Interrupt.h"
extern "C" {
#include <bsp_flp/hw_timer/hw_timer.h>
#include <bsp_flp/hw_uart/hw_uart.h>
}
#include "RtemsBasic.h"
ReturnValue_t Interrupt::enableInterrupt(InterruptNumber_t interruptNumber) {
volatile uint32_t* irqMask = hw_irq_mask;
uint32_t expectedValue = *irqMask | (1 << interruptNumber);
*irqMask = expectedValue;
uint32_t tempValue = *irqMask;
if (tempValue == expectedValue) {
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t Interrupt::setInterruptServiceRoutine(IsrHandler_t handler,
InterruptNumber_t interrupt, IsrHandler_t* oldHandler) {
IsrHandler_t oldHandler_local;
if (oldHandler == NULL) {
oldHandler = &oldHandler_local;
}
//+ 0x10 comes because of trap type assignment to IRQs in UT699 processor
rtems_status_code status = rtems_interrupt_catch(handler, interrupt + 0x10,
oldHandler);
switch(status){
case RTEMS_SUCCESSFUL:
//ISR established successfully
return HasReturnvaluesIF::RETURN_OK;
case RTEMS_INVALID_NUMBER:
//illegal vector number
return HasReturnvaluesIF::RETURN_FAILED;
case RTEMS_INVALID_ADDRESS:
//illegal ISR entry point or invalid old_isr_handler
return HasReturnvaluesIF::RETURN_FAILED;
default:
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t Interrupt::disableInterrupt(InterruptNumber_t interruptNumber) {
//TODO Not implemented
return HasReturnvaluesIF::RETURN_FAILED;
}
//SHOULDDO: Make default values (edge, polarity) settable?
ReturnValue_t Interrupt::enableGpioInterrupt(InterruptNumber_t interrupt) {
volatile uint32_t* irqMask = hw_irq_mask;
uint32_t expectedValue = *irqMask | (1 << interrupt);
*irqMask = expectedValue;
uint32_t tempValue = *irqMask;
if (tempValue == expectedValue) {
volatile hw_gpio_port_t* ioPorts = hw_gpio_port;
ioPorts->direction &= ~(1 << interrupt); //Direction In
ioPorts->interrupt_edge |= 1 << interrupt; //Edge triggered
ioPorts->interrupt_polarity |= 1 << interrupt; //Trigger on rising edge
ioPorts->interrupt_mask |= 1 << interrupt; //Enable
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t Interrupt::disableGpioInterrupt(InterruptNumber_t interrupt) {
volatile uint32_t* irqMask = hw_irq_mask;
uint32_t expectedValue = *irqMask & ~(1 << interrupt);
*irqMask = expectedValue;
uint32_t tempValue = *irqMask;
if (tempValue == expectedValue) {
//Disable gpio IRQ
volatile hw_gpio_port_t* ioPorts = hw_gpio_port;
ioPorts->interrupt_mask &= ~(1 << interrupt);
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
bool Interrupt::isInterruptInProgress() {
return rtems_interrupt_is_in_progress();
}

View File

@ -1,50 +0,0 @@
#ifndef OS_RTEMS_INTERRUPT_H_
#define OS_RTEMS_INTERRUPT_H_
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <cstring>
#include <rtems.h>
typedef rtems_isr_entry IsrHandler_t;
typedef rtems_isr IsrReturn_t;
typedef rtems_vector_number InterruptNumber_t;
class Interrupt {
public:
virtual ~Interrupt(){};
/**
* Establishes a new interrupt service routine.
* @param handler The service routine to establish
* @param interrupt The interrupt (NOT trap type) the routine shall react to.
* @return RETURN_OK on success. Otherwise, the OS failure code is returned.
*/
static ReturnValue_t setInterruptServiceRoutine(IsrHandler_t handler,
InterruptNumber_t interrupt, IsrHandler_t *oldHandler = NULL);
static ReturnValue_t enableInterrupt(InterruptNumber_t interruptNumber);
static ReturnValue_t disableInterrupt(InterruptNumber_t interruptNumber);
/**
* Enables the interrupt given.
* The function tests, if the InterruptMask register was written successfully.
* @param interrupt The interrupt to enable.
* @return RETURN_OK if the interrupt was set successfully. RETURN_FAILED else.
*/
static ReturnValue_t enableGpioInterrupt(InterruptNumber_t interrupt);
/**
* Disables the interrupt given.
* @param interrupt The interrupt to disable.
* @return RETURN_OK if the interrupt was set successfully. RETURN_FAILED else.
*/
static ReturnValue_t disableGpioInterrupt(InterruptNumber_t interrupt);
/**
* Checks if the current executing context is an ISR.
* @return true if handling an interrupt, false else.
*/
static bool isInterruptInProgress();
};
#endif /* OS_RTEMS_INTERRUPT_H_ */

View File

@ -1,14 +1,15 @@
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../objectmanager/ObjectManagerIF.h"
#include "MessageQueue.h" #include "MessageQueue.h"
#include "RtemsBasic.h" #include "RtemsBasic.h"
#include <cstring> #include <cstring>
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) : MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) :
id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(NULL) { id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(nullptr) {
rtems_name name = ('Q' << 24) + (queueCounter++ << 8); rtems_name name = ('Q' << 24) + (queueCounter++ << 8);
rtems_status_code status = rtems_message_queue_create(name, message_depth, rtems_status_code status = rtems_message_queue_create(name, message_depth,
max_message_size, 0, &(this->id)); max_message_size, 0, &(this->id));
if (status != RTEMS_SUCCESSFUL) { if (status != RTEMS_SUCCESSFUL) {
error << "MessageQueue::MessageQueue: Creating Queue " << std::hex sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex
<< name << std::dec << " failed with status:" << name << std::dec << " failed with status:"
<< (uint32_t) status << std::endl; << (uint32_t) status << std::endl;
this->id = 0; this->id = 0;
@ -20,15 +21,15 @@ MessageQueue::~MessageQueue() {
} }
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo,
MessageQueueMessage* message, bool ignoreFault) { MessageQueueMessageIF* message, bool ignoreFault) {
return sendMessageFrom(sendTo, message, this->getId(), ignoreFault); return sendMessageFrom(sendTo, message, this->getId(), ignoreFault);
} }
ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessage* message) { ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) {
return sendToDefaultFrom(message, this->getId()); return sendToDefaultFrom(message, this->getId());
} }
ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) { ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
if (this->lastPartner != 0) { if (this->lastPartner != 0) {
return sendMessage(this->lastPartner, message, this->getId()); return sendMessage(this->lastPartner, message, this->getId());
} else { } else {
@ -36,27 +37,29 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) {
} }
} }
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message, ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message,
MessageQueueId_t* receivedFrom) { MessageQueueId_t* receivedFrom) {
ReturnValue_t status = this->receiveMessage(message); ReturnValue_t status = this->receiveMessage(message);
*receivedFrom = this->lastPartner; *receivedFrom = this->lastPartner;
return status; return status;
} }
ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
size_t size = 0;
rtems_status_code status = rtems_message_queue_receive(id, rtems_status_code status = rtems_message_queue_receive(id,
message->getBuffer(), &(message->messageSize), message->getBuffer(),&size,
RTEMS_NO_WAIT, 1); RTEMS_NO_WAIT, 1);
if (status == RTEMS_SUCCESSFUL) { if (status == RTEMS_SUCCESSFUL) {
message->setMessageSize(size);
this->lastPartner = message->getSender(); this->lastPartner = message->getSender();
//Check size of incoming message. //Check size of incoming message.
if (message->messageSize < message->getMinimumMessageSize()) { if (message->getMessageSize() < message->getMinimumMessageSize()) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} else { } else {
//No message was received. Keep lastPartner anyway, I might send something later. //No message was received. Keep lastPartner anyway, I might send something later.
//But still, delete packet content. //But still, delete packet content.
memset(message->getData(), 0, message->MAX_DATA_SIZE); memset(message->getData(), 0, message->getMaximumMessageSize());
} }
return convertReturnCode(status); return convertReturnCode(status);
} }
@ -79,20 +82,20 @@ void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) {
} }
ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
MessageQueueMessage* message, MessageQueueId_t sentFrom, MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault) { bool ignoreFault) {
message->setSender(sentFrom); message->setSender(sentFrom);
rtems_status_code result = rtems_message_queue_send(sendTo, rtems_status_code result = rtems_message_queue_send(sendTo,
message->getBuffer(), message->messageSize); message->getBuffer(), message->getMessageSize());
//TODO: Check if we're in ISR. //TODO: Check if we're in ISR.
if (result != RTEMS_SUCCESSFUL && !ignoreFault) { if (result != RTEMS_SUCCESSFUL && !ignoreFault) {
if (internalErrorReporter == NULL) { if (internalErrorReporter == nullptr) {
internalErrorReporter = objectManager->get<InternalErrorReporterIF>( internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
objects::INTERNAL_ERROR_REPORTER); objects::INTERNAL_ERROR_REPORTER);
} }
if (internalErrorReporter != NULL) { if (internalErrorReporter != nullptr) {
internalErrorReporter->queueMessageNotSent(); internalErrorReporter->queueMessageNotSent();
} }
} }
@ -105,7 +108,7 @@ ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo,
return returnCode; return returnCode;
} }
ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessage* message, ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
MessageQueueId_t sentFrom, bool ignoreFault) { MessageQueueId_t sentFrom, bool ignoreFault) {
return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault); return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault);
} }

View File

@ -1,14 +1,5 @@
/** #ifndef FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
* @file MessageQueue.h #define FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_
*
* @date 10/02/2012
* @author Bastian Baetz
*
* @brief This file contains the definition of the MessageQueue class.
*/
#ifndef MESSAGEQUEUE_H_
#define MESSAGEQUEUE_H_
#include "../../internalError/InternalErrorReporterIF.h" #include "../../internalError/InternalErrorReporterIF.h"
#include "../../ipc/MessageQueueIF.h" #include "../../ipc/MessageQueueIF.h"
@ -60,14 +51,14 @@ public:
* @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full.
*/ */
ReturnValue_t sendMessage(MessageQueueId_t sendTo, ReturnValue_t sendMessage(MessageQueueId_t sendTo,
MessageQueueMessage* message, bool ignoreFault = false ); MessageQueueMessageIF* message, bool ignoreFault = false );
/** /**
* @brief This operation sends a message to the default destination. * @brief This operation sends a message to the default destination.
* @details As in the sendMessage method, this function uses the sendToDefault call of the * @details As in the sendMessage method, this function uses the sendToDefault call of the
* MessageQueueSender parent class and adds its queue id as "sentFrom" information. * MessageQueueSender parent class and adds its queue id as "sentFrom" information.
* @param message A pointer to a previously created message, which is sent. * @param message A pointer to a previously created message, which is sent.
*/ */
ReturnValue_t sendToDefault( MessageQueueMessage* message ); ReturnValue_t sendToDefault( MessageQueueMessageIF* message );
/** /**
* @brief This operation sends a message to the last communication partner. * @brief This operation sends a message to the last communication partner.
* @details This operation simplifies answering an incoming message by using the stored * @details This operation simplifies answering an incoming message by using the stored
@ -75,7 +66,7 @@ public:
* (i.e. lastPartner is zero), an error code is returned. * (i.e. lastPartner is zero), an error code is returned.
* @param message A pointer to a previously created message, which is sent. * @param message A pointer to a previously created message, which is sent.
*/ */
ReturnValue_t reply( MessageQueueMessage* message ); ReturnValue_t reply( MessageQueueMessageIF* message );
/** /**
* @brief This function reads available messages from the message queue and returns the sender. * @brief This function reads available messages from the message queue and returns the sender.
@ -84,7 +75,7 @@ public:
* @param message A pointer to a message in which the received data is stored. * @param message A pointer to a message in which the received data is stored.
* @param receivedFrom A pointer to a queue id in which the sender's id is stored. * @param receivedFrom A pointer to a queue id in which the sender's id is stored.
*/ */
ReturnValue_t receiveMessage(MessageQueueMessage* message, ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
MessageQueueId_t *receivedFrom); MessageQueueId_t *receivedFrom);
/** /**
@ -95,7 +86,7 @@ public:
* message's content is cleared and the function returns immediately. * message's content is cleared and the function returns immediately.
* @param message A pointer to a message in which the received data is stored. * @param message A pointer to a message in which the received data is stored.
*/ */
ReturnValue_t receiveMessage(MessageQueueMessage* message); ReturnValue_t receiveMessage(MessageQueueMessageIF* message);
/** /**
* Deletes all pending messages in the queue. * Deletes all pending messages in the queue.
* @param count The number of flushed messages. * @param count The number of flushed messages.
@ -121,7 +112,7 @@ public:
* This variable is set to zero by default. * This variable is set to zero by default.
* \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. * \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full.
*/ */
virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false ); virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false );
/** /**
* \brief The sendToDefault method sends a queue message to the default destination. * \brief The sendToDefault method sends a queue message to the default destination.
* \details In all other aspects, it works identical to the sendMessage method. * \details In all other aspects, it works identical to the sendMessage method.
@ -129,7 +120,7 @@ public:
* \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message. * \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message.
* This variable is set to zero by default. * This variable is set to zero by default.
*/ */
virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false ); virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false );
/** /**
* \brief This method is a simple setter for the default destination. * \brief This method is a simple setter for the default destination.
*/ */
@ -178,4 +169,4 @@ private:
static ReturnValue_t convertReturnCode(rtems_status_code inValue); static ReturnValue_t convertReturnCode(rtems_status_code inValue);
}; };
#endif /* MESSAGEQUEUE_H_ */ #endif /* FSFW_OSAL_RTEMS_MESSAGEQUEUE_H_ */

View File

@ -30,7 +30,7 @@ ReturnValue_t MultiObjectTask::startTask() {
rtems_status_code status = rtems_task_start(id, MultiObjectTask::taskEntryPoint, rtems_status_code status = rtems_task_start(id, MultiObjectTask::taskEntryPoint,
rtems_task_argument((void *) this)); rtems_task_argument((void *) this));
if (status != RTEMS_SUCCESSFUL) { if (status != RTEMS_SUCCESSFUL) {
error << "ObjectTask::startTask for " << std::hex << this->getId() sif::error << "ObjectTask::startTask for " << std::hex << this->getId()
<< std::dec << " failed." << std::endl; << std::dec << " failed." << std::endl;
} }
switch(status){ switch(status){
@ -63,8 +63,8 @@ void MultiObjectTask::taskFunctionality() {
char nameSpace[8] = { 0 }; char nameSpace[8] = { 0 };
char* ptr = rtems_object_get_name(getId(), sizeof(nameSpace), char* ptr = rtems_object_get_name(getId(), sizeof(nameSpace),
nameSpace); nameSpace);
error << "ObjectTask: " << ptr << " Deadline missed." << std::endl; sif::error << "ObjectTask: " << ptr << " Deadline missed." << std::endl;
if (this->deadlineMissedFunc != NULL) { if (this->deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc(); this->deadlineMissedFunc();
} }
} }
@ -74,7 +74,7 @@ void MultiObjectTask::taskFunctionality() {
ReturnValue_t MultiObjectTask::addComponent(object_id_t object) { ReturnValue_t MultiObjectTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>( ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
object); object);
if (newObject == NULL) { if (newObject == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
objectList.push_back(newObject); objectList.push_back(newObject);

View File

@ -80,7 +80,7 @@ protected:
/** /**
* @brief The pointer to the deadline-missed function. * @brief The pointer to the deadline-missed function.
* @details This pointer stores the function that is executed if the task's deadline is missed. * @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, * So, each may react individually on a timing failure. The pointer may be nullptr,
* then nothing happens on missing the deadline. The deadline is equal to the next execution * then nothing happens on missing the deadline. The deadline is equal to the next execution
* of the periodic task. * of the periodic task.
*/ */

View File

@ -10,7 +10,7 @@ Mutex::Mutex() :
RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, 0, RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, 0,
&mutexId); &mutexId);
if (status != RTEMS_SUCCESSFUL) { if (status != RTEMS_SUCCESSFUL) {
error << "Mutex: creation with name, id " << mutexName << ", " << mutexId sif::error << "Mutex: creation with name, id " << mutexName << ", " << mutexId
<< " failed with " << status << std::endl; << " failed with " << status << std::endl;
} }
} }
@ -18,24 +18,25 @@ Mutex::Mutex() :
Mutex::~Mutex() { Mutex::~Mutex() {
rtems_status_code status = rtems_semaphore_delete(mutexId); rtems_status_code status = rtems_semaphore_delete(mutexId);
if (status != RTEMS_SUCCESSFUL) { if (status != RTEMS_SUCCESSFUL) {
error << "Mutex: deletion for id " << mutexId sif::error << "Mutex: deletion for id " << mutexId
<< " failed with " << status << std::endl; << " failed with " << status << std::endl;
} }
} }
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType = ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType =
TimeoutType::BLOCKING, uint32_t timeoutMs) { TimeoutType::BLOCKING, uint32_t timeoutMs) {
rtems_status_code status = RTEMS_INVALID_ID;
if(timeoutMs == MutexIF::TimeoutType::BLOCKING) { if(timeoutMs == MutexIF::TimeoutType::BLOCKING) {
rtems_status_code status = rtems_semaphore_obtain(mutexId, status = rtems_semaphore_obtain(mutexId,
RTEMS_WAIT, RTEMS_NO_TIMEOUT); RTEMS_WAIT, RTEMS_NO_TIMEOUT);
} }
else if(timeoutMs == MutexIF::TimeoutType::POLLING) { else if(timeoutMs == MutexIF::TimeoutType::POLLING) {
timeoutMs = RTEMS_NO_TIMEOUT; timeoutMs = RTEMS_NO_TIMEOUT;
rtems_status_code status = rtems_semaphore_obtain(mutexId, status = rtems_semaphore_obtain(mutexId,
RTEMS_NO_WAIT, 0); RTEMS_NO_WAIT, 0);
} }
else { else {
rtems_status_code status = rtems_semaphore_obtain(mutexId, status = rtems_semaphore_obtain(mutexId,
RTEMS_WAIT, timeoutMs); RTEMS_WAIT, timeoutMs);
} }

View File

@ -1,5 +1,5 @@
#ifndef FRAMEWORK_OSAL_RTEMS_MUTEX_H_ #ifndef FSFW_OSAL_RTEMS_MUTEX_H_
#define FRAMEWORK_OSAL_RTEMS_MUTEX_H_ #define FSFW_OSAL_RTEMS_MUTEX_H_
#include "../../ipc/MutexIF.h" #include "../../ipc/MutexIF.h"
#include "RtemsBasic.h" #include "RtemsBasic.h"
@ -15,4 +15,4 @@ private:
static uint8_t count; static uint8_t count;
}; };
#endif /* OS_RTEMS_MUTEX_H_ */ #endif /* FSFW_OSAL_RTEMS_MUTEX_H_ */

View File

@ -2,7 +2,6 @@
#include "Mutex.h" #include "Mutex.h"
#include "RtemsBasic.h" #include "RtemsBasic.h"
//TODO: Different variant than the lazy loading in QueueFactory. What's better and why?
MutexFactory* MutexFactory::factoryInstance = new MutexFactory(); MutexFactory* MutexFactory::factoryInstance = new MutexFactory();
MutexFactory::MutexFactory() { MutexFactory::MutexFactory() {

View File

@ -1,5 +1,6 @@
#include "../../devicehandlers/FixedSequenceSlot.h" #include "../../tasks/FixedSequenceSlot.h"
#include "../../objectmanager/SystemObjectIF.h" #include "../../objectmanager/SystemObjectIF.h"
#include "../../objectmanager/ObjectManagerIF.h"
#include "PollingTask.h" #include "PollingTask.h"
#include "RtemsBasic.h" #include "RtemsBasic.h"
#include "../../returnvalues/HasReturnvaluesIF.h" #include "../../returnvalues/HasReturnvaluesIF.h"
@ -34,14 +35,14 @@ rtems_task PollingTask::taskEntryPoint(rtems_task_argument argument) {
PollingTask *originalTask(reinterpret_cast<PollingTask*>(argument)); PollingTask *originalTask(reinterpret_cast<PollingTask*>(argument));
//The task's functionality is called. //The task's functionality is called.
originalTask->taskFunctionality(); originalTask->taskFunctionality();
debug << "Polling task " << originalTask->getId() sif::debug << "Polling task " << originalTask->getId()
<< " returned from taskFunctionality." << std::endl; << " returned from taskFunctionality." << std::endl;
} }
void PollingTask::missedDeadlineCounter() { void PollingTask::missedDeadlineCounter() {
PollingTask::deadlineMissedCount++; PollingTask::deadlineMissedCount++;
if (PollingTask::deadlineMissedCount % 10 == 0) { if (PollingTask::deadlineMissedCount % 10 == 0) {
error << "PST missed " << PollingTask::deadlineMissedCount sif::error << "PST missed " << PollingTask::deadlineMissedCount
<< " deadlines." << std::endl; << " deadlines." << std::endl;
} }
} }
@ -50,7 +51,7 @@ ReturnValue_t PollingTask::startTask() {
rtems_status_code status = rtems_task_start(id, PollingTask::taskEntryPoint, rtems_status_code status = rtems_task_start(id, PollingTask::taskEntryPoint,
rtems_task_argument((void *) this)); rtems_task_argument((void *) this));
if (status != RTEMS_SUCCESSFUL) { if (status != RTEMS_SUCCESSFUL) {
error << "PollingTask::startTask for " << std::hex << this->getId() sif::error << "PollingTask::startTask for " << std::hex << this->getId()
<< std::dec << " failed." << std::endl; << std::dec << " failed." << std::endl;
} }
switch(status){ switch(status){
@ -68,12 +69,13 @@ ReturnValue_t PollingTask::startTask() {
ReturnValue_t PollingTask::addSlot(object_id_t componentId, ReturnValue_t PollingTask::addSlot(object_id_t componentId,
uint32_t slotTimeMs, int8_t executionStep) { uint32_t slotTimeMs, int8_t executionStep) {
if (objectManager->get<ExecutableObjectIF>(componentId) != nullptr) { ExecutableObjectIF* object = objectManager->get<ExecutableObjectIF>(componentId);
pst.addSlot(componentId, slotTimeMs, executionStep, this); if (object != nullptr) {
pst.addSlot(componentId, slotTimeMs, executionStep, object, this);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
error << "Component " << std::hex << componentId << sif::error << "Component " << std::hex << componentId <<
" not found, not adding it to pst" << std::endl; " not found, not adding it to pst" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -90,11 +92,10 @@ ReturnValue_t PollingTask::checkSequence() const {
void PollingTask::taskFunctionality() { void PollingTask::taskFunctionality() {
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry. // A local iterator for the Polling Sequence Table is created to find the start time for the first entry.
std::list<FixedSequenceSlot*>::iterator it = pst.current; FixedSlotSequence::SlotListIter it = pst.current;
//The start time for the first entry is read. //The start time for the first entry is read.
rtems_interval interval = RtemsBasic::convertMsToTicks( rtems_interval interval = RtemsBasic::convertMsToTicks(it->pollingTimeMs);
(*it)->pollingTimeMs);
TaskBase::setAndStartPeriod(interval,&periodId); TaskBase::setAndStartPeriod(interval,&periodId);
//The task's "infinite" inner loop is entered. //The task's "infinite" inner loop is entered.
while (1) { while (1) {
@ -107,7 +108,7 @@ void PollingTask::taskFunctionality() {
//If the deadline was missed, the deadlineMissedFunc is called. //If the deadline was missed, the deadlineMissedFunc is called.
rtems_status_code status = TaskBase::restartPeriod(interval,periodId); rtems_status_code status = TaskBase::restartPeriod(interval,periodId);
if (status == RTEMS_TIMEOUT) { if (status == RTEMS_TIMEOUT) {
if (this->deadlineMissedFunc != NULL) { if (this->deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc(); this->deadlineMissedFunc();
} }
} }

View File

@ -1,7 +1,7 @@
#ifndef POLLINGTASK_H_ #ifndef FSFW_OSAL_RTEMS_POLLINGTASK_H_
#define POLLINGTASK_H_ #define FSFW_OSAL_RTEMS_POLLINGTASK_H_
#include "../../devicehandlers/FixedSlotSequence.h" #include "../../tasks/FixedSlotSequence.h"
#include "../../tasks/FixedTimeslotTaskIF.h" #include "../../tasks/FixedTimeslotTaskIF.h"
#include "TaskBase.h" #include "TaskBase.h"
@ -82,4 +82,4 @@ protected:
void taskFunctionality( void ); void taskFunctionality( void );
}; };
#endif /* POLLINGTASK_H_ */ #endif /* FSFW_OSAL_RTEMS_POLLINGTASK_H_ */

View File

@ -1,16 +1,17 @@
#include "../../ipc/QueueFactory.h" #include "../../ipc/QueueFactory.h"
#include "../../ipc/MessageQueueSenderIF.h"
#include "MessageQueue.h" #include "MessageQueue.h"
#include "RtemsBasic.h" #include "RtemsBasic.h"
QueueFactory* QueueFactory::factoryInstance = NULL; QueueFactory* QueueFactory::factoryInstance = nullptr;
ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) { MessageQueueMessageIF* message, MessageQueueId_t sentFrom,bool ignoreFault) {
//TODO add ignoreFault functionality //TODO add ignoreFault functionality
message->setSender(sentFrom); message->setSender(sentFrom);
rtems_status_code result = rtems_message_queue_send(sendTo, message->getBuffer(), rtems_status_code result = rtems_message_queue_send(sendTo, message->getBuffer(),
message->messageSize); message->getMessageSize());
switch(result){ switch(result){
case RTEMS_SUCCESSFUL: case RTEMS_SUCCESSFUL:
//message sent successfully //message sent successfully
@ -37,7 +38,7 @@ ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
} }
QueueFactory* QueueFactory::instance() { QueueFactory* QueueFactory::instance() {
if (factoryInstance == NULL) { if (factoryInstance == nullptr) {
factoryInstance = new QueueFactory; factoryInstance = new QueueFactory;
} }
return factoryInstance; return factoryInstance;

View File

@ -1,5 +1,5 @@
#ifndef OS_RTEMS_RTEMSBASIC_H_ #ifndef FSFW_OSAL_RTEMS_RTEMSBASIC_H_
#define OS_RTEMS_RTEMSBASIC_H_ #define FSFW_OSAL_RTEMS_RTEMSBASIC_H_
#include "../../returnvalues/HasReturnvaluesIF.h" #include "../../returnvalues/HasReturnvaluesIF.h"
#include <rtems.h> #include <rtems.h>
@ -22,4 +22,4 @@ public:
} }
}; };
#endif /* OS_RTEMS_RTEMSBASIC_H_ */ #endif /* FSFW_OSAL_RTEMS_RTEMSBASIC_H_ */

View File

@ -22,7 +22,7 @@ TaskBase::TaskBase(rtems_task_priority set_priority, size_t stack_size,
} }
ReturnValue_t result = convertReturnCode(status); ReturnValue_t result = convertReturnCode(status);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
error << "TaskBase::TaskBase: createTask with name " << std::hex sif::error << "TaskBase::TaskBase: createTask with name " << std::hex
<< osalName << std::dec << " failed with return code " << osalName << std::dec << " failed with return code "
<< (uint32_t) status << std::endl; << (uint32_t) status << std::endl;
this->id = 0; this->id = 0;

View File

@ -1,5 +1,5 @@
#ifndef TASKBASE_H_ #ifndef FSFW_OSAL_RTEMS_TASKBASE_H_
#define TASKBASE_H_ #define FSFW_OSAL_RTEMS_TASKBASE_H_
#include "RtemsBasic.h" #include "RtemsBasic.h"
#include "../../tasks/PeriodicTaskIF.h" #include "../../tasks/PeriodicTaskIF.h"
@ -44,4 +44,4 @@ private:
}; };
#endif /* TASKBASE_H_ */ #endif /* FSFW_OSAL_RTEMS_TASKBASE_H_ */

View File

@ -2,7 +2,7 @@
#define FRAMEWORK_TIMEMANAGER_CLOCK_H_ #define FRAMEWORK_TIMEMANAGER_CLOCK_H_
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
#include "../ipc/MutexFactory.h" #include "../ipc/MutexHelper.h"
#include "../globalfunctions/timevalOperations.h" #include "../globalfunctions/timevalOperations.h"
#include <cstdint> #include <cstdint>