Merge branch 'mueller/master' into mueller/project/distribDatapool

This commit is contained in:
Robin Müller 2020-08-08 12:04:52 +02:00
commit 4afb19be51
52 changed files with 590 additions and 283 deletions

View File

@ -3,40 +3,57 @@
#include <framework/ipc/MutexHelper.h> #include <framework/ipc/MutexHelper.h>
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size, SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size,
bool overwriteOld, dur_millis_t mutexTimeout): bool overwriteOld, size_t maxExcessBytes, dur_millis_t mutexTimeout):
SystemObject(objectId), SimpleRingBuffer(size, overwriteOld), SystemObject(objectId), SimpleRingBuffer(size, overwriteOld,
mutexTimeout(mutexTimeout) { maxExcessBytes), mutexTimeout(mutexTimeout) {
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
} }
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer, SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
const size_t size, bool overwriteOld, dur_millis_t mutexTimeout): const size_t size, bool overwriteOld, size_t maxExcessBytes,
SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld), dur_millis_t mutexTimeout):
mutexTimeout(mutexTimeout) { SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld,
maxExcessBytes), mutexTimeout(mutexTimeout) {
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
} }
ReturnValue_t SharedRingBuffer::getFreeElementProtected(uint8_t** writePtr,
size_t amount) {
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeout);
return SimpleRingBuffer::getFreeElement(writePtr,amount);
}
ReturnValue_t SharedRingBuffer::writeDataProtected(const uint8_t *data, ReturnValue_t SharedRingBuffer::writeDataProtected(const uint8_t *data,
size_t amount) { size_t amount) {
MutexHelper(mutex, mutexTimeout); MutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeout);
return SimpleRingBuffer::writeData(data,amount); return SimpleRingBuffer::writeData(data,amount);
} }
ReturnValue_t SharedRingBuffer::readDataProtected(uint8_t *data, size_t amount, ReturnValue_t SharedRingBuffer::readDataProtected(uint8_t *data, size_t amount,
bool incrementReadPtr, bool readRemaining, bool incrementReadPtr, bool readRemaining,
size_t *trueAmount) { size_t *trueAmount) {
MutexHelper(mutex, mutexTimeout); MutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeout);
return SimpleRingBuffer::readData(data,amount, incrementReadPtr, return SimpleRingBuffer::readData(data,amount, incrementReadPtr,
readRemaining, trueAmount); readRemaining, trueAmount);
} }
ReturnValue_t SharedRingBuffer::deleteDataProtected(size_t amount, ReturnValue_t SharedRingBuffer::deleteDataProtected(size_t amount,
bool deleteRemaining, size_t *trueAmount) { bool deleteRemaining, size_t *trueAmount) {
MutexHelper(mutex, mutexTimeout); MutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeout);
return SimpleRingBuffer::deleteData(amount, deleteRemaining, trueAmount); return SimpleRingBuffer::deleteData(amount, deleteRemaining, trueAmount);
} }
size_t SharedRingBuffer::getExcessBytes() const {
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeout);
return SimpleRingBuffer::getExcessBytes();
}
void SharedRingBuffer::moveExcessBytesToStart() {
MutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeout);
return SimpleRingBuffer::moveExcessBytesToStart();
}
size_t SharedRingBuffer::getAvailableReadDataProtected(uint8_t n) const { size_t SharedRingBuffer::getAvailableReadDataProtected(uint8_t n) const {
MutexHelper(mutex, mutexTimeout); MutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeout);
return ((write + size) - read[n]) % size; return ((write + size) - read[n]) % size;
} }

View File

@ -17,7 +17,8 @@ public:
* will be overwritten. * will be overwritten.
*/ */
SharedRingBuffer(object_id_t objectId, const size_t size, SharedRingBuffer(object_id_t objectId, const size_t size,
bool overwriteOld, dur_millis_t mutexTimeout = 10); bool overwriteOld, size_t maxExcessBytes,
dur_millis_t mutexTimeout = 10);
/** /**
* This constructor takes an external buffer with the specified size. * This constructor takes an external buffer with the specified size.
@ -28,10 +29,22 @@ public:
* will be overwritten. * will be overwritten.
*/ */
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size,
bool overwriteOld, dur_millis_t mutexTimeout = 10); bool overwriteOld, size_t maxExcessBytes,
dur_millis_t mutexTimeout = 10);
void setMutexTimeout(dur_millis_t newTimeout); void setMutexTimeout(dur_millis_t newTimeout);
virtual size_t getExcessBytes() const override;
/**
* Helper functions which moves any excess bytes to the start
* of the ring buffer.
* @return
*/
virtual void moveExcessBytesToStart() override;
/** Performs mutex protected SimpleRingBuffer::getFreeElement call */
ReturnValue_t getFreeElementProtected(uint8_t** writePtr, size_t amount);
/** Performs mutex protected SimpleRingBuffer::writeData call */ /** Performs mutex protected SimpleRingBuffer::writeData call */
ReturnValue_t writeDataProtected(const uint8_t* data, size_t amount); ReturnValue_t writeDataProtected(const uint8_t* data, size_t amount);

View File

