added introspection
This commit is contained in:
parent
34c50ce3e2
commit
0c057c66b1
@ -15,6 +15,7 @@ add_subdirectory(globalfunctions)
|
||||
add_subdirectory(health)
|
||||
add_subdirectory(housekeeping)
|
||||
add_subdirectory(internalerror)
|
||||
add_subdirectory(introspection)
|
||||
add_subdirectory(ipc)
|
||||
add_subdirectory(memory)
|
||||
add_subdirectory(modes)
|
||||
|
1
src/fsfw/introspection/CMakeLists.txt
Normal file
1
src/fsfw/introspection/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE ParameterTypeSelector.cpp)
|
48
src/fsfw/introspection/ClasslessEnum.h
Normal file
48
src/fsfw/introspection/ClasslessEnum.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include <boost/preprocessor.hpp>
|
||||
|
||||
// TODO ifdef EnumIF, consistent naming of functions arrays and macros (probably enum values and
|
||||
// descriptions)
|
||||
|
||||
#include "EnumIF.h"
|
||||
#include "EnumCommon.h"
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
#define FSFW_CLASSLESS_ENUM(name, type, elements) \
|
||||
enum : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) }; \
|
||||
\
|
||||
class name : public EnumIF { \
|
||||
public: \
|
||||
enum : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) }; \
|
||||
name(type value) : value(value) {} \
|
||||
name() : value(-1) {} \
|
||||
name(const name &other) : value(other.value) {} \
|
||||
int64_t getValue() const override { return value; } \
|
||||
operator type() { return value; } \
|
||||
name &operator=(name other) { \
|
||||
value = other.value; \
|
||||
return *this; \
|
||||
} \
|
||||
name &operator=(type value) { \
|
||||
this->value = value; \
|
||||
return *this; \
|
||||
} \
|
||||
CREATE_KEY_ARRAY(elements, type) \
|
||||
VALUE_CHECK(type) \
|
||||
GET_INDEX() \
|
||||
CREATE_DESCRIPTION_ARRAY(elements) \
|
||||
GET_DESCRIPTION_FUNC() \
|
||||
private: \
|
||||
type value; \
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define FSFW_CLASSLESS_ENUM(name, type, elements) \
|
||||
enum name : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) };
|
||||
|
||||
#endif
|
64
src/fsfw/introspection/Enum.h
Normal file
64
src/fsfw/introspection/Enum.h
Normal file
@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
|
||||
#include <boost/preprocessor.hpp>
|
||||
|
||||
// TODO ifdef EnumIF, consistent naming of functions arrays and macros (probably enum values and
|
||||
// descriptions)
|
||||
|
||||
#include "EnumIF.h"
|
||||
#include "EnumCommon.h"
|
||||
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
#define FSFW_ENUM(name, type, elements) \
|
||||
class name : public EnumIF, public SerializeIF { \
|
||||
public: \
|
||||
enum : type { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) }; \
|
||||
name(type value) : value(value) {} \
|
||||
name() : value(-1) {} \
|
||||
name(const name &other) : value(other.value) {} \
|
||||
int64_t getValue() const override { return value; } \
|
||||
operator type() { return value; } \
|
||||
name &operator=(name other) { \
|
||||
value = other.value; \
|
||||
return *this; \
|
||||
} \
|
||||
name &operator=(type value) { \
|
||||
this->value = value; \
|
||||
return *this; \
|
||||
} \
|
||||
CREATE_KEY_ARRAY(elements, type) \
|
||||
VALUE_CHECK(type) \
|
||||
GET_INDEX() \
|
||||
CREATE_DESCRIPTION_ARRAY(elements) \
|
||||
GET_DESCRIPTION_FUNC() \
|
||||
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, \
|
||||
Endianness streamEndianness) const override { \
|
||||
return SerializeAdapter::serialize<>(&value, buffer, size, maxSize, streamEndianness); \
|
||||
} \
|
||||
virtual size_t getSerializedSize() const override { \
|
||||
return SerializeAdapter::getSerializedSize<>(&value); \
|
||||
} \
|
||||
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, \
|
||||
Endianness streamEndianness) override { \
|
||||
return SerializeAdapter::deSerialize<>(&value, buffer, size, streamEndianness); \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
type value; \
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define FSFW_ENUM(name, type, elements) \
|
||||
enum class name : type { \
|
||||
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(CLEAN_ENUM_ITEM, "", elements)) \
|
||||
};
|
||||
|
||||
|
||||
#endif
|
62
src/fsfw/introspection/EnumCommon.h
Normal file
62
src/fsfw/introspection/EnumCommon.h
Normal file
@ -0,0 +1,62 @@
|
||||
#define CLEAN_ENUM_ITEM(r, data, element) \
|
||||
BOOST_PP_IF(BOOST_PP_SUB(BOOST_PP_TUPLE_SIZE(element), 2), \
|
||||
(BOOST_PP_TUPLE_ELEM(0, element) = BOOST_PP_TUPLE_ELEM(1, element)), \
|
||||
(BOOST_PP_TUPLE_ELEM(0, element)))
|
||||
|
||||
#if defined FSFW_ENUM_VALUE_CHECKS || defined FSFW_INTROSPECTION
|
||||
|
||||
|
||||
#define GET_KEY(r, data, element) (BOOST_PP_TUPLE_ELEM(0, element))
|
||||
#define GET_DESCRIPTION(r, data, element) \
|
||||
BOOST_PP_IF(BOOST_PP_SUB(BOOST_PP_TUPLE_SIZE(element), 2), (BOOST_PP_TUPLE_ELEM(2, element)), \
|
||||
(BOOST_PP_TUPLE_ELEM(1, element)))
|
||||
|
||||
#define CREATE_KEY_ARRAY(enum_elements, type) \
|
||||
/*was static constexpr, but clang won't compile that*/ \
|
||||
int64_t elements[BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_FOR_EACH(GET_KEY, "", enum_elements))] = { \
|
||||
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(GET_KEY, "", enum_elements))}; \
|
||||
const int64_t *getElements() const override { return elements; } \
|
||||
size_t getSize() const override { \
|
||||
return BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_FOR_EACH(GET_KEY, "", enum_elements)); \
|
||||
}
|
||||
#define VALUE_CHECK(type) \
|
||||
bool isValid() const override { \
|
||||
for (size_t i = 0; i < sizeof(elements) / sizeof(elements[0]); i++) { \
|
||||
if (value == elements[i]) { \
|
||||
return true; \
|
||||
} \
|
||||
} \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
#define CREATE_DESCRIPTION_ARRAY(elements) \
|
||||
/*was static constexpr, but clang won't compile that*/ \
|
||||
const char \
|
||||
*descriptions[BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_FOR_EACH(GET_DESCRIPTION, "", elements))] = { \
|
||||
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(GET_DESCRIPTION, "", elements))}; \
|
||||
const char *const *getDescriptions() const override { return descriptions; }
|
||||
#define GET_INDEX() \
|
||||
size_t getIndex(int64_t value) const override { \
|
||||
for (size_t i = 0; i < sizeof(elements) / sizeof(elements[0]); i++) { \
|
||||
if (value == elements[i]) { \
|
||||
return i; \
|
||||
} \
|
||||
} \
|
||||
return -1; \
|
||||
}
|
||||
#define GET_DESCRIPTION_FUNC() \
|
||||
const char *getDescription() const override { \
|
||||
if (getIndex(value) == static_cast<size_t>(-1)) { \
|
||||
return nullptr; \
|
||||
} else { \
|
||||
return descriptions[getIndex(value)]; \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define GET_INDEX()
|
||||
#define CREATE_DESCRIPTION_ARRAY(elements)
|
||||
#define GET_DESCRIPTION_FUNC()
|
||||
#endif
|
||||
|
||||
#endif
|
15
src/fsfw/introspection/EnumIF.h
Normal file
15
src/fsfw/introspection/EnumIF.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
class EnumIF {
|
||||
public:
|
||||
virtual int64_t getValue() const = 0;
|
||||
virtual bool isValid() const = 0;
|
||||
virtual size_t getSize() const = 0;
|
||||
virtual size_t getIndex(int64_t value) const = 0;
|
||||
virtual const int64_t *getElements() const = 0;
|
||||
virtual const char *const *getDescriptions() const = 0;
|
||||
virtual const char *getDescription() const = 0;
|
||||
};
|
56
src/fsfw/introspection/ParameterTypeSelector.cpp
Normal file
56
src/fsfw/introspection/ParameterTypeSelector.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include "ParameterTypeSelector.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
template <typename T>
|
||||
Types::ParameterType ParameterTypeSelector::getType() {
|
||||
return Types::UNSUPPORTED;
|
||||
}
|
||||
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<uint8_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int8_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<uint16_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int16_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<uint32_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int32_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
// template <>
|
||||
// Types::ParameterType ParameterTypeSelector::getType<uint64_t>() {
|
||||
// return Types::UNSIGNED;
|
||||
// }
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<int64_t>() {
|
||||
return Types::SIGNED;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<float>() {
|
||||
return Types::FLOATING;
|
||||
}
|
||||
template <>
|
||||
Types::ParameterType ParameterTypeSelector::getType<double>() {
|
||||
return Types::FLOATING;
|
||||
}
|
||||
|
||||
#endif
|
13
src/fsfw/introspection/ParameterTypeSelector.h
Normal file
13
src/fsfw/introspection/ParameterTypeSelector.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
|
||||
class ParameterTypeSelector {
|
||||
public:
|
||||
template <typename T>
|
||||
static Types::ParameterType getType();
|
||||
};
|
||||
|
||||
#endif
|
8
src/fsfw/introspection/Types.h
Normal file
8
src/fsfw/introspection/Types.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
//maybe call them MIB types as these are the ones exposed to the MIB?
|
||||
// Note: some DBs (Postgress, Mongo) only support signed 64bit integers. To have a common denominator, all integers are int64_t.
|
||||
// As such, ther is no unsigned Type, as there can not be a uint64_t and uint32_t completely fits into int64_t
|
||||
namespace Types {
|
||||
enum ParameterType { SIGNED, FLOATING, ENUM, UNSUPPORTED };
|
||||
} // namespace Types
|
74
src/fsfw/introspection/TypesHelper.h
Normal file
74
src/fsfw/introspection/TypesHelper.h
Normal file
@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include "Enum.h"
|
||||
#include "Types.h"
|
||||
#include "ParameterTypeSelector.h"
|
||||
|
||||
template <bool>
|
||||
class enumHelper;
|
||||
|
||||
template <>
|
||||
class enumHelper<true> {
|
||||
public:
|
||||
static bool isValid(EnumIF *anEnum) { return anEnum->isValid(); }
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
template <typename T>
|
||||
static Types::ParameterType getType() {
|
||||
return Types::ENUM;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T getMin() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T getMax() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static std::vector<int64_t> getEnumValues() { return std::vector<int64_t>(); }
|
||||
|
||||
static std::vector<int64_t> getEnumValues(EnumIF *anEnum) {
|
||||
std::vector<int64_t> vector;
|
||||
for (size_t i = 0; i < anEnum->getSize(); i++) {
|
||||
vector.push_back(anEnum->getElements()[i]);
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
|
||||
static const char *const *getEnumDescriptions(EnumIF *anEnum) {
|
||||
return anEnum->getDescriptions();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <>
|
||||
class enumHelper<false> {
|
||||
public:
|
||||
static bool isValid(void *) { return true; }
|
||||
|
||||
#ifdef FSFW_INTROSPECTION
|
||||
template <typename T>
|
||||
static Types::ParameterType getType() {
|
||||
return ParameterTypeSelector::getType<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T getMin() {
|
||||
return std::numeric_limits<T>::lowest();
|
||||
}
|
||||
template <typename T>
|
||||
static T getMax() {
|
||||
return std::numeric_limits<T>::max();
|
||||
}
|
||||
|
||||
static std::vector<int64_t> getEnumValues(void *) { return std::vector<int64_t>(); }
|
||||
|
||||
static const char *const *getEnumDescriptions(void *) { return nullptr; }
|
||||
#endif
|
||||
};
|
Loading…
Reference in New Issue
Block a user