Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
This commit is contained in:
commit
296bc56e2a
12
CHANGELOG.md
12
CHANGELOG.md
@ -24,14 +24,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
- DHB TM handler `handleDeviceTM` renamed to `handleDeviceTm` and now takes
|
|
||||||
`util::DataWrapper` as the data input argument. This allows more flexibility in the possible
|
|
||||||
types of telemetry.
|
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/669
|
|
||||||
- Add `util::DataWrapper` class inside the `util` module. This is a tagged union which allows
|
|
||||||
to specify raw data either as a classic C-style raw pointer and size or as a `SerializeIF`
|
|
||||||
pointer.
|
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/668
|
|
||||||
- Add new `UnsignedByteField` class
|
- Add new `UnsignedByteField` class
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/660
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/660
|
||||||
|
|
||||||
@ -65,6 +57,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
- `DeviceHandlerBase`: New signature of `handleDeviceTm` which expects
|
- `DeviceHandlerBase`: New signature of `handleDeviceTm` which expects
|
||||||
a `const SerializeIF&` and additional helper variant which expects `const uint8_t*`
|
a `const SerializeIF&` and additional helper variant which expects `const uint8_t*`
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/671
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/671
|
||||||
|
- Move some generic `StorageManagerIF` implementations from `LocalPool` to
|
||||||
|
interface itself so it can be re-used more easily. Also add new
|
||||||
|
abstract function `bool hasDataAtId(store_address_t storeId) const`.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/685
|
||||||
- Improvements for `AcceptsTelemetryIF` and `AcceptsTelecommandsIF`:
|
- Improvements for `AcceptsTelemetryIF` and `AcceptsTelecommandsIF`:
|
||||||
- Make functions `const` where it makes sense
|
- Make functions `const` where it makes sense
|
||||||
- Add `const char* getName const` abstract function
|
- Add `const char* getName const` abstract function
|
||||||
|
@ -140,7 +140,7 @@ find_program( GCOV_PATH gcov )
|
|||||||
find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl)
|
find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl)
|
||||||
find_program( FASTCOV_PATH NAMES fastcov fastcov.py )
|
find_program( FASTCOV_PATH NAMES fastcov fastcov.py )
|
||||||
find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat )
|
find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat )
|
||||||
find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
|
find_program( GCOVR_PATH gcovr )
|
||||||
find_program( CPPFILT_PATH NAMES c++filt )
|
find_program( CPPFILT_PATH NAMES c++filt )
|
||||||
|
|
||||||
if(NOT GCOV_PATH)
|
if(NOT GCOV_PATH)
|
||||||
|
@ -28,9 +28,11 @@ class FixedArrayList : public ArrayList<T, count_t> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FixedArrayList& operator=(FixedArrayList other) {
|
FixedArrayList& operator=(FixedArrayList other) {
|
||||||
memcpy(this->data, other.data, sizeof(this->data));
|
|
||||||
this->entries = data;
|
this->entries = data;
|
||||||
this->size = other.size;
|
this->size = other.size;
|
||||||
|
for (size_t idx = 0; idx < this->size; idx++) {
|
||||||
|
data[idx] = other.data[idx];
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,6 +361,8 @@ void DeviceHandlerBase::doStateMachine() {
|
|||||||
if ((switchState == PowerSwitchIF::SWITCH_ON) || (switchState == NO_SWITCH)) {
|
if ((switchState == PowerSwitchIF::SWITCH_ON) || (switchState == NO_SWITCH)) {
|
||||||
// NOTE: TransitionSourceMode and -SubMode are set by handleCommandedModeTransition
|
// NOTE: TransitionSourceMode and -SubMode are set by handleCommandedModeTransition
|
||||||
childTransitionFailure = CHILD_TIMEOUT;
|
childTransitionFailure = CHILD_TIMEOUT;
|
||||||
|
transitionSourceMode = _MODE_SHUT_DOWN;
|
||||||
|
transitionSourceSubMode = SUBMODE_NONE;
|
||||||
setMode(_MODE_START_UP);
|
setMode(_MODE_START_UP);
|
||||||
callChildStatemachine();
|
callChildStatemachine();
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
|
#include "fsfw/subsystem/ModeTreeConnectionIF.h"
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
#include "fsfw/tasks/PeriodicTaskIF.h"
|
#include "fsfw/tasks/PeriodicTaskIF.h"
|
||||||
#include "fsfw/util/dataWrapper.h"
|
|
||||||
|
|
||||||
namespace Factory {
|
namespace Factory {
|
||||||
void setStaticFrameworkObjectIds();
|
void setStaticFrameworkObjectIds();
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "fsfw/action/HasActionsIF.h"
|
#include "fsfw/action/HasActionsIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||||
#include "fsfw/serialize/SerializeIF.h"
|
#include "fsfw/serialize/SerializeIF.h"
|
||||||
#include "fsfw/util/dataWrapper.h"
|
|
||||||
|
|
||||||
class DeviceTmReportingWrapper : public SerializeIF {
|
class DeviceTmReportingWrapper : public SerializeIF {
|
||||||
public:
|
public:
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include "fsfw/globalfunctions/timevalOperations.h"
|
#include "fsfw/globalfunctions/timevalOperations.h"
|
||||||
|
|
||||||
timeval& operator+=(timeval& lhs, const timeval& rhs) {
|
timeval& operator+=(timeval& lhs, const timeval& rhs) {
|
||||||
int64_t sum = lhs.tv_sec * 1000000. + lhs.tv_usec;
|
int64_t sum = static_cast<int64_t>(lhs.tv_sec) * 1000000. + lhs.tv_usec;
|
||||||
sum += rhs.tv_sec * 1000000. + rhs.tv_usec;
|
sum += static_cast<int64_t>(rhs.tv_sec) * 1000000. + rhs.tv_usec;
|
||||||
lhs.tv_sec = sum / 1000000;
|
lhs.tv_sec = sum / 1000000;
|
||||||
lhs.tv_usec = sum - lhs.tv_sec * 1000000;
|
lhs.tv_usec = sum - lhs.tv_sec * 1000000;
|
||||||
return lhs;
|
return lhs;
|
||||||
|
@ -31,9 +31,8 @@ LocalPool::LocalPool(object_id_t setObjectId, const LocalPoolConfig& poolConfig,
|
|||||||
|
|
||||||
LocalPool::~LocalPool() = default;
|
LocalPool::~LocalPool() = default;
|
||||||
|
|
||||||
ReturnValue_t LocalPool::addData(store_address_t* storageId, const uint8_t* data, size_t size,
|
ReturnValue_t LocalPool::addData(store_address_t* storageId, const uint8_t* data, size_t size) {
|
||||||
bool ignoreFault) {
|
ReturnValue_t status = reserveSpace(size, storageId);
|
||||||
ReturnValue_t status = reserveSpace(size, storageId, ignoreFault);
|
|
||||||
if (status == returnvalue::OK) {
|
if (status == returnvalue::OK) {
|
||||||
write(*storageId, data, size);
|
write(*storageId, data, size);
|
||||||
}
|
}
|
||||||
@ -49,8 +48,8 @@ ReturnValue_t LocalPool::getData(store_address_t packetId, const uint8_t** packe
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPool::getFreeElement(store_address_t* storageId, const size_t size,
|
ReturnValue_t LocalPool::getFreeElement(store_address_t* storageId, const size_t size,
|
||||||
uint8_t** pData, bool ignoreFault) {
|
uint8_t** pData) {
|
||||||
ReturnValue_t status = reserveSpace(size, storageId, ignoreFault);
|
ReturnValue_t status = reserveSpace(size, storageId);
|
||||||
if (status == returnvalue::OK) {
|
if (status == returnvalue::OK) {
|
||||||
*pData = &store[storageId->poolIndex][getRawPosition(*storageId)];
|
*pData = &store[storageId->poolIndex][getRawPosition(*storageId)];
|
||||||
} else {
|
} else {
|
||||||
@ -167,7 +166,7 @@ void LocalPool::clearStore() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPool::reserveSpace(size_t size, store_address_t* storeId, bool ignoreFault) {
|
ReturnValue_t LocalPool::reserveSpace(size_t size, store_address_t* storeId) {
|
||||||
ReturnValue_t status = getSubPoolIndex(size, &storeId->poolIndex);
|
ReturnValue_t status = getSubPoolIndex(size, &storeId->poolIndex);
|
||||||
if (status != returnvalue::OK) {
|
if (status != returnvalue::OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
@ -318,27 +317,3 @@ bool LocalPool::hasDataAtId(store_address_t storeId) const {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPool::getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData) {
|
|
||||||
return StorageManagerIF::getFreeElement(storeId, size, pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstAccessorPair LocalPool::getData(store_address_t storeId) {
|
|
||||||
return StorageManagerIF::getData(storeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPool::addData(store_address_t* storeId, const uint8_t* data, size_t size) {
|
|
||||||
return StorageManagerIF::addData(storeId, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPool::getData(store_address_t storeId, ConstStorageAccessor& accessor) {
|
|
||||||
return StorageManagerIF::getData(storeId, accessor);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPool::modifyData(store_address_t storeId, StorageAccessor& accessor) {
|
|
||||||
return StorageManagerIF::modifyData(storeId, accessor);
|
|
||||||
}
|
|
||||||
|
|
||||||
AccessorPair LocalPool::modifyData(store_address_t storeId) {
|
|
||||||
return StorageManagerIF::modifyData(storeId);
|
|
||||||
}
|
|
||||||
|
@ -86,21 +86,13 @@ class LocalPool : public SystemObject, public StorageManagerIF {
|
|||||||
/**
|
/**
|
||||||
* Documentation: See StorageManagerIF.h
|
* Documentation: See StorageManagerIF.h
|
||||||
*/
|
*/
|
||||||
ReturnValue_t addData(store_address_t* storeId, const uint8_t* data, size_t size,
|
|
||||||
bool ignoreFault) override;
|
|
||||||
ReturnValue_t addData(store_address_t* storeId, const uint8_t* data, size_t size) override;
|
ReturnValue_t addData(store_address_t* storeId, const uint8_t* data, size_t size) override;
|
||||||
|
|
||||||
ReturnValue_t getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData) override;
|
ReturnValue_t getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData) override;
|
||||||
ReturnValue_t getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData,
|
|
||||||
bool ignoreFault) override;
|
|
||||||
|
|
||||||
ConstAccessorPair getData(store_address_t storeId) override;
|
|
||||||
ReturnValue_t getData(store_address_t storeId, ConstStorageAccessor& accessor) override;
|
|
||||||
ReturnValue_t getData(store_address_t storeId, const uint8_t** packet_ptr, size_t* size) override;
|
ReturnValue_t getData(store_address_t storeId, const uint8_t** packet_ptr, size_t* size) override;
|
||||||
|
|
||||||
AccessorPair modifyData(store_address_t storeId) override;
|
|
||||||
ReturnValue_t modifyData(store_address_t storeId, uint8_t** packet_ptr, size_t* size) override;
|
ReturnValue_t modifyData(store_address_t storeId, uint8_t** packet_ptr, size_t* size) override;
|
||||||
ReturnValue_t modifyData(store_address_t storeId, StorageAccessor& accessor) override;
|
|
||||||
|
|
||||||
ReturnValue_t deleteData(store_address_t storeId) override;
|
ReturnValue_t deleteData(store_address_t storeId) override;
|
||||||
ReturnValue_t deleteData(uint8_t* ptr, size_t size, store_address_t* storeId) override;
|
ReturnValue_t deleteData(uint8_t* ptr, size_t size, store_address_t* storeId) override;
|
||||||
@ -136,6 +128,12 @@ class LocalPool : public SystemObject, public StorageManagerIF {
|
|||||||
[[nodiscard]] max_subpools_t getNumberOfSubPools() const override;
|
[[nodiscard]] max_subpools_t getNumberOfSubPools() const override;
|
||||||
[[nodiscard]] bool hasDataAtId(store_address_t storeId) const override;
|
[[nodiscard]] bool hasDataAtId(store_address_t storeId) const override;
|
||||||
|
|
||||||
|
// Using functions provided by StorageManagerIF requires either a fully qualified path
|
||||||
|
// like for example localPool.StorageManagerIF::getFreeElement(...) or re-exporting
|
||||||
|
// the fully qualified path with the using directive.
|
||||||
|
using StorageManagerIF::getData;
|
||||||
|
using StorageManagerIF::modifyData;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* With this helper method, a free element of @c size is reserved.
|
* With this helper method, a free element of @c size is reserved.
|
||||||
@ -144,7 +142,7 @@ class LocalPool : public SystemObject, public StorageManagerIF {
|
|||||||
* @return - returnvalue::OK on success,
|
* @return - returnvalue::OK on success,
|
||||||
* - the return codes of #getPoolIndex or #findEmpty otherwise.
|
* - the return codes of #getPoolIndex or #findEmpty otherwise.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t reserveSpace(size_t size, store_address_t* address, bool ignoreFault);
|
virtual ReturnValue_t reserveSpace(size_t size, store_address_t* address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@ -188,6 +186,8 @@ class LocalPool : public SystemObject, public StorageManagerIF {
|
|||||||
std::vector<std::vector<size_type>> sizeLists =
|
std::vector<std::vector<size_type>> sizeLists =
|
||||||
std::vector<std::vector<size_type>>(NUMBER_OF_SUBPOOLS);
|
std::vector<std::vector<size_type>>(NUMBER_OF_SUBPOOLS);
|
||||||
|
|
||||||
|
bool ignoreFault = false;
|
||||||
|
|
||||||
//! A variable to determine whether higher n pools are used if
|
//! A variable to determine whether higher n pools are used if
|
||||||
//! the store is full.
|
//! the store is full.
|
||||||
bool spillsToHigherPools = false;
|
bool spillsToHigherPools = false;
|
||||||
|
@ -9,10 +9,9 @@ PoolManager::PoolManager(object_id_t setObjectId, const LocalPoolConfig& localPo
|
|||||||
|
|
||||||
PoolManager::~PoolManager() { MutexFactory::instance()->deleteMutex(mutex); }
|
PoolManager::~PoolManager() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||||
|
|
||||||
ReturnValue_t PoolManager::reserveSpace(const size_t size, store_address_t* address,
|
ReturnValue_t PoolManager::reserveSpace(const size_t size, store_address_t* address) {
|
||||||
bool ignoreFault) {
|
|
||||||
MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeoutMs);
|
MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeoutMs);
|
||||||
ReturnValue_t status = LocalPool::reserveSpace(size, address, ignoreFault);
|
ReturnValue_t status = LocalPool::reserveSpace(size, address);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class PoolManager : public LocalPool {
|
|||||||
//! Default mutex timeout value to prevent permanent blocking.
|
//! Default mutex timeout value to prevent permanent blocking.
|
||||||
uint32_t mutexTimeoutMs = 20;
|
uint32_t mutexTimeoutMs = 20;
|
||||||
|
|
||||||
ReturnValue_t reserveSpace(size_t size, store_address_t* address, bool ignoreFault) override;
|
ReturnValue_t reserveSpace(size_t size, store_address_t* address) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The mutex is created in the constructor and makes
|
* @brief The mutex is created in the constructor and makes
|
||||||
|
@ -55,7 +55,7 @@ class StorageManagerIF {
|
|||||||
/**
|
/**
|
||||||
* @brief This is the empty virtual destructor as required for C++ interfaces.
|
* @brief This is the empty virtual destructor as required for C++ interfaces.
|
||||||
*/
|
*/
|
||||||
~StorageManagerIF() = default;
|
virtual ~StorageManagerIF() = default;
|
||||||
/**
|
/**
|
||||||
* @brief With addData, a free storage position is allocated and data
|
* @brief With addData, a free storage position is allocated and data
|
||||||
* stored there.
|
* stored there.
|
||||||
@ -66,12 +66,7 @@ class StorageManagerIF {
|
|||||||
* @return Returns @returnvalue::OK if data was added.
|
* @return Returns @returnvalue::OK if data was added.
|
||||||
* @returnvalue::FAILED if data could not be added, storageId is unchanged then.
|
* @returnvalue::FAILED if data could not be added, storageId is unchanged then.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t* data, size_t size,
|
virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t* data, size_t size) = 0;
|
||||||
bool ignoreFault) = 0;
|
|
||||||
|
|
||||||
virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t* data, size_t size) {
|
|
||||||
return addData(storageId, data, size, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief With deleteData, the storageManager frees the memory region
|
* @brief With deleteData, the storageManager frees the memory region
|
||||||
@ -186,12 +181,8 @@ class StorageManagerIF {
|
|||||||
* @return Returns @returnvalue::OK if data was added.
|
* @return Returns @returnvalue::OK if data was added.
|
||||||
* @returnvalue::FAILED if data could not be added, storageId is unchanged then.
|
* @returnvalue::FAILED if data could not be added, storageId is unchanged then.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t getFreeElement(store_address_t* storageId, size_t size, uint8_t** dataPtr,
|
virtual ReturnValue_t getFreeElement(store_address_t* storageId, size_t size,
|
||||||
bool ignoreFault) = 0;
|
uint8_t** dataPtr) = 0;
|
||||||
|
|
||||||
virtual ReturnValue_t getFreeElement(store_address_t* storageId, size_t size, uint8_t** dataPtr) {
|
|
||||||
return getFreeElement(storageId, size, dataPtr, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] virtual bool hasDataAtId(store_address_t storeId) const = 0;
|
[[nodiscard]] virtual bool hasDataAtId(store_address_t storeId) const = 0;
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage* message) {
|
|||||||
"TmTcBridge::storeDownlinkData: TM downlink max. number "
|
"TmTcBridge::storeDownlinkData: TM downlink max. number "
|
||||||
"of stored packet IDs reached!\n");
|
"of stored packet IDs reached!\n");
|
||||||
#endif
|
#endif
|
||||||
warningSwitch = true;
|
warningSwitch = false;
|
||||||
}
|
}
|
||||||
if (overwriteOld) {
|
if (overwriteOld) {
|
||||||
tmFifo->retrieve(&storeId);
|
tmFifo->retrieve(&storeId);
|
||||||
@ -226,6 +226,7 @@ ReturnValue_t TmTcBridge::handleStoredTm() {
|
|||||||
packetSentCounter++;
|
packetSentCounter++;
|
||||||
|
|
||||||
if (tmFifo->empty()) {
|
if (tmFifo->empty()) {
|
||||||
|
warningSwitch = true;
|
||||||
tmStored = false;
|
tmStored = false;
|
||||||
}
|
}
|
||||||
tmStore->deleteData(storeId);
|
tmStore->deleteData(storeId);
|
||||||
|
@ -72,8 +72,6 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
MessageQueueId_t getRequestQueue() const override;
|
MessageQueueId_t getRequestQueue() const override;
|
||||||
const char* getName() const override;
|
const char* getName() const override;
|
||||||
|
|
||||||
bool warningSwitch = true;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const char* name = "";
|
const char* name = "";
|
||||||
|
|
||||||
@ -93,6 +91,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
//! by default, so telemetry will be handled immediately.
|
//! by default, so telemetry will be handled immediately.
|
||||||
bool communicationLinkUp = true;
|
bool communicationLinkUp = true;
|
||||||
bool tmStored = false;
|
bool tmStored = false;
|
||||||
|
bool warningSwitch = true;
|
||||||
bool overwriteOld = true;
|
bool overwriteOld = true;
|
||||||
uint8_t packetSentCounter = 0;
|
uint8_t packetSentCounter = 0;
|
||||||
|
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
#ifndef FSFW_UTIL_DATAWRAPPER_H
|
|
||||||
#define FSFW_UTIL_DATAWRAPPER_H
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "fsfw/serialize.h"
|
|
||||||
|
|
||||||
namespace util {
|
|
||||||
|
|
||||||
using BufPair = std::pair<const uint8_t*, size_t>;
|
|
||||||
|
|
||||||
struct RawData {
|
|
||||||
RawData() = default;
|
|
||||||
const uint8_t* data = nullptr;
|
|
||||||
size_t len = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DataTypes { NONE, RAW, SERIALIZABLE };
|
|
||||||
|
|
||||||
union DataUnion {
|
|
||||||
RawData raw{};
|
|
||||||
SerializeIF* serializable;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DataWrapper {
|
|
||||||
DataWrapper() = default;
|
|
||||||
|
|
||||||
DataWrapper(const uint8_t* data, size_t size) : type(DataTypes::RAW) { setRawData({data, size}); }
|
|
||||||
|
|
||||||
explicit DataWrapper(BufPair raw) : type(DataTypes::RAW) { setRawData(raw); }
|
|
||||||
|
|
||||||
explicit DataWrapper(SerializeIF& serializable) : type(DataTypes::SERIALIZABLE) {
|
|
||||||
setSerializable(serializable);
|
|
||||||
}
|
|
||||||
|
|
||||||
DataTypes type = DataTypes::NONE;
|
|
||||||
DataUnion dataUnion;
|
|
||||||
|
|
||||||
[[nodiscard]] size_t getLength() const {
|
|
||||||
if (type == DataTypes::RAW) {
|
|
||||||
return dataUnion.raw.len;
|
|
||||||
} else if (type == DataTypes::SERIALIZABLE and dataUnion.serializable != nullptr) {
|
|
||||||
return dataUnion.serializable->getSerializedSize();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool isNull() const {
|
|
||||||
if ((type == DataTypes::NONE) or (type == DataTypes::RAW and dataUnion.raw.data == nullptr) or
|
|
||||||
(type == DataTypes::SERIALIZABLE and dataUnion.serializable == nullptr)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRawData(BufPair bufPair) {
|
|
||||||
type = DataTypes::RAW;
|
|
||||||
dataUnion.raw.data = bufPair.first;
|
|
||||||
dataUnion.raw.len = bufPair.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSerializable(SerializeIF& serializable) {
|
|
||||||
type = DataTypes::SERIALIZABLE;
|
|
||||||
dataUnion.serializable = &serializable;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace util
|
|
||||||
|
|
||||||
#endif // FSFW_UTIL_DATAWRAPPER_H
|
|
@ -56,61 +56,65 @@ TEST_CASE("TimevalTest", "[timevalOperations]") {
|
|||||||
}
|
}
|
||||||
SECTION("Operators") {
|
SECTION("Operators") {
|
||||||
timeval t1;
|
timeval t1;
|
||||||
t1.tv_sec = 1648227422;
|
if (sizeof(t1.tv_sec) == 8) {
|
||||||
t1.tv_usec = 123456;
|
t1.tv_sec = 1648227422;
|
||||||
timeval t2;
|
t1.tv_usec = 123456;
|
||||||
t2.tv_sec = 1648227422;
|
timeval t2;
|
||||||
t2.tv_usec = 123456;
|
t2.tv_sec = 1648227422;
|
||||||
timeval t3 = t1 - t2;
|
t2.tv_usec = 123456;
|
||||||
REQUIRE(t3.tv_sec == 0);
|
timeval t3 = t1 - t2;
|
||||||
REQUIRE(t3.tv_usec == 0);
|
REQUIRE(t3.tv_sec == 0);
|
||||||
timeval t4 = t1 - t3;
|
REQUIRE(t3.tv_usec == 0);
|
||||||
REQUIRE(t4.tv_sec == 1648227422);
|
timeval t4 = t1 - t3;
|
||||||
REQUIRE(t4.tv_usec == 123456);
|
REQUIRE(t4.tv_sec == 1648227422);
|
||||||
timeval t5 = t3 - t1;
|
REQUIRE(t4.tv_usec == 123456);
|
||||||
REQUIRE(t5.tv_sec == -1648227422);
|
timeval t5 = t3 - t1;
|
||||||
REQUIRE(t5.tv_usec == -123456);
|
REQUIRE(t5.tv_sec == -1648227422);
|
||||||
|
REQUIRE(t5.tv_usec == -123456);
|
||||||
|
|
||||||
timeval t6;
|
timeval t6;
|
||||||
t6.tv_sec = 1648227400;
|
t6.tv_sec = 1648227400;
|
||||||
t6.tv_usec = 999999;
|
t6.tv_usec = 999999;
|
||||||
|
|
||||||
timeval t7 = t6 + t1;
|
timeval t7 = t6 + t1;
|
||||||
REQUIRE(t7.tv_sec == (1648227422ull + 1648227400ull + 1ull));
|
// Overflow test
|
||||||
REQUIRE(t7.tv_usec == 123455);
|
REQUIRE(t7.tv_sec == (1648227422ull + 1648227400ull + 1ull));
|
||||||
|
|
||||||
timeval t8 = t1 - t6;
|
REQUIRE(t7.tv_usec == 123455);
|
||||||
REQUIRE(t8.tv_sec == 1648227422 - 1648227400 - 1);
|
|
||||||
REQUIRE(t8.tv_usec == 123457);
|
|
||||||
|
|
||||||
double scalar = 2;
|
timeval t8 = t1 - t6;
|
||||||
timeval t9 = t1 * scalar;
|
REQUIRE(t8.tv_sec == 1648227422 - 1648227400 - 1);
|
||||||
REQUIRE(t9.tv_sec == 3296454844);
|
REQUIRE(t8.tv_usec == 123457);
|
||||||
REQUIRE(t9.tv_usec == 246912);
|
|
||||||
timeval t10 = scalar * t1;
|
|
||||||
REQUIRE(t10.tv_sec == 3296454844);
|
|
||||||
REQUIRE(t10.tv_usec == 246912);
|
|
||||||
timeval t11 = t6 * scalar;
|
|
||||||
REQUIRE(t11.tv_sec == (3296454800 + 1));
|
|
||||||
REQUIRE(t11.tv_usec == 999998);
|
|
||||||
|
|
||||||
timeval t12 = t1 / scalar;
|
double scalar = 2;
|
||||||
REQUIRE(t12.tv_sec == 824113711);
|
timeval t9 = t1 * scalar;
|
||||||
REQUIRE(t12.tv_usec == 61728);
|
REQUIRE(t9.tv_sec == 3296454844);
|
||||||
|
REQUIRE(t9.tv_usec == 246912);
|
||||||
|
timeval t10 = scalar * t1;
|
||||||
|
REQUIRE(t10.tv_sec == 3296454844);
|
||||||
|
REQUIRE(t10.tv_usec == 246912);
|
||||||
|
timeval t11 = t6 * scalar;
|
||||||
|
REQUIRE(t11.tv_sec == (3296454800 + 1));
|
||||||
|
REQUIRE(t11.tv_usec == 999998);
|
||||||
|
|
||||||
timeval t13 = t6 / scalar;
|
timeval t12 = t1 / scalar;
|
||||||
REQUIRE(t13.tv_sec == 824113700);
|
REQUIRE(t12.tv_sec == 824113711);
|
||||||
// Rounding issue
|
REQUIRE(t12.tv_usec == 61728);
|
||||||
REQUIRE(t13.tv_usec == 499999);
|
|
||||||
|
|
||||||
double scalar2 = t9 / t1;
|
timeval t13 = t6 / scalar;
|
||||||
REQUIRE(scalar2 == Catch::Approx(2.0));
|
REQUIRE(t13.tv_sec == 824113700);
|
||||||
double scalar3 = t1 / t6;
|
// Rounding issue
|
||||||
REQUIRE(scalar3 == Catch::Approx(1.000000013));
|
REQUIRE(t13.tv_usec == 499999);
|
||||||
double scalar4 = t3 / t1;
|
|
||||||
REQUIRE(scalar4 == Catch::Approx(0));
|
double scalar2 = t9 / t1;
|
||||||
double scalar5 = t12 / t1;
|
REQUIRE(scalar2 == Catch::Approx(2.0));
|
||||||
REQUIRE(scalar5 == Catch::Approx(0.5));
|
double scalar3 = t1 / t6;
|
||||||
|
REQUIRE(scalar3 == Catch::Approx(1.000000013));
|
||||||
|
double scalar4 = t3 / t1;
|
||||||
|
REQUIRE(scalar4 == Catch::Approx(0));
|
||||||
|
double scalar5 = t12 / t1;
|
||||||
|
REQUIRE(scalar5 == Catch::Approx(0.5));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("timevalOperations::toTimeval") {
|
SECTION("timevalOperations::toTimeval") {
|
||||||
|
@ -1,2 +1,5 @@
|
|||||||
target_sources(${FSFW_TEST_TGT} PRIVATE testCommandExecutor.cpp
|
target_sources(${FSFW_TEST_TGT} PRIVATE testHostFilesystem.cpp testFsMock.cpp)
|
||||||
testHostFilesystem.cpp testFsMock.cpp)
|
|
||||||
|
if(UNIX)
|
||||||
|
target_sources(${FSFW_TEST_TGT} PRIVATE testCommandExecutor.cpp)
|
||||||
|
endif()
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#include "StorageManagerMock.h"
|
#include "StorageManagerMock.h"
|
||||||
|
|
||||||
ReturnValue_t StorageManagerMock::addData(store_address_t *storageId, const uint8_t *data,
|
ReturnValue_t StorageManagerMock::addData(store_address_t *storageId, const uint8_t *data,
|
||||||
size_t size, bool ignoreFault) {
|
size_t size) {
|
||||||
if (nextAddDataCallFails.first) {
|
if (nextAddDataCallFails.first) {
|
||||||
return nextAddDataCallFails.second;
|
return nextAddDataCallFails.second;
|
||||||
}
|
}
|
||||||
return LocalPool::addData(storageId, data, size, ignoreFault);
|
return LocalPool::addData(storageId, data, size);
|
||||||
}
|
}
|
||||||
ReturnValue_t StorageManagerMock::deleteData(store_address_t packet_id) {
|
ReturnValue_t StorageManagerMock::deleteData(store_address_t packet_id) {
|
||||||
if (nextDeleteDataCallFails.first) {
|
if (nextDeleteDataCallFails.first) {
|
||||||
@ -36,11 +36,11 @@ ReturnValue_t StorageManagerMock::modifyData(store_address_t packet_id, uint8_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t StorageManagerMock::getFreeElement(store_address_t *storageId, size_t size,
|
ReturnValue_t StorageManagerMock::getFreeElement(store_address_t *storageId, size_t size,
|
||||||
uint8_t **p_data, bool ignoreFault) {
|
uint8_t **p_data) {
|
||||||
if (nextFreeElementCallFails.first) {
|
if (nextFreeElementCallFails.first) {
|
||||||
return nextFreeElementCallFails.second;
|
return nextFreeElementCallFails.second;
|
||||||
}
|
}
|
||||||
return LocalPool::getFreeElement(storageId, size, p_data, ignoreFault);
|
return LocalPool::getFreeElement(storageId, size, p_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StorageManagerMock::hasDataAtId(store_address_t storeId) const {
|
bool StorageManagerMock::hasDataAtId(store_address_t storeId) const {
|
||||||
|
@ -8,15 +8,13 @@ class StorageManagerMock : public LocalPool {
|
|||||||
public:
|
public:
|
||||||
StorageManagerMock(object_id_t setObjectId, const LocalPoolConfig &poolConfig);
|
StorageManagerMock(object_id_t setObjectId, const LocalPoolConfig &poolConfig);
|
||||||
|
|
||||||
ReturnValue_t addData(store_address_t *storageId, const uint8_t *data, size_t size,
|
ReturnValue_t addData(store_address_t *storageId, const uint8_t *data, size_t size) override;
|
||||||
bool ignoreFault) override;
|
|
||||||
ReturnValue_t deleteData(store_address_t packet_id) override;
|
ReturnValue_t deleteData(store_address_t packet_id) override;
|
||||||
ReturnValue_t deleteData(uint8_t *buffer, size_t size, store_address_t *storeId) override;
|
ReturnValue_t deleteData(uint8_t *buffer, size_t size, store_address_t *storeId) override;
|
||||||
ReturnValue_t getData(store_address_t packet_id, const uint8_t **packet_ptr,
|
ReturnValue_t getData(store_address_t packet_id, const uint8_t **packet_ptr,
|
||||||
size_t *size) override;
|
size_t *size) override;
|
||||||
ReturnValue_t modifyData(store_address_t packet_id, uint8_t **packet_ptr, size_t *size) override;
|
ReturnValue_t modifyData(store_address_t packet_id, uint8_t **packet_ptr, size_t *size) override;
|
||||||
ReturnValue_t getFreeElement(store_address_t *storageId, size_t size, uint8_t **p_data,
|
ReturnValue_t getFreeElement(store_address_t *storageId, size_t size, uint8_t **p_data) override;
|
||||||
bool ignoreFault) override;
|
|
||||||
[[nodiscard]] bool hasDataAtId(store_address_t storeId) const override;
|
[[nodiscard]] bool hasDataAtId(store_address_t storeId) const override;
|
||||||
void clearStore() override;
|
void clearStore() override;
|
||||||
void clearSubPool(uint8_t poolIndex) override;
|
void clearSubPool(uint8_t poolIndex) override;
|
||||||
|
Loading…
Reference in New Issue
Block a user