@ -1,20 +1,55 @@
#include <framework/container/SimpleRingBuffer.h> #include <framework/container/SimpleRingBuffer.h>
#include <cstring> #include <cstring>
SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld) : SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld,
RingBufferBase<>(0, size, overwriteOld) { size_t maxExcessBytes) :
buffer = new uint8_t[size]; RingBufferBase<>(0, size, overwriteOld),
maxExcessBytes(maxExcessBytes) {
if(maxExcessBytes > size) {
this->maxExcessBytes = size;
}
else {
this->maxExcessBytes = maxExcessBytes;
}
buffer = new uint8_t[size + maxExcessBytes];
} }
SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size, SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size,
bool overwriteOld): bool overwriteOld, size_t maxExcessBytes):
RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {} RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {
if(maxExcessBytes > size) {
this->maxExcessBytes = size;
}
else {
this->maxExcessBytes = maxExcessBytes;
}
}
SimpleRingBuffer::~SimpleRingBuffer() { SimpleRingBuffer::~SimpleRingBuffer() {
delete[] buffer; delete[] buffer;
} }
ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer,
size_t amount) {
if (availableWriteSpace() >= amount or overwriteOld) {
size_t amountTillWrap = writeTillWrap();
if (amountTillWrap < amount) {
if((amount - amountTillWrap + excessBytes) > maxExcessBytes) {
return HasReturnvaluesIF::RETURN_FAILED;
}
excessBytes = amount - amountTillWrap;
}
*writePointer = &buffer[write];
incrementWrite(amount);
return HasReturnvaluesIF::RETURN_OK;
}
else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data,
size_t amount) { size_t amount) {
if (availableWriteSpace() >= amount or overwriteOld) { if (availableWriteSpace() >= amount or overwriteOld) {
@ -62,6 +97,17 @@ ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount,
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
size_t SimpleRingBuffer::getExcessBytes() const {
return excessBytes;
}
void SimpleRingBuffer::moveExcessBytesToStart() {
if(excessBytes > 0) {
std::memcpy(buffer, &buffer[size], excessBytes);
excessBytes = 0;
}
}
ReturnValue_t SimpleRingBuffer::deleteData(size_t amount, ReturnValue_t SimpleRingBuffer::deleteData(size_t amount,
bool deleteRemaining, size_t* trueAmount) { bool deleteRemaining, size_t* trueAmount) {
size_t availableData = availableReadData(READ_PTR); size_t availableData = availableReadData(READ_PTR);

View File

@ -16,12 +16,17 @@ class SimpleRingBuffer: public RingBufferBase<> {
public: public:
/** /**
* This constructor allocates a new internal buffer with the supplied size. * This constructor allocates a new internal buffer with the supplied size.
*
* @param size * @param size
* @param overwriteOld * @param overwriteOld If the ring buffer is overflowing at a write
* If the ring buffer is overflowing at a write operartion, the oldest data * operation, the oldest data will be overwritten.
* will be overwritten. * @param maxExcessBytes These additional bytes will be allocated in addtion
* to the specified size to accomodate contiguous write operations
* with getFreeElement.
*
*/ */
SimpleRingBuffer(const size_t size, bool overwriteOld); SimpleRingBuffer(const size_t size, bool overwriteOld,
size_t maxExcessBytes = 0);
/** /**
* This constructor takes an external buffer with the specified size. * This constructor takes an external buffer with the specified size.
* @param buffer * @param buffer
@ -29,8 +34,13 @@ public:
* @param overwriteOld * @param overwriteOld
* If the ring buffer is overflowing at a write operartion, the oldest data * If the ring buffer is overflowing at a write operartion, the oldest data
* will be overwritten. * will be overwritten.
* @param maxExcessBytes
* If the buffer can accomodate additional bytes for contigous write
* operations with getFreeElement, this is the maximum allowed additional
* size
*/ */
SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld); SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld,
size_t maxExcessBytes = 0);
virtual ~SimpleRingBuffer(); virtual ~SimpleRingBuffer();
@ -43,6 +53,25 @@ public:
*/ */
ReturnValue_t writeData(const uint8_t* data, size_t amount); ReturnValue_t writeData(const uint8_t* data, size_t amount);
/**
* Returns a pointer to a free element. If the remaining buffer is
* not large enough, the data will be written past the actual size
* and the amount of excess bytes will be cached.
* @param writePointer Pointer to a pointer which can be used to write
* contiguous blocks into the ring buffer
* @param amount
* @return
*/
ReturnValue_t getFreeElement(uint8_t** writePointer, size_t amount);
virtual size_t getExcessBytes() const;
/**
* Helper functions which moves any excess bytes to the start
* of the ring buffer.
* @return
*/
virtual void moveExcessBytesToStart();
/** /**
* Read from circular buffer at read pointer. * Read from circular buffer at read pointer.
* @param data * @param data
@ -82,6 +111,8 @@ public:
private: private:
static const uint8_t READ_PTR = 0; static const uint8_t READ_PTR = 0;
uint8_t* buffer = nullptr; uint8_t* buffer = nullptr;
size_t maxExcessBytes;
size_t excessBytes = 0;
}; };
#endif /* FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ */ #endif /* FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ */

View File

@ -54,7 +54,8 @@ ReturnValue_t GlobalDataPool::unlockDataPool() {
} }
ReturnValue_t GlobalDataPool::lockDataPool(uint32_t timeoutMs) { ReturnValue_t GlobalDataPool::lockDataPool(uint32_t timeoutMs) {
ReturnValue_t status = mutex->lockMutex(timeoutMs); ReturnValue_t status = mutex->lockMutex(MutexIF::TimeoutType::WAITING,
timeoutMs);
if(status != RETURN_OK) { if(status != RETURN_OK) {
sif::error << "DataPool::DataPool: lock of mutex failed " sif::error << "DataPool::DataPool: lock of mutex failed "
"with error code: " << status << std::endl; "with error code: " << status << std::endl;

View File

@ -1,11 +1,105 @@
#include <framework/datapoollocal/LocalDataPoolManager.h>
#include <framework/datapoollocal/LocalDataSet.h> #include <framework/datapoollocal/LocalDataSet.h>
#include <framework/serialize/SerializeAdapter.h>
LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, const size_t maxSize): #include <cmath>
LocalDataSetBase(hkOwner, nullptr, maxSize), poolVarList(maxSize) { #include <cstring>
this->setContainer(poolVarList.data());
LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner,
const size_t maxNumberOfVariables):
DataSetBase(poolVarList.data(), maxNumberOfVariables) {
poolVarList.reserve(maxNumberOfVariables);
poolVarList.resize(maxNumberOfVariables);
if(hkOwner == nullptr) {
sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!"
<< std::endl;
return;
}
hkManager = hkOwner->getHkManagerHandle();
} }
LocalDataSet::LocalDataSet(object_id_t owner, const size_t maxSize): LocalDataSet::LocalDataSet(object_id_t ownerId,
LocalDataSetBase(owner, nullptr, maxSize), poolVarList(maxSize) { const size_t maxNumberOfVariables):
this->setContainer(poolVarList.data()); DataSetBase(poolVarList.data(), maxNumberOfVariables) {
poolVarList.reserve(maxNumberOfVariables);
poolVarList.resize(maxNumberOfVariables);
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
ownerId);
if(hkOwner == nullptr) {
sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!"
<< std::endl;
return;
}
hkManager = hkOwner->getHkManagerHandle();
}
LocalDataSet::~LocalDataSet() {
}
ReturnValue_t LocalDataSet::lockDataPool(uint32_t timeoutMs) {
MutexIF* mutex = hkManager->getMutexHandle();
return mutex->lockMutex(MutexIF::TimeoutType::WAITING, timeoutMs);
}
ReturnValue_t LocalDataSet::serializeWithValidityBuffer(uint8_t **buffer,
size_t *size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount)/8.0);
uint8_t validityMask[validityMaskSize];
uint8_t validBufferIndex = 0;
uint8_t validBufferIndexBit = 0;
for (uint16_t count = 0; count < fillCount; count++) {
if(registeredVariables[count]->isValid()) {
// set validity buffer here.
this->bitSetter(validityMask + validBufferIndex,
validBufferIndexBit);
if(validBufferIndexBit == 7) {
validBufferIndex ++;
validBufferIndexBit = 0;
}
else {
validBufferIndexBit ++;
}
}
result = registeredVariables[count]->serialize(buffer, size, maxSize,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
// copy validity buffer to end
std::memcpy(*buffer, validityMask, validityMaskSize);
*size += validityMaskSize;
return result;
}
ReturnValue_t LocalDataSet::unlockDataPool() {
MutexIF* mutex = hkManager->getMutexHandle();
return mutex->unlockMutex();
}
ReturnValue_t LocalDataSet::serializeLocalPoolIds(uint8_t** buffer,
size_t* size, size_t maxSize,
SerializeIF::Endianness streamEndianness) const {
for (uint16_t count = 0; count < fillCount; count++) {
lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId();
auto result = SerializeAdapter::serialize(&currentPoolId, buffer,
size, maxSize, streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "LocalDataSet::serializeLocalPoolIds: Serialization"
" error!" << std::endl;
return result;
}
}
return HasReturnvaluesIF::RETURN_OK;
}
void LocalDataSet::bitSetter(uint8_t* byte, uint8_t position) const {
if(position > 7) {
sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl;
return;
}
uint8_t shiftNumber = position + (7 - 2 * position);
*byte |= 1 << shiftNumber;
} }

View File

@ -48,7 +48,8 @@ inline LocalPoolVar<T>::LocalPoolVar(lp_id_t poolId, object_id_t poolOwner,
template<typename T> template<typename T>
inline ReturnValue_t LocalPoolVar<T>::read(dur_millis_t lockTimeout) { inline ReturnValue_t LocalPoolVar<T>::read(dur_millis_t lockTimeout) {
MutexHelper(hkManager->getMutexHandle(), lockTimeout); MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING,
lockTimeout);
return readWithoutLock(); return readWithoutLock();
} }
@ -76,7 +77,8 @@ inline ReturnValue_t LocalPoolVar<T>::readWithoutLock() {
template<typename T> template<typename T>
inline ReturnValue_t LocalPoolVar<T>::commit(dur_millis_t lockTimeout) { inline ReturnValue_t LocalPoolVar<T>::commit(dur_millis_t lockTimeout) {
MutexHelper(hkManager->getMutexHandle(), lockTimeout); MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING,
lockTimeout);
return commitWithoutLock(); return commitWithoutLock();
} }

View File

@ -44,7 +44,8 @@ inline LocalPoolVector<T, vectorSize>::LocalPoolVector(lp_id_t poolId,
template<typename T, uint16_t vectorSize> template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::read(uint32_t lockTimeout) { inline ReturnValue_t LocalPoolVector<T, vectorSize>::read(uint32_t lockTimeout) {
MutexHelper(hkManager->getMutexHandle(), lockTimeout); MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING,
lockTimeout);
return readWithoutLock(); return readWithoutLock();
} }
template<typename T, uint16_t vectorSize> template<typename T, uint16_t vectorSize>
@ -74,7 +75,8 @@ inline ReturnValue_t LocalPoolVector<T, vectorSize>::readWithoutLock() {
template<typename T, uint16_t vectorSize> template<typename T, uint16_t vectorSize>
inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit( inline ReturnValue_t LocalPoolVector<T, vectorSize>::commit(
uint32_t lockTimeout) { uint32_t lockTimeout) {
MutexHelper(hkManager->getMutexHandle(), lockTimeout); MutexHelper(hkManager->getMutexHandle(), MutexIF::TimeoutType::WAITING,
lockTimeout);
return commitWithoutLock(); return commitWithoutLock();
} }

View File

@ -165,9 +165,8 @@ ReturnValue_t AssemblyBase::checkChildrenState() {
} }
ReturnValue_t AssemblyBase::checkChildrenStateOff() { ReturnValue_t AssemblyBase::checkChildrenStateOff() {
for (std::map<object_id_t, ChildInfo>::iterator iter = childrenMap.begin(); for (const auto& childIter: childrenMap) {
iter != childrenMap.end(); iter++) { if (checkChildOff(childIter.first) != RETURN_OK) {
if (checkChildOff(iter->first) != RETURN_OK) {
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
} }
} }

View File

@ -1,10 +1,30 @@
#ifndef ASSEMBLYBASE_H_ #ifndef FRAMEWORK_DEVICEHANDLERS_ASSEMBLYBASE_H_
#define ASSEMBLYBASE_H_ #define FRAMEWORK_DEVICEHANDLERS_ASSEMBLYBASE_H_
#include <framework/container/FixedArrayList.h> #include <framework/container/FixedArrayList.h>
#include <framework/devicehandlers/DeviceHandlerBase.h> #include <framework/devicehandlers/DeviceHandlerBase.h>
#include <framework/subsystem/SubsystemBase.h> #include <framework/subsystem/SubsystemBase.h>
/**
* @brief Base class to implement reconfiguration and failure handling for
* redundant devices by monitoring their modes health states.
* @details
* Documentation: Dissertation Baetz p.156, 157.
*
* This class reduces the complexity of controller components which would
* otherwise be needed for the handling of redundant devices.
*
* The template class monitors mode and health state of its children
* and checks availability of devices on every detected change.
* AssemblyBase does not implement any redundancy logic by itself, but provides
* adaptation points for implementations to do so. Since most monitoring
* activities rely on mode and health state only and are therefore
* generic, it is sufficient for subclasses to provide:
*
* 1. check logic when active-> checkChildrenStateOn
* 2. transition logic to change the mode -> commandChildren
*
*/
class AssemblyBase: public SubsystemBase { class AssemblyBase: public SubsystemBase {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::ASSEMBLY_BASE; static const uint8_t INTERFACE_ID = CLASS_ID::ASSEMBLY_BASE;
@ -16,10 +36,41 @@ public:
static const ReturnValue_t NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE = static const ReturnValue_t NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE =
MAKE_RETURN_CODE(0xa1); MAKE_RETURN_CODE(0xa1);
AssemblyBase(object_id_t objectId, object_id_t parentId, uint16_t commandQueueDepth = 8); AssemblyBase(object_id_t objectId, object_id_t parentId,
uint16_t commandQueueDepth = 8);
virtual ~AssemblyBase(); virtual ~AssemblyBase();
protected: protected:
// SHOULDDO: Change that OVERWRITE_HEALTH may be returned
// (or return internalState directly?)
/**
* Command children to reach [mode,submode] combination
* Can be done by setting #commandsOutstanding correctly,
* or using executeTable()
* @param mode
* @param submode
* @return
* - @c RETURN_OK if ok
* - @c NEED_SECOND_STEP if children need to be commanded again
*/
virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0;
/**
* Check whether desired assembly mode was achieved by checking the modes
* or/and health states of child device handlers.
* The assembly template class will also call this function if a health
* or mode change of a child device handler was detected.
* @param wantedMode
* @param wantedSubmode
* @return
*/
virtual ReturnValue_t checkChildrenStateOn(Mode_t wantedMode,
Submode_t wantedSubmode) = 0;
virtual ReturnValue_t isModeCombinationValid(Mode_t mode,
Submode_t submode) = 0;
enum InternalState { enum InternalState {
STATE_NONE, STATE_NONE,
STATE_OVERWRITE_HEALTH, STATE_OVERWRITE_HEALTH,
@ -36,6 +87,7 @@ protected:
RECOVERY_WAIT RECOVERY_WAIT
} recoveryState; //!< Indicates if one of the children requested a recovery. } recoveryState; //!< Indicates if one of the children requested a recovery.
ChildrenMap::iterator recoveringDevice; ChildrenMap::iterator recoveringDevice;
/** /**
* the mode the current transition is trying to achieve. * the mode the current transition is trying to achieve.
* Can be different from the modehelper.commandedMode! * Can be different from the modehelper.commandedMode!
@ -61,8 +113,8 @@ protected:
bool handleChildrenChanged(); bool handleChildrenChanged();
/** /**
* This method is called if the children changed its mode in a way that the current * This method is called if the children changed its mode in a way that
* mode can't be kept. * the current mode can't be kept.
* Default behavior is to go to MODE_OFF. * Default behavior is to go to MODE_OFF.
* @param result The failure code which was returned by checkChildrenState. * @param result The failure code which was returned by checkChildrenState.
*/ */
@ -75,9 +127,6 @@ protected:
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode); uint32_t *msToReachTheMode);
virtual ReturnValue_t isModeCombinationValid(Mode_t mode,
Submode_t submode) = 0;
virtual void startTransition(Mode_t mode, Submode_t submode); virtual void startTransition(Mode_t mode, Submode_t submode);
virtual void doStartTransition(Mode_t mode, Submode_t submode); virtual void doStartTransition(Mode_t mode, Submode_t submode);
@ -90,24 +139,6 @@ protected:
void sendHealthCommand(MessageQueueId_t sendTo, HealthState health); void sendHealthCommand(MessageQueueId_t sendTo, HealthState health);
//SHOULDDO: Change that OVERWRITE_HEALTH may be returned (or return internalState directly?)
/**
* command children to reach mode,submode
*
* set #commandsOutstanding correctly, or use executeTable()
*
* @param mode
* @param submode
* @return
* - @c RETURN_OK if ok
* - @c NEED_SECOND_STEP if children need to be commanded again
*/
virtual ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) = 0;
//SHOULDDO: Remove wantedMode, wantedSubmode, as targetMode/submode is available?
virtual ReturnValue_t checkChildrenStateOn(Mode_t wantedMode,
Submode_t wantedSubmode) = 0;
virtual ReturnValue_t checkChildrenStateOff(); virtual ReturnValue_t checkChildrenStateOff();
ReturnValue_t checkChildrenState(); ReturnValue_t checkChildrenState();
@ -129,4 +160,4 @@ protected:
}; };
#endif /* ASSEMBLYBASE_H_ */ #endif /* FRAMEWORK_DEVICEHANDLERS_ASSEMBLYBASE_H_ */

View File

@ -39,7 +39,7 @@ ReturnValue_t ChildHandlerBase::initialize() {
parent->registerChild(getObjectId()); parent->registerChild(getObjectId());
} }
healthHelper.setParentQeueue(parentQueue); healthHelper.setParentQueue(parentQueue);
modeHelper.setParentQueue(parentQueue); modeHelper.setParentQueue(parentQueue);

View File

@ -128,6 +128,8 @@ ReturnValue_t DeviceHandlerBase::initialize() {
result = communicationInterface->initializeInterface(comCookie); result = communicationInterface->initializeInterface(comCookie);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::error << "DeviceHandlerBase::initialize: Initializing "
"communication interface failed!" << std::endl;
return result; return result;
} }
@ -678,6 +680,10 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
switch (result) { switch (result) {
case RETURN_OK: case RETURN_OK:
handleReply(receivedData, foundId, foundLen); handleReply(receivedData, foundId, foundLen);
if(foundLen == 0) {
sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!"
" Packet parsing will be stuck." << std::endl;
}
break; break;
case APERIODIC_REPLY: { case APERIODIC_REPLY: {
result = interpretDeviceReply(foundId, receivedData); result = interpretDeviceReply(foundId, receivedData);
@ -686,8 +692,12 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result,
foundId); foundId);
} }
if(foundLen == 0) {
sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!"
" Packet parsing will be stuck." << std::endl;
} }
break; break;
}
case IGNORE_REPLY_DATA: case IGNORE_REPLY_DATA:
break; break;
case IGNORE_FULL_PACKET: case IGNORE_FULL_PACKET:
@ -1134,7 +1144,7 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
void DeviceHandlerBase::setParentQueue(MessageQueueId_t parentQueueId) { void DeviceHandlerBase::setParentQueue(MessageQueueId_t parentQueueId) {
modeHelper.setParentQueue(parentQueueId); modeHelper.setParentQueue(parentQueueId);
healthHelper.setParentQeueue(parentQueueId); healthHelper.setParentQueue(parentQueueId);
} }
bool DeviceHandlerBase::isAwaitingReply() { bool DeviceHandlerBase::isAwaitingReply() {

View File

@ -379,6 +379,8 @@ protected:
* @param deviceCommand Identifier of the command to add. * @param deviceCommand Identifier of the command to add.
* @param maxDelayCycles The maximum number of delay cycles the command * @param maxDelayCycles The maximum number of delay cycles the command
* waits until it times out. * waits until it times out.
* @param replyLen Will be supplied to the requestReceiveMessage call of
* the communication interface.
* @param periodic Indicates if the command is periodic (i.e. it is sent * @param periodic Indicates if the command is periodic (i.e. it is sent
* by the device repeatedly without request) or not. Default is aperiodic (0) * by the device repeatedly without request) or not. Default is aperiodic (0)
* @return - @c RETURN_OK when the command was successfully inserted, * @return - @c RETURN_OK when the command was successfully inserted,

View File

@ -98,7 +98,7 @@ public:
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF; static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
// Standard codes used when building commands. // Standard codes used when building commands.
static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0); //!< If the command size is 0. Checked in DHB static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0); //!< If no command data was given when expected.
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1); //!< Command ID not in commandMap. Checked in DHB static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1); //!< Command ID not in commandMap. Checked in DHB
static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2); //!< Command was already executed. Checked in DHB static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2); //!< Command was already executed. Checked in DHB
static const ReturnValue_t COMMAND_WAS_NOT_SENT = MAKE_RETURN_CODE(0xA3); static const ReturnValue_t COMMAND_WAS_NOT_SENT = MAKE_RETURN_CODE(0xA3);

