Compare commits
31 Commits
docker_d9
...
mohr/warni
Author | SHA1 | Date | |
---|---|---|---|
2ca9eb4204 | |||
45b686a028 | |||
329e80e7ee | |||
4cf52d5dfe | |||
46230e6c6d | |||
e2b66df72e | |||
7b828f233a | |||
c3d1000cd5 | |||
8e0e57714d | |||
cc9e54ea6b | |||
31465a4e0f | |||
c0e5d1eb99 | |||
3bc5d4a2e0 | |||
b1e9dd9e4a | |||
ab86599db3 | |||
034eb34c2e | |||
4374c7c4f4 | |||
5343844be5 | |||
e300490b93 | |||
0f811777a7 | |||
e93137939e | |||
1f88c006d9 | |||
7e94baceef | |||
9b05e8f274 | |||
eb223dae88 | |||
3656662d88 | |||
fe71978467 | |||
b646717a76 | |||
99d8c845f2 | |||
ba62c28b64 | |||
7adb47aecb |
15
CHANGELOG.md
15
CHANGELOG.md
@ -12,6 +12,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Fixes
|
||||
|
||||
- `Service9TimeManagement`: Fix the time dump at the `SET_TIME` subservice: Include clock timeval
|
||||
seconds instead of uptime.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726
|
||||
- HAL MGM3100 Handler: Use axis specific gain/scaling factors. Previously,
|
||||
only the X scaling factor was used.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/724
|
||||
- DHB `setNormalDatapoolEntriesInvalid`: The default implementation did not set the validity
|
||||
to false correctly because the `read` and `write` calls were missing.
|
||||
- PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead
|
||||
of the correct unsegmented flags (0b11) as specified in the standard.
|
||||
- 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.
|
||||
@ -28,6 +38,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Added
|
||||
|
||||
- `Service9TimeManagement`: Add `DUMP_TIME` (129) subservice.
|
||||
- `TcpTmTcServer`: Allow setting the `SO_REUSEADDR` and `SO_REUSEPORT`
|
||||
option on the TCP server. CTOR prototype has changed and expects an explicit
|
||||
TCP configuration struct to be passed.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/722
|
||||
- `DleParser` helper class to parse DLE encoded packets from a byte stream.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/711
|
||||
- `UioMapper` is able to resolve symlinks now.
|
||||
|
@ -480,7 +480,46 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(FSFW_WARNING_FLAGS -Wall -Wno-gnu-anonymous-struct)
|
||||
set(FSFW_WARNING_FLAGS
|
||||
-Weverything
|
||||
|
||||
-Wno-gnu-anonymous-struct
|
||||
-Wno-c++98-compat
|
||||
-Wno-c++98-compat-pedantic
|
||||
-Wno-covered-switch-default
|
||||
-Wno-padded
|
||||
-Wno-documentation
|
||||
-Wno-weak-vtables
|
||||
-Wno-c++98-c++11-compat-binary-literal
|
||||
-Wno-documentation-unknown-command
|
||||
-Wno-reserved-macro-identifier
|
||||
-Wno-global-constructors
|
||||
-Wno-reserved-identifier
|
||||
-Wno-switch-enum
|
||||
|
||||
-Werror
|
||||
#WTH?
|
||||
-Wno-ctad-maybe-unsupported
|
||||
#WIP
|
||||
-Wno-undefined-func-template
|
||||
-Wno-suggest-destructor-override
|
||||
-Wno-suggest-override
|
||||
-Wno-inconsistent-missing-destructor-override
|
||||
-Wno-extra-semi
|
||||
#could be useful:
|
||||
-Wno-sign-conversion
|
||||
-Wno-implicit-int-conversion
|
||||
-Wno-shorten-64-to-32
|
||||
-Wno-double-promotion
|
||||
-Wno-float-conversion
|
||||
-Wno-implicit-int-float-conversion
|
||||
-Wno-implicit-float-conversion
|
||||
-Wno-shadow-field-in-constructor
|
||||
-Wno-shadow-field
|
||||
-Wno-shadow
|
||||
-Wno-unused-parameter
|
||||
|
||||
)
|
||||
endif()
|
||||
|
||||
# Required include paths to compile the FSFW
|
||||
|
3
automation/Jenkinsfile
vendored
3
automation/Jenkinsfile
vendored
@ -9,7 +9,7 @@ pipeline {
|
||||
}
|
||||
agent {
|
||||
docker {
|
||||
image 'fsfw-ci:d8'
|
||||
image 'fsfw-ci:d9'
|
||||
args '--network host --sysctl fs.mqueue.msg_max=100'
|
||||
}
|
||||
}
|
||||
@ -67,6 +67,7 @@ pipeline {
|
||||
dir(BUILDDIR_WIN) {
|
||||
sh 'cmake -DFSFW_OSAL=host -DFSFW_BUILD_TESTS=ON -DFSFW_TESTS_GEN_COV=OFF -DFSFW_CICD_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../unittests/testcfg/windows/cmake/x64-windows-toolchain.cmake -GNinja ..'
|
||||
sh 'cmake --build . -j4'
|
||||
sh 'wine64 fsfw-tests.exe'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ class UserBase {
|
||||
|
||||
public:
|
||||
explicit UserBase(HasFileSystemIF& vfs);
|
||||
virtual ~UserBase() = default;
|
||||
|
||||
virtual void transactionIndication(const TransactionId& id) = 0;
|
||||
virtual void eofSentIndication(const TransactionId& id) = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "helpers.h"
|
||||
|
||||
const char* COND_CODE_STRINGS[14] = {"Unknown",
|
||||
static const char* COND_CODE_STRINGS[14] = {"Unknown",
|
||||
"No Error",
|
||||
"Positive ACK Limit Reached",
|
||||
"Keep Alive Limit Reached",
|
||||
|
@ -8,7 +8,7 @@
|
||||
template <typename Tp>
|
||||
class BinaryNode {
|
||||
public:
|
||||
BinaryNode(Tp* setValue) : value(setValue), left(NULL), right(NULL), parent(NULL) {}
|
||||
BinaryNode(Tp* setValue) : value(setValue), left(nullptr), right(nullptr), parent(nullptr) {}
|
||||
Tp* value;
|
||||
BinaryNode* left;
|
||||
BinaryNode* right;
|
||||
@ -23,31 +23,31 @@ class ExplicitNodeIterator {
|
||||
typedef Tp value_type;
|
||||
typedef Tp* pointer;
|
||||
typedef Tp& reference;
|
||||
ExplicitNodeIterator() : element(NULL) {}
|
||||
ExplicitNodeIterator() : element(nullptr) {}
|
||||
ExplicitNodeIterator(_Node* node) : element(node) {}
|
||||
BinaryNode<Tp>* element;
|
||||
_Self up() { return _Self(element->parent); }
|
||||
_Self left() {
|
||||
if (element != NULL) {
|
||||
if (element != nullptr) {
|
||||
return _Self(element->left);
|
||||
} else {
|
||||
return _Self(NULL);
|
||||
return _Self(nullptr);
|
||||
}
|
||||
}
|
||||
_Self right() {
|
||||
if (element != NULL) {
|
||||
if (element != nullptr) {
|
||||
return _Self(element->right);
|
||||
} else {
|
||||
return _Self(NULL);
|
||||
return _Self(nullptr);
|
||||
}
|
||||
}
|
||||
bool operator==(const _Self& __x) const { return element == __x.element; }
|
||||
bool operator!=(const _Self& __x) const { return element != __x.element; }
|
||||
pointer operator->() const {
|
||||
if (element != NULL) {
|
||||
if (element != nullptr) {
|
||||
return element->value;
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
pointer operator*() const { return this->operator->(); }
|
||||
@ -62,13 +62,13 @@ class BinaryTree {
|
||||
typedef ExplicitNodeIterator<Tp> iterator;
|
||||
typedef BinaryNode<Tp> Node;
|
||||
typedef std::pair<iterator, iterator> children;
|
||||
BinaryTree() : rootNode(NULL) {}
|
||||
BinaryTree() : rootNode(nullptr) {}
|
||||
BinaryTree(Node* rootNode) : rootNode(rootNode) {}
|
||||
iterator begin() const { return iterator(rootNode); }
|
||||
static iterator end() { return iterator(NULL); }
|
||||
static iterator end() { return iterator(nullptr); }
|
||||
iterator insert(bool insertLeft, iterator parentNode, Node* newNode) {
|
||||
newNode->parent = parentNode.element;
|
||||
if (parentNode.element != NULL) {
|
||||
if (parentNode.element != nullptr) {
|
||||
if (insertLeft) {
|
||||
parentNode.element->left = newNode;
|
||||
} else {
|
||||
@ -84,13 +84,13 @@ class BinaryTree {
|
||||
children erase(iterator node) {
|
||||
if (node.element == rootNode) {
|
||||
// We're root node
|
||||
rootNode = NULL;
|
||||
rootNode = nullptr;
|
||||
} else {
|
||||
// Delete parent's reference
|
||||
if (node.up().left() == node) {
|
||||
node.up().element->left = NULL;
|
||||
node.up().element->left = nullptr;
|
||||
} else {
|
||||
node.up().element->right = NULL;
|
||||
node.up().element->right = nullptr;
|
||||
}
|
||||
}
|
||||
return children(node.element->left, node.element->right);
|
||||
|
@ -61,7 +61,7 @@ class PlacementFactory {
|
||||
// Need to call destructor first, in case something was allocated by the object (shouldn't do
|
||||
// that, however).
|
||||
thisElement->~T();
|
||||
uint8_t* pointer = (uint8_t*)(thisElement);
|
||||
uint8_t* pointer = static_cast<uint8_t*>(thisElement);
|
||||
return dataBackend->deleteData(pointer, sizeof(T));
|
||||
}
|
||||
|
||||
|
@ -286,7 +286,6 @@ ReturnValue_t LocalDataPoolManager::addUpdateToStore(HousekeepingSnapshot& updat
|
||||
result = updatePacket.serialize(&storePtr, &serializedSize, updatePacketSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
return result;
|
||||
;
|
||||
}
|
||||
|
||||
void LocalDataPoolManager::handleChangeResetLogic(DataType type, DataId dataId,
|
||||
|
@ -27,7 +27,7 @@ ReturnValue_t ChildHandlerBase::initialize() {
|
||||
|
||||
if (parentId != objects::NO_OBJECT) {
|
||||
SubsystemBase* parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||
if (parent == NULL) {
|
||||
if (parent == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
parentQueue = parent->getCommandQueue();
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
#include "fsfw/datapoollocal/LocalPoolVariable.h"
|
||||
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
|
||||
#include "fsfw/devicehandlers/DeviceTmReportingWrapper.h"
|
||||
@ -933,19 +934,14 @@ DeviceHandlerIF::CommunicationAction DeviceHandlerBase::getComAction() {
|
||||
switch (pstStep) {
|
||||
case 0:
|
||||
return CommunicationAction::PERFORM_OPERATION;
|
||||
break;
|
||||
case 1:
|
||||
return CommunicationAction::SEND_WRITE;
|
||||
break;
|
||||
case 2:
|
||||
return CommunicationAction::GET_WRITE;
|
||||
break;
|
||||
case 3:
|
||||
return CommunicationAction::SEND_READ;
|
||||
break;
|
||||
case 4:
|
||||
return CommunicationAction::GET_READ;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -961,7 +957,7 @@ void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) {
|
||||
replyReturnvalueToCommand(result, RAW_COMMAND_ID);
|
||||
storedRawData.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
} else {
|
||||
cookieInfo.pendingCommand = deviceCommandMap.find((DeviceCommandId_t)RAW_COMMAND_ID);
|
||||
cookieInfo.pendingCommand = deviceCommandMap.find(static_cast<DeviceCommandId_t>(RAW_COMMAND_ID));
|
||||
cookieInfo.pendingCommand->second.isExecuting = true;
|
||||
cookieInfo.state = COOKIE_WRITE_READY;
|
||||
}
|
||||
@ -1505,7 +1501,10 @@ DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
|
||||
void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() {
|
||||
for (const auto& reply : deviceReplyMap) {
|
||||
if (reply.second.dataSet != nullptr) {
|
||||
reply.second.dataSet->setValidity(false, true);
|
||||
PoolReadGuard pg(reply.second.dataSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
reply.second.dataSet->setValidity(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ void DeviceHandlerMessage::clear(CommandMessage* message) {
|
||||
ipcStore->deleteData(getStoreAddress(message));
|
||||
}
|
||||
}
|
||||
/* NO BREAK falls through*/
|
||||
[[fallthrough]];
|
||||
case CMD_SWITCH_ADDRESS:
|
||||
case CMD_WIRETAPPING:
|
||||
message->setCommand(CommandMessage::CMD_NONE);
|
||||
|
@ -7,10 +7,10 @@
|
||||
|
||||
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
||||
: SystemObject(setObjectId),
|
||||
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
|
||||
poolManager(this, commandQueue),
|
||||
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
||||
internalErrorDataset(this) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ class CommandMessage : public MessageQueueMessage, public CommandMessageIF {
|
||||
/**
|
||||
* @brief Default Destructor
|
||||
*/
|
||||
virtual ~CommandMessage() {}
|
||||
~CommandMessage() override {}
|
||||
|
||||
/**
|
||||
* Read the DeviceHandlerCommand_t that is stored in the message,
|
||||
|
@ -37,7 +37,7 @@ class CommandMessageIF {
|
||||
//! par1 should contain the error code
|
||||
static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID(2);
|
||||
|
||||
virtual ~CommandMessageIF(){};
|
||||
virtual ~CommandMessageIF() = default;
|
||||
|
||||
/**
|
||||
* A command message shall have a uint16_t command ID field.
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <fsfw/objectmanager/frameworkObjects.h>
|
||||
|
||||
struct MqArgs {
|
||||
MqArgs(){};
|
||||
MqArgs(){}
|
||||
MqArgs(object_id_t objectId, void* args = nullptr) : objectId(objectId), args(args) {}
|
||||
object_id_t objectId = objects::NO_OBJECT;
|
||||
void* args = nullptr;
|
||||
|
@ -40,7 +40,7 @@ class ObjectManagerIF {
|
||||
/**
|
||||
* @brief This is the empty virtual destructor as requested by C++ interfaces.
|
||||
*/
|
||||
virtual ~ObjectManagerIF(void){};
|
||||
virtual ~ObjectManagerIF(void){}
|
||||
/**
|
||||
* @brief With this call, new objects are inserted to the list.
|
||||
* @details The implementation shall return an error code in case the
|
||||
|
@ -45,7 +45,7 @@ class SystemObject : public SystemObjectIF {
|
||||
/**
|
||||
* @brief On destruction, the object removes itself from the list.
|
||||
*/
|
||||
virtual ~SystemObject();
|
||||
~SystemObject() override;
|
||||
object_id_t getObjectId() const override;
|
||||
virtual ReturnValue_t initialize() override;
|
||||
virtual ReturnValue_t checkObjectConnections() override;
|
||||
|
@ -36,7 +36,7 @@ class SystemObjectIF : public EventReportingProxyIF {
|
||||
/**
|
||||
* The empty virtual destructor as required for C++ interfaces.
|
||||
*/
|
||||
virtual ~SystemObjectIF() {}
|
||||
~SystemObjectIF() override {}
|
||||
/**
|
||||
* @brief Initializes the object.
|
||||
* There are initialization steps which can also be done in the constructor.
|
||||
|
@ -26,12 +26,12 @@ typedef SSIZE_T ssize_t;
|
||||
const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
|
||||
|
||||
TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
|
||||
size_t receptionBufferSize, size_t ringBufferSize,
|
||||
std::string customTcpServerPort, ReceptionModes receptionMode)
|
||||
TcpTmTcServer::TcpConfig cfg, size_t receptionBufferSize,
|
||||
size_t ringBufferSize, ReceptionModes receptionMode)
|
||||
: SystemObject(objectId),
|
||||
tmtcBridgeId(tmtcTcpBridge),
|
||||
receptionMode(receptionMode),
|
||||
tcpConfig(std::move(customTcpServerPort)),
|
||||
tcpConfig(cfg),
|
||||
receptionBuffer(receptionBufferSize),
|
||||
ringBuffer(ringBufferSize, true) {}
|
||||
|
||||
@ -91,6 +91,15 @@ ReturnValue_t TcpTmTcServer::initialize() {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
if (tcpConfig.reuseAddr) {
|
||||
unsigned int enable = 1;
|
||||
setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
|
||||
}
|
||||
if (tcpConfig.reusePort) {
|
||||
unsigned int enable = 1;
|
||||
setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(enable));
|
||||
}
|
||||
|
||||
// Bind to the address found by getaddrinfo
|
||||
retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
|
||||
if (retval == SOCKET_ERROR) {
|
||||
|
@ -41,11 +41,11 @@ class SpacePacketParser;
|
||||
*/
|
||||
class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableObjectIF {
|
||||
public:
|
||||
enum class ReceptionModes { SPACE_PACKETS };
|
||||
|
||||
struct TcpConfig {
|
||||
public:
|
||||
explicit TcpConfig(std::string tcpPort) : tcpPort(std::move(tcpPort)) {}
|
||||
TcpConfig(bool reuseAddr, bool reusePort) : reuseAddr(reuseAddr), reusePort(reusePort) {}
|
||||
TcpConfig(std::string tcpPort, bool reuseAddr, bool reusePort)
|
||||
: tcpPort(std::move(tcpPort)), reuseAddr(reuseAddr), reusePort(reusePort) {}
|
||||
|
||||
/**
|
||||
* Passed to the recv call
|
||||
@ -63,8 +63,24 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
|
||||
*/
|
||||
int tcpTmFlags = 0;
|
||||
|
||||
const std::string tcpPort;
|
||||
std::string tcpPort = DEFAULT_SERVER_PORT;
|
||||
|
||||
/**
|
||||
* Sets the SO_REUSEADDR option on the socket. See
|
||||
* https://man7.org/linux/man-pages/man7/socket.7.html for more details. This option is
|
||||
* especially useful in a debugging and development environment where an OBSW image might be
|
||||
* re-flashed oftentimes and where all incoming telecommands are received on a dedicated TCP
|
||||
* port.
|
||||
*/
|
||||
bool reuseAddr = false;
|
||||
/**
|
||||
* Sets the SO_REUSEPORT option on the socket. See
|
||||
* https://man7.org/linux/man-pages/man7/socket.7.html for more details.
|
||||
*/
|
||||
bool reusePort = false;
|
||||
|
||||
};
|
||||
enum class ReceptionModes { SPACE_PACKETS };
|
||||
|
||||
static const std::string DEFAULT_SERVER_PORT;
|
||||
|
||||
@ -80,10 +96,9 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb
|
||||
* size will be the Ethernet MTU size
|
||||
* @param customTcpServerPort The user can specify another port than the default (7301) here.
|
||||
*/
|
||||
TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
|
||||
TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, TcpTmTcServer::TcpConfig cfg,
|
||||
size_t receptionBufferSize = RING_BUFFER_SIZE,
|
||||
size_t ringBufferSize = RING_BUFFER_SIZE,
|
||||
std::string customTcpServerPort = DEFAULT_SERVER_PORT,
|
||||
ReceptionModes receptionMode = ReceptionModes::SPACE_PACKETS);
|
||||
~TcpTmTcServer() override;
|
||||
|
||||
|
@ -69,14 +69,14 @@ ReturnValue_t Service20ParameterManagement::checkInterfaceAndAcquireMessageQueue
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Service20ParameterManagement::checkInterfaceAndAcquire"
|
||||
<< "MessageQueue: Can't access object" << std::endl;
|
||||
sif::error << "Object ID: " << std::hex << objectId << std::dec << std::endl;
|
||||
sif::error << "Make sure it implements ReceivesParameterMessagesIF!" << std::endl;
|
||||
sif::error << "Object ID: 0x" << std::hex << *objectId << std::dec << std::endl;
|
||||
sif::error << "Make sure it implements ReceivesParameterMessagesIF" << std::endl;
|
||||
#else
|
||||
sif::printError(
|
||||
"Service20ParameterManagement::checkInterfaceAndAcquire"
|
||||
"MessageQueue: Can't access object\n");
|
||||
sif::printError("Object ID: 0x%08x\n", *objectId);
|
||||
sif::printError("Make sure it implements ReceivesParameterMessagesIF!\n");
|
||||
sif::printError("Make sure it implements ReceivesParameterMessagesIF\n");
|
||||
#endif
|
||||
|
||||
return CommandingServiceBase::INVALID_OBJECT;
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "fsfw/pus/Service9TimeManagement.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "fsfw/events/EventManagerIF.h"
|
||||
#include "fsfw/pus/servicepackets/Service9Packets.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
@ -15,9 +17,17 @@ ReturnValue_t Service9TimeManagement::performService() { return returnvalue::OK;
|
||||
|
||||
ReturnValue_t Service9TimeManagement::handleRequest(uint8_t subservice) {
|
||||
switch (subservice) {
|
||||
case SUBSERVICE::SET_TIME: {
|
||||
case Subservice::SET_TIME: {
|
||||
return setTime();
|
||||
}
|
||||
case Subservice::DUMP_TIME: {
|
||||
timeval newTime;
|
||||
Clock::getClock_timeval(&newTime);
|
||||
uint32_t subsecondMs =
|
||||
static_cast<uint32_t>(std::floor(static_cast<double>(newTime.tv_usec) / 1000.0));
|
||||
triggerEvent(CLOCK_DUMP, newTime.tv_sec, subsecondMs);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
default:
|
||||
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
|
||||
}
|
||||
@ -33,13 +43,14 @@ ReturnValue_t Service9TimeManagement::setTime() {
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO maybe switch to getClock_usecs to report more meaningful data
|
||||
uint32_t formerUptime = Clock::getUptime_ms();
|
||||
timeval time;
|
||||
Clock::getClock_timeval(&time);
|
||||
result = Clock::setClock(&timeToSet);
|
||||
|
||||
if (result == returnvalue::OK) {
|
||||
uint32_t newUptime = Clock::getUptime_ms();
|
||||
triggerEvent(CLOCK_SET, newUptime, formerUptime);
|
||||
timeval newTime;
|
||||
Clock::getClock_timeval(&newTime);
|
||||
triggerEvent(CLOCK_SET, time.tv_sec, newTime.tv_sec);
|
||||
return returnvalue::OK;
|
||||
} else {
|
||||
triggerEvent(CLOCK_SET_FAILURE, result, 0);
|
||||
|
@ -6,10 +6,13 @@
|
||||
class Service9TimeManagement : public PusServiceBase {
|
||||
public:
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
|
||||
static constexpr Event CLOCK_SET =
|
||||
MAKE_EVENT(0, severity::INFO); //!< Clock has been set. P1: New Uptime. P2: Old Uptime
|
||||
static constexpr Event CLOCK_SET_FAILURE =
|
||||
MAKE_EVENT(1, severity::LOW); //!< Clock could not be set. P1: Returncode.
|
||||
|
||||
//!< Clock has been set. P1: old timeval seconds. P2: new timeval seconds.
|
||||
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO);
|
||||
//!< Clock dump event. P1: timeval seconds P2: timeval milliseconds.
|
||||
static constexpr Event CLOCK_DUMP = MAKE_EVENT(1, severity::INFO);
|
||||
//!< Clock could not be set. P1: Returncode.
|
||||
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(2, severity::LOW);
|
||||
|
||||
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
||||
|
||||
@ -30,8 +33,9 @@ class Service9TimeManagement : public PusServiceBase {
|
||||
virtual ReturnValue_t setTime();
|
||||
|
||||
private:
|
||||
enum SUBSERVICE {
|
||||
SET_TIME = 128 //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
|
||||
enum Subservice {
|
||||
SET_TIME = 128, //!< [EXPORT] : [COMMAND] Time command in ASCII, CUC or CDS format
|
||||
DUMP_TIME = 129,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -20,9 +20,6 @@ SerialBufferAdapter<count_t>::SerialBufferAdapter(uint8_t* buffer, count_t buffe
|
||||
buffer(buffer),
|
||||
bufferLength(bufferLength) {}
|
||||
|
||||
template <typename count_t>
|
||||
SerialBufferAdapter<count_t>::~SerialBufferAdapter() = default;
|
||||
|
||||
template <typename count_t>
|
||||
ReturnValue_t SerialBufferAdapter<count_t>::serialize(uint8_t** buffer_, size_t* size,
|
||||
size_t maxSize,
|
||||
|
@ -41,7 +41,7 @@ class SerialBufferAdapter : public SerializeIF {
|
||||
*/
|
||||
SerialBufferAdapter(uint8_t* buffer, count_t bufferLength, bool serializeLength = false);
|
||||
|
||||
~SerialBufferAdapter() override;
|
||||
~SerialBufferAdapter() override = default;
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
@ -74,4 +74,10 @@ class SerialBufferAdapter : public SerializeIF {
|
||||
count_t bufferLength = 0;
|
||||
};
|
||||
|
||||
// declaration of explicit instantiations (which are in the cpp)
|
||||
extern template class SerialBufferAdapter<uint8_t>;
|
||||
extern template class SerialBufferAdapter<uint16_t>;
|
||||
extern template class SerialBufferAdapter<uint32_t>;
|
||||
extern template class SerialBufferAdapter<uint64_t>;
|
||||
|
||||
#endif /* SERIALBUFFERADAPTER_H_ */
|
||||
|
@ -35,6 +35,12 @@ class SerializeIF {
|
||||
MAKE_RETURN_CODE(3); // !< There are too many elements to be deserialized
|
||||
|
||||
virtual ~SerializeIF() = default;
|
||||
// C++11 deprecates automatic generation of copy ctor and assignment operator when
|
||||
// a destructor is defined, so we need to explicitely set them to default
|
||||
SerializeIF(const SerializeIF&) = default;
|
||||
SerializeIF() = default;
|
||||
SerializeIF& operator= ( const SerializeIF & ) = default;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Function to serialize the object into a buffer with maxSize. Size represents the written
|
||||
|
@ -22,7 +22,7 @@ union store_address_t {
|
||||
*/
|
||||
explicit store_address_t(uint32_t rawAddress) : raw(rawAddress) {}
|
||||
|
||||
static store_address_t invalid() { return {}; };
|
||||
static store_address_t invalid() { return {}; }
|
||||
|
||||
/**
|
||||
* Constructor to create an address object using pool
|
||||
|
@ -34,7 +34,7 @@ class ExecutableObjectIF {
|
||||
* a reference to the executing task
|
||||
* @param task_ Pointer to the taskIF of this task
|
||||
*/
|
||||
virtual void setTaskIF(PeriodicTaskIF* task_){};
|
||||
virtual void setTaskIF(PeriodicTaskIF* task_){}
|
||||
|
||||
/**
|
||||
* This function should be called after the object was assigned to a
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
class RawUserDataReaderIF {
|
||||
public:
|
||||
~RawUserDataReaderIF() = default;
|
||||
virtual ~RawUserDataReaderIF() = default;
|
||||
[[nodiscard]] virtual const uint8_t* getUserData() const = 0;
|
||||
[[nodiscard]] virtual size_t getUserDataLen() const = 0;
|
||||
};
|
||||
|
@ -100,5 +100,6 @@ ReturnValue_t PusTcCreator::setSerializableUserData(const SerializeIF &serializa
|
||||
void PusTcCreator::setup() {
|
||||
spCreator.setPacketType(ccsds::PacketType::TC);
|
||||
spCreator.setSecHeaderFlag();
|
||||
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
|
||||
updateSpLengthField();
|
||||
}
|
||||
|
@ -119,6 +119,7 @@ void PusTmCreator::setup() {
|
||||
updateSpLengthField();
|
||||
spCreator.setPacketType(ccsds::PacketType::TM);
|
||||
spCreator.setSecHeaderFlag();
|
||||
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
|
||||
}
|
||||
|
||||
void PusTmCreator::setMessageTypeCounter(uint16_t messageTypeCounter) {
|
||||
|
@ -180,10 +180,6 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
#endif
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "I2cComIF::requestReceiveMessage: Read " << readLen << " of " << requestLen
|
||||
<< " bytes" << std::endl;
|
||||
#endif
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
@ -30,4 +30,4 @@ TEST_CASE("Binary Semaphore Test", "[BinSemaphore]") {
|
||||
|
||||
TEST_CASE("Counting Semaphore Test", "[CountingSemaph]") {
|
||||
SECTION("Simple Test") {}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
namespace addresses {
|
||||
/* Logical addresses have uint32_t datatype */
|
||||
enum logicalAddresses : address_t {};
|
||||
enum LogicAddress : address_t {};
|
||||
} // namespace addresses
|
||||
|
||||
#endif /* CONFIG_DEVICES_LOGICALADDRESSES_H_ */
|
||||
|
Reference in New Issue
Block a user