Compare commits
97 Commits
mohr/dhb2n
...
mueller/ne
Author | SHA1 | Date | |
---|---|---|---|
39310c3fad | |||
d16c5024dc | |||
bf311757a2 | |||
a4531e4ced | |||
cbe1b65a33 | |||
80f0060cd2 | |||
97c629ad84 | |||
bf12f284fa | |||
8589f4d63a | |||
ca80589233 | |||
f2ebaed092 | |||
f0b89e98df | |||
5557d95994 | |||
fc24c9b5d8 | |||
7ef69c839c | |||
9b798d798e | |||
b13453f46b | |||
d0e322d7e2 | |||
ecde164f68 | |||
50930b41ba | |||
d6ee2ed400 | |||
f2150ff9c2 | |||
1b9c98f3fe | |||
742152b28e | |||
bf4ca56658 | |||
16ffa00155 | |||
14c681c93a | |||
0958c3a00e | |||
d699d16307 | |||
3b0fed733f | |||
23d3812fe3 | |||
dec7db3ae2 | |||
65a5abab49 | |||
0129783e34 | |||
cabe0868ec | |||
f05295bada | |||
b85ca64690 | |||
3bc3da5a8d | |||
f8c07ec9cf | |||
8199b8f359 | |||
cbc8dbcdd4 | |||
d31a5306f0 | |||
a236a5ec50 | |||
03620970e2 | |||
8fe8d810e9 | |||
9483c2809d | |||
fe3d6bd432 | |||
2a842666d5 | |||
c013fcc1f5 | |||
1b8fc2af19 | |||
72d7c43445 | |||
ab9b6c8c89 | |||
69d338f9bb | |||
68223869d5 | |||
93fda71989 | |||
7b0db08962 | |||
0956fbc740 | |||
b48e0fdc0d | |||
1d084ee22f | |||
1bea2344f6 | |||
d7e16a67a7 | |||
6021d897b8 | |||
83a6f0b5f8 | |||
a9c6c088f2 | |||
b6a3c206cc | |||
5b352978c5 | |||
819a298b19 | |||
16246d6ece | |||
5c84f12440 | |||
83c2c4825c | |||
c913fe40bf | |||
70ec08bf1d | |||
ef23665d9c | |||
eefc122292 | |||
bee33526a1 | |||
f715b65d6e | |||
c11af63015 | |||
dc1583c932 | |||
81a7de2814 | |||
d26f230bee | |||
4db124c680 | |||
2df66c9304 | |||
54ad6b3016 | |||
73e313c35b | |||
dd2f42d22b | |||
652c31a683 | |||
bfe120636c | |||
a8041f220f | |||
dd636b186b | |||
3349fc36f8 | |||
df06064df0 | |||
e0c780f21c | |||
876815b1c9 | |||
b0ecf87580 | |||
68ce8b5b08 | |||
fe03da6def | |||
4f7f8310c9 |
37
CHANGELOG.md
37
CHANGELOG.md
@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
|
- TC Scheduler Service 11: Add size and CRC check for contained TC.
|
||||||
|
- Only delete health table entry in `HealthHelper` destructor if
|
||||||
|
health table was set.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/710/files
|
||||||
- I2C Bugfixes: Do not keep iterator as member and fix some incorrect handling with the iterator.
|
- I2C Bugfixes: Do not keep iterator as member and fix some incorrect handling with the iterator.
|
||||||
Also properly reset the reply size for successfull transfers and erroneous transfers.
|
Also properly reset the reply size for successfull transfers and erroneous transfers.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/700
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/700
|
||||||
@ -24,19 +28,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
- DHB TM handler `handleDeviceTM` renamed to `handleDeviceTm` and now takes
|
- `DleParser` helper class to parse DLE encoded packets from a byte stream.
|
||||||
`util::DataWrapper` as the data input argument. This allows more flexibility in the possible
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/711
|
||||||
types of telemetry.
|
- `UioMapper` is able to resolve symlinks now.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/669
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/709
|
||||||
- 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
|
||||||
|
|
||||||
## Changes
|
## Changes
|
||||||
|
|
||||||
|
- `AcceptsTelemetryIF`: `getReportReceptionQueue` is const now
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/712
|
||||||
|
- Moved some container returnvalues to dedicated header and namespace
|
||||||
|
to they can be used without template specification.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/707
|
||||||
- Remove default secondary header argument for
|
- Remove default secondary header argument for
|
||||||
`uint16_t getTcSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)` and
|
`uint16_t getTcSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)` and
|
||||||
`uint16_t getTmSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)`
|
`uint16_t getTmSpacePacketIdFromApid(uint16_t apid, bool secondaryHeaderFlag)`
|
||||||
@ -65,6 +70,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
|
||||||
@ -225,6 +234,7 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
|||||||
- https://gitlab.kitware.com/cmake/cmake/-/issues/21696
|
- https://gitlab.kitware.com/cmake/cmake/-/issues/21696
|
||||||
Easiest solution for now: Keep this option OFF by default.
|
Easiest solution for now: Keep this option OFF by default.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/616
|
||||||
|
- Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1
|
||||||
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
- Dedicated Version class and constant `fsfw::FSFW_VERSION` containing version information
|
||||||
inside `fsfw/version.h`
|
inside `fsfw/version.h`
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
||||||
@ -239,17 +249,6 @@ https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
|||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
||||||
- `Subsystem`: New API to add table and sequence entries
|
- `Subsystem`: New API to add table and sequence entries
|
||||||
|
|
||||||
## HAL
|
|
||||||
|
|
||||||
- SPI: Cache the SPI device in the communication interface. Architecturally, this makes a
|
|
||||||
lot more sense because each ComIF should be responsible for one SPI bus.
|
|
||||||
- SPI: Move the empty transfer to update the line polarity to separate function. This means
|
|
||||||
it is not automatically called when calling the setter function for SPI speed and mode.
|
|
||||||
The user should call this function after locking the CS mutex if multiple SPI devices with
|
|
||||||
differing speeds and modes are attached to one bus.
|
|
||||||
- SPI: Getter functions for SPI speed and mode.
|
|
||||||
- I2C: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1.
|
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
- TCP TMTC Server: `MutexGuard` was not created properly in
|
- TCP TMTC Server: `MutexGuard` was not created properly in
|
||||||
|
@ -122,6 +122,7 @@ if(UNIX)
|
|||||||
option(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS "Add Linux peripheral drivers"
|
option(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS "Add Linux peripheral drivers"
|
||||||
OFF)
|
OFF)
|
||||||
option(FSFW_HAL_LINUX_ADD_LIBGPIOD "Attempt to add Linux GPIOD drivers" OFF)
|
option(FSFW_HAL_LINUX_ADD_LIBGPIOD "Attempt to add Linux GPIOD drivers" OFF)
|
||||||
|
option(FSFW_HAL_LINUX_ADD_SERIAL_DRIVERS "Add serial drivers" ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Optional sources
|
# Optional sources
|
||||||
@ -195,7 +196,7 @@ message(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Check whether the user has already installed ETL first
|
# Check whether the user has already installed ETL first
|
||||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} CONFIG QUIET)
|
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
||||||
# Not installed, so use FetchContent to download and provide etl
|
# Not installed, so use FetchContent to download and provide etl
|
||||||
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
||||||
message(
|
message(
|
||||||
|
@ -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)
|
||||||
|
@ -16,8 +16,8 @@ class CommandActionHelper {
|
|||||||
public:
|
public:
|
||||||
explicit CommandActionHelper(CommandsActionsIF* owner);
|
explicit CommandActionHelper(CommandsActionsIF* owner);
|
||||||
virtual ~CommandActionHelper();
|
virtual ~CommandActionHelper();
|
||||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId,
|
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, const uint8_t* data,
|
||||||
const uint8_t* data = nullptr, uint32_t size = 0);
|
uint32_t size);
|
||||||
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
|
ReturnValue_t commandAction(object_id_t commandTo, ActionId_t actionId, SerializeIF* data);
|
||||||
ReturnValue_t initialize();
|
ReturnValue_t initialize();
|
||||||
ReturnValue_t handleReply(CommandMessage* reply);
|
ReturnValue_t handleReply(CommandMessage* reply);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "../returnvalues/returnvalue.h"
|
#include "../returnvalues/returnvalue.h"
|
||||||
#include "../serialize/SerializeAdapter.h"
|
#include "../serialize/SerializeAdapter.h"
|
||||||
#include "../serialize/SerializeIF.h"
|
#include "../serialize/SerializeIF.h"
|
||||||
|
#include "definitions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A List that stores its values in an array.
|
* @brief A List that stores its values in an array.
|
||||||
@ -19,9 +20,6 @@ class ArrayList {
|
|||||||
friend class SerialArrayListAdapter;
|
friend class SerialArrayListAdapter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
|
|
||||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the allocating constructor.
|
* This is the allocating constructor.
|
||||||
* It allocates an array of the specified size.
|
* It allocates an array of the specified size.
|
||||||
@ -187,7 +185,7 @@ class ArrayList {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t insert(T entry) {
|
ReturnValue_t insert(T entry) {
|
||||||
if (size >= maxSize_) {
|
if (size >= maxSize_) {
|
||||||
return FULL;
|
return containers::LIST_FULL;
|
||||||
}
|
}
|
||||||
entries[size] = entry;
|
entries[size] = entry;
|
||||||
++size;
|
++size;
|
||||||
|
@ -20,15 +20,19 @@ class FixedArrayList : public ArrayList<T, count_t> {
|
|||||||
FixedArrayList() : ArrayList<T, count_t>(data, MAX_SIZE) {}
|
FixedArrayList() : ArrayList<T, count_t>(data, MAX_SIZE) {}
|
||||||
|
|
||||||
FixedArrayList(const FixedArrayList& other) : ArrayList<T, count_t>(data, MAX_SIZE) {
|
FixedArrayList(const FixedArrayList& other) : ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||||
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];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "../returnvalues/returnvalue.h"
|
|
||||||
#include "ArrayList.h"
|
#include "ArrayList.h"
|
||||||
|
#include "definitions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Map implementation for maps with a pre-defined size.
|
* @brief Map implementation for maps with a pre-defined size.
|
||||||
@ -24,11 +24,6 @@ class FixedMap : public SerializeIF {
|
|||||||
"derived class from SerializeIF to be serialize-able");
|
"derived class from SerializeIF to be serialize-able");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
|
|
||||||
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
|
|
||||||
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02);
|
|
||||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const key_t EMPTY_SLOT = -1;
|
static const key_t EMPTY_SLOT = -1;
|
||||||
ArrayList<std::pair<key_t, T>, uint32_t> theMap;
|
ArrayList<std::pair<key_t, T>, uint32_t> theMap;
|
||||||
@ -76,10 +71,10 @@ class FixedMap : public SerializeIF {
|
|||||||
|
|
||||||
ReturnValue_t insert(key_t key, T value, Iterator* storedValue = nullptr) {
|
ReturnValue_t insert(key_t key, T value, Iterator* storedValue = nullptr) {
|
||||||
if (exists(key) == returnvalue::OK) {
|
if (exists(key) == returnvalue::OK) {
|
||||||
return KEY_ALREADY_EXISTS;
|
return containers::KEY_ALREADY_EXISTS;
|
||||||
}
|
}
|
||||||
if (_size == theMap.maxSize()) {
|
if (_size == theMap.maxSize()) {
|
||||||
return MAP_FULL;
|
return containers::MAP_FULL;
|
||||||
}
|
}
|
||||||
theMap[_size].first = key;
|
theMap[_size].first = key;
|
||||||
theMap[_size].second = value;
|
theMap[_size].second = value;
|
||||||
@ -93,7 +88,7 @@ class FixedMap : public SerializeIF {
|
|||||||
ReturnValue_t insert(std::pair<key_t, T> pair) { return insert(pair.first, pair.second); }
|
ReturnValue_t insert(std::pair<key_t, T> pair) { return insert(pair.first, pair.second); }
|
||||||
|
|
||||||
ReturnValue_t exists(key_t key) const {
|
ReturnValue_t exists(key_t key) const {
|
||||||
ReturnValue_t result = KEY_DOES_NOT_EXIST;
|
ReturnValue_t result = containers::KEY_DOES_NOT_EXIST;
|
||||||
if (findIndex(key) < _size) {
|
if (findIndex(key) < _size) {
|
||||||
result = returnvalue::OK;
|
result = returnvalue::OK;
|
||||||
}
|
}
|
||||||
@ -103,7 +98,7 @@ class FixedMap : public SerializeIF {
|
|||||||
ReturnValue_t erase(Iterator* iter) {
|
ReturnValue_t erase(Iterator* iter) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if ((i = findIndex((*iter).value->first)) >= _size) {
|
if ((i = findIndex((*iter).value->first)) >= _size) {
|
||||||
return KEY_DOES_NOT_EXIST;
|
return containers::KEY_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
theMap[i] = theMap[_size - 1];
|
theMap[i] = theMap[_size - 1];
|
||||||
--_size;
|
--_size;
|
||||||
@ -114,7 +109,7 @@ class FixedMap : public SerializeIF {
|
|||||||
ReturnValue_t erase(key_t key) {
|
ReturnValue_t erase(key_t key) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if ((i = findIndex(key)) >= _size) {
|
if ((i = findIndex(key)) >= _size) {
|
||||||
return KEY_DOES_NOT_EXIST;
|
return containers::KEY_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
theMap[i] = theMap[_size - 1];
|
theMap[i] = theMap[_size - 1];
|
||||||
--_size;
|
--_size;
|
||||||
|
14
src/fsfw/container/definitions.h
Normal file
14
src/fsfw/container/definitions.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef FSFW_CONTAINER_DEFINITIONS_H_
|
||||||
|
#define FSFW_CONTAINER_DEFINITIONS_H_
|
||||||
|
|
||||||
|
#include "fsfw/retval.h"
|
||||||
|
|
||||||
|
namespace containers {
|
||||||
|
static const ReturnValue_t KEY_ALREADY_EXISTS = returnvalue::makeCode(CLASS_ID::FIXED_MAP, 0x01);
|
||||||
|
static const ReturnValue_t MAP_FULL = returnvalue::makeCode(CLASS_ID::FIXED_MAP, 0x02);
|
||||||
|
static const ReturnValue_t KEY_DOES_NOT_EXIST = returnvalue::makeCode(CLASS_ID::FIXED_MAP, 0x03);
|
||||||
|
|
||||||
|
static const ReturnValue_t LIST_FULL = returnvalue::makeCode(CLASS_ID::ARRAY_LIST, 0x01);
|
||||||
|
} // namespace containers
|
||||||
|
|
||||||
|
#endif /* FSFW_CONTAINER_DEFINITIONS_H_ */
|
@ -13,9 +13,7 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
|||||||
submode(SUBMODE_NONE),
|
submode(SUBMODE_NONE),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
healthHelper(this, setObjectId) {
|
healthHelper(this, setObjectId) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth);
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
commandQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
@ -570,10 +570,6 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(CommandMessage* me
|
|||||||
|
|
||||||
CommandMessage reply;
|
CommandMessage reply;
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
if (result == WRONG_HK_PACKET_TYPE) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "handleHousekeepingMessage",
|
|
||||||
WRONG_HK_PACKET_TYPE);
|
|
||||||
}
|
|
||||||
HousekeepingMessage::setHkRequestFailureReply(&reply, sid, result);
|
HousekeepingMessage::setHkRequestFailureReply(&reply, sid, result);
|
||||||
} else {
|
} else {
|
||||||
HousekeepingMessage::setHkRequestSuccessReply(&reply, sid);
|
HousekeepingMessage::setHkRequestSuccessReply(&reply, sid);
|
||||||
@ -829,8 +825,6 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
|
|||||||
errorPrint = "Dataset not found";
|
errorPrint = "Dataset not found";
|
||||||
} else if (error == POOLOBJECT_NOT_FOUND) {
|
} else if (error == POOLOBJECT_NOT_FOUND) {
|
||||||
errorPrint = "Pool Object not found";
|
errorPrint = "Pool Object not found";
|
||||||
} else if (error == WRONG_HK_PACKET_TYPE) {
|
|
||||||
errorPrint = "Wrong Packet Type";
|
|
||||||
} else if (error == returnvalue::FAILED) {
|
} else if (error == returnvalue::FAILED) {
|
||||||
if (outputType == sif::OutputTypes::OUT_WARNING) {
|
if (outputType == sif::OutputTypes::OUT_WARNING) {
|
||||||
errorPrint = "Generic Warning";
|
errorPrint = "Generic Warning";
|
||||||
|
@ -162,7 +162,6 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
object_id_t getCreatorObjectId();
|
object_id_t getCreatorObjectId();
|
||||||
|
|
||||||
bool getReportingEnabled() const;
|
bool getReportingEnabled() const;
|
||||||
void setReportingEnabled(bool enabled);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current periodic HK generation interval this set
|
* Returns the current periodic HK generation interval this set
|
||||||
@ -190,6 +189,7 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
* Used for periodic generation.
|
* Used for periodic generation.
|
||||||
*/
|
*/
|
||||||
bool reportingEnabled = false;
|
bool reportingEnabled = false;
|
||||||
|
void setReportingEnabled(bool enabled);
|
||||||
|
|
||||||
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
void initializePeriodicHelper(float collectionInterval, dur_millis_t minimumPeriodicInterval,
|
||||||
uint8_t nonDiagIntervalFactor = 5);
|
uint8_t nonDiagIntervalFactor = 5);
|
||||||
|
@ -26,7 +26,11 @@ void AssemblyBase::performChildOperation() {
|
|||||||
|
|
||||||
void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
||||||
doStartTransition(mode, submode);
|
doStartTransition(mode, submode);
|
||||||
triggerModeHelperEvents(mode, submode);
|
if (modeHelper.isForced()) {
|
||||||
|
triggerEvent(FORCING_MODE, mode, submode);
|
||||||
|
} else {
|
||||||
|
triggerEvent(CHANGING_MODE, mode, submode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
|
void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
|
||||||
@ -73,10 +77,9 @@ bool AssemblyBase::handleChildrenChangedHealth() {
|
|||||||
}
|
}
|
||||||
HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
|
HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
|
||||||
if (healthState == HasHealthIF::NEEDS_RECOVERY) {
|
if (healthState == HasHealthIF::NEEDS_RECOVERY) {
|
||||||
triggerEvent(TRYING_RECOVERY, iter->first, 0);
|
triggerEvent(TRYING_RECOVERY);
|
||||||
recoveryState = RECOVERY_STARTED;
|
recoveryState = RECOVERY_STARTED;
|
||||||
recoveringDevice = iter;
|
recoveringDevice = iter;
|
||||||
// The user needs to take care of commanding the children off in commandChildren
|
|
||||||
doStartTransition(targetMode, targetSubmode);
|
doStartTransition(targetMode, targetSubmode);
|
||||||
} else {
|
} else {
|
||||||
triggerEvent(CHILD_CHANGED_HEALTH);
|
triggerEvent(CHILD_CHANGED_HEALTH);
|
||||||
@ -225,9 +228,6 @@ ReturnValue_t AssemblyBase::handleHealthReply(CommandMessage* message) {
|
|||||||
bool AssemblyBase::checkAndHandleRecovery() {
|
bool AssemblyBase::checkAndHandleRecovery() {
|
||||||
switch (recoveryState) {
|
switch (recoveryState) {
|
||||||
case RECOVERY_STARTED:
|
case RECOVERY_STARTED:
|
||||||
// The recovery was already start in #handleChildrenChangedHealth and we just need
|
|
||||||
// to wait for an off time period.
|
|
||||||
// TODO: make time period configurable
|
|
||||||
recoveryState = RECOVERY_WAIT;
|
recoveryState = RECOVERY_WAIT;
|
||||||
recoveryOffTimer.resetTimer();
|
recoveryOffTimer.resetTimer();
|
||||||
return true;
|
return true;
|
||||||
@ -266,11 +266,3 @@ void AssemblyBase::overwriteDeviceHealth(object_id_t objectId, HasHealthIF::Heal
|
|||||||
modeHelper.setForced(true);
|
modeHelper.setForced(true);
|
||||||
sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL);
|
sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssemblyBase::triggerModeHelperEvents(Mode_t mode, Submode_t submode) {
|
|
||||||
if (modeHelper.isForced()) {
|
|
||||||
triggerEvent(FORCING_MODE, mode, submode);
|
|
||||||
} else {
|
|
||||||
triggerEvent(CHANGING_MODE, mode, submode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -12,8 +12,7 @@
|
|||||||
* Documentation: Dissertation Baetz p.156, 157.
|
* Documentation: Dissertation Baetz p.156, 157.
|
||||||
*
|
*
|
||||||
* This class reduces the complexity of controller components which would
|
* This class reduces the complexity of controller components which would
|
||||||
* otherwise be needed for the handling of redundant devices. However, it can also be used to
|
* otherwise be needed for the handling of redundant devices.
|
||||||
* manage the mode keeping and recovery of non-redundant devices
|
|
||||||
*
|
*
|
||||||
* The template class monitors mode and health state of its children
|
* The template class monitors mode and health state of its children
|
||||||
* and checks availability of devices on every detected change.
|
* and checks availability of devices on every detected change.
|
||||||
@ -27,9 +26,11 @@
|
|||||||
*
|
*
|
||||||
* Important:
|
* Important:
|
||||||
*
|
*
|
||||||
* The implementation must call #registerChild for all commanded children during initialization.
|
* The implementation must call registerChild(object_id_t child)
|
||||||
|
* for all commanded children during initialization.
|
||||||
* The implementation must call the initialization function of the base class.
|
* The implementation must call the initialization function of the base class.
|
||||||
* (This will call the function in SubsystemBase)
|
* (This will call the function in SubsystemBase)
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
class AssemblyBase : public SubsystemBase {
|
class AssemblyBase : public SubsystemBase {
|
||||||
public:
|
public:
|
||||||
@ -46,10 +47,9 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Command children to reach [mode,submode] combination. Can be done by setting
|
* Command children to reach [mode,submode] combination
|
||||||
* #commandsOutstanding correctly, or using #executeTable. In case of an FDIR recovery,
|
* Can be done by setting #commandsOutstanding correctly,
|
||||||
* the user needs to ensure that the target devices are healthy. If a device is not healthy,
|
* or using executeTable()
|
||||||
* a recovery might be on-going and the device needs to be commanded to off first.
|
|
||||||
* @param mode
|
* @param mode
|
||||||
* @param submode
|
* @param submode
|
||||||
* @return
|
* @return
|
||||||
@ -120,19 +120,8 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
|
|
||||||
virtual ReturnValue_t handleHealthReply(CommandMessage *message);
|
virtual ReturnValue_t handleHealthReply(CommandMessage *message);
|
||||||
|
|
||||||
/**
|
virtual void performChildOperation();
|
||||||
* @brief Default periodic handler
|
|
||||||
* @details
|
|
||||||
* This is the default periodic handler which will be called by the SubsystemBase
|
|
||||||
* performOperation. It performs the child transitions or reacts to changed health/mode states
|
|
||||||
* of children objects
|
|
||||||
*/
|
|
||||||
virtual void performChildOperation() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function handles changed mode or health states of children
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool handleChildrenChanged();
|
bool handleChildrenChanged();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -145,37 +134,12 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
|
|
||||||
bool handleChildrenChangedHealth();
|
bool handleChildrenChangedHealth();
|
||||||
|
|
||||||
/**
|
|
||||||
* Core transition handler. The default implementation will only do something if
|
|
||||||
* #commandsOutstanding is smaller or equal to zero, which means that all mode commands
|
|
||||||
* from the #doPerformTransition call were executed successfully.
|
|
||||||
*
|
|
||||||
* Unless a second step was requested, the function will then use #checkChildrenState to
|
|
||||||
* determine whether the target mode was reached.
|
|
||||||
*
|
|
||||||
* There is some special handling for certain (internal) modes:
|
|
||||||
* - A second step is necessary. #commandChildren will be performed again
|
|
||||||
* - The device health was overwritten. #commandChildren will be called
|
|
||||||
* - A recovery is ongoing. #checkAndHandleRecovery will be called.
|
|
||||||
*/
|
|
||||||
virtual void handleChildrenTransition();
|
virtual void handleChildrenTransition();
|
||||||
|
|
||||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode);
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode);
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls #doStartTransition and triggers an informative event as well that the mode will
|
|
||||||
* change
|
|
||||||
* @param mode
|
|
||||||
* @param submode
|
|
||||||
*/
|
|
||||||
virtual void startTransition(Mode_t mode, Submode_t submode);
|
virtual void startTransition(Mode_t mode, Submode_t submode);
|
||||||
|
|
||||||
/**
|
|
||||||
* This function starts the transition by setting the internal #targetSubmode and #targetMode
|
|
||||||
* variables and then calling the #commandChildren function.
|
|
||||||
* @param mode
|
|
||||||
* @param submode
|
|
||||||
*/
|
|
||||||
virtual void doStartTransition(Mode_t mode, Submode_t submode);
|
virtual void doStartTransition(Mode_t mode, Submode_t submode);
|
||||||
|
|
||||||
virtual bool isInTransition();
|
virtual bool isInTransition();
|
||||||
@ -196,7 +160,7 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
* Manages recovery of a device
|
* Manages recovery of a device
|
||||||
* @return true if recovery is still ongoing, false else.
|
* @return true if recovery is still ongoing, false else.
|
||||||
*/
|
*/
|
||||||
virtual bool checkAndHandleRecovery();
|
bool checkAndHandleRecovery();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to overwrite health state of one of the children.
|
* Helper method to overwrite health state of one of the children.
|
||||||
@ -204,8 +168,6 @@ class AssemblyBase : public SubsystemBase {
|
|||||||
* @param objectId Must be a registered child.
|
* @param objectId Must be a registered child.
|
||||||
*/
|
*/
|
||||||
void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth);
|
void overwriteDeviceHealth(object_id_t objectId, HasHealthIF::HealthState oldHealth);
|
||||||
|
|
||||||
void triggerModeHelperEvents(Mode_t mode, Submode_t submode);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */
|
#endif /* FSFW_DEVICEHANDLERS_ASSEMBLYBASE_H_ */
|
||||||
|
@ -22,6 +22,8 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
|||||||
CookieIF* comCookie, FailureIsolationBase* fdirInstance,
|
CookieIF* comCookie, FailureIsolationBase* fdirInstance,
|
||||||
size_t cmdQueueSize)
|
size_t cmdQueueSize)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
|
mode(MODE_OFF),
|
||||||
|
submode(SUBMODE_NONE),
|
||||||
wiretappingMode(OFF),
|
wiretappingMode(OFF),
|
||||||
storedRawData(StorageManagerIF::INVALID_ADDRESS),
|
storedRawData(StorageManagerIF::INVALID_ADDRESS),
|
||||||
deviceCommunicationId(deviceCommunication),
|
deviceCommunicationId(deviceCommunication),
|
||||||
@ -36,13 +38,10 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
|||||||
defaultFDIRUsed(fdirInstance == nullptr),
|
defaultFDIRUsed(fdirInstance == nullptr),
|
||||||
switchOffWasReported(false),
|
switchOffWasReported(false),
|
||||||
childTransitionDelay(5000),
|
childTransitionDelay(5000),
|
||||||
mode(MODE_OFF),
|
|
||||||
submode(SUBMODE_NONE),
|
|
||||||
transitionSourceMode(_MODE_POWER_DOWN),
|
transitionSourceMode(_MODE_POWER_DOWN),
|
||||||
transitionSourceSubMode(SUBMODE_NONE) {
|
transitionSourceSubMode(SUBMODE_NONE) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||||
insertInCommandMap(RAW_COMMAND_ID);
|
insertInCommandMap(RAW_COMMAND_ID);
|
||||||
cookieInfo.state = COOKIE_UNUSED;
|
cookieInfo.state = COOKIE_UNUSED;
|
||||||
cookieInfo.pendingCommand = deviceCommandMap.end();
|
cookieInfo.pendingCommand = deviceCommandMap.end();
|
||||||
@ -50,6 +49,9 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
|||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "DeviceHandlerBase", returnvalue::FAILED,
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "DeviceHandlerBase", returnvalue::FAILED,
|
||||||
"Invalid cookie");
|
"Invalid cookie");
|
||||||
}
|
}
|
||||||
|
if (this->fdirInstance == nullptr) {
|
||||||
|
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, defaultFdirParentId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
||||||
@ -127,18 +129,6 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (this->fdirInstance == nullptr) {
|
|
||||||
this->fdirInstance =
|
|
||||||
new DeviceHandlerFailureIsolation(this->getObjectId(), defaultFdirParentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->parent != objects::NO_OBJECT) {
|
|
||||||
HasModesIF* modeIF = ObjectManager::instance()->get<HasModesIF>(this->parent);
|
|
||||||
HasHealthIF* healthIF = ObjectManager::instance()->get<HasHealthIF>(this->parent);
|
|
||||||
if (modeIF != nullptr and healthIF != nullptr) {
|
|
||||||
setParentQueue(modeIF->getCommandQueue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
communicationInterface =
|
communicationInterface =
|
||||||
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
ObjectManager::instance()->get<DeviceCommunicationIF>(deviceCommunicationId);
|
||||||
@ -362,23 +352,27 @@ void DeviceHandlerBase::doStateMachine() {
|
|||||||
currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
||||||
setMode(_MODE_POWER_DOWN);
|
setMode(_MODE_POWER_DOWN);
|
||||||
|
callChildStatemachine();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ReturnValue_t switchState = getStateOfSwitches();
|
ReturnValue_t switchState = getStateOfSwitches();
|
||||||
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();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case _MODE_WAIT_OFF: {
|
case _MODE_WAIT_OFF: {
|
||||||
|
uint32_t currentUptime;
|
||||||
|
Clock::getUptime(¤tUptime);
|
||||||
|
|
||||||
if (powerSwitcher == nullptr) {
|
if (powerSwitcher == nullptr) {
|
||||||
setMode(MODE_OFF);
|
setMode(MODE_OFF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint32_t currentUptime;
|
|
||||||
Clock::getUptime(¤tUptime);
|
|
||||||
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) {
|
||||||
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0);
|
||||||
setMode(MODE_ERROR_ON);
|
setMode(MODE_ERROR_ON);
|
||||||
@ -573,26 +567,13 @@ void DeviceHandlerBase::setTransition(Mode_t modeTo, Submode_t submodeTo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||||
|
/* TODO: This will probably be done by the LocalDataPoolManager now */
|
||||||
/**
|
// changeHK(mode, submode, false);
|
||||||
* handle transition from OFF to NORMAL by continuing towards normal when ON is reached
|
|
||||||
*/
|
|
||||||
if (newMode == MODE_ON and continueToNormal) {
|
|
||||||
continueToNormal = false;
|
|
||||||
mode = _MODE_TO_NORMAL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
submode = newSubmode;
|
submode = newSubmode;
|
||||||
mode = newMode;
|
mode = newMode;
|
||||||
modeChanged();
|
modeChanged();
|
||||||
setNormalDatapoolEntriesInvalid();
|
setNormalDatapoolEntriesInvalid();
|
||||||
if (newMode == MODE_OFF) {
|
|
||||||
disableCommandsAndReplies();
|
|
||||||
}
|
|
||||||
if (!isTransitionalMode()) {
|
if (!isTransitionalMode()) {
|
||||||
// clear this flag when a non-transitional Mode is reached to be safe
|
|
||||||
continueToNormal = false;
|
|
||||||
modeHelper.modeChanged(newMode, newSubmode);
|
modeHelper.modeChanged(newMode, newSubmode);
|
||||||
announceMode(false);
|
announceMode(false);
|
||||||
}
|
}
|
||||||
@ -1077,7 +1058,8 @@ Mode_t DeviceHandlerBase::getBaseMode(Mode_t transitionMode) {
|
|||||||
return transitionMode & ~(TRANSITION_MODE_BASE_ACTION_MASK | TRANSITION_MODE_CHILD_ACTION_MASK);
|
return transitionMode & ~(TRANSITION_MODE_BASE_ACTION_MASK | TRANSITION_MODE_CHILD_ACTION_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SHOULDDO: throw away DHB and write a new one:
|
// SHOULDDO: Allow transition from OFF to NORMAL to reduce complexity in assemblies. And, by the
|
||||||
|
// way, throw away DHB and write a new one:
|
||||||
// - Include power and thermal completely, but more modular :-)
|
// - Include power and thermal completely, but more modular :-)
|
||||||
// - Don't use modes for state transitions, reduce FSM (Finte State Machine) complexity.
|
// - Don't use modes for state transitions, reduce FSM (Finte State Machine) complexity.
|
||||||
// - Modularization?
|
// - Modularization?
|
||||||
@ -1089,10 +1071,11 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, Submode_
|
|||||||
if ((mode == MODE_ERROR_ON) && (commandedMode != MODE_OFF)) {
|
if ((mode == MODE_ERROR_ON) && (commandedMode != MODE_OFF)) {
|
||||||
return TRANS_NOT_ALLOWED;
|
return TRANS_NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
|
if ((commandedMode == MODE_NORMAL) && (mode == MODE_OFF)) {
|
||||||
|
return TRANS_NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
// Do not check thermal state for MODE_RAW
|
if ((commandedMode == MODE_ON) && (mode == MODE_OFF) and (thermalSet != nullptr)) {
|
||||||
if ((mode == MODE_OFF) and ((commandedMode == MODE_ON) or (commandedMode == MODE_NORMAL)) and
|
|
||||||
(thermalSet != nullptr)) {
|
|
||||||
ReturnValue_t result = thermalSet->read();
|
ReturnValue_t result = thermalSet->read();
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
if ((thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) and
|
if ((thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) and
|
||||||
@ -1107,7 +1090,6 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, Submode_
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::startTransition(Mode_t commandedMode, Submode_t commandedSubmode) {
|
void DeviceHandlerBase::startTransition(Mode_t commandedMode, Submode_t commandedSubmode) {
|
||||||
continueToNormal = false;
|
|
||||||
switch (commandedMode) {
|
switch (commandedMode) {
|
||||||
case MODE_ON:
|
case MODE_ON:
|
||||||
handleTransitionToOnMode(commandedMode, commandedSubmode);
|
handleTransitionToOnMode(commandedMode, commandedSubmode);
|
||||||
@ -1137,9 +1119,8 @@ void DeviceHandlerBase::startTransition(Mode_t commandedMode, Submode_t commande
|
|||||||
case MODE_NORMAL:
|
case MODE_NORMAL:
|
||||||
if (mode != MODE_OFF) {
|
if (mode != MODE_OFF) {
|
||||||
setTransition(MODE_NORMAL, commandedSubmode);
|
setTransition(MODE_NORMAL, commandedSubmode);
|
||||||
} else { // mode is off
|
} else {
|
||||||
continueToNormal = true;
|
replyReturnvalueToCommand(HasModesIF::TRANS_NOT_ALLOWED);
|
||||||
handleTransitionToOnMode(MODE_NORMAL, commandedSubmode);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1297,7 +1278,6 @@ void DeviceHandlerBase::handleDeviceTm(const SerializeIF& dataSet, DeviceCommand
|
|||||||
if (iter->second.command != deviceCommandMap.end()) {
|
if (iter->second.command != deviceCommandMap.end()) {
|
||||||
MessageQueueId_t queueId = iter->second.command->second.sendReplyTo;
|
MessageQueueId_t queueId = iter->second.command->second.sendReplyTo;
|
||||||
|
|
||||||
// This may fail, but we'll ignore the fault.
|
|
||||||
if (queueId != NO_COMMANDER) {
|
if (queueId != NO_COMMANDER) {
|
||||||
// This may fail, but we'll ignore the fault.
|
// This may fail, but we'll ignore the fault.
|
||||||
actionHelper.reportData(queueId, replyId, const_cast<SerializeIF*>(&dataSet));
|
actionHelper.reportData(queueId, replyId, const_cast<SerializeIF*>(&dataSet));
|
||||||
@ -1476,8 +1456,6 @@ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task) { executingTask = task;
|
|||||||
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId,
|
void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId,
|
||||||
uint32_t parameter) {}
|
uint32_t parameter) {}
|
||||||
|
|
||||||
Submode_t DeviceHandlerBase::getInitialSubmode() { return SUBMODE_NONE; }
|
|
||||||
|
|
||||||
void DeviceHandlerBase::performOperationHook() {}
|
void DeviceHandlerBase::performOperationHook() {}
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
@ -1500,7 +1478,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
|||||||
this->poolManager.initializeAfterTaskCreation();
|
this->poolManager.initializeAfterTaskCreation();
|
||||||
|
|
||||||
if (setStartupImmediately) {
|
if (setStartupImmediately) {
|
||||||
startTransition(MODE_ON, getInitialSubmode());
|
startTransition(MODE_ON, SUBMODE_NONE);
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
@ -1584,48 +1562,3 @@ MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyI
|
|||||||
}
|
}
|
||||||
return commandIter->second.sendReplyTo;
|
return commandIter->second.sendReplyTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::setCustomFdir(FailureIsolationBase* fdir) { this->fdirInstance = fdir; }
|
|
||||||
|
|
||||||
void DeviceHandlerBase::setParent(object_id_t parent) { this->parent = parent; }
|
|
||||||
|
|
||||||
void DeviceHandlerBase::setPowerSwitcher(PowerSwitchIF* switcher) {
|
|
||||||
this->powerSwitcher = switcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mode_t DeviceHandlerBase::getMode() {
|
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
Submode_t DeviceHandlerBase::getSubmode() {
|
|
||||||
return submode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeviceHandlerBase::disableCommandsAndReplies() {
|
|
||||||
for (auto& command : deviceCommandMap) {
|
|
||||||
if (command.second.isExecuting) {
|
|
||||||
command.second.isExecuting = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto& reply : deviceReplyMap) {
|
|
||||||
if (!reply.second.periodic) {
|
|
||||||
if (reply.second.countdown != nullptr) {
|
|
||||||
reply.second.countdown->timeOut();
|
|
||||||
} else {
|
|
||||||
reply.second.delayCycles = 0;
|
|
||||||
}
|
|
||||||
reply.second.active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::finishAction(bool success, DeviceCommandId_t action,
|
|
||||||
ReturnValue_t result) {
|
|
||||||
auto commandIter = deviceCommandMap.find(action);
|
|
||||||
if (commandIter == deviceCommandMap.end()) {
|
|
||||||
return MessageQueueIF::NO_QUEUE;
|
|
||||||
}
|
|
||||||
commandIter->second.isExecuting = false;
|
|
||||||
actionHelper.finish(success, commandIter->second.sendReplyTo, action, result);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
#include "fsfw/serviceinterface/serviceInterfaceDefintions.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();
|
||||||
@ -103,57 +102,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
||||||
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20);
|
||||||
|
|
||||||
void setCustomFdir(FailureIsolationBase *fdir);
|
|
||||||
void setParent(object_id_t parent);
|
|
||||||
void setPowerSwitcher(PowerSwitchIF *switcher);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* extending the modes of DeviceHandler IF for internal state machine
|
|
||||||
*/
|
|
||||||
static constexpr uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20;
|
|
||||||
static constexpr uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10;
|
|
||||||
//! This is a transitional state which can not be commanded. The device
|
|
||||||
//! handler performs all commands to get the device in a state ready to
|
|
||||||
//! perform commands. When this is completed, the mode changes to @c MODE_ON.
|
|
||||||
static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5;
|
|
||||||
//! This is a transitional state which can not be commanded.
|
|
||||||
//! The device handler performs all actions and commands to get the device
|
|
||||||
//! shut down. When the device is off, the mode changes to @c MODE_OFF.
|
|
||||||
//! It is possible to set the mode to _MODE_SHUT_DOWN to use the to off
|
|
||||||
//! transition if available.
|
|
||||||
static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6;
|
|
||||||
//! It is possible to set the mode to _MODE_TO_ON to use the to on
|
|
||||||
//! transition if available.
|
|
||||||
static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON;
|
|
||||||
//! It is possible to set the mode to _MODE_TO_RAW to use the to raw
|
|
||||||
//! transition if available.
|
|
||||||
static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW;
|
|
||||||
//! It is possible to set the mode to _MODE_TO_NORMAL to use the to normal
|
|
||||||
//! transition if available.
|
|
||||||
static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL;
|
|
||||||
//! This is a transitional state which can not be commanded.
|
|
||||||
//! The device is shut down and ready to be switched off.
|
|
||||||
//! After the command to set the switch off has been sent,
|
|
||||||
//! the mode changes to @c _MODE_WAIT_OFF
|
|
||||||
static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1;
|
|
||||||
//! This is a transitional state which can not be commanded. The device
|
|
||||||
//! will be switched on in this state. After the command to set the switch
|
|
||||||
//! on has been sent, the mode changes to @c _MODE_WAIT_ON.
|
|
||||||
static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2;
|
|
||||||
//! This is a transitional state which can not be commanded. The switch has
|
|
||||||
//! been commanded off and the handler waits for it to be off.
|
|
||||||
//! When the switch is off, the mode changes to @c MODE_OFF.
|
|
||||||
static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3;
|
|
||||||
//! This is a transitional state which can not be commanded. The switch
|
|
||||||
//! has been commanded on and the handler waits for it to be on.
|
|
||||||
//! When the switch is on, the mode changes to @c _MODE_TO_ON.
|
|
||||||
static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4;
|
|
||||||
//! This is a transitional state which can not be commanded. The switch has
|
|
||||||
//! been commanded off and is off now. This state is only to do an RMAP
|
|
||||||
//! cycle once more where the doSendRead() function will set the mode to
|
|
||||||
//! MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board.
|
|
||||||
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5;
|
|
||||||
|
|
||||||
void setHkDestination(object_id_t hkDestination);
|
void setHkDestination(object_id_t hkDestination);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -447,8 +395,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
*/
|
*/
|
||||||
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) = 0;
|
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) = 0;
|
||||||
MessageQueueId_t getCommanderQueueId(DeviceCommandId_t replyId) const;
|
MessageQueueId_t getCommanderQueueId(DeviceCommandId_t replyId) const;
|
||||||
ReturnValue_t finishAction(bool success, DeviceCommandId_t action, ReturnValue_t result);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to get pending command. This is useful for devices
|
* Helper function to get pending command. This is useful for devices
|
||||||
* like SPI sensors to identify the last sent command.
|
* like SPI sensors to identify the last sent command.
|
||||||
@ -517,14 +463,14 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* @brief This is a helper method to insert replies in the reply map.
|
* @brief This is a helper method to insert replies in the reply map.
|
||||||
* @param deviceCommand Identifier of the reply to add.
|
* @param deviceCommand Identifier of the reply to add.
|
||||||
* @param maxDelayCycles The maximum number of delay cycles the reply waits
|
* @param maxDelayCycles The maximum number of delay cycles the reply waits
|
||||||
* until it times out.
|
* until it times out.
|
||||||
* @param periodic Indicates if the command is periodic (i.e. it is sent
|
* @param periodic Indicates if the command is periodic (i.e. it is sent
|
||||||
* by the device repeatedly without request) or not. Default is aperiodic (0).
|
* by the device repeatedly without request) or not. Default is aperiodic (0).
|
||||||
* Please note that periodic replies are disabled by default. You can enable them with
|
* Please note that periodic replies are disabled by default. You can enable them with
|
||||||
* #updatePeriodicReply
|
* #updatePeriodicReply
|
||||||
* @param countdown Instead of using maxDelayCycles to timeout a device reply it is also possible
|
* @param countdown Instead of using maxDelayCycles to timeout a device reply it is also possible
|
||||||
* to provide a pointer to a Countdown object which will signal the timeout
|
* to provide a pointer to a Countdown object which will signal the timeout
|
||||||
* when expired
|
* when expired
|
||||||
* @return - @c returnvalue::OK when the command was successfully inserted,
|
* @return - @c returnvalue::OK when the command was successfully inserted,
|
||||||
* - @c returnvalue::FAILED else.
|
* - @c returnvalue::FAILED else.
|
||||||
*/
|
*/
|
||||||
@ -709,12 +655,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0,
|
virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0,
|
||||||
uint32_t parameter = 0);
|
uint32_t parameter = 0);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Can be overwritten by a child to specify the initial submode when device has been set
|
|
||||||
* to startup immediately.
|
|
||||||
*/
|
|
||||||
virtual Submode_t getInitialSubmode();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
|
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_BASE;
|
||||||
|
|
||||||
@ -744,18 +684,15 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
size_t rawPacketLen = 0;
|
size_t rawPacketLen = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current mode
|
* The mode the device handler is currently in.
|
||||||
*
|
* This should never be changed directly but only with setMode()
|
||||||
* set via setMode()
|
|
||||||
*/
|
*/
|
||||||
Mode_t getMode();
|
Mode_t mode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current Submode
|
* The submode the device handler is currently in.
|
||||||
*
|
* This should never be changed directly but only with setMode()
|
||||||
* set via setMode()
|
|
||||||
*/
|
*/
|
||||||
Submode_t getSubmode();
|
Submode_t submode;
|
||||||
|
|
||||||
/** This is the counter value from performOperation(). */
|
/** This is the counter value from performOperation(). */
|
||||||
uint8_t pstStep = 0;
|
uint8_t pstStep = 0;
|
||||||
@ -836,18 +773,11 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* This is used to keep track of pending replies.
|
* This is used to keep track of pending replies.
|
||||||
*/
|
*/
|
||||||
struct DeviceReplyInfo {
|
struct DeviceReplyInfo {
|
||||||
//! For Command-Reply combinations:
|
|
||||||
//! The maximum number of cycles the handler should wait for a reply
|
//! The maximum number of cycles the handler should wait for a reply
|
||||||
//! to this command.
|
//! to this command.
|
||||||
//!
|
|
||||||
//! Reply Only:
|
|
||||||
//! For periodic replies, this variable will be the number of delay cycles between the replies.
|
|
||||||
//! For the non-periodic variant, this variable is not used as there is no meaningful
|
|
||||||
//! definition for delay
|
|
||||||
uint16_t maxDelayCycles;
|
uint16_t maxDelayCycles;
|
||||||
//! This variable will be set to #maxDelayCycles if a reply is expected.
|
//! The currently remaining cycles the handler should wait for a reply,
|
||||||
//! For non-periodic replies without a command, this variable is unused.
|
//! 0 means there is no reply expected
|
||||||
//! A runtime value of 0 means there is no reply is currently expected.
|
|
||||||
uint16_t delayCycles;
|
uint16_t delayCycles;
|
||||||
size_t replyLen = 0; //!< Expected size of the reply.
|
size_t replyLen = 0; //!< Expected size of the reply.
|
||||||
//! if this is !=0, the delayCycles will not be reset to 0 but to
|
//! if this is !=0, the delayCycles will not be reset to 0 but to
|
||||||
@ -903,7 +833,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
/** Pointer to the used FDIR instance. If not provided by child,
|
/** Pointer to the used FDIR instance. If not provided by child,
|
||||||
* default class is instantiated. */
|
* default class is instantiated. */
|
||||||
FailureIsolationBase *fdirInstance;
|
FailureIsolationBase *fdirInstance;
|
||||||
object_id_t parent = objects::NO_OBJECT;
|
|
||||||
|
|
||||||
//! To correctly delete the default instance.
|
//! To correctly delete the default instance.
|
||||||
bool defaultFDIRUsed;
|
bool defaultFDIRUsed;
|
||||||
@ -944,8 +873,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW).
|
* Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW).
|
||||||
*
|
*
|
||||||
* If the transition is complete, the mode should be set to the target mode,
|
* If the transition is complete, the mode should be set to the target mode,
|
||||||
* which can be deduced from the current mode (which is
|
* which can be deduced from the current mode which is
|
||||||
* [_MODE_TO_ON, _MODE_TO_NORMAL, _MODE_TO_RAW]) using getBaseMode()
|
* [_MODE_TO_ON, _MODE_TO_NORMAL, _MODE_TO_RAW]
|
||||||
*
|
*
|
||||||
* The intended target submode is already set.
|
* The intended target submode is already set.
|
||||||
* The origin submode can be read in subModeFrom.
|
* The origin submode can be read in subModeFrom.
|
||||||
@ -1191,22 +1120,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
*/
|
*/
|
||||||
virtual ReturnValue_t doSendReadHook();
|
virtual ReturnValue_t doSendReadHook();
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a RMAP getRead command.
|
|
||||||
*
|
|
||||||
* The size of the getRead command is #maxDeviceReplyLen.
|
|
||||||
* This is always executed, independently from the current mode.
|
|
||||||
*/
|
|
||||||
virtual void doSendRead(void);
|
|
||||||
/**
|
|
||||||
* Check the getRead reply and the contained data.
|
|
||||||
*
|
|
||||||
* If data was received scanForReply() and, if successful, handleReply()
|
|
||||||
* are called. If the current mode is @c MODE_RAW, the received packet
|
|
||||||
* is sent to the commanding object via commandQueue.
|
|
||||||
*/
|
|
||||||
virtual void doGetRead();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* State a cookie is in.
|
* State a cookie is in.
|
||||||
@ -1257,18 +1170,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
*/
|
*/
|
||||||
uint32_t childTransitionDelay;
|
uint32_t childTransitionDelay;
|
||||||
|
|
||||||
/**
|
|
||||||
* The mode the device handler is currently in.
|
|
||||||
* This should not be changed directly but only with setMode()
|
|
||||||
*/
|
|
||||||
Mode_t mode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The submode the device handler is currently in.
|
|
||||||
* This should not be changed directly but only with setMode()
|
|
||||||
*/
|
|
||||||
Submode_t submode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The mode the current transition originated from
|
* @brief The mode the current transition originated from
|
||||||
*
|
*
|
||||||
@ -1286,15 +1187,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
*/
|
*/
|
||||||
Submode_t transitionSourceSubMode;
|
Submode_t transitionSourceSubMode;
|
||||||
|
|
||||||
/**
|
|
||||||
* used to make the state machine continue from ON to NOMAL when
|
|
||||||
* a Device is commanded to NORMAL in OFF mode
|
|
||||||
*
|
|
||||||
* set in startTransition()
|
|
||||||
* evaluated in setMode() to continue to NORMAL when ON is reached
|
|
||||||
*/
|
|
||||||
bool continueToNormal;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read the command queue
|
* read the command queue
|
||||||
*/
|
*/
|
||||||
@ -1363,6 +1255,21 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* - if the action was successful, the reply timout counter is initialized
|
* - if the action was successful, the reply timout counter is initialized
|
||||||
*/
|
*/
|
||||||
void doGetWrite(void);
|
void doGetWrite(void);
|
||||||
|
/**
|
||||||
|
* Send a RMAP getRead command.
|
||||||
|
*
|
||||||
|
* The size of the getRead command is #maxDeviceReplyLen.
|
||||||
|
* This is always executed, independently from the current mode.
|
||||||
|
*/
|
||||||
|
void doSendRead(void);
|
||||||
|
/**
|
||||||
|
* Check the getRead reply and the contained data.
|
||||||
|
*
|
||||||
|
* If data was received scanForReply() and, if successful, handleReply()
|
||||||
|
* are called. If the current mode is @c MODE_RAW, the received packet
|
||||||
|
* is sent to the commanding object via commandQueue.
|
||||||
|
*/
|
||||||
|
void doGetRead(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resets replies which use a timeout to detect missed replies.
|
* @brief Resets replies which use a timeout to detect missed replies.
|
||||||
@ -1416,11 +1323,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
void printWarningOrError(sif::OutputTypes errorType, const char *functionName,
|
void printWarningOrError(sif::OutputTypes errorType, const char *functionName,
|
||||||
ReturnValue_t errorCode = returnvalue::FAILED,
|
ReturnValue_t errorCode = returnvalue::FAILED,
|
||||||
const char *errorPrint = nullptr);
|
const char *errorPrint = nullptr);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Disables all commands and replies when device is set to MODE_OFF
|
|
||||||
*/
|
|
||||||
void disableCommandsAndReplies();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */
|
||||||
|
@ -29,7 +29,6 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event)
|
|||||||
switch (event->getEvent()) {
|
switch (event->getEvent()) {
|
||||||
case HasModesIF::MODE_TRANSITION_FAILED:
|
case HasModesIF::MODE_TRANSITION_FAILED:
|
||||||
case HasModesIF::OBJECT_IN_INVALID_MODE:
|
case HasModesIF::OBJECT_IN_INVALID_MODE:
|
||||||
case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT:
|
|
||||||
// We'll try a recovery as long as defined in MAX_REBOOT.
|
// We'll try a recovery as long as defined in MAX_REBOOT.
|
||||||
// Might cause some AssemblyBase cycles, so keep number low.
|
// Might cause some AssemblyBase cycles, so keep number low.
|
||||||
handleRecovery(event->getEvent());
|
handleRecovery(event->getEvent());
|
||||||
|
@ -24,6 +24,9 @@ class DeviceHandlerIF {
|
|||||||
static const DeviceCommandId_t RAW_COMMAND_ID = -1;
|
static const DeviceCommandId_t RAW_COMMAND_ID = -1;
|
||||||
static const DeviceCommandId_t NO_COMMAND_ID = -2;
|
static const DeviceCommandId_t NO_COMMAND_ID = -2;
|
||||||
|
|
||||||
|
static constexpr uint8_t TRANSITION_MODE_CHILD_ACTION_MASK = 0x20;
|
||||||
|
static constexpr uint8_t TRANSITION_MODE_BASE_ACTION_MASK = 0x10;
|
||||||
|
|
||||||
using dh_heater_request_t = uint8_t;
|
using dh_heater_request_t = uint8_t;
|
||||||
using dh_thermal_state_t = int8_t;
|
using dh_thermal_state_t = int8_t;
|
||||||
|
|
||||||
@ -51,6 +54,47 @@ class DeviceHandlerIF {
|
|||||||
//! device still is powered. In this mode, only a mode change to @c MODE_OFF
|
//! device still is powered. In this mode, only a mode change to @c MODE_OFF
|
||||||
//! can be commanded, which tries to switch off the device again.
|
//! can be commanded, which tries to switch off the device again.
|
||||||
static const Mode_t MODE_ERROR_ON = 4;
|
static const Mode_t MODE_ERROR_ON = 4;
|
||||||
|
//! This is a transitional state which can not be commanded. The device
|
||||||
|
//! handler performs all commands to get the device in a state ready to
|
||||||
|
//! perform commands. When this is completed, the mode changes to @c MODE_ON.
|
||||||
|
static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5;
|
||||||
|
//! This is a transitional state which can not be commanded.
|
||||||
|
//! The device handler performs all actions and commands to get the device
|
||||||
|
//! shut down. When the device is off, the mode changes to @c MODE_OFF.
|
||||||
|
//! It is possible to set the mode to _MODE_SHUT_DOWN to use the to off
|
||||||
|
//! transition if available.
|
||||||
|
static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6;
|
||||||
|
//! It is possible to set the mode to _MODE_TO_ON to use the to on
|
||||||
|
//! transition if available.
|
||||||
|
static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON;
|
||||||
|
//! It is possible to set the mode to _MODE_TO_RAW to use the to raw
|
||||||
|
//! transition if available.
|
||||||
|
static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW;
|
||||||
|
//! It is possible to set the mode to _MODE_TO_NORMAL to use the to normal
|
||||||
|
//! transition if available.
|
||||||
|
static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL;
|
||||||
|
//! This is a transitional state which can not be commanded.
|
||||||
|
//! The device is shut down and ready to be switched off.
|
||||||
|
//! After the command to set the switch off has been sent,
|
||||||
|
//! the mode changes to @c MODE_WAIT_OFF
|
||||||
|
static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1;
|
||||||
|
//! This is a transitional state which can not be commanded. The device
|
||||||
|
//! will be switched on in this state. After the command to set the switch
|
||||||
|
//! on has been sent, the mode changes to @c MODE_WAIT_ON.
|
||||||
|
static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2;
|
||||||
|
//! This is a transitional state which can not be commanded. The switch has
|
||||||
|
//! been commanded off and the handler waits for it to be off.
|
||||||
|
//! When the switch is off, the mode changes to @c MODE_OFF.
|
||||||
|
static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3;
|
||||||
|
//! This is a transitional state which can not be commanded. The switch
|
||||||
|
//! has been commanded on and the handler waits for it to be on.
|
||||||
|
//! When the switch is on, the mode changes to @c MODE_TO_ON.
|
||||||
|
static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4;
|
||||||
|
//! This is a transitional state which can not be commanded. The switch has
|
||||||
|
//! been commanded off and is off now. This state is only to do an RMAP
|
||||||
|
//! cycle once more where the doSendRead() function will set the mode to
|
||||||
|
//! MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board.
|
||||||
|
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5;
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH;
|
||||||
static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, severity::LOW);
|
static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, severity::LOW);
|
||||||
@ -65,7 +109,6 @@ class DeviceHandlerIF {
|
|||||||
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW);
|
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW);
|
||||||
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW);
|
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW);
|
||||||
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
|
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
|
||||||
static const Event DEVICE_WANTS_HARD_REBOOT = MAKE_EVENT(11, severity::HIGH);
|
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
#ifndef FSFW_DEVICEHANDLERS_DEVICETMREPORTINGWRAPPER_H_
|
#ifndef FSFW_DEVICEHANDLERS_DEVICETMREPORTINGWRAPPER_H_
|
||||||
#define FSFW_DEVICEHANDLERS_DEVICETMREPORTINGWRAPPER_H_
|
#define FSFW_DEVICEHANDLERS_DEVICETMREPORTINGWRAPPER_H_
|
||||||
|
|
||||||
#include "fsfw/action/HasActionsIF.h"
|
#include "../action/HasActionsIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
#include "../objectmanager/SystemObjectIF.h"
|
||||||
#include "fsfw/serialize/SerializeIF.h"
|
#include "../serialize/SerializeIF.h"
|
||||||
#include "fsfw/util/dataWrapper.h"
|
|
||||||
|
|
||||||
class DeviceTmReportingWrapper : public SerializeIF {
|
class DeviceTmReportingWrapper : public SerializeIF {
|
||||||
public:
|
public:
|
||||||
|
@ -8,9 +8,7 @@ HealthDevice::HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue
|
|||||||
parentQueue(parentQueue),
|
parentQueue(parentQueue),
|
||||||
commandQueue(),
|
commandQueue(),
|
||||||
healthHelper(this, setObjectId) {
|
healthHelper(this, setObjectId) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
commandQueue = QueueFactory::instance()->createMessageQueue(3);
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
@ -18,9 +18,8 @@ const LocalPool::LocalPoolConfig EventManager::poolConfig = {
|
|||||||
EventManager::EventManager(object_id_t setObjectId)
|
EventManager::EventManager(object_id_t setObjectId)
|
||||||
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
eventReportQueue = QueueFactory::instance()->createMessageQueue(MAX_EVENTS_PER_CYCLE,
|
||||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(
|
EventMessage::EVENT_MESSAGE_SIZE);
|
||||||
MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EventManager::~EventManager() {
|
EventManager::~EventManager() {
|
||||||
@ -47,20 +46,9 @@ ReturnValue_t EventManager::performOperation(uint8_t opCode) {
|
|||||||
|
|
||||||
void EventManager::notifyListeners(EventMessage* message) {
|
void EventManager::notifyListeners(EventMessage* message) {
|
||||||
lockMutex();
|
lockMutex();
|
||||||
for (auto& listener : listenerList) {
|
for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) {
|
||||||
if (listener.second.match(message)) {
|
if (iter->second.match(message)) {
|
||||||
ReturnValue_t result =
|
MessageQueueSenderIF::sendMessage(iter->first, message, message->getSender());
|
||||||
MessageQueueSenderIF::sendMessage(listener.first, message, message->getSender());
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::error << std::hex << "EventManager::notifyListeners: MSG to 0x" << std::setfill('0')
|
|
||||||
<< std::setw(8) << listener.first << " failed with result 0x" << std::setw(4)
|
|
||||||
<< result << std::setfill(' ') << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("Sending message to listener 0x%08x failed with result %04x\n",
|
|
||||||
listener.first, result);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlockMutex();
|
unlockMutex();
|
||||||
@ -206,19 +194,4 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage* messag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventManager::printListeners() {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::info << "Event manager listener MQ IDs:" << std::setfill('0') << std::hex << std::endl;
|
|
||||||
for (auto& listener : listenerList) {
|
|
||||||
sif::info << "0x" << std::setw(8) << listener.first << std::endl;
|
|
||||||
}
|
|
||||||
sif::info << std::dec << std::setfill(' ');
|
|
||||||
#else
|
|
||||||
sif::printInfo("Event manager listener MQ IDs:\n");
|
|
||||||
for (auto& listener : listenerList) {
|
|
||||||
sif::printInfo("0x%08x\n", listener.first);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */
|
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */
|
||||||
|
@ -43,7 +43,6 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
|||||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||||
bool reporterInverted = false);
|
bool reporterInverted = false);
|
||||||
ReturnValue_t performOperation(uint8_t opCode);
|
ReturnValue_t performOperation(uint8_t opCode);
|
||||||
void printListeners();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageQueueIF* eventReportQueue = nullptr;
|
MessageQueueIF* eventReportQueue = nullptr;
|
||||||
|
@ -9,9 +9,8 @@
|
|||||||
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
|
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
|
||||||
uint8_t messageDepth, uint8_t parameterDomainBase)
|
uint8_t messageDepth, uint8_t parameterDomainBase)
|
||||||
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
|
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
|
||||||
auto mqArgs = MqArgs(owner, static_cast<void*>(this));
|
eventQueue =
|
||||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE);
|
||||||
messageDepth, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FailureIsolationBase::~FailureIsolationBase() {
|
FailureIsolationBase::~FailureIsolationBase() {
|
||||||
@ -62,12 +61,11 @@ ReturnValue_t FailureIsolationBase::initialize() {
|
|||||||
ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
|
ObjectManager::instance()->get<ConfirmsFailuresIF>(faultTreeParent);
|
||||||
if (parentIF == nullptr) {
|
if (parentIF == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "FailureIsolationBase::intialize: Parent object "
|
sif::error << "FailureIsolationBase::intialize: Parent object"
|
||||||
<< "invalid" << std::endl;
|
<< "invalid." << std::endl;
|
||||||
sif::error << "Make sure it implements ConfirmsFailuresIF" << std::endl;
|
#endif
|
||||||
#else
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::printError("FailureIsolationBase::intialize: Parent object invalid\n");
|
sif::error << "Make sure it implements ConfirmsFailuresIF." << std::endl;
|
||||||
sif::printError("Make sure it implements ConfirmsFailuresIF\n");
|
|
||||||
#endif
|
#endif
|
||||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
|
@ -12,12 +12,13 @@
|
|||||||
class FailureIsolationBase : public ConfirmsFailuresIF, public HasParametersIF {
|
class FailureIsolationBase : public ConfirmsFailuresIF, public HasParametersIF {
|
||||||
public:
|
public:
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1;
|
||||||
//! FDIR has an internal state, which changed from par2 (oldState) to par1 (newState).
|
static const Event FDIR_CHANGED_STATE =
|
||||||
static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, severity::INFO);
|
MAKE_EVENT(1, severity::INFO); //!< FDIR has an internal state, which changed from par2
|
||||||
//! FDIR tries to restart device. Par1: event that caused recovery.
|
//!< (oldState) to par1 (newState).
|
||||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, severity::MEDIUM);
|
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(
|
||||||
//! FDIR turns off device. Par1: event that caused recovery.
|
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);
|
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 = objects::NO_OBJECT,
|
FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT,
|
||||||
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);
|
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);
|
||||||
|
@ -40,7 +40,6 @@ class HasFileSystemIF {
|
|||||||
//! [EXPORT] : P1: Can be file system specific error code
|
//! [EXPORT] : P1: Can be file system specific error code
|
||||||
static constexpr ReturnValue_t GENERIC_FILE_ERROR = MAKE_RETURN_CODE(0);
|
static constexpr ReturnValue_t GENERIC_FILE_ERROR = MAKE_RETURN_CODE(0);
|
||||||
static constexpr ReturnValue_t GENERIC_DIR_ERROR = MAKE_RETURN_CODE(1);
|
static constexpr ReturnValue_t GENERIC_DIR_ERROR = MAKE_RETURN_CODE(1);
|
||||||
static constexpr ReturnValue_t FILESYSTEM_INACTIVE = MAKE_RETURN_CODE(2);
|
|
||||||
static constexpr ReturnValue_t GENERIC_RENAME_ERROR = MAKE_RETURN_CODE(3);
|
static constexpr ReturnValue_t GENERIC_RENAME_ERROR = MAKE_RETURN_CODE(3);
|
||||||
|
|
||||||
//! [EXPORT] : File system is currently busy
|
//! [EXPORT] : File system is currently busy
|
||||||
|
@ -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;
|
||||||
|
@ -16,24 +16,26 @@ class HasHealthIF {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF;
|
||||||
static constexpr ReturnValue_t OBJECT_NOT_HEALTHY = returnvalue::makeCode(INTERFACE_ID, 1);
|
static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1);
|
||||||
static constexpr ReturnValue_t INVALID_HEALTH_STATE = returnvalue::makeCode(INTERFACE_ID, 2);
|
static const ReturnValue_t INVALID_HEALTH_STATE = MAKE_RETURN_CODE(2);
|
||||||
static constexpr ReturnValue_t IS_EXTERNALLY_CONTROLLED = returnvalue::makeCode(INTERFACE_ID, 3);
|
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER_1;
|
||||||
//! P1: New Health, P2: Old Health
|
|
||||||
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
|
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
|
||||||
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
|
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
|
||||||
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
|
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
|
||||||
//! Assembly overwrites health information of children to keep satellite alive.
|
static const Event OVERWRITING_HEALTH =
|
||||||
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW);
|
MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep
|
||||||
//! Someone starts a recovery of a component (typically power-cycle). No parameters.
|
//!< satellite alive.
|
||||||
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM);
|
static const Event TRYING_RECOVERY =
|
||||||
//! Recovery is ongoing. Comes twice during recovery.
|
MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically
|
||||||
//! P1: 0 for the first, 1 for the second event. P2: 0
|
//!< power-cycle). No parameters.
|
||||||
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM);
|
static const Event RECOVERY_STEP =
|
||||||
//! Recovery was completed. Not necessarily successful. No parameters.
|
MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1:
|
||||||
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM);
|
//!< 0 for the first, 1 for the second event. P2: 0
|
||||||
|
static const Event RECOVERY_DONE = MAKE_EVENT(
|
||||||
|
12,
|
||||||
|
severity::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
|
||||||
|
|
||||||
virtual ~HasHealthIF() {}
|
virtual ~HasHealthIF() {}
|
||||||
|
|
||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
@ -5,7 +5,11 @@
|
|||||||
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId)
|
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId)
|
||||||
: objectId(objectId), owner(owner) {}
|
: objectId(objectId), owner(owner) {}
|
||||||
|
|
||||||
HealthHelper::~HealthHelper() { healthTable->removeObject(objectId); }
|
HealthHelper::~HealthHelper() {
|
||||||
|
if (healthTable != nullptr) {
|
||||||
|
healthTable->removeObject(objectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t HealthHelper::handleHealthCommand(CommandMessage* message) {
|
ReturnValue_t HealthHelper::handleHealthCommand(CommandMessage* message) {
|
||||||
switch (message->getCommand()) {
|
switch (message->getCommand()) {
|
||||||
|
@ -7,13 +7,11 @@
|
|||||||
|
|
||||||
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
|
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
|
||||||
poolManager(this, commandQueue),
|
poolManager(this, commandQueue),
|
||||||
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
||||||
internalErrorDataset(this) {
|
internalErrorDataset(this) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
|
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||||
@ -38,14 +36,15 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
|||||||
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
||||||
<< "occured: Queue | TM | Store : " << newQueueHits << " | " << newTmHits << " | "
|
<< "occured!" << std::endl;
|
||||||
<< newStoreHits << std::endl;
|
sif::debug << "Queue errors: " << newQueueHits << std::endl;
|
||||||
|
sif::debug << "TM errors: " << newTmHits << std::endl;
|
||||||
|
sif::debug << "Store errors: " << newStoreHits << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printDebug(
|
sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n");
|
||||||
"InternalErrorReporter::performOperation: Errors occured: Queue | TM | Store: %lu | %lu "
|
sif::printDebug("Queue errors: %lu\n", static_cast<unsigned int>(newQueueHits));
|
||||||
"| %lu\n",
|
sif::printDebug("TM errors: %lu\n", static_cast<unsigned int>(newTmHits));
|
||||||
static_cast<unsigned int>(newQueueHits), static_cast<unsigned int>(newTmHits),
|
sif::printDebug("Store errors: %lu\n", static_cast<unsigned int>(newStoreHits));
|
||||||
static_cast<unsigned int>(newStoreHits));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ class CommandMessageIF {
|
|||||||
static const Command_t CMD_NONE = MAKE_COMMAND_ID(0);
|
static const Command_t CMD_NONE = MAKE_COMMAND_ID(0);
|
||||||
static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID(1);
|
static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID(1);
|
||||||
//! Reply indicating that the current command was rejected,
|
//! Reply indicating that the current command was rejected,
|
||||||
//! Parameter 1 should contain the error code
|
//! par1 should contain the error code
|
||||||
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2);
|
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2);
|
||||||
|
|
||||||
virtual ~CommandMessageIF(){};
|
virtual ~CommandMessageIF(){};
|
||||||
|
@ -19,33 +19,32 @@ class HasModesIF {
|
|||||||
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
|
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER;
|
||||||
//! An object announces changing the mode. p1: target mode. p2: target submode
|
static const Event CHANGING_MODE =
|
||||||
static const Event CHANGING_MODE = MAKE_EVENT(0, severity::INFO);
|
MAKE_EVENT(0, severity::INFO); //!< An object announces changing the mode. p1: target mode.
|
||||||
//! An Object announces its mode; parameter1 is mode, parameter2 is submode
|
//!< p2: target submode
|
||||||
static const Event MODE_INFO = MAKE_EVENT(1, severity::INFO);
|
static const Event MODE_INFO = MAKE_EVENT(
|
||||||
|
1,
|
||||||
|
severity::INFO); //!< An Object announces its mode; parameter1 is mode, parameter2 is submode
|
||||||
static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
|
static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
|
||||||
static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
|
static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
|
||||||
static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH);
|
static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH);
|
||||||
//! Indicates a bug or configuration failure: Object is in a mode it should never be in.
|
static const Event OBJECT_IN_INVALID_MODE =
|
||||||
static const Event OBJECT_IN_INVALID_MODE = MAKE_EVENT(5, severity::LOW);
|
MAKE_EVENT(5, severity::LOW); //!< Indicates a bug or configuration failure: Object is in a
|
||||||
//! The mode is changed, but for some reason, the change is forced, i.e. EXTERNAL_CONTROL ignored.
|
//!< mode it should never be in.
|
||||||
//! p1: target mode. p2: target submode
|
static const Event FORCING_MODE = MAKE_EVENT(
|
||||||
static const Event FORCING_MODE = MAKE_EVENT(6, severity::MEDIUM);
|
6, severity::MEDIUM); //!< The mode is changed, but for some reason, the change is forced,
|
||||||
//! A mode command was rejected by the called object. Par1: called object id, Par2: return code.
|
//!< i.e. EXTERNAL_CONTROL ignored. p1: target mode. p2: target submode
|
||||||
static const Event MODE_CMD_REJECTED = MAKE_EVENT(7, severity::LOW);
|
static const Event MODE_CMD_REJECTED =
|
||||||
|
MAKE_EVENT(7, severity::LOW); //!< A mode command was rejected by the called object. Par1:
|
||||||
|
//!< called object id, Par2: return code.
|
||||||
|
|
||||||
//! The device is powered and ready to perform operations. In this mode, no commands are
|
static const Mode_t MODE_ON =
|
||||||
//! sent by the device handler itself, but direct commands van be commanded and will be
|
1; //!< The device is powered and ready to perform operations. In this mode, no commands are
|
||||||
//! interpreted
|
//!< sent by the device handler itself, but direct commands van be commanded and will be
|
||||||
static constexpr Mode_t MODE_ON = 1;
|
//!< interpreted
|
||||||
//! The device is powered off. The only command accepted in this mode is a mode change to on.
|
static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in
|
||||||
static constexpr Mode_t MODE_OFF = 0;
|
//!< this mode is a mode change to on.
|
||||||
|
static const Submode_t SUBMODE_NONE = 0; //!< To avoid checks against magic number "0".
|
||||||
static constexpr Mode_t MODE_INVALID = -1;
|
|
||||||
static constexpr Mode_t MODE_UNDEFINED = -2;
|
|
||||||
|
|
||||||
//! To avoid checks against magic number "0".
|
|
||||||
static const Submode_t SUBMODE_NONE = 0;
|
|
||||||
|
|
||||||
virtual ~HasModesIF() {}
|
virtual ~HasModesIF() {}
|
||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||||
|
@ -95,16 +95,13 @@ void ObjectManager::initialize() {
|
|||||||
for (auto const& it : objectList) {
|
for (auto const& it : objectList) {
|
||||||
result = it.second->initialize();
|
result = it.second->initialize();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
object_id_t var = it.first;
|
||||||
sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8)
|
sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8)
|
||||||
<< std::setfill('0') << it.first << " failed to initialize with code 0x" << result
|
<< std::setfill('0') << var
|
||||||
<< std::dec << std::setfill(' ') << std::endl;
|
<< " failed to "
|
||||||
#else
|
"initialize with code 0x"
|
||||||
sif::printError(
|
<< result << std::dec << std::setfill(' ') << std::endl;
|
||||||
"ObjectManager::initialize: Object 0x%08x failed to initialize with code 0x%04x\n", var,
|
|
||||||
it.first);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
errorCount++;
|
errorCount++;
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,7 @@ elseif(FSFW_OSAL MATCHES "host")
|
|||||||
|
|
||||||
else()
|
else()
|
||||||
|
|
||||||
message(
|
message(WARNING "The OS_FSFW variable was not set. Assuming host OS..")
|
||||||
WARNING
|
|
||||||
"${MSG_PREFIX} The FSFW_OSAL variable was not set. Assuming host OS..")
|
|
||||||
# Not set. Assumuing this is a host build, try to determine host OS
|
# Not set. Assumuing this is a host build, try to determine host OS
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_subdirectory(host)
|
add_subdirectory(host)
|
||||||
|
@ -66,8 +66,7 @@ class HasParametersIF {
|
|||||||
* @param newValues
|
* @param newValues
|
||||||
* @param startAtIndex Linear index, runs left to right, top to bottom for
|
* @param startAtIndex Linear index, runs left to right, top to bottom for
|
||||||
* matrix indexes.
|
* matrix indexes.
|
||||||
* @return returnvalue::OK if parameter is valid and a set function of the parameter wrapper was
|
* @return
|
||||||
* called.
|
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||||
ParameterWrapper *parameterWrapper,
|
ParameterWrapper *parameterWrapper,
|
||||||
|
@ -211,13 +211,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
|||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "ParameterWrapper::copyFrom: Called on read-only variable or "
|
sif::warning << "ParameterWrapper::copyFrom: Called on read-only variable!" << std::endl;
|
||||||
"data pointer not set"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning("ParameterWrapper::copyFrom: Called on read-only variable!\n");
|
||||||
"ParameterWrapper::copyFrom: Called on read-only variable "
|
|
||||||
"or data pointer not set\n");
|
|
||||||
#endif
|
#endif
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
return READONLY;
|
return READONLY;
|
||||||
@ -226,9 +222,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
|||||||
if (from->readonlyData == nullptr) {
|
if (from->readonlyData == nullptr) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "ParameterWrapper::copyFrom: Source not set" << std::endl;
|
sif::warning << "ParameterWrapper::copyFrom: Source not set!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning("ParameterWrapper::copyFrom: Source not set\n");
|
sif::printWarning("ParameterWrapper::copyFrom: Source not set!\n");
|
||||||
#endif
|
#endif
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
return SOURCE_NOT_SET;
|
return SOURCE_NOT_SET;
|
||||||
@ -237,9 +233,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
|||||||
if (type != from->type) {
|
if (type != from->type) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "ParameterWrapper::copyFrom: Datatype missmatch" << std::endl;
|
sif::warning << "ParameterWrapper::copyFrom: Datatype missmatch!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning("ParameterWrapper::copyFrom: Datatype missmatch\n");
|
sif::printWarning("ParameterWrapper::copyFrom: Datatype missmatch!\n");
|
||||||
#endif
|
#endif
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
return DATATYPE_MISSMATCH;
|
return DATATYPE_MISSMATCH;
|
||||||
@ -249,9 +245,9 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
|
|||||||
if (rows == 0 or columns == 0) {
|
if (rows == 0 or columns == 0) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "ParameterWrapper::copyFrom: Columns or rows zero" << std::endl;
|
sif::warning << "ParameterWrapper::copyFrom: Columns or rows zero!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning("ParameterWrapper::copyFrom: Columns or rows zero\n");
|
sif::printWarning("ParameterWrapper::copyFrom: Columns or rows zero!\n");
|
||||||
#endif
|
#endif
|
||||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
return COLUMN_OR_ROWS_ZERO;
|
return COLUMN_OR_ROWS_ZERO;
|
||||||
|
@ -29,9 +29,9 @@ class PowerSwitchIF {
|
|||||||
static const ReturnValue_t FUSE_ON = MAKE_RETURN_CODE(3);
|
static const ReturnValue_t FUSE_ON = MAKE_RETURN_CODE(3);
|
||||||
static const ReturnValue_t FUSE_OFF = MAKE_RETURN_CODE(4);
|
static const ReturnValue_t FUSE_OFF = MAKE_RETURN_CODE(4);
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_2;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_2;
|
||||||
//!< Someone detected that a switch went off which shouldn't. Severity:
|
static const Event SWITCH_WENT_OFF = MAKE_EVENT(
|
||||||
//!< Low, Parameter1: switchId1, Parameter2: switchId2
|
0, severity::LOW); //!< Someone detected that a switch went off which shouldn't. Severity:
|
||||||
static const Event SWITCH_WENT_OFF = MAKE_EVENT(0, severity::LOW);
|
//!< Low, Parameter1: switchId1, Parameter2: switchId2
|
||||||
/**
|
/**
|
||||||
* send a direct command to the Power Unit to enable/disable the specified switch.
|
* send a direct command to the Power Unit to enable/disable the specified switch.
|
||||||
*
|
*
|
||||||
|
@ -41,6 +41,8 @@ class Service11TelecommandScheduling final : public PusServiceBase {
|
|||||||
static constexpr ReturnValue_t INVALID_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 2);
|
static constexpr ReturnValue_t INVALID_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 2);
|
||||||
static constexpr ReturnValue_t TIMESHIFTING_NOT_POSSIBLE = returnvalue::makeCode(CLASS_ID, 3);
|
static constexpr ReturnValue_t TIMESHIFTING_NOT_POSSIBLE = returnvalue::makeCode(CLASS_ID, 3);
|
||||||
static constexpr ReturnValue_t INVALID_RELATIVE_TIME = returnvalue::makeCode(CLASS_ID, 4);
|
static constexpr ReturnValue_t INVALID_RELATIVE_TIME = returnvalue::makeCode(CLASS_ID, 4);
|
||||||
|
static constexpr ReturnValue_t CONTAINED_TC_TOO_SMALL = returnvalue::makeCode(CLASS_ID, 5);
|
||||||
|
static constexpr ReturnValue_t CONTAINED_TC_CRC_MISSMATCH = returnvalue::makeCode(CLASS_ID, 6);
|
||||||
|
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "fsfw/serialize/SerializeAdapter.h"
|
#include "fsfw/serialize/SerializeAdapter.h"
|
||||||
#include "fsfw/serviceinterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||||
|
#include "fsfw/tmtcpacket/pus/tc/PusTcIF.h"
|
||||||
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
|
||||||
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
|
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
|
||||||
|
|
||||||
@ -77,7 +79,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::performService
|
|||||||
// NOTE: The iterator is increased in the loop here. Increasing the iterator as for-loop arg
|
// NOTE: The iterator is increased in the loop here. Increasing the iterator as for-loop arg
|
||||||
// does not work in this case as we are deleting the current element here.
|
// does not work in this case as we are deleting the current element here.
|
||||||
for (auto it = telecommandMap.begin(); it != telecommandMap.end();) {
|
for (auto it = telecommandMap.begin(); it != telecommandMap.end();) {
|
||||||
if (it->first <= static_cast<uint32_t>(tNow.tv_sec)) {
|
if (it->first <= tNow.tv_sec) {
|
||||||
if (schedulingEnabled) {
|
if (schedulingEnabled) {
|
||||||
// release tc
|
// release tc
|
||||||
TmTcMessage releaseMsg(it->second.storeAddr);
|
TmTcMessage releaseMsg(it->second.storeAddr);
|
||||||
@ -171,6 +173,14 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (size < PusTcIF::MIN_SIZE) {
|
||||||
|
return CONTAINED_TC_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CRC::crc16ccitt(data, size) != 0) {
|
||||||
|
return CONTAINED_TC_CRC_MISSMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
// store currentPacket and receive the store address
|
// store currentPacket and receive the store address
|
||||||
store_address_t addr{};
|
store_address_t addr{};
|
||||||
if (tcStore->addData(&addr, data, size) != returnvalue::OK ||
|
if (tcStore->addData(&addr, data, size) != returnvalue::OK ||
|
||||||
|
@ -208,17 +208,17 @@ ReturnValue_t Service3Housekeeping::handleReply(const CommandMessage* reply,
|
|||||||
ReturnValue_t error = returnvalue::FAILED;
|
ReturnValue_t error = returnvalue::FAILED;
|
||||||
HousekeepingMessage::getHkRequestFailureReply(reply, &error);
|
HousekeepingMessage::getHkRequestFailureReply(reply, &error);
|
||||||
failureParameter2 = error;
|
failureParameter2 = error;
|
||||||
return returnvalue::FAILED;
|
return CommandingServiceBase::EXECUTION_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Service3Housekeeping::handleReply: Invalid reply with "
|
sif::warning << "Service3Housekeeping::handleReply: Invalid reply with "
|
||||||
<< "reply command " << command << std::endl;
|
<< "reply command " << command << "!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning(
|
||||||
"Service3Housekeeping::handleReply: Invalid reply with "
|
"Service3Housekeeping::handleReply: Invalid reply with "
|
||||||
"reply command %hu\n",
|
"reply command %hu!\n",
|
||||||
command);
|
command);
|
||||||
#endif
|
#endif
|
||||||
return CommandingServiceBase::INVALID_REPLY;
|
return CommandingServiceBase::INVALID_REPLY;
|
||||||
@ -248,28 +248,19 @@ void Service3Housekeeping::handleUnrequestedReply(CommandMessage* reply) {
|
|||||||
case (HousekeepingMessage::HK_REQUEST_FAILURE): {
|
case (HousekeepingMessage::HK_REQUEST_FAILURE): {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (CommandMessage::REPLY_REJECTED): {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "Service3Housekeeping::handleUnrequestedReply: Unexpected reply "
|
|
||||||
"rejected with error code"
|
|
||||||
<< reply->getParameter() << std::endl;
|
|
||||||
#else
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Service3Housekeeping::handleUnrequestedReply: Invalid reply with reply "
|
sif::warning << "Service3Housekeeping::handleUnrequestedReply: Invalid reply with reply "
|
||||||
"command "
|
"command "
|
||||||
<< command << "" << std::endl;
|
<< command << "!" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning(
|
||||||
"Service3Housekeeping::handleUnrequestedReply: Invalid reply with "
|
"Service3Housekeeping::handleUnrequestedReply: Invalid reply with "
|
||||||
"reply command %hu\n",
|
"reply command %hu!\n",
|
||||||
command);
|
command);
|
||||||
#endif
|
#endif
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +275,6 @@ void Service3Housekeeping::handleUnrequestedReply(CommandMessage* reply) {
|
|||||||
"Could not generate reply!\n");
|
"Could not generate reply!\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
CommandingServiceBase::handleUnrequestedReply(reply);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t Service3Housekeeping::getHkQueue() const { return commandQueue->getId(); }
|
MessageQueueId_t Service3Housekeeping::getHkQueue() const { return commandQueue->getId(); }
|
||||||
|
@ -13,10 +13,8 @@ Service5EventReporting::Service5EventReporting(PsbParams params, size_t maxNumbe
|
|||||||
storeHelper(params.apid),
|
storeHelper(params.apid),
|
||||||
tmHelper(params.serviceId, storeHelper, sendHelper),
|
tmHelper(params.serviceId, storeHelper, sendHelper),
|
||||||
maxNumberReportsPerCycle(maxNumberReportsPerCycle) {
|
maxNumberReportsPerCycle(maxNumberReportsPerCycle) {
|
||||||
auto mqArgs = MqArgs(getObjectId(), static_cast<void*>(this));
|
|
||||||
psbParams.name = "PUS 5 Event Reporting";
|
psbParams.name = "PUS 5 Event Reporting";
|
||||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||||
messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Service5EventReporting::~Service5EventReporting() {
|
Service5EventReporting::~Service5EventReporting() {
|
||||||
@ -40,6 +38,9 @@ ReturnValue_t Service5EventReporting::performService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "Service5EventReporting::generateEventReport: Too many events" << std::endl;
|
||||||
|
#endif
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
class Service9TimeManagement : public PusServiceBase {
|
class Service9TimeManagement : public PusServiceBase {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
|
||||||
//!< Clock has been set. P1: New Uptime. P2: Old Uptime
|
static constexpr Event CLOCK_SET =
|
||||||
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
|
MAKE_EVENT(0, severity::INFO); //!< Clock has been set. P1: New Uptime. P2: Old Uptime
|
||||||
//!< Clock could not be set. P1: Returncode.
|
static constexpr Event CLOCK_SET_FAILURE =
|
||||||
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(1, severity::LOW);
|
MAKE_EVENT(1, severity::LOW); //!< Clock could not be set. P1: Returncode.
|
||||||
|
|
||||||
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -33,12 +33,8 @@ struct SequenceEntry : public TableSequenceBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class extends the SubsystemBase to perform the management of mode tables
|
* @brief TODO: documentation missing
|
||||||
* and mode sequences
|
|
||||||
* @details
|
* @details
|
||||||
* This class is able to use mode tables and sequences to command all its children into the
|
|
||||||
* right mode. Fallback sequences can be used to handle failed transitions or have a fallback
|
|
||||||
* in case a component can't keep its current mode.
|
|
||||||
*/
|
*/
|
||||||
class Subsystem : public SubsystemBase, public HasModeSequenceIF {
|
class Subsystem : public SubsystemBase, public HasModeSequenceIF {
|
||||||
public:
|
public:
|
||||||
|
@ -8,13 +8,11 @@ SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t
|
|||||||
uint16_t commandQueueDepth)
|
uint16_t commandQueueDepth)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
mode(initialMode),
|
mode(initialMode),
|
||||||
|
commandQueue(QueueFactory::instance()->createMessageQueue(commandQueueDepth,
|
||||||
|
CommandMessage::MAX_MESSAGE_SIZE)),
|
||||||
healthHelper(this, setObjectId),
|
healthHelper(this, setObjectId),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
parentId(parent) {
|
parentId(parent) {}
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
commandQueueDepth, CommandMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
|
||||||
@ -33,9 +31,8 @@ ReturnValue_t SubsystemBase::registerChild(object_id_t objectId) {
|
|||||||
info.mode = MODE_OFF;
|
info.mode = MODE_OFF;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// intentional to force an initial command during system startup
|
|
||||||
info.commandQueue = child->getCommandQueue();
|
info.commandQueue = child->getCommandQueue();
|
||||||
info.mode = HasModesIF::MODE_UNDEFINED;
|
info.mode = -1; // intentional to force an initial command during system startup
|
||||||
}
|
}
|
||||||
|
|
||||||
info.submode = SUBMODE_NONE;
|
info.submode = SUBMODE_NONE;
|
||||||
|
@ -15,14 +15,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup subsystems Subsystem Objects
|
* @defgroup subsystems Subsystem Objects
|
||||||
* All Subsystem and Assemblies can derive from this class. It contains helper classes to
|
* Contains all Subsystem and Assemblies
|
||||||
* perform mode and health handling, which allows OBSW developers to build a mode tree for
|
|
||||||
* the whole satellite.
|
|
||||||
*
|
|
||||||
* Aside from setting up a mode tree and being able to executing mode tables, this class does not
|
|
||||||
* provide an implementation on what to do with the features. To build a mode tree, helper classes
|
|
||||||
* like the #AssemblyBase or the #Subsystem class extend and use the functionality of the base
|
|
||||||
* class.
|
|
||||||
*/
|
*/
|
||||||
class SubsystemBase : public SystemObject,
|
class SubsystemBase : public SystemObject,
|
||||||
public HasModesIF,
|
public HasModesIF,
|
||||||
@ -102,7 +95,6 @@ class SubsystemBase : public SystemObject,
|
|||||||
Submode_t targetSubmode);
|
Submode_t targetSubmode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function takes care of sending all according mode commands specified inside a mode table.
|
|
||||||
* We need to know the target Submode, as children are able to inherit the submode
|
* We need to know the target Submode, as children are able to inherit the submode
|
||||||
* Still, we have a default for all child implementations which do not use submode inheritance
|
* Still, we have a default for all child implementations which do not use submode inheritance
|
||||||
*/
|
*/
|
||||||
|
@ -4,13 +4,14 @@
|
|||||||
|
|
||||||
AbstractTemperatureSensor::AbstractTemperatureSensor(object_id_t setObjectid,
|
AbstractTemperatureSensor::AbstractTemperatureSensor(object_id_t setObjectid,
|
||||||
ThermalModuleIF *thermalModule)
|
ThermalModuleIF *thermalModule)
|
||||||
: SystemObject(setObjectid), healthHelper(this, setObjectid), parameterHelper(this) {
|
: SystemObject(setObjectid),
|
||||||
if (thermalModule != nullptr) {
|
commandQueue(NULL),
|
||||||
|
healthHelper(this, setObjectid),
|
||||||
|
parameterHelper(this) {
|
||||||
|
if (thermalModule != NULL) {
|
||||||
thermalModule->registerSensor(this);
|
thermalModule->registerSensor(this);
|
||||||
}
|
}
|
||||||
auto mqArgs = MqArgs(setObjectid, static_cast<void *>(this));
|
commandQueue = QueueFactory::instance()->createMessageQueue();
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractTemperatureSensor::~AbstractTemperatureSensor() {
|
AbstractTemperatureSensor::~AbstractTemperatureSensor() {
|
||||||
|
@ -51,7 +51,7 @@ class AbstractTemperatureSensor : public HasHealthIF,
|
|||||||
HasHealthIF::HealthState getHealth();
|
HasHealthIF::HealthState getHealth();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageQueueIF* commandQueue = nullptr;
|
MessageQueueIF* commandQueue;
|
||||||
HealthHelper healthHelper;
|
HealthHelper healthHelper;
|
||||||
ParameterHelper parameterHelper;
|
ParameterHelper parameterHelper;
|
||||||
|
|
||||||
|
@ -12,9 +12,7 @@ Heater::Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1)
|
|||||||
switch1(switch1),
|
switch1(switch1),
|
||||||
heaterOnCountdown(10800000) /*about two orbits*/,
|
heaterOnCountdown(10800000) /*about two orbits*/,
|
||||||
parameterHelper(this) {
|
parameterHelper(this) {
|
||||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
eventQueue = QueueFactory::instance()->createMessageQueue();
|
||||||
eventQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Heater::~Heater() { QueueFactory::instance()->deleteMessageQueue(eventQueue); }
|
Heater::~Heater() { QueueFactory::instance()->deleteMessageQueue(eventQueue); }
|
||||||
|
@ -13,9 +13,9 @@ class ThermalComponentIF : public HasParametersIF {
|
|||||||
static const Event COMPONENT_TEMP_HIGH = MAKE_EVENT(2, severity::LOW);
|
static const Event COMPONENT_TEMP_HIGH = MAKE_EVENT(2, severity::LOW);
|
||||||
static const Event COMPONENT_TEMP_OOL_LOW = MAKE_EVENT(3, severity::LOW);
|
static const Event COMPONENT_TEMP_OOL_LOW = MAKE_EVENT(3, severity::LOW);
|
||||||
static const Event COMPONENT_TEMP_OOL_HIGH = MAKE_EVENT(4, severity::LOW);
|
static const Event COMPONENT_TEMP_OOL_HIGH = MAKE_EVENT(4, severity::LOW);
|
||||||
//!< Is thrown when a device should start-up, but the temperature is out
|
static const Event TEMP_NOT_IN_OP_RANGE = MAKE_EVENT(
|
||||||
//!< of OP range. P1: thermalState of the component, P2: 0
|
5, severity::LOW); //!< Is thrown when a device should start-up, but the temperature is out
|
||||||
static const Event TEMP_NOT_IN_OP_RANGE = MAKE_EVENT(5, severity::LOW);
|
//!< of OP range. P1: thermalState of the component, P2: 0
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::THERMAL_COMPONENT_IF;
|
static const uint8_t INTERFACE_ID = CLASS_ID::THERMAL_COMPONENT_IF;
|
||||||
static const ReturnValue_t INVALID_TARGET_STATE = MAKE_RETURN_CODE(1);
|
static const ReturnValue_t INVALID_TARGET_STATE = MAKE_RETURN_CODE(1);
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
#include "fsfw/timemanager/Countdown.h"
|
#include "fsfw/timemanager/Countdown.h"
|
||||||
|
|
||||||
Countdown::Countdown(uint32_t initialTimeout, bool startImmediately) : timeout(initialTimeout) {
|
Countdown::Countdown(uint32_t initialTimeout) : timeout(initialTimeout) {
|
||||||
if (startImmediately) {
|
setTimeout(initialTimeout);
|
||||||
setTimeout(initialTimeout);
|
|
||||||
} else {
|
|
||||||
timeout = initialTimeout;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Countdown::~Countdown() {}
|
Countdown::~Countdown() {}
|
||||||
|
@ -26,9 +26,8 @@ class Countdown {
|
|||||||
* Otherwise a call to hasTimedOut might return True.
|
* Otherwise a call to hasTimedOut might return True.
|
||||||
*
|
*
|
||||||
* @param initialTimeout Countdown duration in milliseconds
|
* @param initialTimeout Countdown duration in milliseconds
|
||||||
* @param startImmediately Set to false if countdown should not be started immediately
|
|
||||||
*/
|
*/
|
||||||
Countdown(uint32_t initialTimeout = 0, bool startImmediately = true);
|
Countdown(uint32_t initialTimeout = 0);
|
||||||
~Countdown();
|
~Countdown();
|
||||||
/**
|
/**
|
||||||
* Call to set a new countdown duration.
|
* Call to set a new countdown duration.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef FSFW_TIMEMANAGER_TIMEREADERIF_H
|
#ifndef FSFW_TIMEMANAGER_TIMEREADERIF_H
|
||||||
#define FSFW_TIMEMANAGER_TIMEREADERIF_H
|
#define FSFW_TIMEMANAGER_TIMEREADERIF_H
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "fsfw/platform.h"
|
#include "fsfw/platform.h"
|
||||||
|
@ -33,47 +33,50 @@ class TmStoreBackendIF : public HasParametersIF {
|
|||||||
static const ReturnValue_t INVALID_REQUEST = MAKE_RETURN_CODE(15);
|
static const ReturnValue_t INVALID_REQUEST = MAKE_RETURN_CODE(15);
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MEMORY;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MEMORY;
|
||||||
//! Initiating sending data to store failed. Low, par1:
|
static const Event STORE_SEND_WRITE_FAILED =
|
||||||
//! returnCode, par2: integer (debug info)
|
MAKE_EVENT(0, severity::LOW); //!< Initiating sending data to store failed. Low, par1:
|
||||||
static const Event STORE_SEND_WRITE_FAILED = MAKE_EVENT(0, severity::LOW);
|
//!< returnCode, par2: integer (debug info)
|
||||||
//! Data was sent, but writing failed. Low, par1: returnCode, par2: 0
|
static const Event STORE_WRITE_FAILED = MAKE_EVENT(
|
||||||
static const Event STORE_WRITE_FAILED = MAKE_EVENT(1, severity::LOW);
|
1, severity::LOW); //!< Data was sent, but writing failed. Low, par1: returnCode, par2: 0
|
||||||
//! Initiating reading data from store failed. Low, par1: returnCode, par2: 0
|
static const Event STORE_SEND_READ_FAILED =
|
||||||
static const Event STORE_SEND_READ_FAILED = MAKE_EVENT(2, severity::LOW);
|
MAKE_EVENT(2, severity::LOW); //!< Initiating reading data from store failed. Low, par1:
|
||||||
//! Data was requested, but access failed. Low, par1: returnCode, par2: 0
|
//!< returnCode, par2: 0
|
||||||
static const Event STORE_READ_FAILED = MAKE_EVENT(3, severity::LOW);
|
static const Event STORE_READ_FAILED = MAKE_EVENT(
|
||||||
//! An unexpected TM packet or data message occurred. Low, par1: 0, par2: integer (debug info)
|
3, severity::LOW); //!< Data was requested, but access failed. Low, par1: returnCode, par2: 0
|
||||||
static const Event UNEXPECTED_MSG = MAKE_EVENT(4, severity::LOW);
|
static const Event UNEXPECTED_MSG =
|
||||||
//! Storing data failed. May simply be a full store. Low, par1: returnCode,
|
MAKE_EVENT(4, severity::LOW); //!< An unexpected TM packet or data message occurred. Low,
|
||||||
//! par2: integer (sequence count of failed packet).
|
//!< par1: 0, par2: integer (debug info)
|
||||||
static const Event STORING_FAILED = MAKE_EVENT(5, severity::LOW);
|
static const Event STORING_FAILED = MAKE_EVENT(
|
||||||
//! Dumping retrieved data failed. Low, par1: returnCode,
|
5, severity::LOW); //!< Storing data failed. May simply be a full store. Low, par1:
|
||||||
//! par2: integer (sequence count of failed packet).
|
//!< returnCode, par2: integer (sequence count of failed packet).
|
||||||
static const Event TM_DUMP_FAILED = MAKE_EVENT(6, severity::LOW);
|
static const Event TM_DUMP_FAILED =
|
||||||
//! Corrupted init data or read error. Low, par1: returnCode, par2: integer (debug info)
|
MAKE_EVENT(6, severity::LOW); //!< Dumping retrieved data failed. Low, par1: returnCode,
|
||||||
//! Store was not initialized. Starts empty. Info, parameters both zero.
|
//!< par2: integer (sequence count of failed packet).
|
||||||
static const Event STORE_INIT_FAILED = MAKE_EVENT(7, severity::LOW);
|
static const Event STORE_INIT_FAILED =
|
||||||
//! Data was read out, but it is inconsistent. Low par1:
|
MAKE_EVENT(7, severity::LOW); //!< Corrupted init data or read error. Low, par1: returnCode,
|
||||||
//! Memory address of corruption, par2: integer (debug info)
|
//!< par2: integer (debug info)
|
||||||
static const Event STORE_INIT_EMPTY = MAKE_EVENT(8, severity::INFO);
|
static const Event STORE_INIT_EMPTY = MAKE_EVENT(
|
||||||
|
8, severity::INFO); //!< Store was not initialized. Starts empty. Info, parameters both zero.
|
||||||
static const Event STORE_CONTENT_CORRUPTED = MAKE_EVENT(9, severity::LOW);
|
static const Event STORE_CONTENT_CORRUPTED =
|
||||||
//! Info event indicating the store will be initialized, either at boot or after IOB switch.
|
MAKE_EVENT(9, severity::LOW); //!< Data was read out, but it is inconsistent. Low par1:
|
||||||
//! Info. pars: 0
|
//!< Memory address of corruption, par2: integer (debug info)
|
||||||
static const Event STORE_INITIALIZE = MAKE_EVENT(10, severity::INFO);
|
static const Event STORE_INITIALIZE =
|
||||||
//! Info event indicating the store was successfully initialized, either at boot or after
|
MAKE_EVENT(10, severity::INFO); //!< Info event indicating the store will be initialized,
|
||||||
//! IOB switch. Info. pars: 0
|
//!< either at boot or after IOB switch. Info. pars: 0
|
||||||
static const Event INIT_DONE = MAKE_EVENT(11, severity::INFO);
|
static const Event INIT_DONE = MAKE_EVENT(
|
||||||
//! Info event indicating that dumping finished successfully.
|
11, severity::INFO); //!< Info event indicating the store was successfully initialized,
|
||||||
//! par1: Number of dumped packets. par2: APID/SSC (16bits each)
|
//!< either at boot or after IOB switch. Info. pars: 0
|
||||||
static const Event DUMP_FINISHED = MAKE_EVENT(12, severity::INFO);
|
static const Event DUMP_FINISHED = MAKE_EVENT(
|
||||||
//! Info event indicating that deletion finished successfully.
|
12, severity::INFO); //!< Info event indicating that dumping finished successfully. par1:
|
||||||
//! par1:Number of deleted packets. par2: APID/SSC (16bits each)
|
//!< Number of dumped packets. par2: APID/SSC (16bits each)
|
||||||
static const Event DELETION_FINISHED = MAKE_EVENT(13, severity::INFO);
|
static const Event DELETION_FINISHED = MAKE_EVENT(
|
||||||
//! Info event indicating that something went wrong during deletion. pars: 0
|
13, severity::INFO); //!< Info event indicating that deletion finished successfully. par1:
|
||||||
static const Event DELETION_FAILED = MAKE_EVENT(14, severity::LOW);
|
//!< Number of deleted packets. par2: APID/SSC (16bits each)
|
||||||
//! Info that the a auto catalog report failed
|
static const Event DELETION_FAILED = MAKE_EVENT(
|
||||||
static const Event AUTO_CATALOGS_SENDING_FAILED = MAKE_EVENT(15, severity::INFO);
|
14,
|
||||||
|
severity::LOW); //!< Info event indicating that something went wrong during deletion. pars: 0
|
||||||
|
static const Event AUTO_CATALOGS_SENDING_FAILED =
|
||||||
|
MAKE_EVENT(15, severity::INFO); //!< Info that the a auto catalog report failed
|
||||||
|
|
||||||
virtual ~TmStoreBackendIF() {}
|
virtual ~TmStoreBackendIF() {}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ SpacePacketReader::~SpacePacketReader() = default;
|
|||||||
|
|
||||||
inline uint16_t SpacePacketReader::getPacketIdRaw() const { return ccsds::getPacketId(*spHeader); }
|
inline uint16_t SpacePacketReader::getPacketIdRaw() const { return ccsds::getPacketId(*spHeader); }
|
||||||
|
|
||||||
const uint8_t* SpacePacketReader::getPacketData() { return packetDataField; }
|
const uint8_t* SpacePacketReader::getPacketData() const { return packetDataField; }
|
||||||
|
|
||||||
ReturnValue_t SpacePacketReader::setData(uint8_t* data, size_t maxSize_, void* args) {
|
ReturnValue_t SpacePacketReader::setData(uint8_t* data, size_t maxSize_, void* args) {
|
||||||
return setInternalFields(data, maxSize_);
|
return setInternalFields(data, maxSize_);
|
||||||
|
@ -71,7 +71,7 @@ class SpacePacketReader : public SpacePacketIF,
|
|||||||
// Helper methods:
|
// Helper methods:
|
||||||
[[nodiscard]] ReturnValue_t checkSize() const;
|
[[nodiscard]] ReturnValue_t checkSize() const;
|
||||||
|
|
||||||
const uint8_t* getPacketData();
|
const uint8_t* getPacketData() const;
|
||||||
|
|
||||||
ReturnValue_t setReadOnlyData(const uint8_t* data, size_t maxSize);
|
ReturnValue_t setReadOnlyData(const uint8_t* data, size_t maxSize);
|
||||||
|
|
||||||
|
@ -27,10 +27,8 @@ CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t a
|
|||||||
verificationReporter(verificationReporter),
|
verificationReporter(verificationReporter),
|
||||||
commandMap(numberOfParallelCommands),
|
commandMap(numberOfParallelCommands),
|
||||||
name(name) {
|
name(name) {
|
||||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth);
|
||||||
size_t mqSz = MessageQueueMessage::MAX_MESSAGE_SIZE;
|
requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth);
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth, mqSz, &mqArgs);
|
|
||||||
requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth, mqSz, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandingServiceBase::setPacketSource(object_id_t packetSource_) {
|
void CommandingServiceBase::setPacketSource(object_id_t packetSource_) {
|
||||||
@ -225,7 +223,7 @@ void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, Comma
|
|||||||
|
|
||||||
// In case a new command is to be sent immediately, this is performed here.
|
// In case a new command is to be sent immediately, this is performed here.
|
||||||
// If no new command is sent, only analyse reply result by initializing
|
// If no new command is sent, only analyse reply result by initializing
|
||||||
// sendResult as returnvalue::OK
|
// sendResult as RETURN_OK
|
||||||
ReturnValue_t sendResult = returnvalue::OK;
|
ReturnValue_t sendResult = returnvalue::OK;
|
||||||
if (nextCommand->getCommand() != CommandMessage::CMD_NONE) {
|
if (nextCommand->getCommand() != CommandMessage::CMD_NONE) {
|
||||||
sendResult = commandQueue->sendMessage(reply->getSender(), nextCommand);
|
sendResult = commandQueue->sendMessage(reply->getSender(), nextCommand);
|
||||||
|
@ -11,7 +11,7 @@ class SourceSequenceCounter {
|
|||||||
SourceSequenceCounter(uint16_t initialSequenceCount = 0) : sequenceCount(initialSequenceCount) {}
|
SourceSequenceCounter(uint16_t initialSequenceCount = 0) : sequenceCount(initialSequenceCount) {}
|
||||||
void increment() { sequenceCount = (sequenceCount + 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
void increment() { sequenceCount = (sequenceCount + 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||||
void decrement() { sequenceCount = (sequenceCount - 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
void decrement() { sequenceCount = (sequenceCount - 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||||
uint16_t get() { return this->sequenceCount; }
|
uint16_t get() const { return this->sequenceCount; }
|
||||||
void reset(uint16_t toValue = 0) { sequenceCount = toValue % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
void reset(uint16_t toValue = 0) { sequenceCount = toValue % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||||
SourceSequenceCounter& operator++(int) {
|
SourceSequenceCounter& operator++(int) {
|
||||||
this->increment();
|
this->increment();
|
||||||
|
@ -16,9 +16,7 @@ TmTcBridge::TmTcBridge(const char* name, object_id_t objectId, object_id_t tcDes
|
|||||||
tcDestination(tcDestination)
|
tcDestination(tcDestination)
|
||||||
|
|
||||||
{
|
{
|
||||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH);
|
||||||
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(
|
|
||||||
TMTC_RECEPTION_QUEUE_DEPTH, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); }
|
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); }
|
||||||
@ -37,7 +35,7 @@ ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle(uint8_t sentPacketsPerC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(unsigned int maxNumberOfPacketsStored) {
|
ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored) {
|
||||||
if (maxNumberOfPacketsStored <= LIMIT_DOWNLINK_PACKETS_STORED) {
|
if (maxNumberOfPacketsStored <= LIMIT_DOWNLINK_PACKETS_STORED) {
|
||||||
this->maxNumberOfPacketsStored = maxNumberOfPacketsStored;
|
this->maxNumberOfPacketsStored = maxNumberOfPacketsStored;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
@ -173,18 +171,15 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage* message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tmFifo->full()) {
|
if (tmFifo->full()) {
|
||||||
if (warningSwitch) {
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
|
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
|
||||||
"of stored packet IDs reached!"
|
"of stored packet IDs reached!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning(
|
||||||
"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;
|
|
||||||
}
|
|
||||||
if (overwriteOld) {
|
if (overwriteOld) {
|
||||||
tmFifo->retrieve(&storeId);
|
tmFifo->retrieve(&storeId);
|
||||||
tmStore->deleteData(storeId);
|
tmStore->deleteData(storeId);
|
||||||
|
@ -17,7 +17,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
public:
|
public:
|
||||||
static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
|
static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
|
||||||
static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15;
|
static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15;
|
||||||
static constexpr unsigned int LIMIT_DOWNLINK_PACKETS_STORED = 1000;
|
static constexpr uint8_t LIMIT_DOWNLINK_PACKETS_STORED = 200;
|
||||||
|
|
||||||
static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5;
|
static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5;
|
||||||
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
|
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
|
||||||
@ -42,7 +42,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
* @return -@c returnvalue::OK if value was set successfully
|
* @return -@c returnvalue::OK if value was set successfully
|
||||||
* -@c returnvalue::FAILED otherwise, stored value stays the same
|
* -@c returnvalue::FAILED otherwise, stored value stays the same
|
||||||
*/
|
*/
|
||||||
ReturnValue_t setMaxNumberOfPacketsStored(unsigned int maxNumberOfPacketsStored);
|
ReturnValue_t setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will set up the bridge to overwrite old data in the FIFO.
|
* This will set up the bridge to overwrite old data in the FIFO.
|
||||||
@ -65,15 +65,13 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||||
|
|
||||||
/** AcceptsTelemetryIF override */
|
/** AcceptsTelemetryIF override */
|
||||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override;
|
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
|
||||||
|
|
||||||
/** AcceptsTelecommandsIF override */
|
/** AcceptsTelecommandsIF override */
|
||||||
uint32_t getIdentifier() const override;
|
uint32_t getIdentifier() const override;
|
||||||
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 = "";
|
||||||
|
|
||||||
@ -154,7 +152,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
*/
|
*/
|
||||||
DynamicFIFO<store_address_t>* tmFifo = nullptr;
|
DynamicFIFO<store_address_t>* tmFifo = nullptr;
|
||||||
uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE;
|
uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE;
|
||||||
unsigned int maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED;
|
uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_TMTCSERVICES_TMTCBRIDGE_H_ */
|
#endif /* FSFW_TMTCSERVICES_TMTCBRIDGE_H_ */
|
||||||
|
@ -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
|
|
@ -46,9 +46,9 @@ class GpioIF {
|
|||||||
* an ouput or input gpio.
|
* an ouput or input gpio.
|
||||||
*
|
*
|
||||||
* @param gpioId A unique number which specifies the GPIO to read.
|
* @param gpioId A unique number which specifies the GPIO to read.
|
||||||
* @param gpioState State of GPIO will be written to this reference
|
* @param gpioState State of GPIO will be written to this pointer.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t readGpio(gpioId_t gpioId, gpio::Levels& gpioState) = 0;
|
virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* COMMON_GPIO_GPIOIF_H_ */
|
#endif /* COMMON_GPIO_GPIOIF_H_ */
|
||||||
|
@ -17,7 +17,7 @@ using gpioId_t = uint16_t;
|
|||||||
|
|
||||||
namespace gpio {
|
namespace gpio {
|
||||||
|
|
||||||
enum class Levels : int { LOW = 0, HIGH = 1, FAILED = -1, NONE = 99 };
|
enum class Levels : int { LOW = 0, HIGH = 1, NONE = 99 };
|
||||||
|
|
||||||
enum class Direction : int { IN = 0, OUT = 1 };
|
enum class Direction : int { IN = 0, OUT = 1 };
|
||||||
|
|
||||||
|
@ -252,8 +252,6 @@ ReturnValue_t GyroHandlerL3GD20H::initializeLocalDataPool(localpool::DataPool &l
|
|||||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Y, new PoolEntry<float>({0.0}));
|
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Y, new PoolEntry<float>({0.0}));
|
||||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Z, new PoolEntry<float>({0.0}));
|
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Z, new PoolEntry<float>({0.0}));
|
||||||
localDataPoolMap.emplace(L3GD20H::TEMPERATURE, new PoolEntry<float>({0.0}));
|
localDataPoolMap.emplace(L3GD20H::TEMPERATURE, new PoolEntry<float>({0.0}));
|
||||||
poolManager.subscribeForRegularPeriodicPacket(
|
|
||||||
subdp::RegularHkPeriodicParams(dataset.getSid(), false, 10.0));
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ ReturnValue_t MgmLIS3MDLHandler::scanForReply(const uint8_t *start, size_t len,
|
|||||||
#endif
|
#endif
|
||||||
return DeviceHandlerIF::INVALID_DATA;
|
return DeviceHandlerIF::INVALID_DATA;
|
||||||
}
|
}
|
||||||
if (getMode() == _MODE_START_UP) {
|
if (mode == _MODE_START_UP) {
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +224,7 @@ ReturnValue_t MgmLIS3MDLHandler::scanForReply(const uint8_t *start, size_t len,
|
|||||||
return DeviceHandlerIF::INVALID_DATA;
|
return DeviceHandlerIF::INVALID_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getMode() == _MODE_START_UP) {
|
if (mode == _MODE_START_UP) {
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -371,16 +371,13 @@ float MgmLIS3MDLHandler::getSensitivityFactor(MGMLIS3MDL::Sensitivies sens) {
|
|||||||
|
|
||||||
ReturnValue_t MgmLIS3MDLHandler::enableTemperatureSensor(const uint8_t *commandData,
|
ReturnValue_t MgmLIS3MDLHandler::enableTemperatureSensor(const uint8_t *commandData,
|
||||||
size_t commandDataLen) {
|
size_t commandDataLen) {
|
||||||
if (commandData == nullptr) {
|
|
||||||
return INVALID_COMMAND_PARAMETER;
|
|
||||||
}
|
|
||||||
triggerEvent(CHANGE_OF_SETUP_PARAMETER);
|
triggerEvent(CHANGE_OF_SETUP_PARAMETER);
|
||||||
uint32_t size = 2;
|
uint32_t size = 2;
|
||||||
commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1);
|
commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1);
|
||||||
if (commandDataLen > 1) {
|
if (commandDataLen > 1) {
|
||||||
return INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS;
|
return INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS;
|
||||||
}
|
}
|
||||||
switch (commandData[0]) {
|
switch (*commandData) {
|
||||||
case (MGMLIS3MDL::ON): {
|
case (MGMLIS3MDL::ON): {
|
||||||
commandBuffer[1] = registers[0] | (1 << 7);
|
commandBuffer[1] = registers[0] | (1 << 7);
|
||||||
break;
|
break;
|
||||||
|
@ -169,7 +169,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const
|
|||||||
case (RM3100::CONFIGURE_CYCLE_COUNT):
|
case (RM3100::CONFIGURE_CYCLE_COUNT):
|
||||||
case (RM3100::CONFIGURE_TMRC): {
|
case (RM3100::CONFIGURE_TMRC): {
|
||||||
// We can only check whether write was successful with read operation
|
// We can only check whether write was successful with read operation
|
||||||
if (getMode() == _MODE_START_UP) {
|
if (mode == _MODE_START_UP) {
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -192,7 +192,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const
|
|||||||
if (packet[1] == tmrcRegValue) {
|
if (packet[1] == tmrcRegValue) {
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
// Reading TMRC was commanded. Trigger event to inform ground
|
// Reading TMRC was commanded. Trigger event to inform ground
|
||||||
if (getMode() != _MODE_START_UP) {
|
if (mode != _MODE_START_UP) {
|
||||||
triggerEvent(tmrcSet, tmrcRegValue, 0);
|
triggerEvent(tmrcSet, tmrcRegValue, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -211,7 +211,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const
|
|||||||
return DeviceHandlerIF::DEVICE_REPLY_INVALID;
|
return DeviceHandlerIF::DEVICE_REPLY_INVALID;
|
||||||
}
|
}
|
||||||
// Reading TMRC was commanded. Trigger event to inform ground
|
// Reading TMRC was commanded. Trigger event to inform ground
|
||||||
if (getMode() != _MODE_START_UP) {
|
if (mode != _MODE_START_UP) {
|
||||||
uint32_t eventParam1 = (cycleCountX << 16) | cycleCountY;
|
uint32_t eventParam1 = (cycleCountX << 16) | cycleCountY;
|
||||||
triggerEvent(cycleCountersSet, eventParam1, cycleCountZ);
|
triggerEvent(cycleCountersSet, eventParam1, cycleCountZ);
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,14 @@ endif()
|
|||||||
target_sources(${LIB_FSFW_NAME} PRIVATE UnixFileGuard.cpp CommandExecutor.cpp
|
target_sources(${LIB_FSFW_NAME} PRIVATE UnixFileGuard.cpp CommandExecutor.cpp
|
||||||
utility.cpp)
|
utility.cpp)
|
||||||
|
|
||||||
|
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
|
||||||
|
add_subdirectory(gpio)
|
||||||
|
endif()
|
||||||
|
if(FSFW_HAL_LINUX_ADD_SERIAL_DRIVERS)
|
||||||
|
add_subdirectory(serial)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS)
|
if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS)
|
||||||
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
|
|
||||||
add_subdirectory(gpio)
|
|
||||||
endif()
|
|
||||||
add_subdirectory(uart)
|
|
||||||
# Adding those does not really make sense on Apple systems which are generally
|
# Adding those does not really make sense on Apple systems which are generally
|
||||||
# host systems. It won't even compile as the headers are missing
|
# host systems. It won't even compile as the headers are missing
|
||||||
if(NOT APPLE)
|
if(NOT APPLE)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "fsfw/FSFW.h"
|
#include "fsfw/FSFW.h"
|
||||||
#include "fsfw/serviceinterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
UnixFileGuard::UnixFileGuard(const std::string& device, int* fileDescriptor, int flags,
|
UnixFileGuard::UnixFileGuard(std::string device, int* fileDescriptor, int flags,
|
||||||
std::string diagnosticPrefix)
|
std::string diagnosticPrefix)
|
||||||
: fileDescriptor(fileDescriptor) {
|
: fileDescriptor(fileDescriptor) {
|
||||||
if (fileDescriptor == nullptr) {
|
if (fileDescriptor == nullptr) {
|
||||||
|
@ -15,7 +15,7 @@ class UnixFileGuard {
|
|||||||
|
|
||||||
static constexpr ReturnValue_t OPEN_FILE_FAILED = 1;
|
static constexpr ReturnValue_t OPEN_FILE_FAILED = 1;
|
||||||
|
|
||||||
UnixFileGuard(const std::string& device, int* fileDescriptor, int flags,
|
UnixFileGuard(std::string device, int* fileDescriptor, int flags,
|
||||||
std::string diagnosticPrefix = "");
|
std::string diagnosticPrefix = "");
|
||||||
|
|
||||||
virtual ~UnixFileGuard();
|
virtual ~UnixFileGuard();
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
#ifndef FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_
|
|
||||||
#define FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_
|
|
||||||
|
|
||||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
|
||||||
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Additional abstraction layer for handling GPIOs.
|
|
||||||
*
|
|
||||||
* @author J. Meier
|
|
||||||
*/
|
|
||||||
class Gpio {
|
|
||||||
public:
|
|
||||||
Gpio(gpioId_t gpioId, GpioIF* gpioIF) : gpioId(gpioId), gpioIF(gpioIF) {
|
|
||||||
if (gpioIF == nullptr) {
|
|
||||||
sif::error << "Gpio::Gpio: Invalid GpioIF" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReturnValue_t pullHigh() { return gpioIF->pullHigh(gpioId); }
|
|
||||||
ReturnValue_t pullLow() { return gpioIF->pullLow(gpioId); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
gpioId_t gpioId = gpio::NO_GPIO;
|
|
||||||
GpioIF* gpioIF = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* FSFW_HAL_SRC_FSFW_HAL_LINUX_GPIO_GPIO_H_ */
|
|
@ -214,7 +214,7 @@ ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, struct gpiod
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) {
|
ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) {
|
||||||
auto gpioMapIter = gpioMap.find(gpioId);
|
gpioMapIter = gpioMap.find(gpioId);
|
||||||
if (gpioMapIter == gpioMap.end()) {
|
if (gpioMapIter == gpioMap.end()) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "LinuxLibgpioIF::pullHigh: Unknown GPIO ID " << gpioId << std::endl;
|
sif::warning << "LinuxLibgpioIF::pullHigh: Unknown GPIO ID " << gpioId << std::endl;
|
||||||
@ -244,7 +244,7 @@ ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) {
|
ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) {
|
||||||
auto gpioMapIter = gpioMap.find(gpioId);
|
gpioMapIter = gpioMap.find(gpioId);
|
||||||
if (gpioMapIter == gpioMap.end()) {
|
if (gpioMapIter == gpioMap.end()) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "LinuxLibgpioIF::pullLow: Unknown GPIO ID " << gpioId << std::endl;
|
sif::warning << "LinuxLibgpioIF::pullLow: Unknown GPIO ID " << gpioId << std::endl;
|
||||||
@ -294,8 +294,8 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, GpiodRegularBase& regul
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, gpio::Levels& gpioState) {
|
ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) {
|
||||||
auto gpioMapIter = gpioMap.find(gpioId);
|
gpioMapIter = gpioMap.find(gpioId);
|
||||||
if (gpioMapIter == gpioMap.end()) {
|
if (gpioMapIter == gpioMap.end()) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||||
@ -313,10 +313,7 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, gpio::Levels& gpioState)
|
|||||||
if (regularGpio == nullptr) {
|
if (regularGpio == nullptr) {
|
||||||
return GPIO_TYPE_FAILURE;
|
return GPIO_TYPE_FAILURE;
|
||||||
}
|
}
|
||||||
gpioState = static_cast<gpio::Levels>(gpiod_line_get_value(regularGpio->lineHandle));
|
*gpioState = gpiod_line_get_value(regularGpio->lineHandle);
|
||||||
if (gpioState == gpio::Levels::FAILED) {
|
|
||||||
return GPIO_GET_VALUE_FAILED;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
||||||
if (gpioCallback->callback == nullptr) {
|
if (gpioCallback->callback == nullptr) {
|
||||||
@ -377,7 +374,7 @@ ReturnValue_t LinuxLibgpioIF::checkForConflictsById(gpioId_t gpioIdToCheck,
|
|||||||
gpio::GpioTypes expectedType,
|
gpio::GpioTypes expectedType,
|
||||||
GpioMap& mapToAdd) {
|
GpioMap& mapToAdd) {
|
||||||
// Cross check with private map
|
// Cross check with private map
|
||||||
auto gpioMapIter = gpioMap.find(gpioIdToCheck);
|
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
||||||
if (gpioMapIter != gpioMap.end()) {
|
if (gpioMapIter != gpioMap.end()) {
|
||||||
auto& gpioType = gpioMapIter->second->gpioType;
|
auto& gpioType = gpioMapIter->second->gpioType;
|
||||||
bool eraseDuplicateDifferentType = false;
|
bool eraseDuplicateDifferentType = false;
|
||||||
|
@ -25,8 +25,6 @@ class LinuxLibgpioIF : public GpioIF, public SystemObject {
|
|||||||
static constexpr ReturnValue_t GPIO_INVALID_INSTANCE = returnvalue::makeCode(gpioRetvalId, 4);
|
static constexpr ReturnValue_t GPIO_INVALID_INSTANCE = returnvalue::makeCode(gpioRetvalId, 4);
|
||||||
static constexpr ReturnValue_t GPIO_DUPLICATE_DETECTED = returnvalue::makeCode(gpioRetvalId, 5);
|
static constexpr ReturnValue_t GPIO_DUPLICATE_DETECTED = returnvalue::makeCode(gpioRetvalId, 5);
|
||||||
static constexpr ReturnValue_t GPIO_INIT_FAILED = returnvalue::makeCode(gpioRetvalId, 6);
|
static constexpr ReturnValue_t GPIO_INIT_FAILED = returnvalue::makeCode(gpioRetvalId, 6);
|
||||||
// Will be returned if getting the line value failed. Error type will be set to errno in this case
|
|
||||||
static constexpr ReturnValue_t GPIO_GET_VALUE_FAILED = returnvalue::makeCode(gpioRetvalId, 7);
|
|
||||||
|
|
||||||
LinuxLibgpioIF(object_id_t objectId);
|
LinuxLibgpioIF(object_id_t objectId);
|
||||||
virtual ~LinuxLibgpioIF();
|
virtual ~LinuxLibgpioIF();
|
||||||
@ -34,7 +32,7 @@ class LinuxLibgpioIF : public GpioIF, public SystemObject {
|
|||||||
ReturnValue_t addGpios(GpioCookie* gpioCookie) override;
|
ReturnValue_t addGpios(GpioCookie* gpioCookie) override;
|
||||||
ReturnValue_t pullHigh(gpioId_t gpioId) override;
|
ReturnValue_t pullHigh(gpioId_t gpioId) override;
|
||||||
ReturnValue_t pullLow(gpioId_t gpioId) override;
|
ReturnValue_t pullLow(gpioId_t gpioId) override;
|
||||||
ReturnValue_t readGpio(gpioId_t gpioId, gpio::Levels& gpioState) override;
|
ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const size_t MAX_CHIPNAME_LENGTH = 11;
|
static const size_t MAX_CHIPNAME_LENGTH = 11;
|
||||||
@ -44,6 +42,7 @@ class LinuxLibgpioIF : public GpioIF, public SystemObject {
|
|||||||
|
|
||||||
// Holds the information and configuration of all used GPIOs
|
// Holds the information and configuration of all used GPIOs
|
||||||
GpioUnorderedMap gpioMap;
|
GpioUnorderedMap gpioMap;
|
||||||
|
GpioUnorderedMapIter gpioMapIter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This functions drives line of a GPIO specified by the GPIO ID.
|
* @brief This functions drives line of a GPIO specified by the GPIO ID.
|
||||||
|
2
src/fsfw_hal/linux/serial/CMakeLists.txt
Normal file
2
src/fsfw_hal/linux/serial/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
target_sources(${LIB_FSFW_NAME} PUBLIC SerialComIF.cpp SerialCookie.cpp
|
||||||
|
helper.cpp)
|
@ -1,4 +1,4 @@
|
|||||||
#include "UartComIF.h"
|
#include "SerialComIF.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -11,18 +11,18 @@
|
|||||||
#include "fsfw/serviceinterface.h"
|
#include "fsfw/serviceinterface.h"
|
||||||
#include "fsfw_hal/linux/utility.h"
|
#include "fsfw_hal/linux/utility.h"
|
||||||
|
|
||||||
UartComIF::UartComIF(object_id_t objectId) : SystemObject(objectId) {}
|
SerialComIF::SerialComIF(object_id_t objectId) : SystemObject(objectId) {}
|
||||||
|
|
||||||
UartComIF::~UartComIF() {}
|
SerialComIF::~SerialComIF() {}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
|
ReturnValue_t SerialComIF::initializeInterface(CookieIF* cookie) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
|
|
||||||
if (cookie == nullptr) {
|
if (cookie == nullptr) {
|
||||||
return NULLPOINTER;
|
return NULLPOINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "UartComIF::initializeInterface: Invalid UART Cookie!" << std::endl;
|
sif::error << "UartComIF::initializeInterface: Invalid UART Cookie!" << std::endl;
|
||||||
@ -59,7 +59,7 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UartComIF::configureUartPort(UartCookie* uartCookie) {
|
int SerialComIF::configureUartPort(SerialCookie* uartCookie) {
|
||||||
struct termios options = {};
|
struct termios options = {};
|
||||||
|
|
||||||
std::string deviceFile = uartCookie->getDeviceFile();
|
std::string deviceFile = uartCookie->getDeviceFile();
|
||||||
@ -88,7 +88,7 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
setParityOptions(&options, uartCookie);
|
uart::setParity(options, uartCookie->getParity());
|
||||||
setStopBitOptions(&options, uartCookie);
|
setStopBitOptions(&options, uartCookie);
|
||||||
setDatasizeOptions(&options, uartCookie);
|
setDatasizeOptions(&options, uartCookie);
|
||||||
setFixedOptions(&options);
|
setFixedOptions(&options);
|
||||||
@ -114,24 +114,7 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UartComIF::setParityOptions(struct termios* options, UartCookie* uartCookie) {
|
void SerialComIF::setStopBitOptions(struct termios* options, SerialCookie* uartCookie) {
|
||||||
/* Clear parity bit */
|
|
||||||
options->c_cflag &= ~PARENB;
|
|
||||||
switch (uartCookie->getParity()) {
|
|
||||||
case Parity::EVEN:
|
|
||||||
options->c_cflag |= PARENB;
|
|
||||||
options->c_cflag &= ~PARODD;
|
|
||||||
break;
|
|
||||||
case Parity::ODD:
|
|
||||||
options->c_cflag |= PARENB;
|
|
||||||
options->c_cflag |= PARODD;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UartComIF::setStopBitOptions(struct termios* options, UartCookie* uartCookie) {
|
|
||||||
/* Clear stop field. Sets stop bit to one bit */
|
/* Clear stop field. Sets stop bit to one bit */
|
||||||
options->c_cflag &= ~CSTOPB;
|
options->c_cflag &= ~CSTOPB;
|
||||||
switch (uartCookie->getStopBits()) {
|
switch (uartCookie->getStopBits()) {
|
||||||
@ -143,7 +126,7 @@ void UartComIF::setStopBitOptions(struct termios* options, UartCookie* uartCooki
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCookie) {
|
void SerialComIF::setDatasizeOptions(struct termios* options, SerialCookie* uartCookie) {
|
||||||
/* Clear size bits */
|
/* Clear size bits */
|
||||||
options->c_cflag &= ~CSIZE;
|
options->c_cflag &= ~CSIZE;
|
||||||
switch (uartCookie->getBitsPerWord()) {
|
switch (uartCookie->getBitsPerWord()) {
|
||||||
@ -167,7 +150,7 @@ void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UartComIF::setFixedOptions(struct termios* options) {
|
void SerialComIF::setFixedOptions(struct termios* options) {
|
||||||
/* Disable RTS/CTS hardware flow control */
|
/* Disable RTS/CTS hardware flow control */
|
||||||
options->c_cflag &= ~CRTSCTS;
|
options->c_cflag &= ~CRTSCTS;
|
||||||
/* Turn on READ & ignore ctrl lines (CLOCAL = 1) */
|
/* Turn on READ & ignore ctrl lines (CLOCAL = 1) */
|
||||||
@ -190,7 +173,7 @@ void UartComIF::setFixedOptions(struct termios* options) {
|
|||||||
options->c_oflag &= ~ONLCR;
|
options->c_oflag &= ~ONLCR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
|
ReturnValue_t SerialComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
|
|
||||||
@ -205,7 +188,7 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl;
|
sif::warning << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl;
|
||||||
@ -236,12 +219,12 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; }
|
ReturnValue_t SerialComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; }
|
||||||
|
|
||||||
ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
ReturnValue_t SerialComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
|
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "UartComIF::requestReceiveMessage: Invalid Uart Cookie!" << std::endl;
|
sif::debug << "UartComIF::requestReceiveMessage: Invalid Uart Cookie!" << std::endl;
|
||||||
@ -274,8 +257,8 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceMap::iterator& iter,
|
ReturnValue_t SerialComIF::handleCanonicalRead(SerialCookie& uartCookie,
|
||||||
size_t requestLen) {
|
UartDeviceMap::iterator& iter, size_t requestLen) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
uint8_t maxReadCycles = uartCookie.getReadCycles();
|
uint8_t maxReadCycles = uartCookie.getReadCycles();
|
||||||
uint8_t currentReadCycles = 0;
|
uint8_t currentReadCycles = 0;
|
||||||
@ -332,8 +315,9 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie& uartCookie,
|
ReturnValue_t SerialComIF::handleNoncanonicalRead(SerialCookie& uartCookie,
|
||||||
UartDeviceMap::iterator& iter, size_t requestLen) {
|
UartDeviceMap::iterator& iter,
|
||||||
|
size_t requestLen) {
|
||||||
int fd = iter->second.fileDescriptor;
|
int fd = iter->second.fileDescriptor;
|
||||||
auto bufferPtr = iter->second.replyBuffer.data();
|
auto bufferPtr = iter->second.replyBuffer.data();
|
||||||
// Size check to prevent buffer overflow
|
// Size check to prevent buffer overflow
|
||||||
@ -366,10 +350,10 @@ ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie& uartCookie,
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) {
|
ReturnValue_t SerialComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
|
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "UartComIF::readReceivedMessage: Invalid uart cookie!" << std::endl;
|
sif::debug << "UartComIF::readReceivedMessage: Invalid uart cookie!" << std::endl;
|
||||||
@ -396,9 +380,9 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) {
|
ReturnValue_t SerialComIF::flushUartRxBuffer(CookieIF* cookie) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UartComIF::flushUartRxBuffer: Invalid uart cookie!" << std::endl;
|
sif::warning << "UartComIF::flushUartRxBuffer: Invalid uart cookie!" << std::endl;
|
||||||
@ -415,9 +399,9 @@ ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) {
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) {
|
ReturnValue_t SerialComIF::flushUartTxBuffer(CookieIF* cookie) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UartComIF::flushUartTxBuffer: Invalid uart cookie!" << std::endl;
|
sif::warning << "UartComIF::flushUartTxBuffer: Invalid uart cookie!" << std::endl;
|
||||||
@ -434,9 +418,9 @@ ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) {
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF* cookie) {
|
ReturnValue_t SerialComIF::flushUartTxAndRxBuf(CookieIF* cookie) {
|
||||||
std::string deviceFile;
|
std::string deviceFile;
|
||||||
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
|
||||||
if (uartCookie == nullptr) {
|
if (uartCookie == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UartComIF::flushUartTxAndRxBuf: Invalid uart cookie!" << std::endl;
|
sif::warning << "UartComIF::flushUartTxAndRxBuf: Invalid uart cookie!" << std::endl;
|
@ -3,13 +3,12 @@
|
|||||||
|
|
||||||
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
||||||
#include <fsfw/objectmanager/SystemObject.h>
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw_hal/linux/serial/SerialCookie.h>
|
||||||
|
#include <fsfw_hal/linux/serial/helper.h>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "UartCookie.h"
|
|
||||||
#include "helper.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the communication interface to access serial ports on linux based operating
|
* @brief This is the communication interface to access serial ports on linux based operating
|
||||||
* systems.
|
* systems.
|
||||||
@ -19,7 +18,7 @@
|
|||||||
*
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
class SerialComIF : public DeviceCommunicationIF, public SystemObject {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t uartRetvalId = CLASS_ID::HAL_UART;
|
static constexpr uint8_t uartRetvalId = CLASS_ID::HAL_UART;
|
||||||
|
|
||||||
@ -27,9 +26,9 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
|||||||
static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH = returnvalue::makeCode(uartRetvalId, 2);
|
static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH = returnvalue::makeCode(uartRetvalId, 2);
|
||||||
static constexpr ReturnValue_t UART_RX_BUFFER_TOO_SMALL = returnvalue::makeCode(uartRetvalId, 3);
|
static constexpr ReturnValue_t UART_RX_BUFFER_TOO_SMALL = returnvalue::makeCode(uartRetvalId, 3);
|
||||||
|
|
||||||
UartComIF(object_id_t objectId);
|
SerialComIF(object_id_t objectId);
|
||||||
|
|
||||||
virtual ~UartComIF();
|
virtual ~SerialComIF();
|
||||||
|
|
||||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||||
@ -76,20 +75,9 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
|||||||
* uart device file, baudrate, parity, stopbits etc.
|
* uart device file, baudrate, parity, stopbits etc.
|
||||||
* @return The file descriptor of the configured uart.
|
* @return The file descriptor of the configured uart.
|
||||||
*/
|
*/
|
||||||
int configureUartPort(UartCookie* uartCookie);
|
int configureUartPort(SerialCookie* uartCookie);
|
||||||
|
|
||||||
/**
|
void setStopBitOptions(struct termios* options, SerialCookie* uartCookie);
|
||||||
* @brief This function adds the parity settings to the termios options struct.
|
|
||||||
*
|
|
||||||
* @param options Pointer to termios options struct which will be modified to enable or disable
|
|
||||||
* parity checking.
|
|
||||||
* @param uartCookie Pointer to uart cookie containing the information about the desired
|
|
||||||
* parity settings.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void setParityOptions(struct termios* options, UartCookie* uartCookie);
|
|
||||||
|
|
||||||
void setStopBitOptions(struct termios* options, UartCookie* uartCookie);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function sets options which are not configurable by the uartCookie.
|
* @brief This function sets options which are not configurable by the uartCookie.
|
||||||
@ -99,11 +87,11 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
|
|||||||
/**
|
/**
|
||||||
* @brief With this function the datasize settings are added to the termios options struct.
|
* @brief With this function the datasize settings are added to the termios options struct.
|
||||||
*/
|
*/
|
||||||
void setDatasizeOptions(struct termios* options, UartCookie* uartCookie);
|
void setDatasizeOptions(struct termios* options, SerialCookie* uartCookie);
|
||||||
|
|
||||||
ReturnValue_t handleCanonicalRead(UartCookie& uartCookie, UartDeviceMap::iterator& iter,
|
ReturnValue_t handleCanonicalRead(SerialCookie& uartCookie, UartDeviceMap::iterator& iter,
|
||||||
size_t requestLen);
|
size_t requestLen);
|
||||||
ReturnValue_t handleNoncanonicalRead(UartCookie& uartCookie, UartDeviceMap::iterator& iter,
|
ReturnValue_t handleNoncanonicalRead(SerialCookie& uartCookie, UartDeviceMap::iterator& iter,
|
||||||
size_t requestLen);
|
size_t requestLen);
|
||||||
};
|
};
|
||||||
|
|
51
src/fsfw_hal/linux/serial/SerialCookie.cpp
Normal file
51
src/fsfw_hal/linux/serial/SerialCookie.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "SerialCookie.h"
|
||||||
|
|
||||||
|
#include <fsfw/serviceinterface.h>
|
||||||
|
|
||||||
|
SerialCookie::SerialCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate,
|
||||||
|
size_t maxReplyLen, UartModes uartMode)
|
||||||
|
: handlerId(handlerId),
|
||||||
|
deviceFile(deviceFile),
|
||||||
|
uartMode(uartMode),
|
||||||
|
baudrate(baudrate),
|
||||||
|
maxReplyLen(maxReplyLen) {}
|
||||||
|
|
||||||
|
SerialCookie::~SerialCookie() {}
|
||||||
|
|
||||||
|
UartBaudRate SerialCookie::getBaudrate() const { return baudrate; }
|
||||||
|
|
||||||
|
size_t SerialCookie::getMaxReplyLen() const { return maxReplyLen; }
|
||||||
|
|
||||||
|
std::string SerialCookie::getDeviceFile() const { return deviceFile; }
|
||||||
|
|
||||||
|
void SerialCookie::setParityOdd() { parity = Parity::ODD; }
|
||||||
|
|
||||||
|
void SerialCookie::setParityEven() { parity = Parity::EVEN; }
|
||||||
|
|
||||||
|
Parity SerialCookie::getParity() const { return parity; }
|
||||||
|
|
||||||
|
void SerialCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; }
|
||||||
|
|
||||||
|
BitsPerWord SerialCookie::getBitsPerWord() const { return bitsPerWord; }
|
||||||
|
|
||||||
|
StopBits SerialCookie::getStopBits() const { return stopBits; }
|
||||||
|
|
||||||
|
void SerialCookie::setTwoStopBits() { stopBits = StopBits::TWO_STOP_BITS; }
|
||||||
|
|
||||||
|
void SerialCookie::setOneStopBit() { stopBits = StopBits::ONE_STOP_BIT; }
|
||||||
|
|
||||||
|
UartModes SerialCookie::getUartMode() const { return uartMode; }
|
||||||
|
|
||||||
|
void SerialCookie::setReadCycles(uint8_t readCycles) { this->readCycles = readCycles; }
|
||||||
|
|
||||||
|
void SerialCookie::setToFlushInput(bool enable) { this->flushInput = enable; }
|
||||||
|
|
||||||
|
uint8_t SerialCookie::getReadCycles() const { return readCycles; }
|
||||||
|
|
||||||
|
bool SerialCookie::getInputShouldBeFlushed() { return this->flushInput; }
|
||||||
|
|
||||||
|
object_id_t SerialCookie::getHandlerId() const { return this->handlerId; }
|
||||||
|
|
||||||
|
void SerialCookie::setNoFixedSizeReply() { replySizeFixed = false; }
|
||||||
|
|
||||||
|
bool SerialCookie::isReplySizeFixed() { return replySizeFixed; }
|
@ -3,11 +3,10 @@
|
|||||||
|
|
||||||
#include <fsfw/devicehandlers/CookieIF.h>
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
#include <fsfw/objectmanager/SystemObjectIF.h>
|
#include <fsfw/objectmanager/SystemObjectIF.h>
|
||||||
|
#include <fsfw_hal/linux/serial/helper.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "helper.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Cookie for the UartComIF. There are many options available to configure the UART driver.
|
* @brief Cookie for the UartComIF. There are many options available to configure the UART driver.
|
||||||
* The constructor only requests for common options like the baudrate. Other options can
|
* The constructor only requests for common options like the baudrate. Other options can
|
||||||
@ -15,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class UartCookie : public CookieIF {
|
class SerialCookie : public CookieIF {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor for the uart cookie.
|
* @brief Constructor for the uart cookie.
|
||||||
@ -30,10 +29,10 @@ class UartCookie : public CookieIF {
|
|||||||
* 8 databits (number of bits transfered with one uart frame)
|
* 8 databits (number of bits transfered with one uart frame)
|
||||||
* One stop bit
|
* One stop bit
|
||||||
*/
|
*/
|
||||||
UartCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate,
|
SerialCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate,
|
||||||
size_t maxReplyLen, UartModes uartMode = UartModes::NON_CANONICAL);
|
size_t maxReplyLen, UartModes uartMode = UartModes::NON_CANONICAL);
|
||||||
|
|
||||||
virtual ~UartCookie();
|
virtual ~SerialCookie();
|
||||||
|
|
||||||
UartBaudRate getBaudrate() const;
|
UartBaudRate getBaudrate() const;
|
||||||
size_t getMaxReplyLen() const;
|
size_t getMaxReplyLen() const;
|
163
src/fsfw_hal/linux/serial/helper.cpp
Normal file
163
src/fsfw_hal/linux/serial/helper.cpp
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
#include <fsfw_hal/linux/serial/helper.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
|
void uart::setMode(struct termios& options, UartModes mode) {
|
||||||
|
if (mode == UartModes::NON_CANONICAL) {
|
||||||
|
/* Disable canonical mode */
|
||||||
|
options.c_lflag &= ~ICANON;
|
||||||
|
} else if (mode == UartModes::CANONICAL) {
|
||||||
|
options.c_lflag |= ICANON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
|
||||||
|
switch (baud) {
|
||||||
|
case UartBaudRate::RATE_50:
|
||||||
|
cfsetspeed(&options, B50);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_75:
|
||||||
|
cfsetspeed(&options, B75);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_110:
|
||||||
|
cfsetspeed(&options, B110);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_134:
|
||||||
|
cfsetspeed(&options, B134);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_150:
|
||||||
|
cfsetspeed(&options, B150);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_200:
|
||||||
|
cfsetspeed(&options, B200);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_300:
|
||||||
|
cfsetspeed(&options, B300);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_600:
|
||||||
|
cfsetspeed(&options, B600);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_1200:
|
||||||
|
cfsetspeed(&options, B1200);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_1800:
|
||||||
|
cfsetspeed(&options, B1800);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_2400:
|
||||||
|
cfsetspeed(&options, B2400);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_4800:
|
||||||
|
cfsetspeed(&options, B4800);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_9600:
|
||||||
|
cfsetspeed(&options, B9600);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_19200:
|
||||||
|
cfsetspeed(&options, B19200);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_38400:
|
||||||
|
cfsetspeed(&options, B38400);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_57600:
|
||||||
|
cfsetspeed(&options, B57600);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_115200:
|
||||||
|
cfsetspeed(&options, B115200);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_230400:
|
||||||
|
cfsetspeed(&options, B230400);
|
||||||
|
break;
|
||||||
|
#ifndef __APPLE__
|
||||||
|
case UartBaudRate::RATE_460800:
|
||||||
|
cfsetspeed(&options, B460800);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_500000:
|
||||||
|
cfsetspeed(&options, B500000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_576000:
|
||||||
|
cfsetspeed(&options, B576000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_921600:
|
||||||
|
cfsetspeed(&options, B921600);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_1000000:
|
||||||
|
cfsetspeed(&options, B1000000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_1152000:
|
||||||
|
cfsetspeed(&options, B1152000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_1500000:
|
||||||
|
cfsetspeed(&options, B1500000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_2000000:
|
||||||
|
cfsetspeed(&options, B2000000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_2500000:
|
||||||
|
cfsetspeed(&options, B2500000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_3000000:
|
||||||
|
cfsetspeed(&options, B3000000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_3500000:
|
||||||
|
cfsetspeed(&options, B3500000);
|
||||||
|
break;
|
||||||
|
case UartBaudRate::RATE_4000000:
|
||||||
|
cfsetspeed(&options, B4000000);
|
||||||
|
break;
|
||||||
|
#endif // ! __APPLE__
|
||||||
|
default:
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart::setBitsPerWord(struct termios& options, BitsPerWord bits) {
|
||||||
|
options.c_cflag &= ~CSIZE; // Clear all the size bits
|
||||||
|
if (bits == BitsPerWord::BITS_5) {
|
||||||
|
options.c_cflag |= CS5;
|
||||||
|
} else if (bits == BitsPerWord::BITS_6) {
|
||||||
|
options.c_cflag |= CS6;
|
||||||
|
} else if (bits == BitsPerWord::BITS_7) {
|
||||||
|
options.c_cflag |= CS7;
|
||||||
|
} else if (bits == BitsPerWord::BITS_8) {
|
||||||
|
options.c_cflag |= CS8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart::enableRead(struct termios& options) { options.c_cflag |= CREAD; }
|
||||||
|
|
||||||
|
void uart::ignoreCtrlLines(struct termios& options) { options.c_cflag |= CLOCAL; }
|
||||||
|
|
||||||
|
void uart::setParity(struct termios& options, Parity parity) {
|
||||||
|
/* Clear parity bit */
|
||||||
|
options.c_cflag &= ~PARENB;
|
||||||
|
switch (parity) {
|
||||||
|
case Parity::EVEN:
|
||||||
|
options.c_cflag |= PARENB;
|
||||||
|
options.c_cflag &= ~PARODD;
|
||||||
|
break;
|
||||||
|
case Parity::ODD:
|
||||||
|
options.c_cflag |= PARENB;
|
||||||
|
options.c_cflag |= PARODD;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int uart::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
|
||||||
|
return ioctl(serialPort, TIOCGICOUNT, &icounter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart::setStopbits(struct termios& options, StopBits bits) {
|
||||||
|
if (bits == StopBits::TWO_STOP_BITS) {
|
||||||
|
// Use two stop bits
|
||||||
|
options.c_cflag |= CSTOPB;
|
||||||
|
} else {
|
||||||
|
// Clear stop field, only one stop bit used in communication
|
||||||
|
options.c_cflag &= ~CSTOPB;
|
||||||
|
}
|
||||||
|
}
|
@ -54,6 +54,16 @@ void setMode(struct termios& options, UartModes mode);
|
|||||||
*/
|
*/
|
||||||
void setBaudrate(struct termios& options, UartBaudRate baud);
|
void setBaudrate(struct termios& options, UartBaudRate baud);
|
||||||
|
|
||||||
|
void setStopbits(struct termios& options, StopBits bits);
|
||||||
|
|
||||||
|
void setBitsPerWord(struct termios& options, BitsPerWord bits);
|
||||||
|
|
||||||
|
void enableRead(struct termios& options);
|
||||||
|
|
||||||
|
void setParity(struct termios& options, Parity parity);
|
||||||
|
|
||||||
|
void ignoreCtrlLines(struct termios& options);
|
||||||
|
|
||||||
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
|
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
|
||||||
|
|
||||||
} // namespace uart
|
} // namespace uart
|
@ -1,43 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "fsfw/ipc/MutexIF.h"
|
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
|
||||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
|
||||||
|
|
||||||
class ManualCsLockWrapper {
|
|
||||||
public:
|
|
||||||
ManualCsLockWrapper(MutexIF* lock, GpioIF* gpioIF, SpiCookie* cookie,
|
|
||||||
MutexIF::TimeoutType type = MutexIF::TimeoutType::BLOCKING,
|
|
||||||
uint32_t timeoutMs = 0)
|
|
||||||
: lock(lock), gpioIF(gpioIF), cookie(cookie), type(type), timeoutMs(timeoutMs) {
|
|
||||||
if (cookie == nullptr) {
|
|
||||||
// TODO: Error? Or maybe throw exception..
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cookie->setCsLockManual(true);
|
|
||||||
lockResult = lock->lockMutex(type, timeoutMs);
|
|
||||||
if (lockResult != returnvalue::OK) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gpioResult = gpioIF->pullLow(cookie->getChipSelectPin());
|
|
||||||
}
|
|
||||||
|
|
||||||
~ManualCsLockWrapper() {
|
|
||||||
if (gpioResult == returnvalue::OK) {
|
|
||||||
gpioIF->pullHigh(cookie->getChipSelectPin());
|
|
||||||
}
|
|
||||||
cookie->setCsLockManual(false);
|
|
||||||
if (lockResult == returnvalue::OK) {
|
|
||||||
lock->unlockMutex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReturnValue_t lockResult;
|
|
||||||
ReturnValue_t gpioResult;
|
|
||||||
|
|
||||||
private:
|
|
||||||
MutexIF* lock;
|
|
||||||
GpioIF* gpioIF;
|
|
||||||
SpiCookie* cookie;
|
|
||||||
MutexIF::TimeoutType type;
|
|
||||||
uint32_t timeoutMs = 0;
|
|
||||||
};
|
|
@ -15,9 +15,19 @@
|
|||||||
#include "fsfw_hal/linux/spi/SpiCookie.h"
|
#include "fsfw_hal/linux/spi/SpiCookie.h"
|
||||||
#include "fsfw_hal/linux/utility.h"
|
#include "fsfw_hal/linux/utility.h"
|
||||||
|
|
||||||
SpiComIF::SpiComIF(object_id_t objectId, std::string devname, GpioIF& gpioComIF)
|
SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF)
|
||||||
: SystemObject(objectId), gpioComIF(gpioComIF), dev(std::move(devname)) {
|
: SystemObject(objectId), gpioComIF(gpioComIF) {
|
||||||
csMutex = MutexFactory::instance()->createMutex();
|
if (gpioComIF == nullptr) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "SpiComIF::SpiComIF: GPIO communication interface invalid!" << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("SpiComIF::SpiComIF: GPIO communication interface invalid!\n");
|
||||||
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||||
|
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
spiMutex = MutexFactory::instance()->createMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) {
|
ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) {
|
||||||
@ -65,7 +75,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) {
|
|||||||
/* Pull CS high in any case to be sure that device is inactive */
|
/* Pull CS high in any case to be sure that device is inactive */
|
||||||
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
||||||
if (gpioId != gpio::NO_GPIO) {
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
gpioComIF.pullHigh(gpioId);
|
gpioComIF->pullHigh(gpioId);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t spiSpeed = 0;
|
uint32_t spiSpeed = 0;
|
||||||
@ -75,7 +85,8 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) {
|
|||||||
spiCookie->getSpiParameters(spiMode, spiSpeed, ¶ms);
|
spiCookie->getSpiParameters(spiMode, spiSpeed, ¶ms);
|
||||||
|
|
||||||
int fileDescriptor = 0;
|
int fileDescriptor = 0;
|
||||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
UnixFileGuard fileHelper(spiCookie->getSpiDevice(), &fileDescriptor, O_RDWR,
|
||||||
|
"SpiComIF::initializeInterface");
|
||||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||||
return fileHelper.getOpenResult();
|
return fileHelper.getOpenResult();
|
||||||
}
|
}
|
||||||
@ -171,7 +182,8 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
int retval = 0;
|
int retval = 0;
|
||||||
/* Prepare transfer */
|
/* Prepare transfer */
|
||||||
int fileDescriptor = 0;
|
int fileDescriptor = 0;
|
||||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
std::string device = spiCookie->getSpiDevice();
|
||||||
|
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||||
return OPENING_FILE_FAILED;
|
return OPENING_FILE_FAILED;
|
||||||
}
|
}
|
||||||
@ -184,28 +196,21 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
|
|
||||||
bool fullDuplex = spiCookie->isFullDuplex();
|
bool fullDuplex = spiCookie->isFullDuplex();
|
||||||
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
||||||
bool csLockManual = spiCookie->getCsLockManual();
|
|
||||||
|
|
||||||
MutexIF::TimeoutType csType;
|
/* Pull SPI CS low. For now, no support for active high given */
|
||||||
dur_millis_t csTimeout = 0;
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
// Pull SPI CS low. For now, no support for active high given
|
result = spiMutex->lockMutex(timeoutType, timeoutMs);
|
||||||
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
|
||||||
spiCookie->getMutexParams(csType, csTimeout);
|
|
||||||
result = csMutex->lockMutex(csType, csTimeout);
|
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
|
sif::error << "SpiComIF::sendMessage: Failed to lock mutex" << std::endl;
|
||||||
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
#else
|
||||||
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
sif::printError("SpiComIF::sendMessage: Failed to lock mutex\n");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
updateLinePolarity(fileDescriptor);
|
result = gpioComIF->pullLow(gpioId);
|
||||||
result = gpioComIF.pullLow(gpioId);
|
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
@ -216,8 +221,6 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
updateLinePolarity(fileDescriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute transfer */
|
/* Execute transfer */
|
||||||
@ -245,9 +248,9 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
gpioComIF.pullHigh(gpioId);
|
gpioComIF->pullHigh(gpioId);
|
||||||
result = csMutex->unlockMutex();
|
result = spiMutex->unlockMutex();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "SpiComIF::sendMessage: Failed to unlock mutex" << std::endl;
|
sif::error << "SpiComIF::sendMessage: Failed to unlock mutex" << std::endl;
|
||||||
@ -275,8 +278,9 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
|||||||
|
|
||||||
ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
std::string device = spiCookie->getSpiDevice();
|
||||||
int fileDescriptor = 0;
|
int fileDescriptor = 0;
|
||||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
|
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
|
||||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||||
return OPENING_FILE_FAILED;
|
return OPENING_FILE_FAILED;
|
||||||
}
|
}
|
||||||
@ -288,26 +292,16 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool csLockManual = spiCookie->getCsLockManual();
|
|
||||||
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
||||||
MutexIF::TimeoutType csType;
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
dur_millis_t csTimeout = 0;
|
result = spiMutex->lockMutex(timeoutType, timeoutMs);
|
||||||
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
|
||||||
spiCookie->getMutexParams(csType, csTimeout);
|
|
||||||
result = csMutex->lockMutex(csType, csTimeout);
|
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
|
sif::error << "SpiComIF::getSendSuccess: Failed to lock mutex" << std::endl;
|
||||||
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
|
||||||
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
gpioComIF.pullLow(gpioId);
|
gpioComIF->pullLow(gpioId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read(fileDescriptor, rxBuf, readSize) != static_cast<ssize_t>(readSize)) {
|
if (read(fileDescriptor, rxBuf, readSize) != static_cast<ssize_t>(readSize)) {
|
||||||
@ -321,9 +315,9 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
|||||||
result = HALF_DUPLEX_TRANSFER_FAILED;
|
result = HALF_DUPLEX_TRANSFER_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpioId != gpio::NO_GPIO and not csLockManual) {
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
gpioComIF.pullHigh(gpioId);
|
gpioComIF->pullHigh(gpioId);
|
||||||
result = csMutex->unlockMutex();
|
result = spiMutex->unlockMutex();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "SpiComIF::getSendSuccess: Failed to unlock mutex" << std::endl;
|
sif::error << "SpiComIF::getSendSuccess: Failed to unlock mutex" << std::endl;
|
||||||
@ -352,7 +346,15 @@ ReturnValue_t SpiComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MutexIF* SpiComIF::getCsMutex() { return csMutex; }
|
MutexIF* SpiComIF::getMutex(MutexIF::TimeoutType* timeoutType, uint32_t* timeoutMs) {
|
||||||
|
if (timeoutType != nullptr) {
|
||||||
|
*timeoutType = this->timeoutType;
|
||||||
|
}
|
||||||
|
if (timeoutMs != nullptr) {
|
||||||
|
*timeoutMs = this->timeoutMs;
|
||||||
|
}
|
||||||
|
return spiMutex;
|
||||||
|
}
|
||||||
|
|
||||||
void SpiComIF::performSpiWiretapping(SpiCookie* spiCookie) {
|
void SpiComIF::performSpiWiretapping(SpiCookie* spiCookie) {
|
||||||
if (spiCookie == nullptr) {
|
if (spiCookie == nullptr) {
|
||||||
@ -387,7 +389,7 @@ ReturnValue_t SpiComIF::getReadBuffer(address_t spiAddress, uint8_t** buffer) {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpioIF& SpiComIF::getGpioInterface() { return gpioComIF; }
|
GpioIF* SpiComIF::getGpioInterface() { return gpioComIF; }
|
||||||
|
|
||||||
void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) {
|
void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) {
|
||||||
int retval = ioctl(spiFd, SPI_IOC_WR_MODE, reinterpret_cast<uint8_t*>(&mode));
|
int retval = ioctl(spiFd, SPI_IOC_WR_MODE, reinterpret_cast<uint8_t*>(&mode));
|
||||||
@ -399,27 +401,11 @@ void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed)
|
|||||||
if (retval != 0) {
|
if (retval != 0) {
|
||||||
utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Setting SPI speed failed");
|
utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Setting SPI speed failed");
|
||||||
}
|
}
|
||||||
}
|
// This updates the SPI clock default polarity. Only setting the mode does not update
|
||||||
|
// the line state, which can be an issue on mode switches because the clock line will
|
||||||
void SpiComIF::getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const {
|
// switch the state after the chip select is pulled low
|
||||||
uint8_t tmpMode = 0;
|
|
||||||
int retval = ioctl(spiFd, SPI_IOC_RD_MODE, &tmpMode);
|
|
||||||
if (retval != 0) {
|
|
||||||
utility::handleIoctlError("SpiComIF::getSpiSpeedAndMode: Reading SPI mode failed");
|
|
||||||
}
|
|
||||||
mode = static_cast<spi::SpiModes>(tmpMode);
|
|
||||||
|
|
||||||
retval = ioctl(spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
|
|
||||||
if (retval != 0) {
|
|
||||||
utility::handleIoctlError("SpiComIF::getSpiSpeedAndMode: Getting SPI speed failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& SpiComIF::getSpiDev() const { return dev; }
|
|
||||||
|
|
||||||
void SpiComIF::updateLinePolarity(int spiFd) {
|
|
||||||
clockUpdateTransfer.len = 0;
|
clockUpdateTransfer.len = 0;
|
||||||
int retval = ioctl(spiFd, SPI_IOC_MESSAGE(1), &clockUpdateTransfer);
|
retval = ioctl(spiFd, SPI_IOC_MESSAGE(1), &clockUpdateTransfer);
|
||||||
if (retval != 0) {
|
if (retval != 0) {
|
||||||
utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Updating SPI default clock failed");
|
utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Updating SPI default clock failed");
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
|||||||
static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED =
|
static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED =
|
||||||
returnvalue::makeCode(spiRetvalId, 2);
|
returnvalue::makeCode(spiRetvalId, 2);
|
||||||
|
|
||||||
SpiComIF(object_id_t objectId, std::string devname, GpioIF& gpioComIF);
|
SpiComIF(object_id_t objectId, GpioIF* gpioComIF);
|
||||||
|
|
||||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||||
@ -43,8 +43,7 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
|||||||
* @brief This function returns the mutex which can be used to protect the spi bus when
|
* @brief This function returns the mutex which can be used to protect the spi bus when
|
||||||
* the chip select must be driven from outside of the com if.
|
* the chip select must be driven from outside of the com if.
|
||||||
*/
|
*/
|
||||||
MutexIF* getCsMutex();
|
MutexIF* getMutex(MutexIF::TimeoutType* timeoutType = nullptr, uint32_t* timeoutMs = nullptr);
|
||||||
void setMutexParams(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform a regular send operation using Linux iotcl. This is public so it can be used
|
* Perform a regular send operation using Linux iotcl. This is public so it can be used
|
||||||
@ -57,22 +56,8 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
|||||||
ReturnValue_t performRegularSendOperation(SpiCookie* spiCookie, const uint8_t* sendData,
|
ReturnValue_t performRegularSendOperation(SpiCookie* spiCookie, const uint8_t* sendData,
|
||||||
size_t sendLen);
|
size_t sendLen);
|
||||||
|
|
||||||
GpioIF& getGpioInterface();
|
GpioIF* getGpioInterface();
|
||||||
void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed);
|
void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed);
|
||||||
void getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This updates the SPI clock default polarity. Only setting the mode does not update
|
|
||||||
* the line state, which can be an issue on mode switches because the clock line will
|
|
||||||
* switch the state after the chip select is pulled low.
|
|
||||||
*
|
|
||||||
* It is recommended to call this function after #setSpiSpeedAndMode and after locking the
|
|
||||||
* CS mutex if the SPI bus has multiple SPI devices with different speed and SPI modes attached.
|
|
||||||
* @param spiFd
|
|
||||||
*/
|
|
||||||
void updateLinePolarity(int spiFd);
|
|
||||||
|
|
||||||
const std::string& getSpiDev() const;
|
|
||||||
void performSpiWiretapping(SpiCookie* spiCookie);
|
void performSpiWiretapping(SpiCookie* spiCookie);
|
||||||
|
|
||||||
ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer);
|
ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer);
|
||||||
@ -83,15 +68,11 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
|||||||
std::vector<uint8_t> replyBuffer;
|
std::vector<uint8_t> replyBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
GpioIF& gpioComIF;
|
GpioIF* gpioComIF = nullptr;
|
||||||
std::string dev = "";
|
|
||||||
/**
|
MutexIF* spiMutex = nullptr;
|
||||||
* Protects the chip select operations. Lock when GPIO is pulled low, unlock after it was
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
* pulled high
|
uint32_t timeoutMs = 20;
|
||||||
*/
|
|
||||||
MutexIF* csMutex = nullptr;
|
|
||||||
// MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
|
||||||
// uint32_t timeoutMs = DEFAULT_MUTEX_TIMEOUT;
|
|
||||||
spi_ioc_transfer clockUpdateTransfer = {};
|
spi_ioc_transfer clockUpdateTransfer = {};
|
||||||
|
|
||||||
using SpiDeviceMap = std::unordered_map<address_t, SpiInstance>;
|
using SpiDeviceMap = std::unordered_map<address_t, SpiInstance>;
|
||||||
|
@ -1,25 +1,26 @@
|
|||||||
#include "SpiCookie.h"
|
#include "SpiCookie.h"
|
||||||
|
|
||||||
SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize,
|
SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev,
|
||||||
|
const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed)
|
||||||
|
: SpiCookie(spi::SpiComIfModes::REGULAR, spiAddress, chipSelect, spiDev, maxSize, spiMode,
|
||||||
|
spiSpeed, nullptr, nullptr) {}
|
||||||
|
|
||||||
|
SpiCookie::SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxSize,
|
||||||
spi::SpiModes spiMode, uint32_t spiSpeed)
|
spi::SpiModes spiMode, uint32_t spiSpeed)
|
||||||
: SpiCookie(spi::SpiComIfModes::REGULAR, spiAddress, chipSelect, maxSize, spiMode, spiSpeed,
|
: SpiCookie(spiAddress, gpio::NO_GPIO, spiDev, maxSize, spiMode, spiSpeed) {}
|
||||||
nullptr, nullptr) {}
|
|
||||||
|
|
||||||
SpiCookie::SpiCookie(address_t spiAddress, const size_t maxSize, spi::SpiModes spiMode,
|
SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev,
|
||||||
uint32_t spiSpeed)
|
|
||||||
: SpiCookie(spiAddress, gpio::NO_GPIO, maxSize, spiMode, spiSpeed) {}
|
|
||||||
|
|
||||||
SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize,
|
|
||||||
spi::SpiModes spiMode, uint32_t spiSpeed,
|
|
||||||
spi::send_callback_function_t callback, void* args)
|
|
||||||
: SpiCookie(spi::SpiComIfModes::CALLBACK, spiAddress, chipSelect, maxSize, spiMode, spiSpeed,
|
|
||||||
callback, args) {}
|
|
||||||
|
|
||||||
SpiCookie::SpiCookie(spi::SpiComIfModes comIfMode, address_t spiAddress, gpioId_t chipSelect,
|
|
||||||
const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed,
|
const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed,
|
||||||
spi::send_callback_function_t callback, void* args)
|
spi::send_callback_function_t callback, void* args)
|
||||||
|
: SpiCookie(spi::SpiComIfModes::CALLBACK, spiAddress, chipSelect, spiDev, maxSize, spiMode,
|
||||||
|
spiSpeed, callback, args) {}
|
||||||
|
|
||||||
|
SpiCookie::SpiCookie(spi::SpiComIfModes comIfMode, address_t spiAddress, gpioId_t chipSelect,
|
||||||
|
std::string spiDev, const size_t maxSize, spi::SpiModes spiMode,
|
||||||
|
uint32_t spiSpeed, spi::send_callback_function_t callback, void* args)
|
||||||
: spiAddress(spiAddress),
|
: spiAddress(spiAddress),
|
||||||
chipSelectPin(chipSelect),
|
chipSelectPin(chipSelect),
|
||||||
|
spiDevice(spiDev),
|
||||||
comIfMode(comIfMode),
|
comIfMode(comIfMode),
|
||||||
maxSize(maxSize),
|
maxSize(maxSize),
|
||||||
spiMode(spiMode),
|
spiMode(spiMode),
|
||||||
@ -49,6 +50,8 @@ size_t SpiCookie::getMaxBufferSize() const { return maxSize; }
|
|||||||
|
|
||||||
address_t SpiCookie::getSpiAddress() const { return spiAddress; }
|
address_t SpiCookie::getSpiAddress() const { return spiAddress; }
|
||||||
|
|
||||||
|
std::string SpiCookie::getSpiDevice() const { return spiDevice; }
|
||||||
|
|
||||||
void SpiCookie::setThreeWireSpi(bool enable) { uncommonParameters.threeWireSpi = enable; }
|
void SpiCookie::setThreeWireSpi(bool enable) { uncommonParameters.threeWireSpi = enable; }
|
||||||
|
|
||||||
void SpiCookie::setLsbFirst(bool enable) { uncommonParameters.lsbFirst = enable; }
|
void SpiCookie::setLsbFirst(bool enable) { uncommonParameters.lsbFirst = enable; }
|
||||||
@ -104,17 +107,3 @@ void SpiCookie::getCallback(spi::send_callback_function_t* callback, void** args
|
|||||||
*callback = this->sendCallback;
|
*callback = this->sendCallback;
|
||||||
*args = this->callbackArgs;
|
*args = this->callbackArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpiCookie::setCsLockManual(bool enable) { manualCsLock = enable; }
|
|
||||||
|
|
||||||
bool SpiCookie::getCsLockManual() const { return manualCsLock; }
|
|
||||||
|
|
||||||
void SpiCookie::getMutexParams(MutexIF::TimeoutType& csTimeoutType, dur_millis_t& csTimeout) const {
|
|
||||||
csTimeoutType = this->csTimeoutType;
|
|
||||||
csTimeout = this->csTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpiCookie::setMutexParams(MutexIF::TimeoutType csTimeoutType, dur_millis_t csTimeout) {
|
|
||||||
this->csTimeoutType = csTimeoutType;
|
|
||||||
this->csTimeout = csTimeout;
|
|
||||||
}
|
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
#define LINUX_SPI_SPICOOKIE_H_
|
#define LINUX_SPI_SPICOOKIE_H_
|
||||||
|
|
||||||
#include <fsfw/devicehandlers/CookieIF.h>
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
#include <fsfw/ipc/MutexIF.h>
|
|
||||||
#include <fsfw/timemanager/clockDefinitions.h>
|
|
||||||
#include <linux/spi/spidev.h>
|
#include <linux/spi/spidev.h>
|
||||||
|
|
||||||
#include "../../common/gpio/gpioDefinitions.h"
|
#include "../../common/gpio/gpioDefinitions.h"
|
||||||
@ -22,8 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
class SpiCookie : public CookieIF {
|
class SpiCookie : public CookieIF {
|
||||||
public:
|
public:
|
||||||
static constexpr dur_millis_t DEFAULT_MUTEX_TIMEOUT = 20;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each SPI device will have a corresponding cookie. The cookie is used by the communication
|
* Each SPI device will have a corresponding cookie. The cookie is used by the communication
|
||||||
* interface and contains device specific information like the largest expected size to be
|
* interface and contains device specific information like the largest expected size to be
|
||||||
@ -33,22 +29,23 @@ class SpiCookie : public CookieIF {
|
|||||||
* @param spiDev
|
* @param spiDev
|
||||||
* @param maxSize
|
* @param maxSize
|
||||||
*/
|
*/
|
||||||
SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize, spi::SpiModes spiMode,
|
SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, const size_t maxSize,
|
||||||
uint32_t spiSpeed);
|
spi::SpiModes spiMode, uint32_t spiSpeed);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like constructor above, but without a dedicated GPIO CS. Can be used for hardware
|
* Like constructor above, but without a dedicated GPIO CS. Can be used for hardware
|
||||||
* slave select or if CS logic is performed with decoders.
|
* slave select or if CS logic is performed with decoders.
|
||||||
*/
|
*/
|
||||||
SpiCookie(address_t spiAddress, const size_t maxReplySize, spi::SpiModes spiMode,
|
SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxReplySize,
|
||||||
uint32_t spiSpeed);
|
spi::SpiModes spiMode, uint32_t spiSpeed);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the callback mode of the SPI communication interface. The user can pass the callback
|
* Use the callback mode of the SPI communication interface. The user can pass the callback
|
||||||
* function here or by using the setter function #setCallbackMode
|
* function here or by using the setter function #setCallbackMode
|
||||||
*/
|
*/
|
||||||
SpiCookie(address_t spiAddress, gpioId_t chipSelect, const size_t maxSize, spi::SpiModes spiMode,
|
SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, const size_t maxSize,
|
||||||
uint32_t spiSpeed, spi::send_callback_function_t callback, void* args);
|
spi::SpiModes spiMode, uint32_t spiSpeed, spi::send_callback_function_t callback,
|
||||||
|
void* args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the callback function
|
* Get the callback function
|
||||||
@ -58,6 +55,7 @@ class SpiCookie : public CookieIF {
|
|||||||
void getCallback(spi::send_callback_function_t* callback, void** args);
|
void getCallback(spi::send_callback_function_t* callback, void** args);
|
||||||
|
|
||||||
address_t getSpiAddress() const;
|
address_t getSpiAddress() const;
|
||||||
|
std::string getSpiDevice() const;
|
||||||
gpioId_t getChipSelectPin() const;
|
gpioId_t getChipSelectPin() const;
|
||||||
size_t getMaxBufferSize() const;
|
size_t getMaxBufferSize() const;
|
||||||
|
|
||||||
@ -141,42 +139,9 @@ class SpiCookie : public CookieIF {
|
|||||||
*/
|
*/
|
||||||
void activateCsDeselect(bool deselectCs, uint16_t delayUsecs);
|
void activateCsDeselect(bool deselectCs, uint16_t delayUsecs);
|
||||||
|
|
||||||
void getMutexParams(MutexIF::TimeoutType& csTimeoutType, dur_millis_t& csTimeout) const;
|
|
||||||
void setMutexParams(MutexIF::TimeoutType csTimeoutType, dur_millis_t csTimeout);
|
|
||||||
|
|
||||||
void setCsLockManual(bool enable);
|
|
||||||
bool getCsLockManual() const;
|
|
||||||
|
|
||||||
spi_ioc_transfer* getTransferStructHandle();
|
spi_ioc_transfer* getTransferStructHandle();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
address_t spiAddress;
|
|
||||||
gpioId_t chipSelectPin;
|
|
||||||
|
|
||||||
spi::SpiComIfModes comIfMode;
|
|
||||||
|
|
||||||
// Required for regular mode
|
|
||||||
const size_t maxSize;
|
|
||||||
spi::SpiModes spiMode;
|
|
||||||
/**
|
|
||||||
* If this is set to true, the SPI ComIF will not perform any mutex locking for the
|
|
||||||
* CS mechanism. The user is responsible to locking and unlocking the mutex for the
|
|
||||||
* whole duration of the transfers.
|
|
||||||
*/
|
|
||||||
bool manualCsLock = false;
|
|
||||||
uint32_t spiSpeed;
|
|
||||||
bool halfDuplex = false;
|
|
||||||
|
|
||||||
MutexIF::TimeoutType csTimeoutType = MutexIF::TimeoutType::WAITING;
|
|
||||||
dur_millis_t csTimeout = DEFAULT_MUTEX_TIMEOUT;
|
|
||||||
|
|
||||||
// Required for callback mode
|
|
||||||
spi::send_callback_function_t sendCallback = nullptr;
|
|
||||||
void* callbackArgs = nullptr;
|
|
||||||
|
|
||||||
struct spi_ioc_transfer spiTransferStruct = {};
|
|
||||||
UncommonParameters uncommonParameters;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal constructor which initializes every field
|
* Internal constructor which initializes every field
|
||||||
* @param spiAddress
|
* @param spiAddress
|
||||||
@ -189,8 +154,27 @@ class SpiCookie : public CookieIF {
|
|||||||
* @param args
|
* @param args
|
||||||
*/
|
*/
|
||||||
SpiCookie(spi::SpiComIfModes comIfMode, address_t spiAddress, gpioId_t chipSelect,
|
SpiCookie(spi::SpiComIfModes comIfMode, address_t spiAddress, gpioId_t chipSelect,
|
||||||
const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed,
|
std::string spiDev, const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed,
|
||||||
spi::send_callback_function_t callback, void* args);
|
spi::send_callback_function_t callback, void* args);
|
||||||
|
|
||||||
|
address_t spiAddress;
|
||||||
|
gpioId_t chipSelectPin;
|
||||||
|
std::string spiDevice;
|
||||||
|
|
||||||
|
spi::SpiComIfModes comIfMode;
|
||||||
|
|
||||||
|
// Required for regular mode
|
||||||
|
const size_t maxSize;
|
||||||
|
spi::SpiModes spiMode;
|
||||||
|
uint32_t spiSpeed;
|
||||||
|
bool halfDuplex = false;
|
||||||
|
|
||||||
|
// Required for callback mode
|
||||||
|
spi::send_callback_function_t sendCallback = nullptr;
|
||||||
|
void* callbackArgs = nullptr;
|
||||||
|
|
||||||
|
struct spi_ioc_transfer spiTransferStruct = {};
|
||||||
|
UncommonParameters uncommonParameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* LINUX_SPI_SPICOOKIE_H_ */
|
#endif /* LINUX_SPI_SPICOOKIE_H_ */
|
||||||
|
@ -1 +0,0 @@
|
|||||||
target_sources(${LIB_FSFW_NAME} PUBLIC UartComIF.cpp UartCookie.cpp helper.cpp)
|
|
@ -1,51 +0,0 @@
|
|||||||
#include "UartCookie.h"
|
|
||||||
|
|
||||||
#include <fsfw/serviceinterface.h>
|
|
||||||
|
|
||||||
UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate,
|
|
||||||
size_t maxReplyLen, UartModes uartMode)
|
|
||||||
: handlerId(handlerId),
|
|
||||||
deviceFile(deviceFile),
|
|
||||||
uartMode(uartMode),
|
|
||||||
baudrate(baudrate),
|
|
||||||
maxReplyLen(maxReplyLen) {}
|
|
||||||
|
|
||||||
UartCookie::~UartCookie() {}
|
|
||||||
|
|
||||||
UartBaudRate UartCookie::getBaudrate() const { return baudrate; }
|
|
||||||
|
|
||||||
size_t UartCookie::getMaxReplyLen() const { return maxReplyLen; }
|
|
||||||
|
|
||||||
std::string UartCookie::getDeviceFile() const { return deviceFile; }
|
|
||||||
|
|
||||||
void UartCookie::setParityOdd() { parity = Parity::ODD; }
|
|
||||||
|
|
||||||
void UartCookie::setParityEven() { parity = Parity::EVEN; }
|
|
||||||
|
|
||||||
Parity UartCookie::getParity() const { return parity; }
|
|
||||||
|
|
||||||
void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; }
|
|
||||||
|
|
||||||
BitsPerWord UartCookie::getBitsPerWord() const { return bitsPerWord; }
|
|
||||||
|
|
||||||
StopBits UartCookie::getStopBits() const { return stopBits; }
|
|
||||||
|
|
||||||
void UartCookie::setTwoStopBits() { stopBits = StopBits::TWO_STOP_BITS; }
|
|
||||||
|
|
||||||
void UartCookie::setOneStopBit() { stopBits = StopBits::ONE_STOP_BIT; }
|
|
||||||
|
|
||||||
UartModes UartCookie::getUartMode() const { return uartMode; }
|
|
||||||
|
|
||||||
void UartCookie::setReadCycles(uint8_t readCycles) { this->readCycles = readCycles; }
|
|
||||||
|
|
||||||
void UartCookie::setToFlushInput(bool enable) { this->flushInput = enable; }
|
|
||||||
|
|
||||||
uint8_t UartCookie::getReadCycles() const { return readCycles; }
|
|
||||||
|
|
||||||
bool UartCookie::getInputShouldBeFlushed() { return this->flushInput; }
|
|
||||||
|
|
||||||
object_id_t UartCookie::getHandlerId() const { return this->handlerId; }
|
|
||||||
|
|
||||||
void UartCookie::setNoFixedSizeReply() { replySizeFixed = false; }
|
|
||||||
|
|
||||||
bool UartCookie::isReplySizeFixed() { return replySizeFixed; }
|
|
@ -1,148 +0,0 @@
|
|||||||
#include "helper.h"
|
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
#include "fsfw/serviceinterface.h"
|
|
||||||
|
|
||||||
void uart::setMode(struct termios& options, UartModes mode) {
|
|
||||||
if (mode == UartModes::NON_CANONICAL) {
|
|
||||||
/* Disable canonical mode */
|
|
||||||
options.c_lflag &= ~ICANON;
|
|
||||||
} else if (mode == UartModes::CANONICAL) {
|
|
||||||
options.c_lflag |= ICANON;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
|
|
||||||
switch (baud) {
|
|
||||||
case UartBaudRate::RATE_50:
|
|
||||||
cfsetispeed(&options, B50);
|
|
||||||
cfsetospeed(&options, B50);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_75:
|
|
||||||
cfsetispeed(&options, B75);
|
|
||||||
cfsetospeed(&options, B75);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_110:
|
|
||||||
cfsetispeed(&options, B110);
|
|
||||||
cfsetospeed(&options, B110);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_134:
|
|
||||||
cfsetispeed(&options, B134);
|
|
||||||
cfsetospeed(&options, B134);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_150:
|
|
||||||
cfsetispeed(&options, B150);
|
|
||||||
cfsetospeed(&options, B150);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_200:
|
|
||||||
cfsetispeed(&options, B200);
|
|
||||||
cfsetospeed(&options, B200);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_300:
|
|
||||||
cfsetispeed(&options, B300);
|
|
||||||
cfsetospeed(&options, B300);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_600:
|
|
||||||
cfsetispeed(&options, B600);
|
|
||||||
cfsetospeed(&options, B600);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_1200:
|
|
||||||
cfsetispeed(&options, B1200);
|
|
||||||
cfsetospeed(&options, B1200);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_1800:
|
|
||||||
cfsetispeed(&options, B1800);
|
|
||||||
cfsetospeed(&options, B1800);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_2400:
|
|
||||||
cfsetispeed(&options, B2400);
|
|
||||||
cfsetospeed(&options, B2400);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_4800:
|
|
||||||
cfsetispeed(&options, B4800);
|
|
||||||
cfsetospeed(&options, B4800);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_9600:
|
|
||||||
cfsetispeed(&options, B9600);
|
|
||||||
cfsetospeed(&options, B9600);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_19200:
|
|
||||||
cfsetispeed(&options, B19200);
|
|
||||||
cfsetospeed(&options, B19200);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_38400:
|
|
||||||
cfsetspeed(&options, B38400);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_57600:
|
|
||||||
cfsetispeed(&options, B57600);
|
|
||||||
cfsetospeed(&options, B57600);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_115200:
|
|
||||||
cfsetspeed(&options, B115200);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_230400:
|
|
||||||
cfsetispeed(&options, B230400);
|
|
||||||
cfsetospeed(&options, B230400);
|
|
||||||
break;
|
|
||||||
#ifndef __APPLE__
|
|
||||||
case UartBaudRate::RATE_460800:
|
|
||||||
cfsetispeed(&options, B460800);
|
|
||||||
cfsetospeed(&options, B460800);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_500000:
|
|
||||||
cfsetispeed(&options, B500000);
|
|
||||||
cfsetospeed(&options, B500000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_576000:
|
|
||||||
cfsetispeed(&options, B576000);
|
|
||||||
cfsetospeed(&options, B576000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_921600:
|
|
||||||
cfsetispeed(&options, B921600);
|
|
||||||
cfsetospeed(&options, B921600);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_1000000:
|
|
||||||
cfsetispeed(&options, B1000000);
|
|
||||||
cfsetospeed(&options, B1000000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_1152000:
|
|
||||||
cfsetispeed(&options, B1152000);
|
|
||||||
cfsetospeed(&options, B1152000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_1500000:
|
|
||||||
cfsetispeed(&options, B1500000);
|
|
||||||
cfsetospeed(&options, B1500000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_2000000:
|
|
||||||
cfsetispeed(&options, B2000000);
|
|
||||||
cfsetospeed(&options, B2000000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_2500000:
|
|
||||||
cfsetispeed(&options, B2500000);
|
|
||||||
cfsetospeed(&options, B2500000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_3000000:
|
|
||||||
cfsetispeed(&options, B3000000);
|
|
||||||
cfsetospeed(&options, B3000000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_3500000:
|
|
||||||
cfsetispeed(&options, B3500000);
|
|
||||||
cfsetospeed(&options, B3500000);
|
|
||||||
break;
|
|
||||||
case UartBaudRate::RATE_4000000:
|
|
||||||
cfsetispeed(&options, B4000000);
|
|
||||||
cfsetospeed(&options, B4000000);
|
|
||||||
break;
|
|
||||||
#endif // ! __APPLE__
|
|
||||||
default:
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int uart::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
|
|
||||||
return ioctl(serialPort, TIOCGICOUNT, &icounter);
|
|
||||||
}
|
|
@ -21,10 +21,12 @@ UioMapper::UioMapper(std::string uioFile, int mapNum) : mapNum(mapNum) {
|
|||||||
char* res = realpath(uioFile.c_str(), nullptr);
|
char* res = realpath(uioFile.c_str(), nullptr);
|
||||||
if (res) {
|
if (res) {
|
||||||
this->uioFile = res;
|
this->uioFile = res;
|
||||||
|
free(res);
|
||||||
} else {
|
} else {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "Could not resolve real path of UIO file " << uioFile << std::endl;
|
sif::error << "Could not resolve real path of UIO file " << uioFile << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
free(res);
|
|
||||||
} else {
|
} else {
|
||||||
this->uioFile = std::move(uioFile);
|
this->uioFile = std::move(uioFile);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ ReturnValue_t TestDevice::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t TestDevice::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
ReturnValue_t TestDevice::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||||
if (getMode() == _MODE_TO_ON) {
|
if (mode == _MODE_TO_ON) {
|
||||||
if (fullInfoPrintout) {
|
if (fullInfoPrintout) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "TestDevice" << deviceIdx
|
sif::info << "TestDevice" << deviceIdx
|
||||||
@ -80,7 +80,7 @@ ReturnValue_t TestDevice::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (getMode() == _MODE_TO_NORMAL) {
|
if (mode == _MODE_TO_NORMAL) {
|
||||||
if (fullInfoPrintout) {
|
if (fullInfoPrintout) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "TestDevice" << deviceIdx
|
sif::info << "TestDevice" << deviceIdx
|
||||||
@ -97,7 +97,7 @@ ReturnValue_t TestDevice::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
|||||||
|
|
||||||
setMode(MODE_NORMAL);
|
setMode(MODE_NORMAL);
|
||||||
}
|
}
|
||||||
if (getMode() == _MODE_SHUT_DOWN) {
|
if (mode == _MODE_SHUT_DOWN) {
|
||||||
if (fullInfoPrintout) {
|
if (fullInfoPrintout) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "TestDevice" << deviceIdx
|
sif::info << "TestDevice" << deviceIdx
|
||||||
@ -118,7 +118,7 @@ ReturnValue_t TestDevice::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TestDevice::doTransition(Mode_t modeFrom, Submode_t submodeFrom) {
|
void TestDevice::doTransition(Mode_t modeFrom, Submode_t submodeFrom) {
|
||||||
if (getMode() == _MODE_TO_NORMAL) {
|
if (mode == _MODE_TO_NORMAL) {
|
||||||
if (fullInfoPrintout) {
|
if (fullInfoPrintout) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "TestDevice" << deviceIdx
|
sif::info << "TestDevice" << deviceIdx
|
||||||
|
@ -43,7 +43,7 @@ TEST_CASE("Array List", "[containers]") {
|
|||||||
for (auto i = 0; i < 20; i++) {
|
for (auto i = 0; i < 20; i++) {
|
||||||
REQUIRE(list.insert(i) == static_cast<int>(returnvalue::OK));
|
REQUIRE(list.insert(i) == static_cast<int>(returnvalue::OK));
|
||||||
}
|
}
|
||||||
REQUIRE(list.insert(20) == static_cast<int>(ArrayList<uint16_t>::FULL));
|
REQUIRE(list.insert(20) == static_cast<int>(containers::LIST_FULL));
|
||||||
ArrayList<uint16_t>::Iterator it = list.begin();
|
ArrayList<uint16_t>::Iterator it = list.begin();
|
||||||
REQUIRE((*it) == 0);
|
REQUIRE((*it) == 0);
|
||||||
it++;
|
it++;
|
||||||
|
@ -31,7 +31,7 @@ TEST_CASE("FixedArrayList Tests", "[containers]") {
|
|||||||
for (auto i = 1; i < 260; i++) {
|
for (auto i = 1; i < 260; i++) {
|
||||||
REQUIRE(list.insert(i) == static_cast<int>(returnvalue::OK));
|
REQUIRE(list.insert(i) == static_cast<int>(returnvalue::OK));
|
||||||
}
|
}
|
||||||
REQUIRE(list.insert(260) == static_cast<int>(ArrayList<uint32_t, uint16_t>::FULL));
|
REQUIRE(list.insert(260) == static_cast<int>(containers::LIST_FULL));
|
||||||
list.clear();
|
list.clear();
|
||||||
REQUIRE(list.size == 0);
|
REQUIRE(list.size == 0);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
template class FixedMap<unsigned int, unsigned short>;
|
template class FixedMap<unsigned int, unsigned short>;
|
||||||
|
|
||||||
|
using namespace returnvalue;
|
||||||
|
|
||||||
TEST_CASE("FixedMap Tests", "[containers]") {
|
TEST_CASE("FixedMap Tests", "[containers]") {
|
||||||
INFO("FixedMap Tests");
|
INFO("FixedMap Tests");
|
||||||
|
|
||||||
@ -24,9 +26,9 @@ TEST_CASE("FixedMap Tests", "[containers]") {
|
|||||||
REQUIRE(map.find(i)->second == i + 1);
|
REQUIRE(map.find(i)->second == i + 1);
|
||||||
REQUIRE(not map.empty());
|
REQUIRE(not map.empty());
|
||||||
}
|
}
|
||||||
REQUIRE(map.insert(0, 0) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_ALREADY_EXISTS));
|
REQUIRE(map.insert(0, 0) == static_cast<int>(containers::KEY_ALREADY_EXISTS));
|
||||||
REQUIRE(map.insert(31, 0) == static_cast<int>(FixedMap<uint32_t, uint16_t>::MAP_FULL));
|
REQUIRE(map.insert(31, 0) == static_cast<int>(containers::MAP_FULL));
|
||||||
REQUIRE(map.exists(31) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
REQUIRE(map.exists(31) == static_cast<int>(containers::KEY_DOES_NOT_EXIST));
|
||||||
REQUIRE(map.size() == 30);
|
REQUIRE(map.size() == 30);
|
||||||
REQUIRE(map.full());
|
REQUIRE(map.full());
|
||||||
{
|
{
|
||||||
@ -34,15 +36,14 @@ TEST_CASE("FixedMap Tests", "[containers]") {
|
|||||||
REQUIRE(map.find(5, &ptr) == static_cast<int>(returnvalue::OK));
|
REQUIRE(map.find(5, &ptr) == static_cast<int>(returnvalue::OK));
|
||||||
REQUIRE(*ptr == 6);
|
REQUIRE(*ptr == 6);
|
||||||
REQUIRE(*(map.findValue(6)) == 7);
|
REQUIRE(*(map.findValue(6)) == 7);
|
||||||
REQUIRE(map.find(31, &ptr) ==
|
REQUIRE(map.find(31, &ptr) == static_cast<int>(containers::KEY_DOES_NOT_EXIST));
|
||||||
static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
REQUIRE(map.getSerializedSize() ==
|
REQUIRE(map.getSerializedSize() ==
|
||||||
(sizeof(uint32_t) + 30 * (sizeof(uint32_t) + sizeof(uint16_t))));
|
(sizeof(uint32_t) + 30 * (sizeof(uint32_t) + sizeof(uint16_t))));
|
||||||
REQUIRE(map.erase(2) == static_cast<int>(returnvalue::OK));
|
REQUIRE(map.erase(2) == static_cast<int>(returnvalue::OK));
|
||||||
REQUIRE(map.erase(31) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
REQUIRE(map.erase(31) == static_cast<int>(containers::KEY_DOES_NOT_EXIST));
|
||||||
REQUIRE(map.exists(2) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
REQUIRE(map.exists(2) == static_cast<int>(containers::KEY_DOES_NOT_EXIST));
|
||||||
REQUIRE(map.size() == 29);
|
REQUIRE(map.size() == 29);
|
||||||
|
|
||||||
for (auto element : map) {
|
for (auto element : map) {
|
||||||
@ -79,8 +80,7 @@ TEST_CASE("FixedMap Tests", "[containers]") {
|
|||||||
REQUIRE(map.insert(37, 38, nullptr) == static_cast<int>(returnvalue::OK));
|
REQUIRE(map.insert(37, 38, nullptr) == static_cast<int>(returnvalue::OK));
|
||||||
REQUIRE(map.find(37)->second == 38);
|
REQUIRE(map.find(37)->second == 38);
|
||||||
REQUIRE(map.size() == 2);
|
REQUIRE(map.size() == 2);
|
||||||
REQUIRE(map.insert(37, 24, nullptr) ==
|
REQUIRE(map.insert(37, 24, nullptr) == static_cast<int>(containers::KEY_ALREADY_EXISTS));
|
||||||
static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_ALREADY_EXISTS));
|
|
||||||
REQUIRE(map.find(37)->second != 24);
|
REQUIRE(map.find(37)->second != 24);
|
||||||
REQUIRE(map.size() == 2);
|
REQUIRE(map.size() == 2);
|
||||||
};
|
};
|
||||||
@ -137,7 +137,7 @@ TEST_CASE("FixedMap Tests", "[containers]") {
|
|||||||
FixedMap<uint32_t, uint16_t>::Iterator it;
|
FixedMap<uint32_t, uint16_t>::Iterator it;
|
||||||
std::pair<uint32_t, uint16_t> pair = std::make_pair(44, 43);
|
std::pair<uint32_t, uint16_t> pair = std::make_pair(44, 43);
|
||||||
it = FixedMap<uint32_t, uint16_t>::Iterator(&pair);
|
it = FixedMap<uint32_t, uint16_t>::Iterator(&pair);
|
||||||
REQUIRE(map.erase(&it) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
REQUIRE(map.erase(&it) == static_cast<int>(containers::KEY_DOES_NOT_EXIST));
|
||||||
REQUIRE(map.find(45) == map.end());
|
REQUIRE(map.find(45) == map.end());
|
||||||
size_t toLargeMap = 100;
|
size_t toLargeMap = 100;
|
||||||
const uint8_t* ptr = reinterpret_cast<uint8_t*>(&toLargeMap);
|
const uint8_t* ptr = reinterpret_cast<uint8_t*>(&toLargeMap);
|
||||||
|
@ -269,7 +269,7 @@ TEST_CASE("DataSetTest", "[DataSetTest]") {
|
|||||||
|
|
||||||
{
|
{
|
||||||
// PoolReadGuard rg(&sharedSet);
|
// PoolReadGuard rg(&sharedSet);
|
||||||
// CHECK(rg.getReadResult() == returnvalue::OK);
|
// CHECK(rg.getReadResult() == result::OK);
|
||||||
localSet.localPoolVarUint8.value = 5;
|
localSet.localPoolVarUint8.value = 5;
|
||||||
localSet.localPoolUint16Vec.value[0] = 1;
|
localSet.localPoolUint16Vec.value[0] = 1;
|
||||||
localSet.localPoolUint16Vec.value[1] = 2;
|
localSet.localPoolUint16Vec.value[1] = 2;
|
||||||
|
@ -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()
|
||||||
|
@ -78,7 +78,7 @@ TEST_CASE("Command Executor", "[hal][linux]") {
|
|||||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||||
// This ensures that the tests do not block indefinitely
|
// This ensures that the tests do not block indefinitely
|
||||||
usleep(500);
|
usleep(500);
|
||||||
REQUIRE(limitIdx < 50000);
|
REQUIRE(limitIdx < 500);
|
||||||
}
|
}
|
||||||
limitIdx = 0;
|
limitIdx = 0;
|
||||||
CHECK(bytesHaveBeenRead == true);
|
CHECK(bytesHaveBeenRead == true);
|
||||||
|
@ -6,7 +6,7 @@ AcceptsTmMock::AcceptsTmMock(object_id_t registeredId, MessageQueueId_t queueToR
|
|||||||
AcceptsTmMock::AcceptsTmMock(MessageQueueId_t queueToReturn)
|
AcceptsTmMock::AcceptsTmMock(MessageQueueId_t queueToReturn)
|
||||||
: SystemObject(objects::NO_OBJECT, false), returnedQueue(queueToReturn) {}
|
: SystemObject(objects::NO_OBJECT, false), returnedQueue(queueToReturn) {}
|
||||||
|
|
||||||
MessageQueueId_t AcceptsTmMock::getReportReceptionQueue(uint8_t virtualChannel) {
|
MessageQueueId_t AcceptsTmMock::getReportReceptionQueue(uint8_t virtualChannel) const {
|
||||||
return returnedQueue;
|
return returnedQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ class AcceptsTmMock : public SystemObject, public AcceptsTelemetryIF {
|
|||||||
AcceptsTmMock(object_id_t registeredId, MessageQueueId_t queueToReturn);
|
AcceptsTmMock(object_id_t registeredId, MessageQueueId_t queueToReturn);
|
||||||
explicit AcceptsTmMock(MessageQueueId_t queueToReturn);
|
explicit AcceptsTmMock(MessageQueueId_t queueToReturn);
|
||||||
|
|
||||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) override;
|
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
|
||||||
const char* getName() const override;
|
const char* getName() const override;
|
||||||
|
|
||||||
MessageQueueId_t returnedQueue;
|
MessageQueueId_t returnedQueue;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user