View File

@ -38,7 +38,7 @@ MessageQueueId_t HealthDevice::getCommandQueue() const {
} }
void HealthDevice::setParentQueue(MessageQueueId_t parentQueue) { void HealthDevice::setParentQueue(MessageQueueId_t parentQueue) {
healthHelper.setParentQeueue(parentQueue); healthHelper.setParentQueue(parentQueue);
} }
bool HealthDevice::hasHealthChanged() { bool HealthDevice::hasHealthChanged() {

View File

@ -18,6 +18,8 @@ enum {
SYSTEM_MANAGER = 74, SYSTEM_MANAGER = 74,
SYSTEM_MANAGER_1 = 75, SYSTEM_MANAGER_1 = 75,
SYSTEM_1 = 79, SYSTEM_1 = 79,
PUS_SERVICE_1 = 80,
FW_SUBSYSTEM_ID_RANGE
}; };
} }

View File

@ -7,8 +7,8 @@
FailureIsolationBase::FailureIsolationBase(object_id_t owner, FailureIsolationBase::FailureIsolationBase(object_id_t owner,
object_id_t parent, uint8_t messageDepth, uint8_t parameterDomainBase) : object_id_t parent, uint8_t messageDepth, uint8_t parameterDomainBase) :
eventQueue(NULL), ownerId(owner), owner(NULL), ownerId(owner), faultTreeParent(parent),
faultTreeParent(parent), parameterDomainBase(parameterDomainBase) { parameterDomainBase(parameterDomainBase) {
eventQueue = QueueFactory::instance()->createMessageQueue(messageDepth, eventQueue = QueueFactory::instance()->createMessageQueue(messageDepth,
EventMessage::EVENT_MESSAGE_SIZE); EventMessage::EVENT_MESSAGE_SIZE);
} }
@ -104,9 +104,9 @@ MessageQueueId_t FailureIsolationBase::getEventReceptionQueue() {
ReturnValue_t FailureIsolationBase::sendConfirmationRequest(EventMessage* event, ReturnValue_t FailureIsolationBase::sendConfirmationRequest(EventMessage* event,
MessageQueueId_t destination) { MessageQueueId_t destination) {
event->setMessageId(EventMessage::CONFIRMATION_REQUEST); event->setMessageId(EventMessage::CONFIRMATION_REQUEST);
if (destination != 0) { if (destination != MessageQueueIF::NO_QUEUE) {
return eventQueue->sendMessage(destination, event); return eventQueue->sendMessage(destination, event);
} else if (faultTreeParent != 0) { } else if (faultTreeParent != objects::NO_OBJECT) {
return eventQueue->sendToDefault(event); return eventQueue->sendToDefault(event);
} }
return RETURN_FAILED; return RETURN_FAILED;

View File

@ -33,9 +33,9 @@ public:
virtual void triggerEvent(Event event, uint32_t parameter1 = 0, virtual void triggerEvent(Event event, uint32_t parameter1 = 0,
uint32_t parameter2 = 0); uint32_t parameter2 = 0);
protected: protected:
MessageQueueIF* eventQueue; MessageQueueIF* eventQueue = nullptr;
object_id_t ownerId; object_id_t ownerId;
HasHealthIF* owner; HasHealthIF* owner = nullptr;
object_id_t faultTreeParent; object_id_t faultTreeParent;
uint8_t parameterDomainBase; uint8_t parameterDomainBase;
void setOwnerHealth(HasHealthIF::HealthState health); void setOwnerHealth(HasHealthIF::HealthState health);
@ -45,7 +45,7 @@ protected:
virtual ReturnValue_t confirmFault(EventMessage* event); virtual ReturnValue_t confirmFault(EventMessage* event);
virtual void decrementFaultCounters() = 0; virtual void decrementFaultCounters() = 0;
ReturnValue_t sendConfirmationRequest(EventMessage* event, ReturnValue_t sendConfirmationRequest(EventMessage* event,
MessageQueueId_t destination = 0); MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
void throwFdirEvent(Event event, uint32_t parameter1 = 0, void throwFdirEvent(Event event, uint32_t parameter1 = 0,
uint32_t parameter2 = 0); uint32_t parameter2 = 0);
private: private:

View File

@ -28,11 +28,11 @@ HasHealthIF::HealthState HealthHelper::getHealth() {
} }
ReturnValue_t HealthHelper::initialize(MessageQueueId_t parentQueue) { ReturnValue_t HealthHelper::initialize(MessageQueueId_t parentQueue) {
setParentQeueue(parentQueue); setParentQueue(parentQueue);
return initialize(); return initialize();
} }
void HealthHelper::setParentQeueue(MessageQueueId_t parentQueue) { void HealthHelper::setParentQueue(MessageQueueId_t parentQueue) {
this->parentQueue = parentQueue; this->parentQueue = parentQueue;
} }

View File

@ -79,7 +79,7 @@ public:
/** /**
* @param parentQueue the Queue id of the parent object. Set to 0 if no parent present * @param parentQueue the Queue id of the parent object. Set to 0 if no parent present
*/ */
void setParentQeueue(MessageQueueId_t parentQueue); void setParentQueue(MessageQueueId_t parentQueue);
/** /**
* *

View File

@ -88,6 +88,7 @@ void CommandMessage::setToUnknownCommand() {
void CommandMessage::setReplyRejected(ReturnValue_t reason, void CommandMessage::setReplyRejected(ReturnValue_t reason,
Command_t initialCommand) { Command_t initialCommand) {
setCommand(REPLY_REJECTED);
setParameter(reason); setParameter(reason);
setParameter2(initialCommand); setParameter2(initialCommand);
} }

View File

@ -6,9 +6,11 @@
class MutexHelper { class MutexHelper {
public: public:
MutexHelper(MutexIF* mutex, uint32_t timeoutMs) : MutexHelper(MutexIF* mutex, MutexIF::TimeoutType timeoutType =
MutexIF::TimeoutType::BLOCKING, uint32_t timeoutMs = 0) :
internalMutex(mutex) { internalMutex(mutex) {
ReturnValue_t status = mutex->lockMutex(timeoutMs); ReturnValue_t status = mutex->lockMutex(timeoutType,
timeoutMs);
if(status == MutexIF::MUTEX_TIMEOUT) { if(status == MutexIF::MUTEX_TIMEOUT) {
sif::error << "MutexHelper: Lock of mutex failed with timeout of " sif::error << "MutexHelper: Lock of mutex failed with timeout of "
<< timeoutMs << " milliseconds!" << std::endl; << timeoutMs << " milliseconds!" << std::endl;

View File

@ -5,7 +5,6 @@
/** /**
* @brief Common interface for OS Mutex objects which provide MUTual EXclusion. * @brief Common interface for OS Mutex objects which provide MUTual EXclusion.
*
* @details https://en.wikipedia.org/wiki/Lock_(computer_science) * @details https://en.wikipedia.org/wiki/Lock_(computer_science)
* @ingroup osal * @ingroup osal
* @ingroup interface * @ingroup interface
@ -13,19 +12,24 @@
class MutexIF { class MutexIF {
public: public:
/** /**
* @brief Timeout value used for polling lock attempt. * Different types of timeout for the mutex lock.
* @details
* If the lock is not successfull, MUTEX_TIMEOUT will be returned
* immediately. Value needs to be defined in implementation.
*/ */
static const uint32_t POLLING; enum TimeoutType {
POLLING, //!< If mutex is not available, return immediately
WAITING, //!< Wait a specified time for the mutex to become available
BLOCKING //!< Block indefinitely until the mutex becomes available.
};
/** /**
* @brief Timeout value used for permanent blocking lock attempt. * Lock the mutex. The timeout value will only be used for
* @details * TimeoutType::WAITING
* The task will be blocked (indefinitely) until the mutex is unlocked. * @param timeoutType
* Value needs to be defined in implementation. * @param timeoutMs
* @return
*/ */
static const uint32_t BLOCKING; virtual ReturnValue_t lockMutex(TimeoutType timeoutType =
TimeoutType::BLOCKING, uint32_t timeoutMs = 0) = 0;
virtual ReturnValue_t unlockMutex() = 0;
static const uint8_t INTERFACE_ID = CLASS_ID::MUTEX_IF; static const uint8_t INTERFACE_ID = CLASS_ID::MUTEX_IF;
/** /**
@ -78,8 +82,6 @@ public:
static const ReturnValue_t MUTEX_DESTROYED_WHILE_WAITING = MAKE_RETURN_CODE(12); static const ReturnValue_t MUTEX_DESTROYED_WHILE_WAITING = MAKE_RETURN_CODE(12);
virtual ~MutexIF() {} virtual ~MutexIF() {}
virtual ReturnValue_t lockMutex(uint32_t timeoutMs) = 0;
virtual ReturnValue_t unlockMutex() = 0;
}; };

View File

@ -5,11 +5,12 @@
uint32_t FixedTimeslotTask::deadlineMissedCount = 0; uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE; 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, TaskStackSize setStack, TaskPeriod overallPeriod,
void (*setDeadlineMissedFunc)()) : void (*setDeadlineMissedFunc)()) :
started(false), handle(NULL), pst(overallPeriod * 1000) { 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. // All additional attributes are applied to the object.
this->deadlineMissedFunc = setDeadlineMissedFunc; this->deadlineMissedFunc = setDeadlineMissedFunc;
} }
@ -125,19 +126,18 @@ void FixedTimeslotTask::checkMissedDeadline(const TickType_t xLastWakeTime,
* it. */ * it. */
TickType_t currentTickCount = xTaskGetTickCount(); TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval; TickType_t timeToWake = xLastWakeTime + interval;
// Tick count has overflown // Time to wake has not overflown.
if(currentTickCount < xLastWakeTime) { if(timeToWake > xLastWakeTime) {
// Time to wake has overflown as well. If the tick count /* If the current time has overflown exclusively or the current
// is larger than the time to wake, a deadline was missed. * tick count is simply larger than the time to wake, a deadline was
if(timeToWake < xLastWakeTime and * missed */
currentTickCount > timeToWake) { if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) {
handleMissedDeadline(); handleMissedDeadline();
} }
} }
// No tick count overflow. If the timeToWake has not overflown /* Time to wake has overflown. A deadline was missed if the current time
// and the current tick count is larger than the time to wake, * is larger than the time to wake */
// a deadline was missed. else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) {
else if(timeToWake > xLastWakeTime and currentTickCount > timeToWake) {
handleMissedDeadline(); handleMissedDeadline();
} }
} }

