Merge branch 'mueller_framework' into front_branch
This commit is contained in:
commit
9716bcdd74
@ -7,84 +7,62 @@
|
||||
template<uint8_t N_READ_PTRS = 1>
|
||||
class RingBufferBase {
|
||||
public:
|
||||
RingBufferBase(uint32_t startAddress, const size_t size, bool overwriteOld) :
|
||||
RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld) :
|
||||
start(startAddress), write(startAddress), size(size),
|
||||
overwriteOld(overwriteOld) {
|
||||
for (uint8_t count = 0; count < N_READ_PTRS; count++) {
|
||||
read[count] = startAddress;
|
||||
}
|
||||
}
|
||||
ReturnValue_t readData(uint32_t amount, uint8_t n = 0) {
|
||||
if (availableReadData(n) >= amount) {
|
||||
incrementRead(amount, n);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
ReturnValue_t writeData(uint32_t amount) {
|
||||
if (availableWriteSpace() >= amount || overwriteOld) {
|
||||
incrementWrite(amount);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
uint32_t availableReadData(uint8_t n = 0) const {
|
||||
return ((write + size) - read[n]) % size;
|
||||
}
|
||||
uint32_t availableWriteSpace(uint8_t n = 0) const {
|
||||
//One less to avoid ambiguous full/empty problem.
|
||||
return (((read[n] + size) - write - 1) % size);
|
||||
}
|
||||
|
||||
virtual ~RingBufferBase() {}
|
||||
|
||||
bool isFull(uint8_t n = 0) {
|
||||
return (availableWriteSpace(n) == 0);
|
||||
}
|
||||
bool isEmpty(uint8_t n = 0) {
|
||||
return (availableReadData(n) == 0);
|
||||
}
|
||||
virtual ~RingBufferBase() {
|
||||
|
||||
size_t availableReadData(uint8_t n = 0) const {
|
||||
return ((write + size) - read[n]) % size;
|
||||
}
|
||||
uint32_t getRead(uint8_t n = 0) const {
|
||||
return read[n];
|
||||
size_t availableWriteSpace(uint8_t n = 0) const {
|
||||
//One less to avoid ambiguous full/empty problem.
|
||||
return (((read[n] + size) - write - 1) % size);
|
||||
}
|
||||
void setRead(uint32_t read, uint8_t n = 0) {
|
||||
if (read >= start && read < (start+size)) {
|
||||
this->read[n] = read;
|
||||
|
||||
bool overwritesOld() const {
|
||||
return overwriteOld;
|
||||
}
|
||||
|
||||
size_t maxSize() const {
|
||||
return size - 1;
|
||||
}
|
||||
uint32_t getWrite() const {
|
||||
return write;
|
||||
}
|
||||
void setWrite(uint32_t write) {
|
||||
this->write = write;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
write = start;
|
||||
for (uint8_t count = 0; count < N_READ_PTRS; count++) {
|
||||
read[count] = start;
|
||||
}
|
||||
}
|
||||
uint32_t writeTillWrap() {
|
||||
|
||||
size_t writeTillWrap() {
|
||||
return (start + size) - write;
|
||||
}
|
||||
uint32_t readTillWrap(uint8_t n = 0) {
|
||||
|
||||
size_t readTillWrap(uint8_t n = 0) {
|
||||
return (start + size) - read[n];
|
||||
}
|
||||
uint32_t getStart() const {
|
||||
|
||||
size_t getStart() const {
|
||||
return start;
|
||||
}
|
||||
bool overwritesOld() const {
|
||||
return overwriteOld;
|
||||
}
|
||||
uint32_t maxSize() const {
|
||||
return size - 1;
|
||||
}
|
||||
|
||||
protected:
|
||||
const uint32_t start;
|
||||
uint32_t write;
|
||||
uint32_t read[N_READ_PTRS];
|
||||
const size_t start;
|
||||
size_t write;
|
||||
size_t read[N_READ_PTRS];
|
||||
const size_t size;
|
||||
const bool overwriteOld;
|
||||
void incrementWrite(uint32_t amount) {
|
||||
@ -93,6 +71,43 @@ protected:
|
||||
void incrementRead(uint32_t amount, uint8_t n = 0) {
|
||||
read[n] = ((read[n] + amount - start) % size) + start;
|
||||
}
|
||||
|
||||
ReturnValue_t readData(uint32_t amount, uint8_t n = 0) {
|
||||
if (availableReadData(n) >= amount) {
|
||||
incrementRead(amount, n);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t writeData(uint32_t amount) {
|
||||
if (availableWriteSpace() >= amount or overwriteOld) {
|
||||
incrementWrite(amount);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t getRead(uint8_t n = 0) const {
|
||||
return read[n];
|
||||
}
|
||||
|
||||
void setRead(uint32_t read, uint8_t n = 0) {
|
||||
if (read >= start && read < (start+size)) {
|
||||
this->read[n] = read;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t getWrite() const {
|
||||
return write;
|
||||
}
|
||||
|
||||
void setWrite(uint32_t write) {
|
||||
this->write = write;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ */
|
||||
|
42
container/SharedRingBuffer.cpp
Normal file
42
container/SharedRingBuffer.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include <framework/container/SharedRingBuffer.h>
|
||||
#include <framework/ipc/MutexFactory.h>
|
||||
#include <framework/ipc/MutexHelper.h>
|
||||
|
||||
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size,
|
||||
bool overwriteOld, dur_millis_t mutexTimeout):
|
||||
SystemObject(objectId), SimpleRingBuffer(size, overwriteOld),
|
||||
mutexTimeout(mutexTimeout) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
|
||||
const size_t size, bool overwriteOld, dur_millis_t mutexTimeout):
|
||||
SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld),
|
||||
mutexTimeout(mutexTimeout) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
ReturnValue_t SharedRingBuffer::writeDataProtected(const uint8_t *data,
|
||||
size_t amount) {
|
||||
MutexHelper(mutex, mutexTimeout);
|
||||
return SimpleRingBuffer::writeData(data,amount);
|
||||
}
|
||||
|
||||
ReturnValue_t SharedRingBuffer::readDataProtected(uint8_t *data, size_t amount,
|
||||
bool incrementReadPtr, bool readRemaining,
|
||||
size_t *trueAmount) {
|
||||
MutexHelper(mutex, mutexTimeout);
|
||||
return SimpleRingBuffer::readData(data,amount, incrementReadPtr,
|
||||
readRemaining, trueAmount);
|
||||
}
|
||||
|
||||
ReturnValue_t SharedRingBuffer::deleteDataProtected(size_t amount,
|
||||
bool deleteRemaining, size_t *trueAmount) {
|
||||
MutexHelper(mutex, mutexTimeout);
|
||||
return SimpleRingBuffer::deleteData(amount, deleteRemaining, trueAmount);
|
||||
}
|
||||
|
||||
size_t SharedRingBuffer::getAvailableReadDataProtected(uint8_t n) const {
|
||||
MutexHelper(mutex, mutexTimeout);
|
||||
return ((write + size) - read[n]) % size;
|
||||
}
|
55
container/SharedRingBuffer.h
Normal file
55
container/SharedRingBuffer.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_
|
||||
#define FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_
|
||||
|
||||
#include <framework/container/SimpleRingBuffer.h>
|
||||
#include <framework/ipc/MutexIF.h>
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
#include <framework/timemanager/Clock.h>
|
||||
|
||||
class SharedRingBuffer: public SystemObject,
|
||||
public SimpleRingBuffer {
|
||||
public:
|
||||
/**
|
||||
* This constructor allocates a new internal buffer with the supplied size.
|
||||
* @param size
|
||||
* @param overwriteOld
|
||||
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||
* will be overwritten.
|
||||
*/
|
||||
SharedRingBuffer(object_id_t objectId, const size_t size,
|
||||
bool overwriteOld, dur_millis_t mutexTimeout = 10);
|
||||
|
||||
/**
|
||||
* This constructor takes an external buffer with the specified size.
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @param overwriteOld
|
||||
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||
* will be overwritten.
|
||||
*/
|
||||
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size,
|
||||
bool overwriteOld, dur_millis_t mutexTimeout = 10);
|
||||
|
||||
void setMutexTimeout(dur_millis_t newTimeout);
|
||||
|
||||
/** Performs mutex protected SimpleRingBuffer::writeData call */
|
||||
ReturnValue_t writeDataProtected(const uint8_t* data, size_t amount);
|
||||
|
||||
/** Performs mutex protected SimpleRingBuffer::readData call */
|
||||
ReturnValue_t readDataProtected(uint8_t *data, size_t amount,
|
||||
bool incrementReadPtr = false,
|
||||
bool readRemaining = false, size_t *trueAmount = nullptr);
|
||||
|
||||
/** Performs mutex protected SimpleRingBuffer::deleteData call */
|
||||
ReturnValue_t deleteDataProtected(size_t amount,
|
||||
bool deleteRemaining = false, size_t* trueAmount = nullptr);
|
||||
|
||||
size_t getAvailableReadDataProtected (uint8_t n = 0) const;
|
||||
private:
|
||||
dur_millis_t mutexTimeout;
|
||||
MutexIF* mutex = nullptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ */
|
@ -16,12 +16,14 @@ SimpleRingBuffer::~SimpleRingBuffer() {
|
||||
}
|
||||
|
||||
ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data,
|
||||
uint32_t amount) {
|
||||
size_t amount) {
|
||||
if (availableWriteSpace() >= amount or overwriteOld) {
|
||||
uint32_t amountTillWrap = writeTillWrap();
|
||||
size_t amountTillWrap = writeTillWrap();
|
||||
if (amountTillWrap >= amount) {
|
||||
// remaining size in buffer is sufficient to fit full amount.
|
||||
memcpy(&buffer[write], data, amount);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
memcpy(&buffer[write], data, amountTillWrap);
|
||||
memcpy(buffer, data + amountTillWrap, amount - amountTillWrap);
|
||||
}
|
||||
@ -32,12 +34,13 @@ ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data,
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, uint32_t amount,
|
||||
bool readRemaining, uint32_t* trueAmount) {
|
||||
uint32_t availableData = availableReadData(READ_PTR);
|
||||
uint32_t amountTillWrap = readTillWrap(READ_PTR);
|
||||
ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount,
|
||||
bool incrementReadPtr, bool readRemaining, size_t* trueAmount) {
|
||||
size_t availableData = availableReadData(READ_PTR);
|
||||
size_t amountTillWrap = readTillWrap(READ_PTR);
|
||||
if (availableData < amount) {
|
||||
if (readRemaining) {
|
||||
// more data available than amount specified.
|
||||
amount = availableData;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
@ -52,12 +55,16 @@ ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, uint32_t amount,
|
||||
memcpy(data, &buffer[read[READ_PTR]], amountTillWrap);
|
||||
memcpy(data + amountTillWrap, buffer, amount - amountTillWrap);
|
||||
}
|
||||
|
||||
if(incrementReadPtr) {
|
||||
deleteData(amount, readRemaining);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t SimpleRingBuffer::deleteData(uint32_t amount,
|
||||
bool deleteRemaining, uint32_t* trueAmount) {
|
||||
uint32_t availableData = availableReadData(READ_PTR);
|
||||
ReturnValue_t SimpleRingBuffer::deleteData(size_t amount,
|
||||
bool deleteRemaining, size_t* trueAmount) {
|
||||
size_t availableData = availableReadData(READ_PTR);
|
||||
if (availableData < amount) {
|
||||
if (deleteRemaining) {
|
||||
amount = availableData;
|
||||
|
@ -18,6 +18,8 @@ public:
|
||||
* This constructor allocates a new internal buffer with the supplied size.
|
||||
* @param size
|
||||
* @param overwriteOld
|
||||
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||
* will be overwritten.
|
||||
*/
|
||||
SimpleRingBuffer(const size_t size, bool overwriteOld);
|
||||
/**
|
||||
@ -25,41 +27,59 @@ public:
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @param overwriteOld
|
||||
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||
* will be overwritten.
|
||||
*/
|
||||
SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld);
|
||||
|
||||
virtual ~SimpleRingBuffer();
|
||||
|
||||
/**
|
||||
* Write to circular buffer and increment write pointer by amount
|
||||
* Write to circular buffer and increment write pointer by amount.
|
||||
* @param data
|
||||
* @param amount
|
||||
* @return
|
||||
* @return -@c RETURN_OK if write operation was successfull
|
||||
* -@c RETURN_FAILED if
|
||||
*/
|
||||
ReturnValue_t writeData(const uint8_t* data, uint32_t amount);
|
||||
ReturnValue_t writeData(const uint8_t* data, size_t amount);
|
||||
|
||||
/**
|
||||
* Read from circular buffer at read pointer
|
||||
* Read from circular buffer at read pointer.
|
||||
* @param data
|
||||
* @param amount
|
||||
* @param incrementReadPtr
|
||||
* If this is set to true, the read pointer will be incremented.
|
||||
* If readRemaining is set to true, the read pointer will be incremented
|
||||
* accordingly.
|
||||
* @param readRemaining
|
||||
* @param trueAmount
|
||||
* If this is set to true, the data will be read even if the amount
|
||||
* specified exceeds the read data available.
|
||||
* @param trueAmount [out]
|
||||
* If readRemaining was set to true, the true amount read will be assigned
|
||||
* to the passed value.
|
||||
* @return
|
||||
* - @c RETURN_OK if data was read successfully
|
||||
* - @c RETURN_FAILED if not enough data was available and readRemaining
|
||||
* was set to false.
|
||||
*/
|
||||
ReturnValue_t readData(uint8_t* data, uint32_t amount,
|
||||
bool readRemaining = false, uint32_t* trueAmount = nullptr);
|
||||
ReturnValue_t readData(uint8_t* data, size_t amount,
|
||||
bool incrementReadPtr = false, bool readRemaining = false,
|
||||
size_t* trueAmount = nullptr);
|
||||
|
||||
/**
|
||||
* Delete data starting by incrementing read pointer
|
||||
* Delete data by incrementing read pointer.
|
||||
* @param amount
|
||||
* @param deleteRemaining
|
||||
* @param trueAmount
|
||||
* If the amount specified is larger than the remaing size to read and this
|
||||
* is set to true, the remaining amount will be deleted as well
|
||||
* @param trueAmount [out]
|
||||
* If deleteRemaining was set to true, the amount deleted will be assigned
|
||||
* to the passed value.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t deleteData(uint32_t amount, bool deleteRemaining = false,
|
||||
uint32_t* trueAmount = nullptr);
|
||||
ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false,
|
||||
size_t* trueAmount = nullptr);
|
||||
private:
|
||||
// static const uint8_t TEMP_READ_PTR = 1;
|
||||
static const uint8_t READ_PTR = 0;
|
||||
uint8_t* buffer = nullptr;
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef DATASET_H_
|
||||
#define DATASET_H_
|
||||
#ifndef FRAMEWORK_DATAPOOLGLOB_DATASET_H_
|
||||
#define FRAMEWORK_DATAPOOLGLOB_DATASET_H_
|
||||
|
||||
#include <framework/datapool/DataSetBase.h>
|
||||
|
||||
@ -93,4 +93,4 @@ private:
|
||||
PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE];
|
||||
};
|
||||
|
||||
#endif /* DATASET_H_ */
|
||||
#endif /* FRAMEWORK_DATAPOOLGLOB_DATASET_H_ */
|
||||
|
@ -36,9 +36,9 @@ using LocalDataPoolMapIter = LocalDataPool::iterator;
|
||||
* pragmatic solution I found was to offer the client the full interface
|
||||
* of the LocalDataPoolManager.
|
||||
*/
|
||||
class OwnsLocalDataPoolIF {
|
||||
class HasLocalDataPoolIF {
|
||||
public:
|
||||
virtual~ OwnsLocalDataPoolIF() {};
|
||||
virtual~ HasLocalDataPoolIF() {};
|
||||
|
||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF;
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include <array>
|
||||
|
||||
LocalDataPoolManager::LocalDataPoolManager(OwnsLocalDataPoolIF* owner,
|
||||
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner,
|
||||
MessageQueueIF* queueToUse, bool appendValidityBuffer):
|
||||
appendValidityBuffer(appendValidityBuffer) {
|
||||
if(owner == nullptr) {
|
||||
@ -63,7 +63,7 @@ LocalDataPoolManager::~LocalDataPoolManager() {}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
|
||||
if(not mapInitialized) {
|
||||
ReturnValue_t result = owner->initializePoolEntries(localDpMap);
|
||||
ReturnValue_t result = owner->initializePoolEntries(localPoolMap);
|
||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
||||
mapInitialized = true;
|
||||
}
|
||||
@ -96,8 +96,8 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::printPoolEntry(
|
||||
lp_id_t localPoolId) {
|
||||
auto poolIter = localDpMap.find(localPoolId);
|
||||
if (poolIter == localDpMap.end()) {
|
||||
auto poolIter = localPoolMap.find(localPoolId);
|
||||
if (poolIter == localPoolMap.end()) {
|
||||
sif::debug << "HousekeepingManager::fechPoolEntry:"
|
||||
" Pool entry not found." << std::endl;
|
||||
return POOL_ENTRY_NOT_FOUND;
|
||||
@ -110,7 +110,7 @@ MutexIF* LocalDataPoolManager::getMutexHandle() {
|
||||
return mutex;
|
||||
}
|
||||
|
||||
const OwnsLocalDataPoolIF* LocalDataPoolManager::getOwner() const {
|
||||
const HasLocalDataPoolIF* LocalDataPoolManager::getOwner() const {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@ -213,4 +213,6 @@ ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore(
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::performHkOperation() {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
#ifndef FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_
|
||||
#define FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_
|
||||
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
||||
#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
||||
|
||||
#include <framework/datapool/DataSetIF.h>
|
||||
#include <framework/objectmanager/SystemObjectIF.h>
|
||||
#include <framework/ipc/MutexIF.h>
|
||||
|
||||
#include <framework/housekeeping/HousekeepingMessage.h>
|
||||
#include <framework/datapool/PoolEntry.h>
|
||||
#include <framework/datapoollocal/OwnsLocalDataPoolIF.h>
|
||||
#include <framework/datapoollocal/HasLocalDataPoolIF.h>
|
||||
#include <framework/ipc/CommandMessage.h>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
#include <framework/ipc/MutexHelper.h>
|
||||
@ -20,7 +21,7 @@ class LocalDataSet;
|
||||
* @details
|
||||
* The actual data pool structure is a member of this class. Any class which
|
||||
* has a local data pool shall have this class as a member and implement
|
||||
* the OwnsLocalDataPoolIF.
|
||||
* the HasLocalDataPoolIF.
|
||||
*
|
||||
* Users of the data pool use the helper classes LocalDataSet,
|
||||
* LocalPoolVariable and LocalPoolVector to access pool entries in
|
||||
@ -57,16 +58,25 @@ public:
|
||||
* @param queueToUse
|
||||
* @param appendValidityBuffer
|
||||
*/
|
||||
LocalDataPoolManager(OwnsLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
||||
LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
||||
bool appendValidityBuffer = true);
|
||||
virtual~ LocalDataPoolManager();
|
||||
|
||||
/**
|
||||
* Initializes the map by calling the map initialization function of the
|
||||
* owner abd assigns the queue to use.
|
||||
* owner and assigns the queue to use.
|
||||
* @param queueToUse
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t initialize(MessageQueueIF* queueToUse,
|
||||
object_id_t hkDestination);
|
||||
|
||||
/**
|
||||
* This should be called in the periodic handler of the owner.
|
||||
* It performs all the periodic functionalities of the data pool manager.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t performHkOperation();
|
||||
/**
|
||||
* This function is used to set the default HK packet destination.
|
||||
* This destination will usually only be set once.
|
||||
@ -74,8 +84,6 @@ public:
|
||||
*/
|
||||
void setHkPacketDestination(MessageQueueId_t hkDestination);
|
||||
|
||||
virtual~ LocalDataPoolManager();
|
||||
|
||||
/**
|
||||
* Generate a housekeeping packet with a given SID.
|
||||
* @param sid
|
||||
@ -95,14 +103,57 @@ public:
|
||||
*/
|
||||
ReturnValue_t initializeHousekeepingPoolEntriesOnce();
|
||||
|
||||
const OwnsLocalDataPoolIF* getOwner() const;
|
||||
const HasLocalDataPoolIF* getOwner() const;
|
||||
|
||||
ReturnValue_t printPoolEntry(lp_id_t localPoolId);
|
||||
|
||||
/**
|
||||
* Different types of housekeeping reporting are possible.
|
||||
* 1. PERIODIC: HK packets are generated in fixed intervals
|
||||
* 2. UPDATED: HK packets are generated if a value was updated
|
||||
* 3. REQUESTED: HK packets are only generated if explicitely requested
|
||||
*/
|
||||
enum class ReportingType: uint8_t {
|
||||
PERIODIC,
|
||||
ON_UPDATE,
|
||||
REQUESTED
|
||||
};
|
||||
|
||||
/* Copying forbidden */
|
||||
LocalDataPoolManager(const LocalDataPoolManager &) = delete;
|
||||
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
|
||||
|
||||
private:
|
||||
LocalDataPool localPoolMap;
|
||||
/** Every housekeeping data manager has a mutex to protect access
|
||||
* to it's data pool. */
|
||||
MutexIF* mutex = nullptr;
|
||||
/** The class which actually owns the manager (and its datapool). */
|
||||
HasLocalDataPoolIF* owner = nullptr;
|
||||
|
||||
/**
|
||||
* The data pool manager will keep an internal map of HK receivers.
|
||||
*/
|
||||
struct HkReceiver {
|
||||
LocalDataSet* dataSet = nullptr;
|
||||
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE;
|
||||
ReportingType reportingType = ReportingType::PERIODIC;
|
||||
bool reportingStatus = true;
|
||||
/** Different members of this union will be used depending on reporting
|
||||
* type */
|
||||
union hkParameter {
|
||||
/** This parameter will be used for the PERIODIC type */
|
||||
dur_seconds_t collectionInterval = 0;
|
||||
/** This parameter will be used for the ON_UPDATE type */
|
||||
bool hkDataChanged;
|
||||
};
|
||||
};
|
||||
|
||||
/** Using a multimap as the same object might request multiple datasets */
|
||||
using HkReceiversMap = std::multimap<object_id_t, struct HkReceiver>;
|
||||
|
||||
HkReceiversMap hkReceiversMap;
|
||||
|
||||
/** This is the map holding the actual data. Should only be initialized
|
||||
* once ! */
|
||||
bool mapInitialized = false;
|
||||
@ -110,13 +161,6 @@ private:
|
||||
* of generated housekeeping packets. */
|
||||
bool appendValidityBuffer = true;
|
||||
|
||||
LocalDataPool localDpMap;
|
||||
|
||||
/** Every housekeeping data manager has a mutex to protect access
|
||||
* to it's data pool. */
|
||||
MutexIF * mutex = nullptr;
|
||||
/** The class which actually owns the manager (and its datapool). */
|
||||
OwnsLocalDataPoolIF* owner = nullptr;
|
||||
/**
|
||||
* @brief Queue used for communication, for example commands.
|
||||
* Is also used to send messages. Can be set either in the constructor
|
||||
@ -165,10 +209,10 @@ private:
|
||||
template<class T> inline
|
||||
ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
|
||||
PoolEntry<T> **poolEntry) {
|
||||
auto poolIter = localDpMap.find(localPoolId);
|
||||
if (poolIter == localDpMap.end()) {
|
||||
sif::debug << "HousekeepingManager::fechPoolEntry:"
|
||||
" Pool entry not found." << std::endl;
|
||||
auto poolIter = localPoolMap.find(localPoolId);
|
||||
if (poolIter == localPoolMap.end()) {
|
||||
sif::warning << "HousekeepingManager::fechPoolEntry: Pool entry "
|
||||
"not found." << std::endl;
|
||||
return POOL_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
@ -182,4 +226,4 @@ ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
|
||||
}
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_ */
|
||||
#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ */
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
LocalDataSet::LocalDataSet(OwnsLocalDataPoolIF *hkOwner,
|
||||
LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner,
|
||||
const size_t maxNumberOfVariables):
|
||||
DataSetBase(poolVarList.data(), maxNumberOfVariables) {
|
||||
poolVarList.reserve(maxNumberOfVariables);
|
||||
@ -23,7 +23,7 @@ LocalDataSet::LocalDataSet(object_id_t ownerId,
|
||||
DataSetBase(poolVarList.data(), maxNumberOfVariables) {
|
||||
poolVarList.reserve(maxNumberOfVariables);
|
||||
poolVarList.resize(maxNumberOfVariables);
|
||||
OwnsLocalDataPoolIF* hkOwner = objectManager->get<OwnsLocalDataPoolIF>(
|
||||
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
|
||||
ownerId);
|
||||
if(hkOwner == nullptr) {
|
||||
sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!"
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_
|
||||
#include <framework/datapool/DataSetBase.h>
|
||||
#include <framework/datapool/DataSetIF.h>
|
||||
#include <framework/datapoollocal/OwnsLocalDataPoolIF.h>
|
||||
#include <framework/datapoollocal/HasLocalDataPoolIF.h>
|
||||
#include <framework/serialize/SerializeIF.h>
|
||||
|
||||
#include <vector>
|
||||
@ -37,7 +37,7 @@ public:
|
||||
* The constructor simply sets the fill_count to zero and sets
|
||||
* the state to "uninitialized".
|
||||
*/
|
||||
LocalDataSet(OwnsLocalDataPoolIF *hkOwner,
|
||||
LocalDataSet(HasLocalDataPoolIF *hkOwner,
|
||||
const size_t maxNumberOfVariables);
|
||||
|
||||
/**
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
#include <framework/datapool/PoolVariableIF.h>
|
||||
#include <framework/datapool/DataSetIF.h>
|
||||
#include <framework/datapoollocal/HasLocalDataPoolIF.h>
|
||||
#include <framework/datapoollocal/LocalDataPoolManager.h>
|
||||
#include <framework/datapoollocal/OwnsLocalDataPoolIF.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
|
||||
#include <framework/serialize/SerializeAdapter.h>
|
||||
@ -42,7 +42,7 @@ public:
|
||||
* @param dataSet The data set in which the variable shall register itself.
|
||||
* If nullptr, the variable is not registered.
|
||||
*/
|
||||
LocalPoolVar(lp_id_t poolId, OwnsLocalDataPoolIF* hkOwner,
|
||||
LocalPoolVar(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
|
||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE,
|
||||
DataSetIF* dataSet = nullptr);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
template<typename T>
|
||||
inline LocalPoolVar<T>::LocalPoolVar(lp_id_t poolId,
|
||||
OwnsLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode,
|
||||
HasLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode,
|
||||
DataSetIF* dataSet):
|
||||
localPoolId(poolId),readWriteMode(setReadWriteMode) {
|
||||
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
||||
@ -33,8 +33,8 @@ inline LocalPoolVar<T>::LocalPoolVar(lp_id_t poolId, object_id_t poolOwner,
|
||||
sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the "
|
||||
"NO_PARAMETER value!" << std::endl;
|
||||
}
|
||||
OwnsLocalDataPoolIF* hkOwner =
|
||||
objectManager->get<OwnsLocalDataPoolIF>(poolOwner);
|
||||
HasLocalDataPoolIF* hkOwner =
|
||||
objectManager->get<HasLocalDataPoolIF>(poolOwner);
|
||||
if(hkOwner == nullptr) {
|
||||
sif::error << "LocalPoolVariable: The supplied pool owner did not implement"
|
||||
"the correct interface HasHkPoolParametersIF!" << std::endl;
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
* @param dataSet The data set in which the variable shall register itself.
|
||||
* If nullptr, the variable is not registered.
|
||||
*/
|
||||
LocalPoolVector(lp_id_t poolId, OwnsLocalDataPoolIF* hkOwner,
|
||||
LocalPoolVector(lp_id_t poolId, HasLocalDataPoolIF* hkOwner,
|
||||
pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE,
|
||||
DataSetIF* dataSet = nullptr);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
template<typename T, uint16_t vectorSize>
|
||||
inline LocalPoolVector<T, vectorSize>::LocalPoolVector(lp_id_t poolId,
|
||||
OwnsLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode,
|
||||
HasLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode,
|
||||
DataSetIF* dataSet) :
|
||||
localPoolId(poolId), valid(false), readWriteMode(setReadWriteMode) {
|
||||
if(poolId == PoolVariableIF::NO_PARAMETER) {
|
||||
@ -29,8 +29,8 @@ inline LocalPoolVector<T, vectorSize>::LocalPoolVector(lp_id_t poolId,
|
||||
sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the "
|
||||
"NO_PARAMETER value!" << std::endl;
|
||||
}
|
||||
OwnsLocalDataPoolIF* hkOwner =
|
||||
objectManager->get<OwnsLocalDataPoolIF>(poolOwner);
|
||||
HasLocalDataPoolIF* hkOwner =
|
||||
objectManager->get<HasLocalDataPoolIF>(poolOwner);
|
||||
if(hkOwner == nullptr) {
|
||||
sif::error << "LocalPoolVariable: The supplied pool owner did not implement"
|
||||
"the correct interface HasHkPoolParametersIF!" << std::endl;
|
||||
|
@ -4,15 +4,19 @@
|
||||
|
||||
ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId,
|
||||
object_id_t deviceCommunication, CookieIF * cookie,
|
||||
uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch,
|
||||
object_id_t hkDestination, uint32_t thermalStatePoolId,
|
||||
uint32_t thermalRequestPoolId, uint32_t parent,
|
||||
uint8_t setDeviceSwitch, object_id_t hkDestination,
|
||||
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
|
||||
object_id_t parent,
|
||||
FailureIsolationBase* customFdir, size_t cmdQueueSize) :
|
||||
DeviceHandlerBase(setObjectId, deviceCommunication, cookie,
|
||||
hkDestination, setDeviceSwitch, thermalStatePoolId,
|
||||
thermalRequestPoolId, (customFdir == NULL? &childHandlerFdir : customFdir),
|
||||
(customFdir == nullptr? &childHandlerFdir : customFdir),
|
||||
cmdQueueSize),
|
||||
parentId(parent), childHandlerFdir(setObjectId) {
|
||||
this->setDeviceSwitch(setDeviceSwitch);
|
||||
this->setHkDestination(hkDestination);
|
||||
this->setThermalStateRequestPoolIds(thermalStatePoolId,
|
||||
thermalRequestPoolId);
|
||||
|
||||
}
|
||||
|
||||
ChildHandlerBase::~ChildHandlerBase() {
|
||||
@ -26,7 +30,7 @@ ReturnValue_t ChildHandlerBase::initialize() {
|
||||
|
||||
MessageQueueId_t parentQueue = 0;
|
||||
|
||||
if (parentId != 0) {
|
||||
if (parentId != objects::NO_OBJECT) {
|
||||
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
|
||||
if (parent == NULL) {
|
||||
return RETURN_FAILED;
|
||||
|
@ -7,9 +7,9 @@
|
||||
class ChildHandlerBase: public DeviceHandlerBase {
|
||||
public:
|
||||
ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication,
|
||||
CookieIF * cookie, uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch,
|
||||
CookieIF * cookie, uint8_t setDeviceSwitch,
|
||||
object_id_t hkDestination, uint32_t thermalStatePoolId,
|
||||
uint32_t thermalRequestPoolId, uint32_t parent,
|
||||
uint32_t thermalRequestPoolId, object_id_t parent = objects::NO_OBJECT,
|
||||
FailureIsolationBase* customFdir = nullptr, size_t cmdQueueSize = 20);
|
||||
virtual ~ChildHandlerBase();
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include <framework/datapoolglob/GlobalDataSet.h>
|
||||
#include <framework/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <framework/objectmanager/ObjectManager.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
#include <framework/thermal/ThermalComponentIF.h>
|
||||
#include <framework/devicehandlers/AcceptsDeviceResponsesIF.h>
|
||||
|
||||
#include <framework/datapoolglob/GlobalDataSet.h>
|
||||
#include <framework/datapoolglob/GlobalPoolVariable.h>
|
||||
#include <framework/devicehandlers/DeviceTmReportingWrapper.h>
|
||||
#include <framework/globalfunctions/CRC.h>
|
||||
@ -18,43 +18,55 @@
|
||||
|
||||
object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
||||
object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT;
|
||||
object_id_t DeviceHandlerBase::defaultFDIRParentId = 0;
|
||||
object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT;
|
||||
object_id_t DeviceHandlerBase::defaultHkDestination = objects::NO_OBJECT;
|
||||
|
||||
DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
|
||||
object_id_t deviceCommunication, CookieIF * comCookie,
|
||||
uint8_t setDeviceSwitch, object_id_t hkDestination,
|
||||
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId,
|
||||
FailureIsolationBase* fdirInstance, size_t cmdQueueSize) :
|
||||
SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE),
|
||||
wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS),
|
||||
deviceCommunicationId(deviceCommunication), comCookie(comCookie),
|
||||
healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
|
||||
actionHelper(this, nullptr), hkManager(this, nullptr),
|
||||
deviceThermalStatePoolId(thermalStatePoolId),
|
||||
deviceThermalRequestPoolId(thermalRequestPoolId),
|
||||
childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance),
|
||||
hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr),
|
||||
switchOffWasReported(false), hkDestination(hkDestination),
|
||||
childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN),
|
||||
transitionSourceSubMode(SUBMODE_NONE), deviceSwitch(setDeviceSwitch) {
|
||||
switchOffWasReported(false), childTransitionDelay(5000),
|
||||
transitionSourceMode(_MODE_POWER_DOWN),
|
||||
transitionSourceSubMode(SUBMODE_NONE) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
|
||||
MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
insertInCommandMap(RAW_COMMAND_ID);
|
||||
cookieInfo.state = COOKIE_UNUSED;
|
||||
cookieInfo.pendingCommand = deviceCommandMap.end();
|
||||
if (comCookie == nullptr) {
|
||||
sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex <<
|
||||
std::setw(8) << std::setfill('0') << this->getObjectId() <<
|
||||
std::dec << ": Do not pass nullptr as a cookie, consider "
|
||||
<< std::setfill(' ') << "passing a dummy cookie instead!" <<
|
||||
std::endl;
|
||||
sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex
|
||||
<< std::setw(8) << std::setfill('0') << this->getObjectId()
|
||||
<< std::dec << ": Do not pass nullptr as a cookie, consider "
|
||||
<< std::setfill(' ') << "passing a dummy cookie instead!"
|
||||
<< std::endl;
|
||||
}
|
||||
if (this->fdirInstance == nullptr) {
|
||||
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId,
|
||||
defaultFDIRParentId);
|
||||
defaultFdirParentId);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
||||
this->hkDestination = hkDestination;
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setThermalStateRequestPoolIds(
|
||||
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId) {
|
||||
this->deviceThermalRequestPoolId = thermalStatePoolId;
|
||||
this->deviceThermalRequestPoolId = thermalRequestPoolId;
|
||||
}
|
||||
|
||||
|
||||
void DeviceHandlerBase::setDeviceSwitch(uint8_t deviceSwitch) {
|
||||
this->deviceSwitch = deviceSwitch;
|
||||
}
|
||||
|
||||
DeviceHandlerBase::~DeviceHandlerBase() {
|
||||
delete comCookie;
|
||||
if (defaultFDIRUsed) {
|
||||
@ -110,8 +122,12 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
|
||||
communicationInterface = objectManager->get<DeviceCommunicationIF>(
|
||||
deviceCommunicationId);
|
||||
if (communicationInterface == NULL) {
|
||||
return RETURN_FAILED;
|
||||
if (communicationInterface == nullptr) {
|
||||
sif::error << "DeviceHandlerBase::initialize: Communication interface "
|
||||
"invalid." << std::endl;
|
||||
sif::error << "Make sure it is set up properly and implements"
|
||||
" DeviceCommunicationIF" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
result = communicationInterface->initializeInterface(comCookie);
|
||||
@ -120,8 +136,10 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
}
|
||||
|
||||
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if (IPCStore == NULL) {
|
||||
return RETURN_FAILED;
|
||||
if (IPCStore == nullptr) {
|
||||
sif::error << "DeviceHandlerBase::initialize: IPC store not set up in "
|
||||
"factory." << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
if(rawDataReceiverId != objects::NO_OBJECT) {
|
||||
@ -140,8 +158,12 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
|
||||
if(powerSwitcherId != objects::NO_OBJECT) {
|
||||
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
|
||||
if (powerSwitcher == NULL) {
|
||||
return RETURN_FAILED;
|
||||
if (powerSwitcher == nullptr) {
|
||||
sif::error << "DeviceHandlerBase::initialize: Power switcher "
|
||||
<< "object ID set but no valid object found." << std::endl;
|
||||
sif::error << "Make sure the raw receiver object is set up properly"
|
||||
<< " and implements PowerSwitchIF" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,6 +199,10 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
return result;
|
||||
}
|
||||
|
||||
if(hkDestination == objects::NO_OBJECT) {
|
||||
hkDestination = defaultHkDestination;
|
||||
}
|
||||
|
||||
result = hkManager.initialize(commandQueue, hkDestination);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
@ -202,7 +228,7 @@ void DeviceHandlerBase::decrementDeviceReplyMap() {
|
||||
if (iter->second.delayCycles != 0) {
|
||||
iter->second.delayCycles--;
|
||||
if (iter->second.delayCycles == 0) {
|
||||
if (iter->second.periodic != 0) {
|
||||
if (iter->second.periodic) {
|
||||
iter->second.delayCycles = iter->second.maxDelayCycles;
|
||||
}
|
||||
replyToReply(iter, TIMEOUT);
|
||||
@ -322,7 +348,7 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
|
||||
if(powerSwitcher == nullptr) {
|
||||
setMode(MODE_OFF);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||
@ -806,21 +832,6 @@ MessageQueueId_t DeviceHandlerBase::getCommandQueue() const {
|
||||
return commandQueue->getId();
|
||||
}
|
||||
|
||||
//ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) {
|
||||
// DeviceCommunicationIF *newCommunication = objectManager->get<
|
||||
// DeviceCommunicationIF>(newChannelId);
|
||||
//
|
||||
// if (newCommunication != NULL) {
|
||||
// ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress,
|
||||
// maxDeviceReplyLen);
|
||||
// if (result != RETURN_OK) {
|
||||
// return result;
|
||||
// }
|
||||
// return RETURN_OK;
|
||||
// }
|
||||
// return RETURN_FAILED;
|
||||
//}
|
||||
|
||||
void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) {
|
||||
storedRawData = DeviceHandlerMessage::getStoreAddress(commandMessage);
|
||||
ReturnValue_t result = getStorageData(storedRawData, &rawPacket,
|
||||
|
@ -17,10 +17,9 @@
|
||||
#include <framework/health/HealthHelper.h>
|
||||
#include <framework/parameters/ParameterHelper.h>
|
||||
#include <framework/datapool/HkSwitchHelper.h>
|
||||
#include <framework/datapoollocal/HasLocalDataPoolIF.h>
|
||||
#include <framework/datapoollocal/LocalDataPoolManager.h>
|
||||
#include <framework/devicehandlers/DeviceHandlerFailureIsolation.h>
|
||||
#include <framework/datapoollocal/OwnsLocalDataPoolIF.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace Factory{
|
||||
@ -88,7 +87,7 @@ class DeviceHandlerBase: public DeviceHandlerIF,
|
||||
public HasHealthIF,
|
||||
public HasActionsIF,
|
||||
public ReceivesParameterMessagesIF,
|
||||
public OwnsLocalDataPoolIF {
|
||||
public HasLocalDataPoolIF {
|
||||
friend void (Factory::setStaticFrameworkObjectIds)();
|
||||
public:
|
||||
/**
|
||||
@ -106,13 +105,14 @@ public:
|
||||
* @param cmdQueueSize
|
||||
*/
|
||||
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication,
|
||||
CookieIF * comCookie, uint8_t setDeviceSwitch,
|
||||
object_id_t hkDestination = objects::NO_OBJECT,
|
||||
uint32_t thermalStatePoolId = PoolVariableIF::NO_PARAMETER,
|
||||
uint32_t thermalRequestPoolId = PoolVariableIF::NO_PARAMETER,
|
||||
FailureIsolationBase* fdirInstance = nullptr,
|
||||
CookieIF * comCookie, FailureIsolationBase* fdirInstance = nullptr,
|
||||
size_t cmdQueueSize = 20);
|
||||
|
||||
void setDeviceSwitch(uint8_t deviceSwitch);
|
||||
void setHkDestination(object_id_t hkDestination);
|
||||
void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId,
|
||||
uint32_t thermalRequestPoolId);
|
||||
|
||||
/**
|
||||
* @brief This function is the device handler base core component and is
|
||||
* called periodically.
|
||||
@ -386,7 +386,7 @@ protected:
|
||||
* - @c RETURN_FAILED else.
|
||||
*/
|
||||
ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand,
|
||||
uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = 0,
|
||||
uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = false,
|
||||
bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0);
|
||||
|
||||
/**
|
||||
@ -400,7 +400,7 @@ protected:
|
||||
* - @c RETURN_FAILED else.
|
||||
*/
|
||||
ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand,
|
||||
uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = 0);
|
||||
uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = false);
|
||||
|
||||
/**
|
||||
* @brief A simple command to add a command to the commandList.
|
||||
@ -426,7 +426,7 @@ protected:
|
||||
*/
|
||||
ReturnValue_t updateReplyMapEntry(DeviceCommandId_t deviceReply,
|
||||
uint16_t delayCycles, uint16_t maxDelayCycles,
|
||||
bool periodic = 0);
|
||||
bool periodic = false);
|
||||
|
||||
/**
|
||||
* @brief Can be implemented by child handler to
|
||||
@ -691,14 +691,14 @@ protected:
|
||||
*
|
||||
* can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking
|
||||
*/
|
||||
uint32_t deviceThermalStatePoolId;
|
||||
uint32_t deviceThermalStatePoolId = PoolVariableIF::NO_PARAMETER;
|
||||
|
||||
/**
|
||||
* this is the datapool variable with the thermal request of the device
|
||||
*
|
||||
* can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking
|
||||
*/
|
||||
uint32_t deviceThermalRequestPoolId;
|
||||
uint32_t deviceThermalRequestPoolId = PoolVariableIF::NO_PARAMETER;
|
||||
|
||||
/**
|
||||
* Optional Error code
|
||||
@ -724,7 +724,7 @@ protected:
|
||||
|
||||
static object_id_t rawDataReceiverId; //!< Object which receives RAW data by default.
|
||||
|
||||
static object_id_t defaultFDIRParentId; //!< Object which may be the root cause of an identified fault.
|
||||
static object_id_t defaultFdirParentId; //!< Object which may be the root cause of an identified fault.
|
||||
/**
|
||||
* Helper function to report a missed reply
|
||||
*
|
||||
@ -1047,6 +1047,8 @@ private:
|
||||
PowerSwitchIF *powerSwitcher = nullptr;
|
||||
|
||||
/** Cached for initialize() */
|
||||
static object_id_t defaultHkDestination;
|
||||
/** HK destination can also be set individually */
|
||||
object_id_t hkDestination = objects::NO_OBJECT;
|
||||
|
||||
/**
|
||||
@ -1082,7 +1084,7 @@ private:
|
||||
*
|
||||
* for devices using two switches override getSwitches()
|
||||
*/
|
||||
const uint8_t deviceSwitch;
|
||||
uint8_t deviceSwitch;
|
||||
|
||||
/**
|
||||
* read the command queue
|
||||
@ -1213,5 +1215,5 @@ private:
|
||||
size_t receivedDataLen);
|
||||
};
|
||||
|
||||
#endif /* DEVICEHANDLERBASE_H_ */
|
||||
#endif /* FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
||||
|
||||
|
@ -29,7 +29,7 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (ownerId != 0) {
|
||||
if (ownerId != objects::NO_OBJECT) {
|
||||
result = manager->subscribeToAllEventsFrom(eventQueue->getId(), ownerId);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
@ -41,10 +41,15 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
}
|
||||
if (faultTreeParent != 0) {
|
||||
if (faultTreeParent != objects::NO_OBJECT) {
|
||||
ConfirmsFailuresIF* parentIF = objectManager->get<ConfirmsFailuresIF>(
|
||||
faultTreeParent);
|
||||
if (parentIF == NULL) {
|
||||
if (parentIF == nullptr) {
|
||||
sif::error << "FailureIsolationBase::intialize: Parent object"
|
||||
<< "invalid." << std::endl;
|
||||
sif::error << "Make sure it implements ConfirmsFailuresIF."
|
||||
<< std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
eventQueue->setDefaultDestination(parentIF->getEventReceptionQueue());
|
||||
|
@ -17,8 +17,11 @@ public:
|
||||
static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, SEVERITY::INFO); //!< FDIR has an internal state, which changed from par2 (oldState) to par1 (newState).
|
||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, SEVERITY::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery.
|
||||
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, SEVERITY::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery.
|
||||
FailureIsolationBase(object_id_t owner, object_id_t parent = 0,
|
||||
|
||||
FailureIsolationBase(object_id_t owner,
|
||||
object_id_t parent = objects::NO_OBJECT,
|
||||
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);
|
||||
|
||||
virtual ~FailureIsolationBase();
|
||||
virtual ReturnValue_t initialize();
|
||||
|
||||
@ -26,7 +29,7 @@ public:
|
||||
* This is called by the DHB in performOperation()
|
||||
*/
|
||||
void checkForFailures();
|
||||
MessageQueueId_t getEventReceptionQueue();
|
||||
MessageQueueId_t getEventReceptionQueue() override;
|
||||
virtual void triggerEvent(Event event, uint32_t parameter1 = 0,
|
||||
uint32_t parameter2 = 0);
|
||||
protected:
|
||||
|
@ -81,8 +81,7 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream,
|
||||
|
||||
while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen)
|
||||
&& (sourceStream[encodedIndex] != ETX)
|
||||
&& (sourceStream[encodedIndex] != STX))
|
||||
{
|
||||
&& (sourceStream[encodedIndex] != STX)) {
|
||||
if (sourceStream[encodedIndex] == DLE) {
|
||||
nextByte = sourceStream[encodedIndex + 1];
|
||||
// The next byte is a DLE character that was escaped by another
|
||||
|
@ -1,26 +1,19 @@
|
||||
/**
|
||||
* @file SystemObjectIF.h
|
||||
* @brief This file contains the definition of the SystemObjectIF interface.
|
||||
* @date 18.09.2012
|
||||
* @author Bastian Baetz
|
||||
*/
|
||||
|
||||
#ifndef SYSTEMOBJECTIF_H_
|
||||
#define SYSTEMOBJECTIF_H_
|
||||
#ifndef FRAMEWORK_OBJECTMANAGER_SYSTEMOBJECTIF_H_
|
||||
#define FRAMEWORK_OBJECTMANAGER_SYSTEMOBJECTIF_H_
|
||||
|
||||
#include <framework/events/EventReportingProxyIF.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
/**
|
||||
* \defgroup system_objects Software System Object Management
|
||||
* The classes to create System Objects and classes to manage these are contained in this group.
|
||||
* System Objects are software elements that can be controlled externally. They all have a unique
|
||||
* object identifier.
|
||||
* @defgroup system_objects Software System Object Management
|
||||
* The classes to create System Objects and classes to manage these are
|
||||
* contained in this group. System Objects are software elements that can be
|
||||
* controlled externally. They all have a unique object identifier.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the typedef for object identifiers.
|
||||
* \ingroup system_objects
|
||||
* @ingroup system_objects
|
||||
*/
|
||||
typedef uint32_t object_id_t;
|
||||
|
||||
@ -29,7 +22,8 @@ typedef uint32_t object_id_t;
|
||||
* list.
|
||||
* It does not provide any method definitions, still it is required to
|
||||
* perform a type check with dynamic_cast.
|
||||
* \ingroup system_objects
|
||||
* @author Bastian Baetz
|
||||
* @ingroup system_objects
|
||||
*/
|
||||
class SystemObjectIF : public EventReportingProxyIF {
|
||||
public:
|
||||
@ -41,24 +35,28 @@ public:
|
||||
/**
|
||||
* The empty virtual destructor as required for C++ interfaces.
|
||||
*/
|
||||
virtual ~SystemObjectIF() {
|
||||
}
|
||||
virtual ~SystemObjectIF() {}
|
||||
/**
|
||||
* Initializes all inter-object dependencies.
|
||||
* This is necessary to avoid circular dependencies of not-fully
|
||||
* initialized objects on start up.
|
||||
* @return - \c RETURN_OK in case the initialization was successful
|
||||
* - \c RETURN_FAILED otherwise
|
||||
* @brief Initializes the object.
|
||||
* There are initialization steps which can also be done in the constructor.
|
||||
* However, there is no clean way to get a returnvalue from a constructor.
|
||||
* Furthermore some components require other system object to be created
|
||||
* which might not have been built yet.
|
||||
* Therefore, a two-step initialization resolves this problem and prevents
|
||||
* circular dependencies of not-fully initialized objects on start up.
|
||||
* @return - @c RETURN_OK in case the initialization was successful
|
||||
* - @c RETURN_FAILED otherwise
|
||||
*/
|
||||
virtual ReturnValue_t initialize() = 0;
|
||||
/**
|
||||
* Checks, if all object-object interconnections are satisfying for operation.
|
||||
* Some objects need certain other objects (or a certain number), to be registered as children.
|
||||
* These checks can be done in this method.
|
||||
* @return - \c RETURN_OK in case the check was successful
|
||||
* - \c any other code otherwise
|
||||
* @brief Checks if all object-object interconnections are satisfying
|
||||
* for operation.
|
||||
* Some objects need certain other objects (or a certain number), to be
|
||||
* registered as children. These checks can be done in this method.
|
||||
* @return - @c RETURN_OK in case the check was successful
|
||||
* - @c any other code otherwise
|
||||
*/
|
||||
virtual ReturnValue_t checkObjectConnections() = 0;
|
||||
};
|
||||
|
||||
#endif /* SYSTEMOBJECTIF_H_ */
|
||||
#endif /* FRAMEWORK_OBJECTMANAGER_SYSTEMOBJECTIF_H_ */
|
||||
|
119
pus/CService200ModeCommanding.cpp
Normal file
119
pus/CService200ModeCommanding.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
#include <framework/pus/CService200ModeCommanding.h>
|
||||
#include <framework/pus/servicepackets/Service200Packets.h>
|
||||
|
||||
#include <framework/modes/HasModesIF.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/serialize/SerialLinkedListAdapter.h>
|
||||
#include <framework/modes/ModeMessage.h>
|
||||
|
||||
CService200ModeCommanding::CService200ModeCommanding(object_id_t objectId,
|
||||
uint16_t apid, uint8_t serviceId):
|
||||
CommandingServiceBase(objectId, apid, serviceId,
|
||||
NUMBER_OF_PARALLEL_COMMANDS,COMMAND_TIMEOUT_SECONDS) {}
|
||||
|
||||
CService200ModeCommanding::~CService200ModeCommanding() {}
|
||||
|
||||
ReturnValue_t CService200ModeCommanding::isValidSubservice(uint8_t subservice) {
|
||||
switch(subservice) {
|
||||
case(Subservice::COMMAND_MODE_COMMAND):
|
||||
case(Subservice::COMMAND_MODE_READ):
|
||||
case(Subservice::COMMAND_MODE_ANNCOUNCE):
|
||||
return RETURN_OK;
|
||||
default:
|
||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t CService200ModeCommanding::getMessageQueueAndObject(
|
||||
uint8_t subservice, const uint8_t *tcData, size_t tcDataLen,
|
||||
MessageQueueId_t *id, object_id_t *objectId) {
|
||||
if(tcDataLen < sizeof(object_id_t)) {
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
}
|
||||
SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen,
|
||||
SerializeIF::Endianness::BIG);
|
||||
|
||||
return checkInterfaceAndAcquireMessageQueue(id,objectId);
|
||||
}
|
||||
|
||||
ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue(
|
||||
MessageQueueId_t* messageQueueToSet, object_id_t* objectId) {
|
||||
HasModesIF * destination = objectManager->get<HasModesIF>(*objectId);
|
||||
if(destination == nullptr) {
|
||||
return CommandingServiceBase::INVALID_OBJECT;
|
||||
|
||||
}
|
||||
|
||||
*messageQueueToSet = destination->getCommandQueue();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t CService200ModeCommanding::prepareCommand(
|
||||
CommandMessage* message,uint8_t subservice, const uint8_t *tcData,
|
||||
size_t tcDataLen, uint32_t *state, object_id_t objectId) {
|
||||
ModePacket modeCommandPacket;
|
||||
ReturnValue_t result = modeCommandPacket.deSerialize(&tcData,
|
||||
&tcDataLen, SerializeIF::Endianness::BIG);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ModeMessage::setModeMessage(dynamic_cast<CommandMessage*>(message),
|
||||
ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(),
|
||||
modeCommandPacket.getSubmode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t CService200ModeCommanding::handleReply(
|
||||
const CommandMessage* reply, Command_t previousCommand,
|
||||
uint32_t *state, CommandMessage* optionalNextCommand,
|
||||
object_id_t objectId, bool *isStep) {
|
||||
Command_t replyId = reply->getCommand();
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
||||
switch(replyId) {
|
||||
case(ModeMessage::REPLY_MODE_REPLY): {
|
||||
result = prepareModeReply(reply, objectId);
|
||||
break;
|
||||
}
|
||||
case(ModeMessage::REPLY_WRONG_MODE_REPLY): {
|
||||
result = prepareWrongModeReply(reply, objectId);
|
||||
break;
|
||||
}
|
||||
case(ModeMessage::REPLY_CANT_REACH_MODE): {
|
||||
result = prepareCantReachModeReply(reply, objectId);
|
||||
break;
|
||||
}
|
||||
case(ModeMessage::REPLY_MODE_INFO):
|
||||
result = INVALID_REPLY;
|
||||
break;
|
||||
default:
|
||||
result = RETURN_FAILED;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t CService200ModeCommanding::prepareModeReply(
|
||||
const CommandMessage *reply, object_id_t objectId) {
|
||||
ModePacket modeReplyPacket(objectId,
|
||||
ModeMessage::getMode(reply),
|
||||
ModeMessage::getSubmode(reply));
|
||||
return sendTmPacket(Subservice::REPLY_MODE_REPLY, &modeReplyPacket);
|
||||
}
|
||||
|
||||
ReturnValue_t CService200ModeCommanding::prepareWrongModeReply(
|
||||
const CommandMessage *reply, object_id_t objectId) {
|
||||
ModePacket wrongModeReply(objectId, ModeMessage::getMode(reply),
|
||||
ModeMessage::getSubmode(reply));
|
||||
return sendTmPacket(Subservice::REPLY_WRONG_MODE_REPLY, &wrongModeReply);
|
||||
}
|
||||
|
||||
ReturnValue_t CService200ModeCommanding::prepareCantReachModeReply(
|
||||
const CommandMessage *reply, object_id_t objectId) {
|
||||
CantReachModePacket cantReachModePacket(objectId,
|
||||
ModeMessage::getCantReachModeReason(reply));
|
||||
return sendTmPacket(Subservice::REPLY_CANT_REACH_MODE,
|
||||
&cantReachModePacket);
|
||||
}
|
85
pus/CService200ModeCommanding.h
Normal file
85
pus/CService200ModeCommanding.h
Normal file
@ -0,0 +1,85 @@
|
||||
#ifndef FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_
|
||||
#define FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_
|
||||
|
||||
#include <framework/tmtcservices/CommandingServiceBase.h>
|
||||
|
||||
/**
|
||||
* @brief Custom PUS service to set mode of all objects implementing HasModesIF
|
||||
*
|
||||
* Examples: Device Handlers, Assemblies or Subsystems.
|
||||
* Full Documentation: ECSS-E-ST-70-41C or ECSS-E-70-41A
|
||||
* Dissertation Baetz p. 115, 116, 165-167.
|
||||
*
|
||||
* This is a gateway service. It relays device commands using the software bus.
|
||||
* @ingroup pus_services
|
||||
*/
|
||||
class CService200ModeCommanding: public CommandingServiceBase {
|
||||
public:
|
||||
static constexpr uint8_t NUMBER_OF_PARALLEL_COMMANDS = 4;
|
||||
static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60;
|
||||
|
||||
CService200ModeCommanding(object_id_t objectId,
|
||||
uint16_t apid, uint8_t serviceId);
|
||||
virtual~ CService200ModeCommanding();
|
||||
|
||||
protected:
|
||||
//! CommandingServiceBase (CSB) abstract functions. See CSB documentation.
|
||||
ReturnValue_t isValidSubservice(uint8_t subservice) override;
|
||||
ReturnValue_t getMessageQueueAndObject(uint8_t subservice,
|
||||
const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id,
|
||||
object_id_t *objectId) override;
|
||||
ReturnValue_t prepareCommand(CommandMessage* message,
|
||||
uint8_t subservice, const uint8_t *tcData, size_t tcDataLen,
|
||||
uint32_t *state, object_id_t objectId) override;
|
||||
ReturnValue_t handleReply(const CommandMessage* reply,
|
||||
Command_t previousCommand, uint32_t *state,
|
||||
CommandMessage* optionalNextCommand, object_id_t objectId,
|
||||
bool *isStep) override;
|
||||
|
||||
private:
|
||||
ReturnValue_t checkAndAcquireTargetID(object_id_t* objectIdToSet,
|
||||
const uint8_t* tcData, uint32_t tcDataLen);
|
||||
ReturnValue_t checkInterfaceAndAcquireMessageQueue(
|
||||
MessageQueueId_t* MessageQueueToSet, object_id_t* objectId);
|
||||
|
||||
ReturnValue_t prepareModeReply(const CommandMessage *reply,
|
||||
object_id_t objectId);
|
||||
ReturnValue_t prepareWrongModeReply(const CommandMessage *reply,
|
||||
object_id_t objectId);
|
||||
ReturnValue_t prepareCantReachModeReply(const CommandMessage *reply,
|
||||
object_id_t objectId);
|
||||
|
||||
enum Subservice { //!< [EXPORT] : [COMMENT] Mode Commanding Subservices
|
||||
//!< [EXPORT] : [COMMAND] Command assembly, subsystem or device mode
|
||||
COMMAND_MODE_COMMAND = 1,
|
||||
//!< [EXPORT] : [COMMAND] Command to set the specified Mode,
|
||||
//! regardless of external control flag
|
||||
COMMAND_MODE_COMMAND_FORCED = 2,
|
||||
//!< [EXPORT] : [COMMAND] Read the current mode and
|
||||
//! reply with a REPLY_MODE_REPLY
|
||||
COMMAND_MODE_READ = 3,
|
||||
//!< [EXPORT] : [COMMAND] Trigger an ModeInfo Event.
|
||||
//! This command does NOT have a reply
|
||||
COMMAND_MODE_ANNCOUNCE = 4,
|
||||
//!< [EXPORT] : [COMMAND] Trigger a ModeInfo Event and to send this
|
||||
//! command to every child. This command does NOT have a reply.
|
||||
COMMAND_MODE_ANNOUNCE_RECURSIVELY = 5,
|
||||
//!< [EXPORT] : [REPLY] Reply to a CMD_MODE_COMMAND or CMD_MODE_READ
|
||||
REPLY_MODE_REPLY = 6,
|
||||
//!< [EXPORT] : [REPLY] Reply in case a mode command can't be executed.
|
||||
REPLY_CANT_REACH_MODE = 7,
|
||||
//!< [EXPORT] : [REPLY] Reply to a CMD_MODE_COMMAND, indicating that a
|
||||
//! mode was commanded and a transition started but was aborted,
|
||||
//! the parameters contain the mode that was reached
|
||||
REPLY_WRONG_MODE_REPLY = 8
|
||||
};
|
||||
|
||||
enum modeParameters {
|
||||
MODE_OFF = 0,
|
||||
MODE_ON = 1,
|
||||
MODE_NORMAL = 2,
|
||||
MODE_RAW = 3
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_ */
|
@ -59,8 +59,7 @@ ReturnValue_t Service5EventReporting::generateEventReport(
|
||||
}
|
||||
|
||||
ReturnValue_t Service5EventReporting::handleRequest(uint8_t subservice) {
|
||||
switch(subservice)
|
||||
{
|
||||
switch(subservice) {
|
||||
case Subservice::ENABLE: {
|
||||
enableEventReport = true;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <framework/pus/Service8FunctionManagement.h>
|
||||
#include <framework/pus/servicepackets/Service8Packets.h>
|
||||
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/objectmanager/SystemObjectIF.h>
|
||||
#include <framework/action/HasActionsIF.h>
|
||||
#include <framework/devicehandlers/DeviceHandlerIF.h>
|
||||
@ -54,13 +53,9 @@ ReturnValue_t Service8FunctionManagement::checkInterfaceAndAcquireMessageQueue(
|
||||
ReturnValue_t Service8FunctionManagement::prepareCommand(
|
||||
CommandMessage* message, uint8_t subservice, const uint8_t* tcData,
|
||||
size_t tcDataLen, uint32_t* state, object_id_t objectId) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
||||
if(subservice == static_cast<uint8_t>(Subservice::DIRECT_COMMANDING)) {
|
||||
result = prepareDirectCommand(dynamic_cast<CommandMessage*>(message),
|
||||
return prepareDirectCommand(dynamic_cast<CommandMessage*>(message),
|
||||
tcData, tcDataLen);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t Service8FunctionManagement::prepareDirectCommand(
|
||||
CommandMessage *message, const uint8_t *tcData, size_t tcDataLen) {
|
||||
@ -100,18 +95,7 @@ ReturnValue_t Service8FunctionManagement::handleReply(
|
||||
break;
|
||||
}
|
||||
case ActionMessage::DATA_REPLY: {
|
||||
store_address_t storeId = ActionMessage::getStoreId(reply);
|
||||
size_t size = 0;
|
||||
const uint8_t * buffer = nullptr;
|
||||
result = IPCStore->getData(storeId, &buffer, &size);
|
||||
if(result != RETURN_OK) {
|
||||
sif::error << "Service 8: Could not retrieve data for data reply";
|
||||
return result;
|
||||
}
|
||||
DataReply dataReply(objectId,actionId,buffer,size);
|
||||
sendTmPacket(static_cast<uint8_t>(
|
||||
Subservice::DIRECT_COMMANDING_DATA_REPLY), &dataReply);
|
||||
result = IPCStore ->deleteData(storeId);
|
||||
result = handleDataReply(reply, objectId, actionId);
|
||||
break;
|
||||
}
|
||||
case ActionMessage::STEP_FAILED:
|
||||
@ -126,4 +110,26 @@ ReturnValue_t Service8FunctionManagement::handleReply(
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t Service8FunctionManagement::handleDataReply(
|
||||
const CommandMessage* reply, object_id_t objectId,
|
||||
ActionId_t actionId) {
|
||||
store_address_t storeId = ActionMessage::getStoreId(reply);
|
||||
size_t size = 0;
|
||||
const uint8_t * buffer = nullptr;
|
||||
ReturnValue_t result = IPCStore->getData(storeId, &buffer, &size);
|
||||
if(result != RETURN_OK) {
|
||||
sif::error << "Service 8: Could not retrieve data for data reply"
|
||||
<< std::endl;
|
||||
return result;
|
||||
}
|
||||
DataReply dataReply(objectId, actionId, buffer, size);
|
||||
result = sendTmPacket(static_cast<uint8_t>(
|
||||
Subservice::DIRECT_COMMANDING_DATA_REPLY), &dataReply);
|
||||
|
||||
auto deletionResult = IPCStore->deleteData(storeId);
|
||||
if(deletionResult != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::warning << "Service8FunctionManagement::handleReply: Deletion"
|
||||
<< " of data in pool failed." << std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_
|
||||
#define FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_
|
||||
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/tmtcservices/CommandingServiceBase.h>
|
||||
|
||||
/**
|
||||
@ -59,6 +60,8 @@ private:
|
||||
MessageQueueId_t* messageQueueToSet, object_id_t* objectId);
|
||||
ReturnValue_t prepareDirectCommand(CommandMessage* message,
|
||||
const uint8_t* tcData, size_t tcDataLen);
|
||||
ReturnValue_t handleDataReply(const CommandMessage* reply,
|
||||
object_id_t objectId, ActionId_t actionId);
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ */
|
||||
|
63
pus/servicepackets/Service200Packets.h
Normal file
63
pus/servicepackets/Service200Packets.h
Normal file
@ -0,0 +1,63 @@
|
||||
#ifndef FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_
|
||||
#define FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_
|
||||
|
||||
#include <framework/serialize/SerialLinkedListAdapter.h>
|
||||
#include <framework/modes/ModeMessage.h>
|
||||
#include <framework/serialize/SerializeIF.h>
|
||||
|
||||
/**
|
||||
* @brief Subservice 1, 2, 3, 4, 5
|
||||
* @ingroup spacepackets
|
||||
*/
|
||||
class ModePacket : public SerialLinkedListAdapter<SerializeIF> { //!< [EXPORT] : [SUBSERVICE] 1, 2, 6
|
||||
public:
|
||||
|
||||
ModePacket() {
|
||||
setLinks();
|
||||
}
|
||||
|
||||
ModePacket(object_id_t objectId, Mode_t mode, Submode_t submode) :
|
||||
objectId(objectId), mode(mode), submode(submode) {
|
||||
setLinks();
|
||||
}
|
||||
|
||||
Mode_t getMode() {
|
||||
return mode.entry;
|
||||
}
|
||||
|
||||
Submode_t getSubmode() {
|
||||
return submode.entry;
|
||||
}
|
||||
|
||||
// Forbid copying, pointers are used.
|
||||
ModePacket(const ModePacket&) = delete;
|
||||
ModePacket& operator=(const ModePacket&) = delete;
|
||||
private:
|
||||
|
||||
void setLinks() {
|
||||
setStart(&objectId);
|
||||
objectId.setNext(&mode);
|
||||
mode.setNext(&submode);
|
||||
}
|
||||
SerializeElement<object_id_t> objectId; //!< [EXPORT] : [COMMENT] Target or source object
|
||||
SerializeElement<Mode_t> mode; //!< [EXPORT] : [COMMENT] 0: MODE_OFF, 1: MODE_ON, 2: MODE_NORMAL, 3: MODE_RAW
|
||||
SerializeElement<Submode_t> submode; //!< [EXPORT] : [COMMENT] Usually 0, device specific submode possible
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Subservice 7
|
||||
* @ingroup spacepackets
|
||||
*/
|
||||
class CantReachModePacket: public SerialLinkedListAdapter<SerializeIF> { //!< [EXPORT] : [SUBSERVICE] 7
|
||||
public:
|
||||
CantReachModePacket(object_id_t objectId, ReturnValue_t reason):
|
||||
objectId(objectId), reason(reason) {
|
||||
setStart(&this->objectId);
|
||||
this->objectId.setNext(&this->reason);
|
||||
}
|
||||
|
||||
SerializeElement<object_id_t> objectId; //!< [EXPORT] : [COMMENT] Reply source object
|
||||
SerializeElement<ReturnValue_t> reason; //!< [EXPORT] : [COMMENT] Reason the mode could not be reached
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ */
|
@ -17,10 +17,11 @@ class StorageAccessor: public ConstStorageAccessor {
|
||||
public:
|
||||
StorageAccessor(store_address_t storeId);
|
||||
StorageAccessor(store_address_t storeId, StorageManagerIF* store);
|
||||
|
||||
/**
|
||||
* @brief Move ctor and move assignment allow returning accessors as
|
||||
* a returnvalue. They prevent resource being free prematurely.
|
||||
* Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/
|
||||
* a returnvalue. They prevent resource being freed prematurely.
|
||||
* See: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/
|
||||
* move-constructors-and-move-assignment-operators-cpp.md
|
||||
* @param
|
||||
* @return
|
||||
|
@ -9,8 +9,8 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
//! Don't use these for time points, type is not large enough for UNIX epoch.
|
||||
typedef uint32_t dur_millis_t;
|
||||
typedef double dur_seconds_t;
|
||||
using dur_millis_t = uint32_t;
|
||||
using dur_seconds_t = double;
|
||||
|
||||
class Clock {
|
||||
public:
|
||||
|
@ -34,6 +34,7 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service,
|
||||
size + headerSize + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1);
|
||||
}
|
||||
|
||||
// todo: Endianness flags as optional parameter?
|
||||
TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service,
|
||||
uint8_t subservice, uint8_t packetSubcounter, SerializeIF *content,
|
||||
SerializeIF *header) :
|
||||
|
@ -8,8 +8,8 @@
|
||||
#include <framework/tmtcpacket/pus/TcPacketStored.h>
|
||||
#include <framework/tmtcpacket/pus/TmPacketStored.h>
|
||||
|
||||
object_id_t CommandingServiceBase::packetSource = objects::NO_OBJECT;
|
||||
object_id_t CommandingServiceBase::packetDestination = objects::NO_OBJECT;
|
||||
object_id_t CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;
|
||||
object_id_t CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
||||
|
||||
CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId,
|
||||
uint16_t apid, uint8_t service, uint8_t numberOfParallelCommands,
|
||||
@ -62,10 +62,18 @@ ReturnValue_t CommandingServiceBase::initialize() {
|
||||
return result;
|
||||
}
|
||||
|
||||
if(packetDestination == objects::NO_OBJECT) {
|
||||
packetDestination = defaultPacketDestination;
|
||||
}
|
||||
AcceptsTelemetryIF* packetForwarding =
|
||||
objectManager->get<AcceptsTelemetryIF>(packetDestination);
|
||||
|
||||
if(packetSource == objects::NO_OBJECT) {
|
||||
packetSource = defaultPacketSource;
|
||||
}
|
||||
PUSDistributorIF* distributor = objectManager->get<PUSDistributorIF>(
|
||||
packetSource);
|
||||
|
||||
if (packetForwarding == nullptr or distributor == nullptr) {
|
||||
sif::error << "CommandingServiceBase::intialize: Packet source or "
|
||||
"packet destination invalid!" << std::endl;
|
||||
|
@ -114,16 +114,17 @@ public:
|
||||
* Implementation of ExecutableObjectIF function
|
||||
*
|
||||
* 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);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Check the target subservice
|
||||
* @param subservice[in]
|
||||
* @return -@c RETURN_OK on success
|
||||
* -@c INVALID_SUBSERVICE if service is not known
|
||||
* @return
|
||||
* -@c RETURN_OK Subservice valid, continue message handling
|
||||
* -@c INVALID_SUBSERVICE if service is not known, rejects packet.
|
||||
*/
|
||||
virtual ReturnValue_t isValidSubservice(uint8_t subservice) = 0;
|
||||
|
||||
@ -136,9 +137,10 @@ protected:
|
||||
* @param tcDataLen
|
||||
* @param id MessageQueue ID is stored here
|
||||
* @param objectId Object ID is extracted and stored here
|
||||
* @return - @c RETURN_OK on success
|
||||
* - @c RETURN_FAILED
|
||||
* - @c CSB or implementation specific return codes
|
||||
* @return
|
||||
* - @c RETURN_OK Cotinue message handling
|
||||
* - @c RETURN_FAILED Reject the packet and generates a start failure
|
||||
* verification
|
||||
*/
|
||||
virtual ReturnValue_t getMessageQueueAndObject(uint8_t subservice,
|
||||
const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id,
|
||||
@ -157,6 +159,11 @@ protected:
|
||||
* communication
|
||||
* @param objectId Target object ID
|
||||
* @return
|
||||
* - @c RETURN_OK to generate a verification start message
|
||||
* - @c EXECUTION_COMPELTE Fire-and-forget command. Generate a completion
|
||||
* verification message.
|
||||
* - @c Anything else rejects the packets and generates a start failure
|
||||
* verification.
|
||||
*/
|
||||
virtual ReturnValue_t prepareCommand(CommandMessage* message,
|
||||
uint8_t subservice, const uint8_t *tcData, size_t tcDataLen,
|
||||
@ -181,7 +188,7 @@ protected:
|
||||
* @return
|
||||
* - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to
|
||||
* generate TC verification success
|
||||
* - @c INVALID_REPLY calls handleUnrequestedReply
|
||||
* - @c INVALID_REPLY Calls handleUnrequestedReply
|
||||
* - Anything else triggers a TC verification failure. If RETURN_FAILED
|
||||
* is returned and the command ID is CommandMessage::REPLY_REJECTED,
|
||||
* a failure verification message with the reason as the error parameter
|
||||
@ -248,8 +255,10 @@ protected:
|
||||
uint32_t failureParameter1 = 0;
|
||||
uint32_t failureParameter2 = 0;
|
||||
|
||||
static object_id_t packetSource;
|
||||
static object_id_t packetDestination;
|
||||
static object_id_t defaultPacketSource;
|
||||
object_id_t packetSource = objects::NO_OBJECT;
|
||||
static object_id_t defaultPacketDestination;
|
||||
object_id_t packetDestination = objects::NO_OBJECT;
|
||||
|
||||
/**
|
||||
* Pointer to the task which executes this component,
|
||||
|
@ -24,8 +24,9 @@ ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle(
|
||||
return RETURN_OK;
|
||||
}
|
||||
else {
|
||||
sif::warning << "TmTcBridge: Number of packets sent per cycle "
|
||||
"exceeds limits. Keeping default value." << std::endl;
|
||||
sif::warning << "TmTcBridge::setNumberOfSentPacketsPerCycle: Number of "
|
||||
<< "packets sent per cycle exceeds limits. "
|
||||
<< "Keeping default value." << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
@ -37,8 +38,9 @@ ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(
|
||||
return RETURN_OK;
|
||||
}
|
||||
else {
|
||||
sif::warning << "TmTcBridge: Number of packets stored "
|
||||
"exceeds limits. Keeping default value." << std::endl;
|
||||
sif::warning << "TmTcBridge::setMaxNumberOfPacketsStored: Number of "
|
||||
<< "packets stored exceeds limits. "
|
||||
<< "Keeping default value." << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
@ -72,11 +74,13 @@ ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) {
|
||||
ReturnValue_t result;
|
||||
result = handleTc();
|
||||
if(result != RETURN_OK) {
|
||||
sif::error << "TMTC Bridge: Error handling TCs" << std::endl;
|
||||
sif::debug << "TmTcBridge::performOperation: "
|
||||
<< "Error handling TCs" << std::endl;
|
||||
}
|
||||
result = handleTm();
|
||||
if (result != RETURN_OK) {
|
||||
sif::error << "TMTC Bridge: Error handling TMs" << std::endl;
|
||||
sif::debug << "TmTcBridge::performOperation: "
|
||||
<< "Error handling TMs" << std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -88,7 +92,7 @@ ReturnValue_t TmTcBridge::handleTc() {
|
||||
ReturnValue_t TmTcBridge::handleTm() {
|
||||
ReturnValue_t result = handleTmQueue();
|
||||
if(result != RETURN_OK) {
|
||||
sif::error << "TMTC Bridge: Reading TM Queue failed" << std::endl;
|
||||
sif::warning << "TmTcBridge: Reading TM Queue failed" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
@ -118,7 +122,7 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
|
||||
|
||||
result = sendTm(data, size);
|
||||
if (result != RETURN_OK) {
|
||||
sif::error << "TMTC Bridge: Could not send TM packet"<< std::endl;
|
||||
sif::warning << "TmTcBridge: Could not send TM packet" << std::endl;
|
||||
tmStore->deleteData(message.getStorageId());
|
||||
return result;
|
||||
|
||||
@ -129,13 +133,12 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
|
||||
}
|
||||
|
||||
ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) {
|
||||
//debug << "TMTC Bridge: Comm Link down. "
|
||||
// "Saving packet ID to be sent later\r\n" << std::flush;
|
||||
store_address_t storeId = 0;
|
||||
|
||||
if(tmFifo.full()) {
|
||||
sif::error << "TMTC Bridge: TM downlink max. number of stored packet IDs "
|
||||
"reached! Overwriting old data" << std::endl;
|
||||
sif::error << "TmTcBridge::storeDownlinkData: TM downlink max. number "
|
||||
<< "of stored packet IDs reached! "
|
||||
<< "Overwriting old data" << std::endl;
|
||||
tmFifo.retrieve(&storeId);
|
||||
tmStore->deleteData(storeId);
|
||||
}
|
||||
|
@ -76,13 +76,14 @@ protected:
|
||||
object_id_t tcDestination = objects::NO_OBJECT;
|
||||
|
||||
//! Used to send and receive TMTC messages.
|
||||
//! TmTcMessage is used to transport messages between tasks.
|
||||
//! The TmTcMessage class is used to transport messages between tasks.
|
||||
MessageQueueIF* tmTcReceptionQueue = nullptr;
|
||||
|
||||
StorageManagerIF* tmStore = nullptr;
|
||||
StorageManagerIF* tcStore = nullptr;
|
||||
|
||||
//! Used to specify whether communication link is up by default.
|
||||
//! Used to specify whether communication link is up. Will be true
|
||||
//! by default, so telemetry will be handled immediately.
|
||||
bool communicationLinkUp = true;
|
||||
bool tmStored = false;
|
||||
|
||||
@ -103,7 +104,8 @@ protected:
|
||||
virtual ReturnValue_t handleTm();
|
||||
|
||||
/**
|
||||
* Read the TM Queue and send TM if necessary. Default implementation provided
|
||||
* Read the TM Queue and send TM if necessary.
|
||||
* Default implementation provided
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t handleTmQueue();
|
||||
@ -116,7 +118,8 @@ protected:
|
||||
|
||||
/**
|
||||
* Implemented by child class. Perform sending of Telemetry by implementing
|
||||
* communication drivers or wrappers, e.g. UART communication or lwIP stack.
|
||||
* communication drivers or wrappers, e.g. serial communication or a socket
|
||||
* call.
|
||||
* @param data
|
||||
* @param dataLen
|
||||
* @return
|
||||
|
Loading…
Reference in New Issue
Block a user