Merge branch 'mueller/master' into mueller/project/distribDatapool
This commit is contained in:
commit
4afb19be51
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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_ */
|
||||||
|
@ -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;
|
||||||
|
@ -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(¤tPoolId, 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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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_ */
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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() {
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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() {
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)());
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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,27 +52,35 @@ 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
|
||||||
//The value specified by mutex does not refer to an initialized mutex object.
|
// parameter specified a nanoseconds field value less than zero or
|
||||||
|
// greater than or equal to 1000 million.
|
||||||
|
// The value specified by mutex does not refer to an initialized mutex object.
|
||||||
//return MUTEX_NOT_FOUND;
|
//return MUTEX_NOT_FOUND;
|
||||||
case EBUSY:
|
case EBUSY:
|
||||||
//The mutex could not be acquired because it was already locked.
|
// The mutex could not be acquired because it was already locked.
|
||||||
return MUTEX_ALREADY_LOCKED;
|
return MUTEX_ALREADY_LOCKED;
|
||||||
case ETIMEDOUT:
|
case ETIMEDOUT:
|
||||||
//The mutex could not be locked before the specified timeout expired.
|
// The mutex could not be locked before the specified timeout expired.
|
||||||
return MUTEX_TIMEOUT;
|
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
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_ */
|
||||||
|
@ -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_) :
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user