View File

@ -24,7 +24,7 @@ public:
* @param setDeadlineMissedFunc Callback if a deadline was missed. * @param setDeadlineMissedFunc Callback if a deadline was missed.
* @return Pointer to the newly created task. * @return Pointer to the newly created task.
*/ */
FixedTimeslotTask(const char *name, TaskPriority setPriority, FixedTimeslotTask(TaskName name, TaskPriority setPriority,
TaskStackSize setStack, TaskPeriod overallPeriod, TaskStackSize setStack, TaskPeriod overallPeriod,
void (*setDeadlineMissedFunc)()); void (*setDeadlineMissedFunc)());

View File

@ -123,11 +123,20 @@ bool MessageQueue::isDefaultDestinationSet() const {
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom, MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault, CallContext callContext) { bool ignoreFault, CallContext callContext) {
BaseType_t result = pdFALSE;
QueueHandle_t destination = nullptr;
if(sendTo == MessageQueueIF::NO_QUEUE) {
return MessageQueueIF::DESTINVATION_INVALID;
}
else {
destination = reinterpret_cast<QueueHandle_t>(sendTo);
}
message->setSender(sentFrom); message->setSender(sentFrom);
BaseType_t result;
if(callContext == CallContext::TASK) { if(callContext == CallContext::TASK) {
result = xQueueSendToBack(reinterpret_cast<QueueHandle_t>(sendTo), result = xQueueSendToBack(destination,
static_cast<const void*>(message->getBuffer()), 0); static_cast<const void*>(message->getBuffer()), 0);
} }
else { else {

View File

@ -2,13 +2,10 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
const uint32_t MutexIF::POLLING = 0;
const uint32_t MutexIF::BLOCKING = portMAX_DELAY;
Mutex::Mutex() { Mutex::Mutex() {
handle = xSemaphoreCreateMutex(); handle = xSemaphoreCreateMutex();
if(handle == nullptr) { if(handle == nullptr) {
sif::error << "Mutex: Creation failure" << std::endl; sif::error << "Mutex::Mutex(FreeRTOS): Creation failure" << std::endl;
} }
} }
@ -19,15 +16,17 @@ Mutex::~Mutex() {
} }
ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType,
uint32_t timeoutMs) {
if (handle == nullptr) { if (handle == nullptr) {
return MutexIF::MUTEX_NOT_FOUND; return MutexIF::MUTEX_NOT_FOUND;
} }
TickType_t timeout = MutexIF::POLLING; // If the timeout type is BLOCKING, this will be the correct value.
if(timeoutMs == MutexIF::BLOCKING) { uint32_t timeout = portMAX_DELAY;
timeout = MutexIF::BLOCKING; if(timeoutType == TimeoutType::POLLING) {
timeout = 0;
} }
else if(timeoutMs > MutexIF::POLLING){ else if(timeoutType == TimeoutType::WAITING){
timeout = pdMS_TO_TICKS(timeoutMs); timeout = pdMS_TO_TICKS(timeoutMs);
} }

View File

@ -18,8 +18,10 @@ class Mutex : public MutexIF {
public: public:
Mutex(); Mutex();
~Mutex(); ~Mutex();
ReturnValue_t lockMutex(uint32_t timeoutMs = MutexIF::BLOCKING) override; ReturnValue_t lockMutex(TimeoutType timeoutType,
uint32_t timeoutMs) override;
ReturnValue_t unlockMutex() override; ReturnValue_t unlockMutex() override;
private: private:
SemaphoreHandle_t handle; SemaphoreHandle_t handle;
}; };

View File

@ -5,12 +5,13 @@
PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority, PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority,
TaskStackSize setStack, TaskPeriod setPeriod, TaskStackSize setStack, TaskPeriod setPeriod,
void (*setDeadlineMissedFunc)()) : TaskDeadlineMissedFunction deadlineMissedFunc) :
started(false), handle(NULL), period(setPeriod), deadlineMissedFunc( started(false), handle(NULL), period(setPeriod), deadlineMissedFunc(
setDeadlineMissedFunc) deadlineMissedFunc)
{ {
configSTACK_DEPTH_TYPE stackSize = setStack / sizeof(configSTACK_DEPTH_TYPE);
BaseType_t status = xTaskCreate(taskEntryPoint, name, BaseType_t status = xTaskCreate(taskEntryPoint, name,
setStack, this, setPriority, &handle); stackSize, this, setPriority, &handle);
if(status != pdPASS){ if(status != pdPASS){
sif::debug << "PeriodicTask Insufficient heap memory remaining. " sif::debug << "PeriodicTask Insufficient heap memory remaining. "
"Status: " << status << std::endl; "Status: " << status << std::endl;
@ -81,7 +82,7 @@ void PeriodicTask::taskFunctionality() {
} }
} }
ReturnValue_t PeriodicTask::addComponent(object_id_t object, bool setTaskIF) { ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>( ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
object); object);
if (newObject == nullptr) { if (newObject == nullptr) {
@ -90,12 +91,9 @@ ReturnValue_t PeriodicTask::addComponent(object_id_t object, bool setTaskIF) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
objectList.push_back(newObject); objectList.push_back(newObject);
if(setTaskIF) {
newObject->setTaskIF(this); newObject->setTaskIF(this);
}
ReturnValue_t result = newObject->initializeAfterTaskCreation(); return newObject->initializeAfterTaskCreation();
return result;
} }
uint32_t PeriodicTask::getPeriodMs() const { uint32_t PeriodicTask::getPeriodMs() const {
@ -109,19 +107,18 @@ void PeriodicTask::checkMissedDeadline(const TickType_t xLastWakeTime,
* it. */ * it. */
TickType_t currentTickCount = xTaskGetTickCount(); TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval; TickType_t timeToWake = xLastWakeTime + interval;
// Tick count has overflown // Time to wake has not overflown.
if(currentTickCount < xLastWakeTime) { if(timeToWake > xLastWakeTime) {
// Time to wake has overflown as well. If the tick count /* If the current time has overflown exclusively or the current
// is larger than the time to wake, a deadline was missed. * tick count is simply larger than the time to wake, a deadline was
if(timeToWake < xLastWakeTime and * missed */
currentTickCount > timeToWake) { if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) {
handleMissedDeadline(); handleMissedDeadline();
} }
} }
// No tick count overflow. If the timeToWake has not overflown /* Time to wake has overflown. A deadline was missed if the current time
// and the current tick count is larger than the time to wake, * is larger than the time to wake */
// a deadline was missed. else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) {
else if(timeToWake > xLastWakeTime and currentTickCount > timeToWake) {
handleMissedDeadline(); handleMissedDeadline();
} }
} }

View File

@ -40,9 +40,9 @@ public:
* The function pointer to the deadline missed function that shall * The function pointer to the deadline missed function that shall
* be assigned. * be assigned.
*/ */
PeriodicTask(const char *name, TaskPriority setPriority, PeriodicTask(TaskName name, TaskPriority setPriority,
TaskStackSize setStack, TaskPeriod setPeriod, TaskStackSize setStack, TaskPeriod setPeriod,
void (*setDeadlineMissedFunc)()); TaskDeadlineMissedFunction deadlineMissedFunc);
/** /**
* @brief Currently, the executed object's lifetime is not coupled with * @brief Currently, the executed object's lifetime is not coupled with
* the task object's lifetime, so the destructor is empty. * the task object's lifetime, so the destructor is empty.
@ -65,8 +65,7 @@ public:
* -@c RETURN_OK on success * -@c RETURN_OK on success
* -@c RETURN_FAILED if the object could not be added. * -@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;
bool setTaskIF = true) override;
uint32_t getPeriodMs() const override; uint32_t getPeriodMs() const override;

View File

@ -18,8 +18,8 @@ PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_,
TaskPriority taskPriority_, TaskStackSize stackSize_, TaskPriority taskPriority_, TaskStackSize stackSize_,
TaskPeriod period_, TaskPeriod period_,
TaskDeadlineMissedFunction deadLineMissedFunction_) { TaskDeadlineMissedFunction deadLineMissedFunction_) {
return (PeriodicTaskIF*) (new PeriodicTask(name_, taskPriority_, stackSize_, return dynamic_cast<PeriodicTaskIF*>(new PeriodicTask(name_, taskPriority_,
period_, deadLineMissedFunction_)); stackSize_, period_, deadLineMissedFunction_));
} }
/** /**
@ -29,8 +29,8 @@ FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_,
TaskPriority taskPriority_, TaskStackSize stackSize_, TaskPriority taskPriority_, TaskStackSize stackSize_,
TaskPeriod period_, TaskPeriod period_,
TaskDeadlineMissedFunction deadLineMissedFunction_) { TaskDeadlineMissedFunction deadLineMissedFunction_) {
return (FixedTimeslotTaskIF*) (new FixedTimeslotTask(name_, taskPriority_, return dynamic_cast<FixedTimeslotTaskIF*>(new FixedTimeslotTask(name_,
stackSize_, period_, deadLineMissedFunction_)); taskPriority_,stackSize_, period_, deadLineMissedFunction_));
} }
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {

View File

@ -2,8 +2,6 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/timemanager/Clock.h> #include <framework/timemanager/Clock.h>
const uint32_t MutexIF::BLOCKING = 0xffffffff;
const uint32_t MutexIF::POLLING = 0;
uint8_t Mutex::count = 0; uint8_t Mutex::count = 0;
@ -40,9 +38,13 @@ Mutex::~Mutex() {
pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutex);
} }
ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
int status = 0; int status = 0;
if (timeoutMs != MutexIF::BLOCKING) {
if(timeoutType == TimeoutType::POLLING) {
status = pthread_mutex_trylock(&mutex);
}
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;
@ -50,14 +52,20 @@ ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) {
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;
status = pthread_mutex_timedlock(&mutex, &timeOut); status = pthread_mutex_timedlock(&mutex, &timeOut);
} else { }
else if(timeoutType == TimeoutType::BLOCKING) {
status = pthread_mutex_lock(&mutex); status = pthread_mutex_lock(&mutex);
} }
switch (status) { switch (status) {
case EINVAL: 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; 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 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 value specified by mutex does not refer to an initialized mutex object.
//return MUTEX_NOT_FOUND; //return MUTEX_NOT_FOUND;
case EBUSY: case EBUSY:
@ -67,10 +75,12 @@ ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) {
// 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; return MUTEX_TIMEOUT;
case EAGAIN: 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; return MUTEX_MAX_LOCKS;
case EDEADLK: 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; return CURR_THREAD_ALREADY_OWNS_MUTEX;
case 0: case 0:
//Success //Success

View File

@ -12,7 +12,7 @@ class Mutex : public MutexIF {
public: public:
Mutex(); Mutex();
virtual ~Mutex(); virtual ~Mutex();
virtual ReturnValue_t lockMutex(uint32_t timeoutMs); virtual ReturnValue_t lockMutex(TimeoutType timeoutType, uint32_t timeoutMs);
virtual ReturnValue_t unlockMutex(); virtual ReturnValue_t unlockMutex();
private: private:
pthread_mutex_t mutex; pthread_mutex_t mutex;

View File

@ -22,8 +22,7 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) {
return NULL; return NULL;
} }
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) {
bool setTaskIF) {
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>( ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
object); object);
if (newObject == nullptr) { if (newObject == nullptr) {
@ -32,13 +31,9 @@ ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object,
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
objectList.push_back(newObject); objectList.push_back(newObject);
if(setTaskIF) {
newObject->setTaskIF(this); newObject->setTaskIF(this);
}
ReturnValue_t result = newObject->initializeAfterTaskCreation(); return newObject->initializeAfterTaskCreation();
return result;
} }
ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) {

View File

@ -39,8 +39,7 @@ public:
* @param object Id of the object to add. * @param object Id of the object to add.
* @return RETURN_OK on success, RETURN_FAILED if the object could not be added. * @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;
bool setTaskIF = true) override;
uint32_t getPeriodMs() const override; uint32_t getPeriodMs() const override;

View File

@ -85,7 +85,7 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
} }
void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) {
MutexHelper lock(mutex, 10); MutexHelper lock(mutex, MutexIF::TimeoutType::WAITING, 10);
// char ipAddress [15]; // char ipAddress [15];
// sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, // sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET,

View File

@ -5,8 +5,23 @@
#include <framework/returnvalues/HasReturnvaluesIF.h> #include <framework/returnvalues/HasReturnvaluesIF.h>
#include <stdint.h> #include <stdint.h>
/** Each parameter is identified with a unique parameter ID */
typedef uint32_t ParameterId_t; typedef uint32_t ParameterId_t;
/**
* @brief This interface is used by components which have modifiable
* parameters, e.g. atittude controllers
* @details
* Each parameter has a unique parameter ID. The first byte of the parameter
* ID is the domain ID which can be used to identify unqiue spacecraft domains
* (e.g. control and sensor domain in the AOCS controller).
*
* The second and third byte represent the matrix ID, which can represent
* a 8-bit row and column number and the last byte...
*
* Yeah, it it matrix ID oder parameter ID now and is index a 16 bit number
* of a 8 bit number now?
*/
class HasParametersIF { class HasParametersIF {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_PARAMETERS_IF; static const uint8_t INTERFACE_ID = CLASS_ID::HAS_PARAMETERS_IF;
@ -32,13 +47,11 @@ public:
return (domainId << 24) + (parameterId << 8) + index; return (domainId << 24) + (parameterId << 8) + index;
} }
virtual ~HasParametersIF() { virtual ~HasParametersIF() {}
}
/** /**
* Always set parameter before checking newValues! * Always set parameter before checking newValues!
* *
*
* @param domainId * @param domainId
* @param parameterId * @param parameterId
* @param parameterWrapper * @param parameterWrapper

View File

@ -26,7 +26,6 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) {
} }
break; break;
case ParameterMessage::CMD_PARAMETER_LOAD: { case ParameterMessage::CMD_PARAMETER_LOAD: {
uint8_t domain = HasParametersIF::getDomain( uint8_t domain = HasParametersIF::getDomain(
ParameterMessage::getParameterId(message)); ParameterMessage::getParameterId(message));
uint16_t parameterId = HasParametersIF::getMatrixId( uint16_t parameterId = HasParametersIF::getMatrixId(
@ -34,12 +33,14 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) {
uint8_t index = HasParametersIF::getIndex( uint8_t index = HasParametersIF::getIndex(
ParameterMessage::getParameterId(message)); ParameterMessage::getParameterId(message));
const uint8_t *storedStream; const uint8_t *storedStream = nullptr;
size_t storedStreamSize; size_t storedStreamSize = 0;
result = storage->getData( result = storage->getData(
ParameterMessage::getStoreId(message), &storedStream, ParameterMessage::getStoreId(message), &storedStream,
&storedStreamSize); &storedStreamSize);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "ParameterHelper::handleParameterMessage: Getting"
" store data failed for load command." << std::endl;
break; break;
} }

View File

@ -5,6 +5,12 @@
#include <framework/parameters/ParameterMessage.h> #include <framework/parameters/ParameterMessage.h>
#include <framework/parameters/ReceivesParameterMessagesIF.h> #include <framework/parameters/ReceivesParameterMessagesIF.h>
/**
* @brief Helper class to handle parameter messages
* @details
* This class simplfiies handling of parameter messages, which are sent
* to a class which implements ReceivesParameterMessagesIF.
*/
class ParameterHelper { class ParameterHelper {
public: public:
ParameterHelper(ReceivesParameterMessagesIF *owner); ParameterHelper(ReceivesParameterMessagesIF *owner);

View File

@ -1,20 +1,19 @@
#include <framework/parameters/ParameterWrapper.h> #include <framework/parameters/ParameterWrapper.h>
ParameterWrapper::ParameterWrapper() : ParameterWrapper::ParameterWrapper() :
pointsToStream(false), type(Type::UNKNOWN_TYPE), rows(0), columns(0), data( pointsToStream(false), type(Type::UNKNOWN_TYPE) {
NULL), readonlyData(NULL) {
} }
ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns, ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns,
void *data) : void *data) :
pointsToStream(false), type(type), rows(rows), columns(columns), data( pointsToStream(false), type(type), rows(rows), columns(columns),
data), readonlyData(data) { data(data), readonlyData(data) {
} }
ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns, ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns,
const void *data) : const void *data) :
pointsToStream(false), type(type), rows(rows), columns(columns), data( pointsToStream(false), type(type), rows(rows), columns(columns),
NULL), readonlyData(data) { data(nullptr), readonlyData(data) {
} }
ParameterWrapper::~ParameterWrapper() { ParameterWrapper::~ParameterWrapper() {
@ -266,15 +265,14 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
result = UNKNOW_DATATYPE; result = UNKNOW_DATATYPE;
break; break;
} }
} else { }
else {
//need a type to do arithmetic //need a type to do arithmetic
uint8_t *toDataWithType = (uint8_t*) data; uint8_t* typedData = static_cast<uint8_t*>(data);
for (uint8_t fromRow = 0; fromRow < from->rows; fromRow++) { for (uint8_t fromRow = 0; fromRow < from->rows; fromRow++) {
memcpy( uint8_t offset = (((startingRow + fromRow) * columns) + startingColumn) * typeSize;
toDataWithType std::memcpy(typedData + offset, from->readonlyData,
+ (((startingRow + fromRow) * columns) typeSize * from->columns);
+ startingColumn) * typeSize,
from->readonlyData, typeSize * from->columns);
} }
} }

View File

@ -1,5 +1,5 @@
#ifndef PARAMETERWRAPPER_H_ #ifndef FRAMEWORK_PARAMETERS_PARAMETERWRAPPER_H_
#define PARAMETERWRAPPER_H_ #define FRAMEWORK_PARAMETERS_PARAMETERWRAPPER_H_
#include <framework/returnvalues/HasReturnvaluesIF.h> #include <framework/returnvalues/HasReturnvaluesIF.h>
#include <framework/serialize/SerializeAdapter.h> #include <framework/serialize/SerializeAdapter.h>
@ -7,6 +7,10 @@
#include <stddef.h> #include <stddef.h>
#include <framework/globalfunctions/Type.h> #include <framework/globalfunctions/Type.h>
/**
* @brief
* @details
*/
class ParameterWrapper: public SerializeIF { class ParameterWrapper: public SerializeIF {
friend class DataPoolParameterWrapper; friend class DataPoolParameterWrapper;
public: public:
@ -36,32 +40,21 @@ public:
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness, uint16_t startWritingAtIndex = 0); Endianness streamEndianness, uint16_t startWritingAtIndex = 0);
/**
* Get a specific parameter value by supplying the row and the column.
* @tparam T Type of target data
* @param value [out] Pointer to storage location
* @param row
* @param column
* @return
* -@c RETURN_OK if element was retrieved successfully
* -@c NOT_SET data has not been set yet
* -@c DATATYPE_MISSMATCH Invalid supplied type
* -@c OUT_OF_BOUNDS Invalid row and/or column.
*/
template<typename T> template<typename T>
ReturnValue_t getElement(T *value, uint8_t row = 0, uint8_t column = 0) const { ReturnValue_t getElement(T *value, uint8_t row = 0,
if (readonlyData == NULL){ uint8_t column = 0) const;
return NOT_SET;
}
if (PodTypeConversion<T>::type != type) {
return DATATYPE_MISSMATCH;
}
if ((row >= rows) || (column >= columns)) {
return OUT_OF_BOUNDS;
}
if (pointsToStream) {
const uint8_t *streamWithtype = (const uint8_t *) readonlyData;
streamWithtype += (row * columns + column) * type.getSize();
int32_t size = type.getSize();
return SerializeAdapter::deSerialize(value, &streamWithtype,
&size, true);
} else {
const T *dataWithType = (const T *) readonlyData;
*value = dataWithType[row * columns + column];
return HasReturnvaluesIF::RETURN_OK;
}
}
template<typename T> template<typename T>
void set(T *data, uint8_t rows, uint8_t columns) { void set(T *data, uint8_t rows, uint8_t columns) {
@ -111,21 +104,22 @@ public:
void setMatrix(const T& member) { void setMatrix(const T& member) {
this->set(member[0], sizeof(member)/sizeof(member[0]), sizeof(member[0])/sizeof(member[0][0])); this->set(member[0], sizeof(member)/sizeof(member[0]), sizeof(member[0])/sizeof(member[0][0]));
} }
ReturnValue_t set(const uint8_t *stream, size_t streamSize, ReturnValue_t set(const uint8_t *stream, size_t streamSize,
const uint8_t **remainingStream = NULL, size_t *remainingSize = const uint8_t **remainingStream = nullptr,
NULL); size_t *remainingSize = nullptr);
ReturnValue_t copyFrom(const ParameterWrapper *from, ReturnValue_t copyFrom(const ParameterWrapper *from,
uint16_t startWritingAtIndex); uint16_t startWritingAtIndex);
private: private:
bool pointsToStream; bool pointsToStream = false;
Type type; Type type;
uint8_t rows; uint8_t rows = 0;
uint8_t columns; uint8_t columns = 0;
void *data; void *data = nullptr;
const void *readonlyData; const void *readonlyData = nullptr;
template<typename T> template<typename T>
ReturnValue_t serializeData(uint8_t** buffer, size_t* size, ReturnValue_t serializeData(uint8_t** buffer, size_t* size,
@ -136,4 +130,33 @@ private:
const void *from, uint8_t fromRows, uint8_t fromColumns); const void *from, uint8_t fromRows, uint8_t fromColumns);
}; };
template <typename T>
inline ReturnValue_t ParameterWrapper::getElement(T *value, uint8_t row,
uint8_t column) const {
if (readonlyData == nullptr){
return NOT_SET;
}
if (PodTypeConversion<T>::type != type) {
return DATATYPE_MISSMATCH;
}
if ((row >= rows) or (column >= columns)) {
return OUT_OF_BOUNDS;
}
if (pointsToStream) {
const uint8_t *streamWithType = static_cast<const uint8_t*>(readonlyData);
streamWithType += (row * columns + column) * type.getSize();
int32_t size = type.getSize();
return SerializeAdapter::deSerialize(value, &streamWithType,
&size, true);
}
else {
const T *dataWithType = static_cast<const T*>(readonlyData);
*value = dataWithType[row * columns + column];
return HasReturnvaluesIF::RETURN_OK;
}
}
#endif /* PARAMETERWRAPPER_H_ */ #endif /* PARAMETERWRAPPER_H_ */

View File

@ -1,22 +1,22 @@
/**
* @defgroup spacepackets PUS Packet Definitions
* This group contains all implemented TM or TM packages that are sent to
* or sent by the OBC.They are exported later to display
* packet structures in Mission Information Base (MIB).
*/
#ifndef MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ #ifndef MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_
#define MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ #define MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_
#include <framework/serialize/SerializeAdapter.h> #include <framework/serialize/SerializeAdapter.h>
#include <framework/tmtcservices/VerificationCodes.h> #include <framework/tmtcservices/VerificationCodes.h>
/**
* @defgroup spacepackets PUS Packet Definitions
* This group contains all implemented TM or TM packages that are sent to
* or sent by the OBC.They are exported later to display
* packet structures in Mission Information Base (MIB).
*/
/** /**
* @brief FailureReport class to serialize a failure report * @brief FailureReport class to serialize a failure report
* @brief Subservice 1, 3, 5, 7 * @brief Subservice 1, 3, 5, 7
* @ingroup spacepackets * @ingroup spacepackets
*/ */
class FailureReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 3, 5, 7 class FailureReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6, 8
public: public:
FailureReport(uint8_t failureSubtype_, uint16_t packetId_, FailureReport(uint8_t failureSubtype_, uint16_t packetId_,
uint16_t packetSequenceControl_, uint8_t stepNumber_, uint16_t packetSequenceControl_, uint8_t stepNumber_,
@ -111,7 +111,7 @@ private:
* @brief Subservices 2, 4, 6, 8 * @brief Subservices 2, 4, 6, 8
* @ingroup spacepackets * @ingroup spacepackets
*/ */
class SuccessReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6, 8 class SuccessReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 3, 5, 7
public: public:
SuccessReport(uint8_t subtype_, uint16_t packetId_, SuccessReport(uint8_t subtype_, uint16_t packetId_,
uint16_t packetSequenceControl_,uint8_t stepNumber_) : uint16_t packetSequenceControl_,uint8_t stepNumber_) :

View File

@ -78,9 +78,9 @@ int ServiceInterfaceBuffer::sync(void) {
} }
size_t preambleSize = 0; size_t preambleSize = 0;
auto preamble = getPreamble(&preambleSize); std::string* preamble = getPreamble(&preambleSize);
// Write logMessage and time // Write logMessage and time
this->putChars(preamble.data(), preamble.data() + preambleSize); this->putChars(preamble->data(), preamble->data() + preambleSize);
// Handle output // Handle output
this->putChars(pbase(), pptr()); this->putChars(pbase(), pptr());
// This tells that buffer is empty again // This tells that buffer is empty again
@ -92,7 +92,7 @@ bool ServiceInterfaceBuffer::isBuffered() const {
return buffered; return buffered;
} }
std::string ServiceInterfaceBuffer::getPreamble(size_t * preambleSize) { std::string* ServiceInterfaceBuffer::getPreamble(size_t * preambleSize) {
Clock::TimeOfDay_t loggerTime; Clock::TimeOfDay_t loggerTime;
Clock::getDateAndTime(&loggerTime); Clock::getDateAndTime(&loggerTime);
size_t currentSize = 0; size_t currentSize = 0;
@ -110,18 +110,18 @@ std::string ServiceInterfaceBuffer::getPreamble(size_t * preambleSize) {
loggerTime.usecond /1000); loggerTime.usecond /1000);
if(charCount < 0) { if(charCount < 0) {
printf("ServiceInterfaceBuffer: Failure parsing preamble\r\n"); printf("ServiceInterfaceBuffer: Failure parsing preamble\r\n");
return ""; return &preamble;
} }
if(charCount > MAX_PREAMBLE_SIZE) { if(charCount > MAX_PREAMBLE_SIZE) {
printf("ServiceInterfaceBuffer: Char count too large for maximum " printf("ServiceInterfaceBuffer: Char count too large for maximum "
"preamble size"); "preamble size");
return ""; return &preamble;
} }
currentSize += charCount; currentSize += charCount;
if(preambleSize != nullptr) { if(preambleSize != nullptr) {
*preambleSize = currentSize; *preambleSize = currentSize;
} }
return preamble; return &preamble;
} }

View File

@ -60,7 +60,7 @@ private:
//! In this function, the characters are parsed. //! In this function, the characters are parsed.
void putChars(char const* begin, char const* end); void putChars(char const* begin, char const* end);
std::string getPreamble(size_t * preambleSize = nullptr); std::string* getPreamble(size_t * preambleSize = nullptr);
}; };
#endif #endif

View File

@ -9,7 +9,7 @@ void ServiceInterfaceStream::setActive( bool myActive) {
this->streambuf.isActive = myActive; this->streambuf.isActive = myActive;
} }
std::string ServiceInterfaceStream::getPreamble() { std::string* ServiceInterfaceStream::getPreamble() {
return streambuf.getPreamble(); return streambuf.getPreamble();
} }

View File

@ -33,7 +33,7 @@ public:
* the unbuffered mode. * the unbuffered mode.
* @return Preamle consisting of log message and timestamp. * @return Preamle consisting of log message and timestamp.
*/ */
std::string getPreamble(); std::string* getPreamble();
/** /**
* This prints an error with a preamble. Useful if using the unbuffered * This prints an error with a preamble. Useful if using the unbuffered

View File

@ -21,7 +21,8 @@ inline PoolManager<NUMBER_OF_POOLS>::~PoolManager(void) {
template<uint8_t NUMBER_OF_POOLS> template<uint8_t NUMBER_OF_POOLS>
inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::reserveSpace( inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::reserveSpace(
const uint32_t size, store_address_t* address, bool ignoreFault) { const uint32_t size, store_address_t* address, bool ignoreFault) {
MutexHelper mutexHelper(mutex, mutexTimeout); MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING,
mutexTimeout);
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::reserveSpace(size, ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::reserveSpace(size,
address,ignoreFault); address,ignoreFault);
return status; return status;
@ -33,7 +34,8 @@ inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(
// debug << "PoolManager( " << translateObject(getObjectId()) << // debug << "PoolManager( " << translateObject(getObjectId()) <<
// " )::deleteData from store " << packet_id.pool_index << // " )::deleteData from store " << packet_id.pool_index <<
// ". id is "<< packet_id.packet_index << std::endl; // ". id is "<< packet_id.packet_index << std::endl;
MutexHelper mutexHelper(mutex, mutexTimeout); MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING,
mutexTimeout);
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(packet_id); ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(packet_id);
return status; return status;
} }
@ -41,7 +43,8 @@ inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(
template<uint8_t NUMBER_OF_POOLS> template<uint8_t NUMBER_OF_POOLS>
inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(uint8_t* buffer, inline ReturnValue_t PoolManager<NUMBER_OF_POOLS>::deleteData(uint8_t* buffer,
size_t size, store_address_t* storeId) { size_t size, store_address_t* storeId) {
MutexHelper mutexHelper(mutex, mutexTimeout); MutexHelper mutexHelper(mutex, MutexIF::TimeoutType::WAITING,
mutexTimeout);
ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(buffer, ReturnValue_t status = LocalPool<NUMBER_OF_POOLS>::deleteData(buffer,
size, storeId); size, storeId);
return status; return status;

View File

@ -5,9 +5,9 @@
SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent,
Mode_t initialMode, uint16_t commandQueueDepth) : Mode_t initialMode, uint16_t commandQueueDepth) :
SystemObject(setObjectId), mode(initialMode), submode(SUBMODE_NONE), childrenChangedMode( SystemObject(setObjectId), mode(initialMode), submode(SUBMODE_NONE),
false), commandsOutstanding(0), commandQueue(NULL), healthHelper(this, childrenChangedMode(false), commandsOutstanding(0), commandQueue(NULL),
setObjectId), modeHelper(this), parentId(parent) { healthHelper(this, setObjectId), modeHelper(this), parentId(parent) {
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth, commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth,
MessageQueueMessage::MAX_MESSAGE_SIZE); MessageQueueMessage::MAX_MESSAGE_SIZE);
} }
@ -23,8 +23,8 @@ ReturnValue_t SubsystemBase::registerChild(object_id_t objectId) {
HasModesIF *child = objectManager->get<HasModesIF>(objectId); HasModesIF *child = objectManager->get<HasModesIF>(objectId);
//This is a rather ugly hack to have the changedHealth info for all children available. (needed for FOGs). //This is a rather ugly hack to have the changedHealth info for all children available. (needed for FOGs).
HasHealthIF* healthChild = objectManager->get<HasHealthIF>(objectId); HasHealthIF* healthChild = objectManager->get<HasHealthIF>(objectId);
if (child == NULL) { if (child == nullptr) {
if (healthChild == NULL) { if (healthChild == nullptr) {
return CHILD_DOESNT_HAVE_MODES; return CHILD_DOESNT_HAVE_MODES;
} else { } else {
info.commandQueue = healthChild->getCommandQueue(); info.commandQueue = healthChild->getCommandQueue();
@ -76,14 +76,15 @@ ReturnValue_t SubsystemBase::checkStateAgainstTable(
return RETURN_OK; return RETURN_OK;
} }
void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter, Submode_t targetSubmode) { void SubsystemBase::executeTable(HybridIterator<ModeListEntry> tableIter,
Submode_t targetSubmode) {
CommandMessage command; CommandMessage command;
std::map<object_id_t, ChildInfo>::iterator iter; std::map<object_id_t, ChildInfo>::iterator iter;
commandsOutstanding = 0; commandsOutstanding = 0;
for (; tableIter.value != NULL; ++tableIter) { for (; tableIter.value != nullptr; ++tableIter) {
object_id_t object = tableIter.value->getObject(); object_id_t object = tableIter.value->getObject();
if ((iter = childrenMap.find(object)) == childrenMap.end()) { if ((iter = childrenMap.find(object)) == childrenMap.end()) {
//illegal table entry, should only happen due to misconfigured mode table //illegal table entry, should only happen due to misconfigured mode table

View File

@ -36,8 +36,7 @@ public:
* to the component. * to the component.
* @return * @return
*/ */
virtual ReturnValue_t addComponent(object_id_t object, virtual ReturnValue_t addComponent(object_id_t object) {
bool setTaskIF = true) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
}; };

View File

@ -1,7 +1,6 @@
#ifndef FRAMEWORK_TASKS_TYPEDEF_H_ #ifndef FRAMEWORK_TASKS_TYPEDEF_H_
#define FRAMEWORK_TASKS_TYPEDEF_H_ #define FRAMEWORK_TASKS_TYPEDEF_H_
//TODO more generic?
typedef const char* TaskName; typedef const char* TaskName;
typedef uint8_t TaskPriority; typedef uint8_t TaskPriority;
typedef size_t TaskStackSize; typedef size_t TaskStackSize;

View File

@ -126,11 +126,11 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) {
&nextCommand, iter->objectId, &isStep); &nextCommand, iter->objectId, &isStep);
/* If the child implementation does not implement special handling for /* If the child implementation does not implement special handling for
* rejected replies (RETURN_FAILED is returned), a failure verification * rejected replies (RETURN_FAILED or INVALID_REPLY is returned), a
* will be generated with the reason as the return code and the initial * failure verification will be generated with the reason as the
* command as failure parameter 1 */ * return code and the initial command as failure parameter 1 */
if(reply->getCommand() == CommandMessage::REPLY_REJECTED and if((reply->getCommand() == CommandMessage::REPLY_REJECTED) and
result == RETURN_FAILED) { (result == RETURN_FAILED or result == INVALID_REPLY)) {
result = reply->getReplyRejectedReason(); result = reply->getReplyRejectedReason();
failureParameter1 = iter->command; failureParameter1 = iter->command;
} }
@ -230,8 +230,8 @@ void CommandingServiceBase::handleRequestQueue() {
address = message.getStorageId(); address = message.getStorageId();
packet.setStoreAddress(address); packet.setStoreAddress(address);
if (packet.getSubService() == 0 if ((packet.getSubService() == 0)
or isValidSubservice(packet.getSubService()) != RETURN_OK) { or (isValidSubservice(packet.getSubService()) != RETURN_OK)) {
rejectPacket(TC_VERIFY::START_FAILURE, &packet, INVALID_SUBSERVICE); rejectPacket(TC_VERIFY::START_FAILURE, &packet, INVALID_SUBSERVICE);
continue; continue;
} }

View File

@ -87,7 +87,7 @@ public:
* @param opCode is unused here at the moment * @param opCode is unused here at the moment
* @return RETURN_OK * @return RETURN_OK
*/ */
virtual ReturnValue_t performOperation(uint8_t opCode); virtual ReturnValue_t performOperation(uint8_t opCode) override;
virtual uint16_t getIdentifier(); virtual uint16_t getIdentifier();
@ -116,7 +116,7 @@ public:
* Used to setup the reference of the task, that executes this component * Used to setup the reference of the task, that executes this component
* @param task Pointer to the taskIF of this task * @param task Pointer to the taskIF of this task
*/ */
virtual void setTaskIF(PeriodicTaskIF* task); virtual void setTaskIF(PeriodicTaskIF* task) override;
protected: protected:
/** /**
@ -173,9 +173,7 @@ protected:
* This function is implemented by child services to specify how replies * This function is implemented by child services to specify how replies
* to a command from another software component are handled. * to a command from another software component are handled.
* @param reply * @param reply
* This is the reply which can be accessed via the command message * This is the reply in form of a generic read-only command message.
* interface. The internal message pointer can be passed to different
* command message implementations (see CommandMessageIF)
* @param previousCommand * @param previousCommand
* Command_t of related command * Command_t of related command
* @param state [out/in] * @param state [out/in]
@ -189,10 +187,11 @@ protected:
* - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to * - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to
* generate TC verification success * generate TC verification success
* - @c INVALID_REPLY Calls handleUnrequestedReply * - @c INVALID_REPLY Calls handleUnrequestedReply
* - Anything else triggers a TC verification failure. If RETURN_FAILED * - Anything else triggers a TC verification failure. If RETURN_FAILED or
* is returned and the command ID is CommandMessage::REPLY_REJECTED, * INVALID_REPLY is returned and the command ID is
* a failure verification message with the reason as the error parameter * CommandMessage::REPLY_REJECTED, a failure verification message with
* and the initial command as failure parameter 1. * the reason as the error parameter and the initial command as
* failure parameter 1 is generated.
*/ */
virtual ReturnValue_t handleReply(const CommandMessage* reply, virtual ReturnValue_t handleReply(const CommandMessage* reply,
Command_t previousCommand, uint32_t *state, Command_t previousCommand, uint32_t *state,