From b7f3eff74230fa89fc02cc28a368460b32cfb80d Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Fri, 18 Feb 2022 19:08:06 +0100 Subject: [PATCH 01/26] WIP unit tests --- scripts/helper.py | 4 -- .../internalerror/InternalErrorReporter.cpp | 3 + .../internalerror/InternalErrorReporter.h | 6 +- tests/src/fsfw_tests/unit/CMakeLists.txt | 1 + .../unit/internalerror/CMakeLists.txt | 3 + .../TestInternalErrorReporter.cpp | 71 +++++++++++++++++++ .../unit/mocks/PeriodicTaskIFMock.h | 45 ++++++++++++ .../fsfw_tests/unit/osal/TestMessageQueue.cpp | 21 ++++++ 8 files changed, 147 insertions(+), 7 deletions(-) create mode 100644 tests/src/fsfw_tests/unit/internalerror/CMakeLists.txt create mode 100644 tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp create mode 100644 tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h diff --git a/scripts/helper.py b/scripts/helper.py index 68693c40..079a5548 100755 --- a/scripts/helper.py +++ b/scripts/helper.py @@ -143,10 +143,6 @@ def handle_tests_type(args, build_dir_list: list): if which("valgrind") is None: print("Please install valgrind first") sys.exit(1) - if os.path.split(os.getcwd())[1] != UNITTEST_FOLDER_NAME: - # If we are in a different directory we try to switch into it but - # this might fail - os.chdir(UNITTEST_FOLDER_NAME) os.system("valgrind --leak-check=full ./fsfw-tests") os.chdir("..") diff --git a/src/fsfw/internalerror/InternalErrorReporter.cpp b/src/fsfw/internalerror/InternalErrorReporter.cpp index e7088e2c..98ed2af3 100644 --- a/src/fsfw/internalerror/InternalErrorReporter.cpp +++ b/src/fsfw/internalerror/InternalErrorReporter.cpp @@ -57,6 +57,9 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) { internalErrorDataset.storeHits.value += newStoreHits; internalErrorDataset.tmHits.value += newTmHits; internalErrorDataset.setValidity(true, true); + if((newQueueHits != 0) or (newStoreHits !=0) or (newTmHits != 0)){ + internalErrorDataset.setChanged(true); + } } } diff --git a/src/fsfw/internalerror/InternalErrorReporter.h b/src/fsfw/internalerror/InternalErrorReporter.h index 98711139..a946b81c 100644 --- a/src/fsfw/internalerror/InternalErrorReporter.h +++ b/src/fsfw/internalerror/InternalErrorReporter.h @@ -46,11 +46,11 @@ class InternalErrorReporter : public SystemObject, virtual ReturnValue_t initializeAfterTaskCreation() override; virtual ReturnValue_t performOperation(uint8_t opCode) override; - virtual void queueMessageNotSent(); + virtual void queueMessageNotSent() override; - virtual void lostTm(); + virtual void lostTm() override; - virtual void storeFull(); + virtual void storeFull() override; virtual void setTaskIF(PeriodicTaskIF* task) override; diff --git a/tests/src/fsfw_tests/unit/CMakeLists.txt b/tests/src/fsfw_tests/unit/CMakeLists.txt index fc73f7b5..a83e2f7f 100644 --- a/tests/src/fsfw_tests/unit/CMakeLists.txt +++ b/tests/src/fsfw_tests/unit/CMakeLists.txt @@ -23,3 +23,4 @@ add_subdirectory(timemanager) add_subdirectory(tmtcpacket) add_subdirectory(cfdp) add_subdirectory(hal) +add_subdirectory(internalerror) diff --git a/tests/src/fsfw_tests/unit/internalerror/CMakeLists.txt b/tests/src/fsfw_tests/unit/internalerror/CMakeLists.txt new file mode 100644 index 00000000..d49ce006 --- /dev/null +++ b/tests/src/fsfw_tests/unit/internalerror/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(${FSFW_TEST_TGT} PRIVATE + TestInternalErrorReporter.cpp +) diff --git a/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp new file mode 100644 index 00000000..d394166e --- /dev/null +++ b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include "fsfw/action/ActionMessage.h" +#include "fsfw/ipc/CommandMessage.h" +#include "fsfw/ipc/MessageQueueMessage.h" +#include "fsfw/objectmanager/frameworkObjects.h" +#include "fsfw_tests/unit/CatchDefinitions.h" +#include "fsfw_tests/unit/mocks/PeriodicTaskIFMock.h" + +TEST_CASE("Internal Error Reporter", "[TestInternalError]") { + PeriodicTaskMock task(10); + ObjectManagerIF* manager = ObjectManager::instance(); + if(manager == nullptr){ + FAIL(); + } + InternalErrorReporter* internalErrorReporter = + dynamic_cast(ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER)); + task.addComponent(objects::INTERNAL_ERROR_REPORTER); + MessageQueueIF* testQueue = QueueFactory::instance()->createMessageQueue(1); + MessageQueueIF* hkQueue = QueueFactory::instance()->createMessageQueue(1); + internalErrorReporter->getSubscriptionInterface()-> + subscribeForSetUpdateMessage(InternalErrorDataset::ERROR_SET_ID, objects::NO_OBJECT, hkQueue->getId(), true); + StorageManagerIF* ipcStore = ObjectManager::instance()->get(objects::IPC_STORE); + SECTION("MessageQueueFull"){ + CommandMessage message; + ActionMessage::setCompletionReply(&message, 10, true); + auto result = hkQueue->sendMessage(testQueue->getId(), &message); + REQUIRE(result == retval::CATCH_OK); + internalErrorReporter->performOperation(0); + { + CommandMessage hkMessage; + result = hkQueue->receiveMessage(&hkMessage); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + REQUIRE(hkMessage.getCommand() == HousekeepingMessage::UPDATE_SNAPSHOT_SET); + store_address_t storeAddress; + gp_id_t gpid = HousekeepingMessage::getUpdateSnapshotVariableCommand(&hkMessage, &storeAddress); + REQUIRE(gpid.objectId == objects::INTERNAL_ERROR_REPORTER); + InternalErrorDataset dataset(objects::NO_OBJECT); + CCSDSTime::CDS_short time; + ConstAccessorPair data = ipcStore->getData(storeAddress); + HousekeepingSnapshot hkSnapshot(&time, &dataset); + const uint8_t* buffer = data.second.data(); + size_t size = data.second.size(); + hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE); + } + result = hkQueue->sendMessage(testQueue->getId(), &message); + REQUIRE(result == MessageQueueIF::FULL); + { + internalErrorReporter->performOperation(0); + CommandMessage hkMessage; + result = hkQueue->receiveMessage(&hkMessage); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + REQUIRE(hkMessage.getCommand() == HousekeepingMessage::UPDATE_SNAPSHOT_SET); + store_address_t storeAddress; + gp_id_t gpid = HousekeepingMessage::getUpdateSnapshotVariableCommand(&hkMessage, &storeAddress); + REQUIRE(gpid.objectId == objects::INTERNAL_ERROR_REPORTER); + + ConstAccessorPair data = ipcStore->getData(storeAddress); + REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK); + } + } + delete testQueue; + delete hkQueue; +} \ No newline at end of file diff --git a/tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h b/tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h new file mode 100644 index 00000000..dd5bca12 --- /dev/null +++ b/tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h @@ -0,0 +1,45 @@ +#ifndef FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_ +#define FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_ + +#include +#include + +class PeriodicTaskMock: public PeriodicTaskIF{ +public: + PeriodicTaskMock(uint32_t period = 5):period(period){ + + } + /** + * @brief A virtual destructor as it is mandatory for interfaces. + */ + virtual ~PeriodicTaskMock() {} + /** + * @brief With the startTask method, a created task can be started + * for the first time. + */ + virtual ReturnValue_t startTask() override{ + return HasReturnvaluesIF::RETURN_OK; + }; + + virtual ReturnValue_t addComponent(object_id_t object) override{ + ExecutableObjectIF* executableObject = ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER); + if(executableObject == nullptr){ + return HasReturnvaluesIF::RETURN_FAILED; + } + executableObject->setTaskIF(this); + executableObject->initializeAfterTaskCreation(); + return HasReturnvaluesIF::RETURN_OK; + }; + + virtual ReturnValue_t sleepFor(uint32_t ms) override{ + return HasReturnvaluesIF::RETURN_OK; + }; + + virtual uint32_t getPeriodMs() const override{ + return period; + }; + uint32_t period; +}; + + +#endif // FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_ \ No newline at end of file diff --git a/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp b/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp index 232ffb94..365df379 100644 --- a/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp +++ b/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp @@ -35,4 +35,25 @@ TEST_CASE("MessageQueue Basic Test", "[TestMq]") { senderId = testReceiverMq->getLastPartner(); CHECK(senderId == testSenderMqId); } + SECTION("Test Full") { + auto result = testSenderMq->sendMessage(testReceiverMqId, &testMessage); + REQUIRE(result == retval::CATCH_OK); + result = testSenderMq->sendMessage(testReceiverMqId, &testMessage); + REQUIRE(result == MessageQueueIF::FULL); + // We try another message + result = testSenderMq->sendMessage(testReceiverMqId, &testMessage); + REQUIRE(result == MessageQueueIF::FULL); + MessageQueueMessage recvMessage; + result = testReceiverMq->receiveMessage(&recvMessage); + REQUIRE(result == retval::CATCH_OK); + CHECK(recvMessage.getData()[0] == 42); + result = testSenderMq->sendMessage(testReceiverMqId, &testMessage); + REQUIRE(result == retval::CATCH_OK); + result = testReceiverMq->receiveMessage(&recvMessage); + REQUIRE(result == retval::CATCH_OK); + CHECK(recvMessage.getData()[0] == 42); + } + // We have to clear MQs ourself ATM + delete testSenderMq; + delete testReceiverMq; } From 45ea09291a76c8d609a0315fa7f1ba59ef2b64a4 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Fri, 18 Feb 2022 19:57:36 +0100 Subject: [PATCH 02/26] Still test for InternalError Reporter --- .../internalerror/TestInternalErrorReporter.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp index d394166e..1103037d 100644 --- a/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp +++ b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,7 @@ TEST_CASE("Internal Error Reporter", "[TestInternalError]") { auto result = hkQueue->sendMessage(testQueue->getId(), &message); REQUIRE(result == retval::CATCH_OK); internalErrorReporter->performOperation(0); + uint32_t queueHits = 0; { CommandMessage hkMessage; result = hkQueue->receiveMessage(&hkMessage); @@ -45,10 +47,13 @@ TEST_CASE("Internal Error Reporter", "[TestInternalError]") { InternalErrorDataset dataset(objects::NO_OBJECT); CCSDSTime::CDS_short time; ConstAccessorPair data = ipcStore->getData(storeAddress); + REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK); HousekeepingSnapshot hkSnapshot(&time, &dataset); const uint8_t* buffer = data.second.data(); size_t size = data.second.size(); - hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE); + result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + queueHits = dataset.queueHits.value; } result = hkQueue->sendMessage(testQueue->getId(), &message); REQUIRE(result == MessageQueueIF::FULL); @@ -64,6 +69,14 @@ TEST_CASE("Internal Error Reporter", "[TestInternalError]") { ConstAccessorPair data = ipcStore->getData(storeAddress); REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK); + CCSDSTime::CDS_short time; + InternalErrorDataset dataset(objects::NO_OBJECT); + HousekeepingSnapshot hkSnapshot(&time, &dataset); + const uint8_t* buffer = data.second.data(); + size_t size = data.second.size(); + result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + REQUIRE(dataset.queueHits == (queueHits + 1)); } } delete testQueue; From 2f1b92300996c61a5e9ef8c2ba4e738eb477a0b2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 11:06:00 +0100 Subject: [PATCH 03/26] this module should not be needed anymore --- src/fsfw/controller/ControllerBase.h | 1 - src/fsfw/datapool/HkSwitchHelper.cpp | 67 ---------------------------- src/fsfw/datapool/HkSwitchHelper.h | 44 ------------------ 3 files changed, 112 deletions(-) delete mode 100644 src/fsfw/datapool/HkSwitchHelper.cpp delete mode 100644 src/fsfw/datapool/HkSwitchHelper.h diff --git a/src/fsfw/controller/ControllerBase.h b/src/fsfw/controller/ControllerBase.h index db75982c..7032f817 100644 --- a/src/fsfw/controller/ControllerBase.h +++ b/src/fsfw/controller/ControllerBase.h @@ -1,7 +1,6 @@ #ifndef FSFW_CONTROLLER_CONTROLLERBASE_H_ #define FSFW_CONTROLLER_CONTROLLERBASE_H_ -#include "fsfw/datapool/HkSwitchHelper.h" #include "fsfw/health/HasHealthIF.h" #include "fsfw/health/HealthHelper.h" #include "fsfw/modes/HasModesIF.h" diff --git a/src/fsfw/datapool/HkSwitchHelper.cpp b/src/fsfw/datapool/HkSwitchHelper.cpp deleted file mode 100644 index 7f6ffd17..00000000 --- a/src/fsfw/datapool/HkSwitchHelper.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "fsfw/datapool/HkSwitchHelper.h" - -#include "fsfw/ipc/QueueFactory.h" - -HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) - : commandActionHelper(this), eventProxy(eventProxy) { - actionQueue = QueueFactory::instance()->createMessageQueue(); -} - -HkSwitchHelper::~HkSwitchHelper() { QueueFactory::instance()->deleteMessageQueue(actionQueue); } - -ReturnValue_t HkSwitchHelper::initialize() { - ReturnValue_t result = commandActionHelper.initialize(); - - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - - return result; -} - -ReturnValue_t HkSwitchHelper::performOperation(uint8_t operationCode) { - CommandMessage command; - while (actionQueue->receiveMessage(&command) == HasReturnvaluesIF::RETURN_OK) { - ReturnValue_t result = commandActionHelper.handleReply(&command); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; - } - command.setToUnknownCommand(); - actionQueue->reply(&command); - } - - return HasReturnvaluesIF::RETURN_OK; -} - -void HkSwitchHelper::stepSuccessfulReceived(ActionId_t actionId, uint8_t step) {} - -void HkSwitchHelper::stepFailedReceived(ActionId_t actionId, uint8_t step, - ReturnValue_t returnCode) { - eventProxy->forwardEvent(SWITCHING_TM_FAILED, returnCode, actionId); -} - -void HkSwitchHelper::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {} - -void HkSwitchHelper::completionSuccessfulReceived(ActionId_t actionId) {} - -void HkSwitchHelper::completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) { - eventProxy->forwardEvent(SWITCHING_TM_FAILED, returnCode, actionId); -} - -ReturnValue_t HkSwitchHelper::switchHK(SerializeIF* sids, bool enable) { - // ActionId_t action = HKService::DISABLE_HK; - // if (enable) { - // action = HKService::ENABLE_HK; - // } - // - // ReturnValue_t result = commandActionHelper.commandAction( - // objects::PUS_HK_SERVICE, action, sids); - // - // if (result != HasReturnvaluesIF::RETURN_OK) { - // eventProxy->forwardEvent(SWITCHING_TM_FAILED, result); - // } - // return result; - return HasReturnvaluesIF::RETURN_OK; -} - -MessageQueueIF* HkSwitchHelper::getCommandQueuePtr() { return actionQueue; } diff --git a/src/fsfw/datapool/HkSwitchHelper.h b/src/fsfw/datapool/HkSwitchHelper.h deleted file mode 100644 index a0becd81..00000000 --- a/src/fsfw/datapool/HkSwitchHelper.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_ -#define FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_ - -#include "fsfw/action/CommandsActionsIF.h" -#include "fsfw/events/EventReportingProxyIF.h" -#include "fsfw/tasks/ExecutableObjectIF.h" - -// TODO this class violations separation between mission and framework -// but it is only a transitional solution until the Datapool is -// implemented decentrally - -class HkSwitchHelper : public ExecutableObjectIF, public CommandsActionsIF { - public: - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HK; - static const Event SWITCHING_TM_FAILED = - MAKE_EVENT(1, severity::LOW); //!< Commanding the HK Service failed, p1: error code, p2 - //!< action: 0 disable / 1 enable - - HkSwitchHelper(EventReportingProxyIF* eventProxy); - virtual ~HkSwitchHelper(); - - ReturnValue_t initialize(); - - virtual ReturnValue_t performOperation(uint8_t operationCode = 0); - - ReturnValue_t switchHK(SerializeIF* sids, bool enable); - - virtual void setTaskIF(PeriodicTaskIF* task_){}; - - protected: - virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step); - virtual void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode); - virtual void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size); - virtual void completionSuccessfulReceived(ActionId_t actionId); - virtual void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode); - virtual MessageQueueIF* getCommandQueuePtr(); - - private: - CommandActionHelper commandActionHelper; - MessageQueueIF* actionQueue; - EventReportingProxyIF* eventProxy; -}; - -#endif /* FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_ */ From 6fb64f9ada241b1d0567d363ef4340c3f1bd7f3e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 11:11:54 +0100 Subject: [PATCH 04/26] removed source from cmakelists.txt --- src/fsfw/datapool/CMakeLists.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/fsfw/datapool/CMakeLists.txt b/src/fsfw/datapool/CMakeLists.txt index 0d53e1ba..be4606aa 100644 --- a/src/fsfw/datapool/CMakeLists.txt +++ b/src/fsfw/datapool/CMakeLists.txt @@ -1,6 +1,4 @@ -target_sources(${LIB_FSFW_NAME} - PRIVATE - HkSwitchHelper.cpp - PoolDataSetBase.cpp - PoolEntry.cpp +target_sources(${LIB_FSFW_NAME} PRIVATE + PoolDataSetBase.cpp + PoolEntry.cpp ) \ No newline at end of file From 025f79fcb46cb5200ac6310dadc33e411bf20c12 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 11:16:14 +0100 Subject: [PATCH 05/26] apply clang format --- src/fsfw/globalfunctions/CRC.cpp | 2 +- src/fsfw/osal/linux/PeriodicPosixTask.h | 7 ++++--- src/fsfw/osal/rtems/PeriodicTask.h | 4 ++-- src/fsfw/rmap/RMAP.h | 8 ++++---- src/fsfw/rmap/RMAPChannelIF.h | 12 ++++++------ 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/fsfw/globalfunctions/CRC.cpp b/src/fsfw/globalfunctions/CRC.cpp index 6b8140c5..033920d0 100644 --- a/src/fsfw/globalfunctions/CRC.cpp +++ b/src/fsfw/globalfunctions/CRC.cpp @@ -117,7 +117,7 @@ uint16_t CRC::crc16ccitt(uint8_t const input[], uint32_t length, uint16_t starti // { // if (xor_out[i] == true) // crc_value = crc_value + pow(2,(15 -i)); // reverse CrC result before - //Final XOR + // Final XOR // } // // crc_value = 0;// for debug mode diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h index 3c9a3a0d..1c3a52c7 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.h +++ b/src/fsfw/osal/linux/PeriodicPosixTask.h @@ -65,9 +65,10 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { /** * @brief The function containing the actual functionality of the task. * @details The method sets and starts - * the task's period, then enters a loop that is repeated indefinitely. Within the - * loop, all performOperation methods of the added objects are called. Afterwards the task will be - * blocked until the next period. On missing the deadline, the deadlineMissedFunction is executed. + * the task's period, then enters a loop that is repeated indefinitely. Within + * the loop, all performOperation methods of the added objects are called. Afterwards the task + * will be blocked until the next period. On missing the deadline, the deadlineMissedFunction is + * executed. */ virtual void taskFunctionality(void); /** diff --git a/src/fsfw/osal/rtems/PeriodicTask.h b/src/fsfw/osal/rtems/PeriodicTask.h index ff8617fc..119329f2 100644 --- a/src/fsfw/osal/rtems/PeriodicTask.h +++ b/src/fsfw/osal/rtems/PeriodicTask.h @@ -13,8 +13,8 @@ class ExecutableObjectIF; * @brief This class represents a specialized task for periodic activities of multiple objects. * * @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute - * multiple objects that implement the ExecutableObjectIF interface. The objects - * must be added prior to starting the task. + * multiple objects that implement the ExecutableObjectIF interface. The + * objects must be added prior to starting the task. * @author baetz * @ingroup task_handling */ diff --git a/src/fsfw/rmap/RMAP.h b/src/fsfw/rmap/RMAP.h index 42ee1ac5..7c654262 100644 --- a/src/fsfw/rmap/RMAP.h +++ b/src/fsfw/rmap/RMAP.h @@ -169,8 +169,8 @@ class RMAP : public HasReturnvaluesIF { * @param buffer the data to write * @param length length of data * @return - * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in - * write command + * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL + * in write command * - return codes of RMAPChannelIF::sendCommand() */ static ReturnValue_t sendWriteCommand(RMAPCookie *cookie, const uint8_t *buffer, size_t length); @@ -205,8 +205,8 @@ class RMAP : public HasReturnvaluesIF { * @param cookie to cookie to read from * @param expLength the expected maximum length of the reply * @return - * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in - * write command, or nullpointer in read command + * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL + * in write command, or nullpointer in read command * - return codes of RMAPChannelIF::sendCommand() */ static ReturnValue_t sendReadCommand(RMAPCookie *cookie, uint32_t expLength); diff --git a/src/fsfw/rmap/RMAPChannelIF.h b/src/fsfw/rmap/RMAPChannelIF.h index 20dfd5f8..7dab07c1 100644 --- a/src/fsfw/rmap/RMAPChannelIF.h +++ b/src/fsfw/rmap/RMAPChannelIF.h @@ -75,10 +75,10 @@ class RMAPChannelIF { * - @c RETURN_OK * - @c COMMAND_NO_DESCRIPTORS_AVAILABLE no descriptors available for sending * command; command was not sent - * - @c COMMAND_BUFFER_FULL no receiver buffer available for expected len; - * command was not sent - * - @c COMMAND_TOO_BIG the data that was to be sent was too long for the hw - * to handle (write command) or the expected len was bigger than maximal expected len (read + * - @c COMMAND_BUFFER_FULL no receiver buffer available for expected + * len; command was not sent + * - @c COMMAND_TOO_BIG the data that was to be sent was too long for the + * hw to handle (write command) or the expected len was bigger than maximal expected len (read * command) command was not sent * - @c COMMAND_CHANNEL_DEACTIVATED the channel has no port set * - @c NOT_SUPPORTED if you dont feel like @@ -97,8 +97,8 @@ class RMAPChannelIF { * - @c REPLY_NO_REPLY no reply was received * - @c REPLY_NOT_SENT command was not sent, implies no reply * - @c REPLY_NOT_YET_SENT command is still waiting to be sent - * - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission buffer still - * being processed) + * - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission buffer + * still being processed) * - @c WRITE_REPLY_TRANSMISSION_ERROR Interface encountered errors during last * operation, data could not be processed. (transmission error) * - @c WRITE_REPLY_INVALID_DATA Invalid data (amount / value) From 90b8ad1e6d9607a67b374e5118a4959d3511dfc5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 11:16:33 +0100 Subject: [PATCH 06/26] apply clang format --- src/fsfw/globalfunctions/CRC.cpp | 2 +- src/fsfw/osal/linux/PeriodicPosixTask.h | 7 ++++--- src/fsfw/osal/rtems/PeriodicTask.h | 4 ++-- src/fsfw/rmap/RMAP.h | 8 ++++---- src/fsfw/rmap/RMAPChannelIF.h | 12 ++++++------ 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/fsfw/globalfunctions/CRC.cpp b/src/fsfw/globalfunctions/CRC.cpp index 6b8140c5..033920d0 100644 --- a/src/fsfw/globalfunctions/CRC.cpp +++ b/src/fsfw/globalfunctions/CRC.cpp @@ -117,7 +117,7 @@ uint16_t CRC::crc16ccitt(uint8_t const input[], uint32_t length, uint16_t starti // { // if (xor_out[i] == true) // crc_value = crc_value + pow(2,(15 -i)); // reverse CrC result before - //Final XOR + // Final XOR // } // // crc_value = 0;// for debug mode diff --git a/src/fsfw/osal/linux/PeriodicPosixTask.h b/src/fsfw/osal/linux/PeriodicPosixTask.h index 3c9a3a0d..1c3a52c7 100644 --- a/src/fsfw/osal/linux/PeriodicPosixTask.h +++ b/src/fsfw/osal/linux/PeriodicPosixTask.h @@ -65,9 +65,10 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF { /** * @brief The function containing the actual functionality of the task. * @details The method sets and starts - * the task's period, then enters a loop that is repeated indefinitely. Within the - * loop, all performOperation methods of the added objects are called. Afterwards the task will be - * blocked until the next period. On missing the deadline, the deadlineMissedFunction is executed. + * the task's period, then enters a loop that is repeated indefinitely. Within + * the loop, all performOperation methods of the added objects are called. Afterwards the task + * will be blocked until the next period. On missing the deadline, the deadlineMissedFunction is + * executed. */ virtual void taskFunctionality(void); /** diff --git a/src/fsfw/osal/rtems/PeriodicTask.h b/src/fsfw/osal/rtems/PeriodicTask.h index ff8617fc..119329f2 100644 --- a/src/fsfw/osal/rtems/PeriodicTask.h +++ b/src/fsfw/osal/rtems/PeriodicTask.h @@ -13,8 +13,8 @@ class ExecutableObjectIF; * @brief This class represents a specialized task for periodic activities of multiple objects. * * @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute - * multiple objects that implement the ExecutableObjectIF interface. The objects - * must be added prior to starting the task. + * multiple objects that implement the ExecutableObjectIF interface. The + * objects must be added prior to starting the task. * @author baetz * @ingroup task_handling */ diff --git a/src/fsfw/rmap/RMAP.h b/src/fsfw/rmap/RMAP.h index 42ee1ac5..7c654262 100644 --- a/src/fsfw/rmap/RMAP.h +++ b/src/fsfw/rmap/RMAP.h @@ -169,8 +169,8 @@ class RMAP : public HasReturnvaluesIF { * @param buffer the data to write * @param length length of data * @return - * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in - * write command + * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL + * in write command * - return codes of RMAPChannelIF::sendCommand() */ static ReturnValue_t sendWriteCommand(RMAPCookie *cookie, const uint8_t *buffer, size_t length); @@ -205,8 +205,8 @@ class RMAP : public HasReturnvaluesIF { * @param cookie to cookie to read from * @param expLength the expected maximum length of the reply * @return - * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in - * write command, or nullpointer in read command + * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL + * in write command, or nullpointer in read command * - return codes of RMAPChannelIF::sendCommand() */ static ReturnValue_t sendReadCommand(RMAPCookie *cookie, uint32_t expLength); diff --git a/src/fsfw/rmap/RMAPChannelIF.h b/src/fsfw/rmap/RMAPChannelIF.h index 20dfd5f8..7dab07c1 100644 --- a/src/fsfw/rmap/RMAPChannelIF.h +++ b/src/fsfw/rmap/RMAPChannelIF.h @@ -75,10 +75,10 @@ class RMAPChannelIF { * - @c RETURN_OK * - @c COMMAND_NO_DESCRIPTORS_AVAILABLE no descriptors available for sending * command; command was not sent - * - @c COMMAND_BUFFER_FULL no receiver buffer available for expected len; - * command was not sent - * - @c COMMAND_TOO_BIG the data that was to be sent was too long for the hw - * to handle (write command) or the expected len was bigger than maximal expected len (read + * - @c COMMAND_BUFFER_FULL no receiver buffer available for expected + * len; command was not sent + * - @c COMMAND_TOO_BIG the data that was to be sent was too long for the + * hw to handle (write command) or the expected len was bigger than maximal expected len (read * command) command was not sent * - @c COMMAND_CHANNEL_DEACTIVATED the channel has no port set * - @c NOT_SUPPORTED if you dont feel like @@ -97,8 +97,8 @@ class RMAPChannelIF { * - @c REPLY_NO_REPLY no reply was received * - @c REPLY_NOT_SENT command was not sent, implies no reply * - @c REPLY_NOT_YET_SENT command is still waiting to be sent - * - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission buffer still - * being processed) + * - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission buffer + * still being processed) * - @c WRITE_REPLY_TRANSMISSION_ERROR Interface encountered errors during last * operation, data could not be processed. (transmission error) * - @c WRITE_REPLY_INVALID_DATA Invalid data (amount / value) From 6739890d5368d1e6ecf3e1cb743111113fb384d8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 11:19:49 +0100 Subject: [PATCH 07/26] add i2c wiretapping option --- hal/src/fsfw_hal/linux/i2c/I2cComIF.cpp | 26 +++++++++++++++++++------ src/fsfw/FSFW.h.in | 5 +++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/hal/src/fsfw_hal/linux/i2c/I2cComIF.cpp b/hal/src/fsfw_hal/linux/i2c/I2cComIF.cpp index dc23542d..4f53dc1f 100644 --- a/hal/src/fsfw_hal/linux/i2c/I2cComIF.cpp +++ b/hal/src/fsfw_hal/linux/i2c/I2cComIF.cpp @@ -1,4 +1,13 @@ -#include "fsfw_hal/linux/i2c/I2cComIF.h" +#include "I2cComIF.h" + +#include "fsfw/FSFW.h" +#include "fsfw/serviceinterface.h" +#include "fsfw_hal/linux/UnixFileGuard.h" +#include "fsfw_hal/linux/utility.h" + +#if FSFW_HAL_I2C_WIRETAPPING == 1 +#include "fsfw/globalfunctions/arrayprinter.h" +#endif #include #include @@ -8,11 +17,6 @@ #include -#include "fsfw/FSFW.h" -#include "fsfw/serviceinterface.h" -#include "fsfw_hal/linux/UnixFileGuard.h" -#include "fsfw_hal/linux/utility.h" - I2cComIF::I2cComIF(object_id_t objectId) : SystemObject(objectId) {} I2cComIF::~I2cComIF() {} @@ -112,6 +116,11 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s #endif return HasReturnvaluesIF::RETURN_FAILED; } + +#if FSFW_HAL_I2C_WIRETAPPING == 1 + sif::info << "Sent I2C data to bus " << deviceFile << ":" << std::endl; + arrayprinter::print(sendData, sendLen); +#endif return HasReturnvaluesIF::RETURN_OK; } @@ -176,6 +185,11 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe return HasReturnvaluesIF::RETURN_FAILED; } +#if FSFW_HAL_I2C_WIRETAPPING == 1 + sif::info << "I2C read bytes from bus " << deviceFile << ":" << std::endl; + arrayprinter::print(replyBuffer, requestLen); +#endif + i2cDeviceMapIter->second.replyLen = requestLen; return HasReturnvaluesIF::RETURN_OK; } diff --git a/src/fsfw/FSFW.h.in b/src/fsfw/FSFW.h.in index 88ad10cf..28e0c0bf 100644 --- a/src/fsfw/FSFW.h.in +++ b/src/fsfw/FSFW.h.in @@ -69,4 +69,9 @@ #define FSFW_HAL_LIS3MDL_MGM_DEBUG 0 #endif /* FSFW_HAL_LIS3MDL_MGM_DEBUG */ +// Can be used for low-level debugging of the I2C bus +#ifndef FSFW_HAL_I2C_WIRETAPPING +#define FSFW_HAL_I2C_WIRETAPPING 0 +#endif + #endif /* FSFW_FSFW_H_ */ From d119479c0a793708d4858e2bef6674814c5600ac Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 11:22:20 +0100 Subject: [PATCH 08/26] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 335c0f7b..e061b6f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +# [v5.0.0] + +## Additions + +- Linux HAL: Add wiretapping option for I2C. Enabled with `FSFW_HAL_I2C_WIRETAPPING` defined to 1 + # [v4.0.0] ## Additions From 68ace0b74a03dc772457c4d8332f15cf167f8b5d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 11:23:29 +0100 Subject: [PATCH 09/26] update changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 335c0f7b..62882082 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +# [v5.0.0] + +## Removed + +- Removed the `HkSwitchHelper`. This module should not be needed anymore, now that the local + datapools have been implemented + # [v4.0.0] ## Additions From 9c2ceb4a9f5dbe2517a224572846fa7a996ddcac Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 11:29:23 +0100 Subject: [PATCH 10/26] one shot flag not static anymore --- CHANGELOG.md | 6 ++++++ tests/src/fsfw_tests/integration/task/TestTask.cpp | 1 - tests/src/fsfw_tests/integration/task/TestTask.h | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 335c0f7b..ac5f004f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +# [v5.0.0] + +## Changes + +- `oneShotAction` flag in the `TestTask` class is not static anymore + # [v4.0.0] ## Additions diff --git a/tests/src/fsfw_tests/integration/task/TestTask.cpp b/tests/src/fsfw_tests/integration/task/TestTask.cpp index 65e444e3..765f780e 100644 --- a/tests/src/fsfw_tests/integration/task/TestTask.cpp +++ b/tests/src/fsfw_tests/integration/task/TestTask.cpp @@ -3,7 +3,6 @@ #include #include -bool TestTask::oneShotAction = true; MutexIF* TestTask::testLock = nullptr; TestTask::TestTask(object_id_t objectId) : SystemObject(objectId), testMode(testModes::A) { diff --git a/tests/src/fsfw_tests/integration/task/TestTask.h b/tests/src/fsfw_tests/integration/task/TestTask.h index 557b50b2..cd630ee3 100644 --- a/tests/src/fsfw_tests/integration/task/TestTask.h +++ b/tests/src/fsfw_tests/integration/task/TestTask.h @@ -29,7 +29,7 @@ class TestTask : public SystemObject, public ExecutableObjectIF, public HasRetur bool testFlag = false; private: - static bool oneShotAction; + bool oneShotAction = true; static MutexIF* testLock; StorageManagerIF* IPCStore; }; From aebd4817b8318cde3412314cc839a6d805eda578 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 11:33:41 +0100 Subject: [PATCH 11/26] periodic printouts are runtime configurable now --- .../devicehandlers/GyroL3GD20Handler.cpp | 35 +++++++------ .../devicehandlers/GyroL3GD20Handler.h | 8 +-- .../devicehandlers/MgmLIS3MDLHandler.cpp | 52 +++++++++++-------- .../devicehandlers/MgmLIS3MDLHandler.h | 8 +-- .../devicehandlers/MgmRM3100Handler.cpp | 37 ++++++------- .../devicehandlers/MgmRM3100Handler.h | 11 ++-- src/fsfw/FSFW.h.in | 12 ----- 7 files changed, 78 insertions(+), 85 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp index be4c9aa9..94e1331c 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp @@ -8,11 +8,7 @@ GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceC CookieIF *comCookie, uint32_t transitionDelayMs) : DeviceHandlerBase(objectId, deviceCommunication, comCookie), transitionDelayMs(transitionDelayMs), - dataset(this) { -#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1 - debugDivider = new PeriodicOperationDivider(3); -#endif -} + dataset(this) {} GyroHandlerL3GD20H::~GyroHandlerL3GD20H() {} @@ -193,22 +189,22 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id, int8_t temperaturOffset = (-1) * packet[L3GD20H::TEMPERATURE_IDX]; float temperature = 25.0 + temperaturOffset; -#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1 - if (debugDivider->checkAndIncrement()) { - /* Set terminal to utf-8 if there is an issue with micro printout. */ + if (periodicPrintout) { + if (debugDivider.checkAndIncrement()) { + /* Set terminal to utf-8 if there is an issue with micro printout. */ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "GyroHandlerL3GD20H: Angular velocities (deg/s):" << std::endl; - sif::info << "X: " << angVelocX << std::endl; - sif::info << "Y: " << angVelocY << std::endl; - sif::info << "Z: " << angVelocZ << std::endl; + sif::info << "GyroHandlerL3GD20H: Angular velocities (deg/s):" << std::endl; + sif::info << "X: " << angVelocX << std::endl; + sif::info << "Y: " << angVelocY << std::endl; + sif::info << "Z: " << angVelocZ << std::endl; #else - sif::printInfo("GyroHandlerL3GD20H: Angular velocities (deg/s):\n"); - sif::printInfo("X: %f\n", angVelocX); - sif::printInfo("Y: %f\n", angVelocY); - sif::printInfo("Z: %f\n", angVelocZ); + sif::printInfo("GyroHandlerL3GD20H: Angular velocities (deg/s):\n"); + sif::printInfo("X: %f\n", angVelocX); + sif::printInfo("Y: %f\n", angVelocY); + sif::printInfo("Z: %f\n", angVelocZ); #endif + } } -#endif PoolReadGuard readSet(&dataset); if (readSet.getReadResult() == HasReturnvaluesIF::RETURN_OK) { @@ -272,3 +268,8 @@ void GyroHandlerL3GD20H::setAbsoluteLimits(float limitX, float limitY, float lim this->absLimitY = limitY; this->absLimitZ = limitZ; } + +void GyroHandlerL3GD20H::enablePeriodicPrintouts(bool enable, uint8_t divider) { + periodicPrintout = enable; + debugDivider.setDivider(divider); +} diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h index 784dcf4c..7c1ebdac 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h @@ -5,7 +5,6 @@ #include #include "devicedefinitions/GyroL3GD20Definitions.h" -#include "fsfw/FSFW.h" /** * @brief Device Handler for the L3GD20H gyroscope sensor @@ -22,6 +21,8 @@ class GyroHandlerL3GD20H : public DeviceHandlerBase { uint32_t transitionDelayMs); virtual ~GyroHandlerL3GD20H(); + void enablePeriodicPrintouts(bool enable, uint8_t divider); + /** * Set the absolute limit for the values on the axis in degrees per second. * The dataset values will be marked as invalid if that limit is exceeded @@ -80,9 +81,8 @@ class GyroHandlerL3GD20H : public DeviceHandlerBase { // Set default value float sensitivity = L3GD20H::SENSITIVITY_00; -#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1 - PeriodicOperationDivider *debugDivider = nullptr; -#endif + bool periodicPrintout = false; + PeriodicOperationDivider debugDivider = PeriodicOperationDivider(3); }; #endif /* MISSION_DEVICES_GYROL3GD20HANDLER_H_ */ diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index f3ea9942..69f6311e 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -12,9 +12,6 @@ MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCom : DeviceHandlerBase(objectId, deviceCommunication, comCookie), dataset(this), transitionDelay(transitionDelay) { -#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 - debugDivider = new PeriodicOperationDivider(3); -#endif // Set to default values right away registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT; registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT; @@ -264,7 +261,7 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons int16_t mgmMeasurementRawZ = packet[MGMLIS3MDL::Z_HIGHBYTE_IDX] << 8 | packet[MGMLIS3MDL::Z_LOWBYTE_IDX]; - /* Target value in microtesla */ + // Target value in microtesla float mgmX = static_cast(mgmMeasurementRawX) * sensitivityFactor * MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR; float mgmY = static_cast(mgmMeasurementRawY) * sensitivityFactor * @@ -272,23 +269,24 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons float mgmZ = static_cast(mgmMeasurementRawZ) * sensitivityFactor * MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR; -#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 - if (debugDivider->checkAndIncrement()) { + if (periodicPrintout) { + if (debugDivider.checkAndIncrement()) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "MGMHandlerLIS3: Magnetic field strength in" - " microtesla:" - << std::endl; - sif::info << "X: " << mgmX << " uT" << std::endl; - sif::info << "Y: " << mgmY << " uT" << std::endl; - sif::info << "Z: " << mgmZ << " uT" << std::endl; + sif::info << "MGMHandlerLIS3: Magnetic field strength in" + " microtesla:" + << std::endl; + sif::info << "X: " << mgmX << " uT" << std::endl; + sif::info << "Y: " << mgmY << " uT" << std::endl; + sif::info << "Z: " << mgmZ << " uT" << std::endl; #else - sif::printInfo("MGMHandlerLIS3: Magnetic field strength in microtesla:\n"); - sif::printInfo("X: %f uT\n", mgmX); - sif::printInfo("Y: %f uT\n", mgmY); - sif::printInfo("Z: %f uT\n", mgmZ); + sif::printInfo("MGMHandlerLIS3: Magnetic field strength in microtesla:\n"); + sif::printInfo("X: %f uT\n", mgmX); + sif::printInfo("Y: %f uT\n", mgmY); + sif::printInfo("Z: %f uT\n", mgmZ); #endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */ + } } -#endif /* OBSW_VERBOSE_LEVEL >= 1 */ + PoolReadGuard readHelper(&dataset); if (readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) { if (std::abs(mgmX) < absLimitX) { @@ -318,15 +316,16 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons case MGMLIS3MDL::READ_TEMPERATURE: { int16_t tempValueRaw = packet[2] << 8 | packet[1]; float tempValue = 25.0 + ((static_cast(tempValueRaw)) / 8.0); -#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 - if (debugDivider->check()) { + if (periodicPrintout) { + if (debugDivider.check()) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "MGMHandlerLIS3: Temperature: " << tempValue << " C" << std::endl; + sif::info << "MGMHandlerLIS3: Temperature: " << tempValue << " C" << std::endl; #else - sif::printInfo("MGMHandlerLIS3: Temperature: %f C\n"); + sif::printInfo("MGMHandlerLIS3: Temperature: %f C\n"); #endif + } } -#endif + ReturnValue_t result = dataset.read(); if (result == HasReturnvaluesIF::RETURN_OK) { dataset.temperature = tempValue; @@ -462,7 +461,9 @@ ReturnValue_t MgmLIS3MDLHandler::prepareCtrlRegisterWrite() { return RETURN_OK; } -void MgmLIS3MDLHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {} +void MgmLIS3MDLHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { + DeviceHandlerBase::doTransition(modeFrom, subModeFrom); +} uint32_t MgmLIS3MDLHandler::getTransitionDelayMs(Mode_t from, Mode_t to) { return transitionDelay; } @@ -482,3 +483,8 @@ void MgmLIS3MDLHandler::setAbsoluteLimits(float xLimit, float yLimit, float zLim this->absLimitY = yLimit; this->absLimitZ = zLimit; } + +void MgmLIS3MDLHandler::enablePeriodicPrintouts(bool enable, uint8_t divider) { + periodicPrintout = enable; + debugDivider.setDivider(divider); +} diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h index b7cfc378..42bd5d4c 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h @@ -3,8 +3,8 @@ #include "devicedefinitions/MgmLIS3HandlerDefs.h" #include "events/subsystemIdRanges.h" -#include "fsfw/FSFW.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h" +#include "fsfw/globalfunctions/PeriodicOperationDivider.h" class PeriodicOperationDivider; @@ -30,6 +30,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase { uint32_t transitionDelay); virtual ~MgmLIS3MDLHandler(); + void enablePeriodicPrintouts(bool enable, uint8_t divider); /** * Set the absolute limit for the values on the axis in microtesla. The dataset values will * be marked as invalid if that limit is exceeded @@ -167,9 +168,8 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase { */ ReturnValue_t prepareCtrlRegisterWrite(); -#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 - PeriodicOperationDivider *debugDivider; -#endif + bool periodicPrintout = false; + PeriodicOperationDivider debugDivider = PeriodicOperationDivider(3); }; #endif /* MISSION_DEVICES_MGMLIS3MDLHANDLER_H_ */ diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp index 4c6e09b1..f9929d63 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp @@ -10,11 +10,7 @@ MgmRM3100Handler::MgmRM3100Handler(object_id_t objectId, object_id_t deviceCommu CookieIF *comCookie, uint32_t transitionDelay) : DeviceHandlerBase(objectId, deviceCommunication, comCookie), primaryDataset(this), - transitionDelay(transitionDelay) { -#if FSFW_HAL_RM3100_MGM_DEBUG == 1 - debugDivider = new PeriodicOperationDivider(3); -#endif -} + transitionDelay(transitionDelay) {} MgmRM3100Handler::~MgmRM3100Handler() {} @@ -337,23 +333,23 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) { float fieldStrengthY = fieldStrengthRawY * scaleFactorX; float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX; -#if FSFW_HAL_RM3100_MGM_DEBUG == 1 - if (debugDivider->checkAndIncrement()) { + if (periodicPrintout) { + if (debugDivider.checkAndIncrement()) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "MgmRM3100Handler: Magnetic field strength in" - " microtesla:" - << std::endl; - sif::info << "X: " << fieldStrengthX << " uT" << std::endl; - sif::info << "Y: " << fieldStrengthY << " uT" << std::endl; - sif::info << "Z: " << fieldStrengthZ << " uT" << std::endl; + sif::info << "MgmRM3100Handler: Magnetic field strength in" + " microtesla:" + << std::endl; + sif::info << "X: " << fieldStrengthX << " uT" << std::endl; + sif::info << "Y: " << fieldStrengthY << " uT" << std::endl; + sif::info << "Z: " << fieldStrengthZ << " uT" << std::endl; #else - sif::printInfo("MgmRM3100Handler: Magnetic field strength in microtesla:\n"); - sif::printInfo("X: %f uT\n", fieldStrengthX); - sif::printInfo("Y: %f uT\n", fieldStrengthY); - sif::printInfo("Z: %f uT\n", fieldStrengthZ); + sif::printInfo("MgmRM3100Handler: Magnetic field strength in microtesla:\n"); + sif::printInfo("X: %f uT\n", fieldStrengthX); + sif::printInfo("Y: %f uT\n", fieldStrengthY); + sif::printInfo("Z: %f uT\n", fieldStrengthZ); #endif + } } -#endif // TODO: Sanity check on values? PoolReadGuard readGuard(&primaryDataset); @@ -365,3 +361,8 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) { } return RETURN_OK; } + +void MgmRM3100Handler::enablePeriodicPrintouts(bool enable, uint8_t divider) { + periodicPrintout = enable; + debugDivider.setDivider(divider); +} diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h index 67362f59..d1048cb6 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h @@ -2,12 +2,8 @@ #define MISSION_DEVICES_MGMRM3100HANDLER_H_ #include "devicedefinitions/MgmRM3100HandlerDefs.h" -#include "fsfw/FSFW.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h" - -#if FSFW_HAL_RM3100_MGM_DEBUG == 1 #include "fsfw/globalfunctions/PeriodicOperationDivider.h" -#endif /** * @brief Device Handler for the RM3100 geomagnetic magnetometer sensor @@ -33,6 +29,7 @@ class MgmRM3100Handler : public DeviceHandlerBase { uint32_t transitionDelay); virtual ~MgmRM3100Handler(); + void enablePeriodicPrintouts(bool enable, uint8_t divider); /** * Configure device handler to go to normal mode after startup immediately * @param enable @@ -98,9 +95,9 @@ class MgmRM3100Handler : public DeviceHandlerBase { size_t commandDataLen); ReturnValue_t handleDataReadout(const uint8_t *packet); -#if FSFW_HAL_RM3100_MGM_DEBUG == 1 - PeriodicOperationDivider *debugDivider; -#endif + + bool periodicPrintout = false; + PeriodicOperationDivider debugDivider = PeriodicOperationDivider(3); }; #endif /* MISSION_DEVICEHANDLING_MGMRM3100HANDLER_H_ */ diff --git a/src/fsfw/FSFW.h.in b/src/fsfw/FSFW.h.in index 88ad10cf..563f3094 100644 --- a/src/fsfw/FSFW.h.in +++ b/src/fsfw/FSFW.h.in @@ -57,16 +57,4 @@ #define FSFW_HAL_SPI_WIRETAPPING 0 #endif -#ifndef FSFW_HAL_L3GD20_GYRO_DEBUG -#define FSFW_HAL_L3GD20_GYRO_DEBUG 0 -#endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */ - -#ifndef FSFW_HAL_RM3100_MGM_DEBUG -#define FSFW_HAL_RM3100_MGM_DEBUG 0 -#endif /* FSFW_HAL_RM3100_MGM_DEBUG */ - -#ifndef FSFW_HAL_LIS3MDL_MGM_DEBUG -#define FSFW_HAL_LIS3MDL_MGM_DEBUG 0 -#endif /* FSFW_HAL_LIS3MDL_MGM_DEBUG */ - #endif /* FSFW_FSFW_H_ */ From 0c4835bfb52b79cd6cdd56ae73480cbf37293f45 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 11:37:38 +0100 Subject: [PATCH 12/26] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 335c0f7b..8da336b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +# [v5.0.0] + +## Changes + +- HAL Devicehandlers: Periodic printout is run-time configurable now + # [v4.0.0] ## Additions From eac7e6db0708a596ab04ef3be4b930c27f135944 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 11:40:31 +0100 Subject: [PATCH 13/26] try readme tweak --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 89a10f4b..dff87b2e 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,9 @@ add and link against the FSFW library in general. 4. Link against the FSFW library - ```cmake - target_link_libraries( PRIVATE fsfw) - ``` + ```cmake + target_link_libraries(${YourProjectName} PRIVATE fsfw) + ``` 5. It should now be possible use the FSFW as a static library from the user code. From a50b52df5137ecae86f0c2a8db21210ec507cece Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 22 Feb 2022 13:37:28 +0100 Subject: [PATCH 14/26] Fixed an issue in host OSAL and added more coverage to IER --- .../datapoollocal/LocalDataPoolManager.cpp | 2 +- src/fsfw/osal/host/MessageQueue.cpp | 7 +++++ .../TestInternalErrorReporter.cpp | 30 +++++++++++++++---- .../fsfw_tests/unit/osal/TestMessageQueue.cpp | 4 +-- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index 9057de31..cab13207 100644 --- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp +++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp @@ -84,7 +84,7 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { return result; } - printWarningOrError(sif::OutputTypes::OUT_WARNING, "initialize", HasReturnvaluesIF::RETURN_FAILED, + printWarningOrError(sif::OutputTypes::OUT_WARNING, "initializeHousekeepingPoolEntriesOnce", HasReturnvaluesIF::RETURN_FAILED, "The map should only be initialized once"); return HasReturnvaluesIF::RETURN_OK; } diff --git a/src/fsfw/osal/host/MessageQueue.cpp b/src/fsfw/osal/host/MessageQueue.cpp index db66b671..62151164 100644 --- a/src/fsfw/osal/host/MessageQueue.cpp +++ b/src/fsfw/osal/host/MessageQueue.cpp @@ -125,6 +125,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, memcpy(targetQueue->messageQueue.back().data(), message->getBuffer(), message->getMaximumMessageSize()); } else { + if (not ignoreFault) { + InternalErrorReporterIF* internalErrorReporter = + ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER); + if (internalErrorReporter != nullptr) { + internalErrorReporter->queueMessageNotSent(); + } + } return MessageQueueIF::FULL; } return HasReturnvaluesIF::RETURN_OK; diff --git a/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp index 1103037d..1e63a57b 100644 --- a/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp +++ b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp @@ -23,6 +23,9 @@ TEST_CASE("Internal Error Reporter", "[TestInternalError]") { } InternalErrorReporter* internalErrorReporter = dynamic_cast(ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER)); + if(internalErrorReporter == nullptr){ + FAIL(); + } task.addComponent(objects::INTERNAL_ERROR_REPORTER); MessageQueueIF* testQueue = QueueFactory::instance()->createMessageQueue(1); MessageQueueIF* hkQueue = QueueFactory::instance()->createMessageQueue(1); @@ -34,8 +37,13 @@ TEST_CASE("Internal Error Reporter", "[TestInternalError]") { ActionMessage::setCompletionReply(&message, 10, true); auto result = hkQueue->sendMessage(testQueue->getId(), &message); REQUIRE(result == retval::CATCH_OK); - internalErrorReporter->performOperation(0); uint32_t queueHits = 0; + uint32_t lostTm = 0; + uint32_t storeHits = 0; + /* We don't know if another test caused a queue Hit so we will enforce one, + then remeber the queueHit count and force another hit */ + internalErrorReporter->queueMessageNotSent(); + internalErrorReporter->performOperation(0); { CommandMessage hkMessage; result = hkQueue->receiveMessage(&hkMessage); @@ -44,7 +52,8 @@ TEST_CASE("Internal Error Reporter", "[TestInternalError]") { store_address_t storeAddress; gp_id_t gpid = HousekeepingMessage::getUpdateSnapshotVariableCommand(&hkMessage, &storeAddress); REQUIRE(gpid.objectId == objects::INTERNAL_ERROR_REPORTER); - InternalErrorDataset dataset(objects::NO_OBJECT); + // We need the object ID of the reporter here (NO_OBJECT) + InternalErrorDataset dataset(objects::INTERNAL_ERROR_REPORTER); CCSDSTime::CDS_short time; ConstAccessorPair data = ipcStore->getData(storeAddress); REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK); @@ -53,10 +62,15 @@ TEST_CASE("Internal Error Reporter", "[TestInternalError]") { size_t size = data.second.size(); result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE); REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + // Remember the amount of queueHits before to see the increase queueHits = dataset.queueHits.value; + lostTm = dataset.tmHits.value; + storeHits = dataset.storeHits.value; } result = hkQueue->sendMessage(testQueue->getId(), &message); REQUIRE(result == MessageQueueIF::FULL); + internalErrorReporter->lostTm(); + internalErrorReporter->storeFull(); { internalErrorReporter->performOperation(0); CommandMessage hkMessage; @@ -70,15 +84,19 @@ TEST_CASE("Internal Error Reporter", "[TestInternalError]") { ConstAccessorPair data = ipcStore->getData(storeAddress); REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK); CCSDSTime::CDS_short time; - InternalErrorDataset dataset(objects::NO_OBJECT); + // We need the object ID of the reporter here (NO_OBJECT) + InternalErrorDataset dataset(objects::INTERNAL_ERROR_REPORTER); HousekeepingSnapshot hkSnapshot(&time, &dataset); const uint8_t* buffer = data.second.data(); size_t size = data.second.size(); result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE); REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - REQUIRE(dataset.queueHits == (queueHits + 1)); + // Test that we had one more queueHit + REQUIRE(dataset.queueHits.value == (queueHits + 1)); + REQUIRE(dataset.tmHits.value == (lostTm + 1)); + REQUIRE(dataset.storeHits.value == (storeHits + 1)); } } - delete testQueue; - delete hkQueue; + QueueFactory::instance()->deleteMessageQueue(testQueue); + QueueFactory::instance()->deleteMessageQueue(hkQueue); } \ No newline at end of file diff --git a/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp b/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp index 365df379..11c0739b 100644 --- a/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp +++ b/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp @@ -54,6 +54,6 @@ TEST_CASE("MessageQueue Basic Test", "[TestMq]") { CHECK(recvMessage.getData()[0] == 42); } // We have to clear MQs ourself ATM - delete testSenderMq; - delete testReceiverMq; + QueueFactory::instance()->deleteMessageQueue(testSenderMq); + QueueFactory::instance()->deleteMessageQueue(testReceiverMq); } From 4862edfdb5dec18e34e0678930f25aeacd2ed409 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 22 Feb 2022 13:42:56 +0100 Subject: [PATCH 15/26] Clang format --- .../internalerror/InternalErrorReporter.cpp | 2 +- src/fsfw/osal/host/MessageQueue.cpp | 4 +- .../TestInternalErrorReporter.cpp | 168 +++++++++--------- .../unit/mocks/PeriodicTaskIFMock.h | 34 ++-- 4 files changed, 101 insertions(+), 107 deletions(-) diff --git a/src/fsfw/internalerror/InternalErrorReporter.cpp b/src/fsfw/internalerror/InternalErrorReporter.cpp index 98ed2af3..08d37feb 100644 --- a/src/fsfw/internalerror/InternalErrorReporter.cpp +++ b/src/fsfw/internalerror/InternalErrorReporter.cpp @@ -57,7 +57,7 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) { internalErrorDataset.storeHits.value += newStoreHits; internalErrorDataset.tmHits.value += newTmHits; internalErrorDataset.setValidity(true, true); - if((newQueueHits != 0) or (newStoreHits !=0) or (newTmHits != 0)){ + if ((newQueueHits != 0) or (newStoreHits != 0) or (newTmHits != 0)) { internalErrorDataset.setChanged(true); } } diff --git a/src/fsfw/osal/host/MessageQueue.cpp b/src/fsfw/osal/host/MessageQueue.cpp index 62151164..d328fb82 100644 --- a/src/fsfw/osal/host/MessageQueue.cpp +++ b/src/fsfw/osal/host/MessageQueue.cpp @@ -125,13 +125,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, memcpy(targetQueue->messageQueue.back().data(), message->getBuffer(), message->getMaximumMessageSize()); } else { - if (not ignoreFault) { + if (not ignoreFault) { InternalErrorReporterIF* internalErrorReporter = ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER); if (internalErrorReporter != nullptr) { internalErrorReporter->queueMessageNotSent(); } - } + } return MessageQueueIF::FULL; } return HasReturnvaluesIF::RETURN_OK; diff --git a/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp index 1e63a57b..a7f5e109 100644 --- a/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp +++ b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp @@ -1,9 +1,9 @@ +#include +#include #include #include -#include #include #include -#include #include #include @@ -16,87 +16,89 @@ #include "fsfw_tests/unit/mocks/PeriodicTaskIFMock.h" TEST_CASE("Internal Error Reporter", "[TestInternalError]") { - PeriodicTaskMock task(10); - ObjectManagerIF* manager = ObjectManager::instance(); - if(manager == nullptr){ - FAIL(); + PeriodicTaskMock task(10); + ObjectManagerIF* manager = ObjectManager::instance(); + if (manager == nullptr) { + FAIL(); + } + InternalErrorReporter* internalErrorReporter = dynamic_cast( + ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER)); + if (internalErrorReporter == nullptr) { + FAIL(); + } + task.addComponent(objects::INTERNAL_ERROR_REPORTER); + MessageQueueIF* testQueue = QueueFactory::instance()->createMessageQueue(1); + MessageQueueIF* hkQueue = QueueFactory::instance()->createMessageQueue(1); + internalErrorReporter->getSubscriptionInterface()->subscribeForSetUpdateMessage( + InternalErrorDataset::ERROR_SET_ID, objects::NO_OBJECT, hkQueue->getId(), true); + StorageManagerIF* ipcStore = ObjectManager::instance()->get(objects::IPC_STORE); + SECTION("MessageQueueFull") { + CommandMessage message; + ActionMessage::setCompletionReply(&message, 10, true); + auto result = hkQueue->sendMessage(testQueue->getId(), &message); + REQUIRE(result == retval::CATCH_OK); + uint32_t queueHits = 0; + uint32_t lostTm = 0; + uint32_t storeHits = 0; + /* We don't know if another test caused a queue Hit so we will enforce one, + then remeber the queueHit count and force another hit */ + internalErrorReporter->queueMessageNotSent(); + internalErrorReporter->performOperation(0); + { + CommandMessage hkMessage; + result = hkQueue->receiveMessage(&hkMessage); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + REQUIRE(hkMessage.getCommand() == HousekeepingMessage::UPDATE_SNAPSHOT_SET); + store_address_t storeAddress; + gp_id_t gpid = + HousekeepingMessage::getUpdateSnapshotVariableCommand(&hkMessage, &storeAddress); + REQUIRE(gpid.objectId == objects::INTERNAL_ERROR_REPORTER); + // We need the object ID of the reporter here (NO_OBJECT) + InternalErrorDataset dataset(objects::INTERNAL_ERROR_REPORTER); + CCSDSTime::CDS_short time; + ConstAccessorPair data = ipcStore->getData(storeAddress); + REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK); + HousekeepingSnapshot hkSnapshot(&time, &dataset); + const uint8_t* buffer = data.second.data(); + size_t size = data.second.size(); + result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + // Remember the amount of queueHits before to see the increase + queueHits = dataset.queueHits.value; + lostTm = dataset.tmHits.value; + storeHits = dataset.storeHits.value; } - InternalErrorReporter* internalErrorReporter = - dynamic_cast(ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER)); - if(internalErrorReporter == nullptr){ - FAIL(); + result = hkQueue->sendMessage(testQueue->getId(), &message); + REQUIRE(result == MessageQueueIF::FULL); + internalErrorReporter->lostTm(); + internalErrorReporter->storeFull(); + { + internalErrorReporter->performOperation(0); + CommandMessage hkMessage; + result = hkQueue->receiveMessage(&hkMessage); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + REQUIRE(hkMessage.getCommand() == HousekeepingMessage::UPDATE_SNAPSHOT_SET); + store_address_t storeAddress; + gp_id_t gpid = + HousekeepingMessage::getUpdateSnapshotVariableCommand(&hkMessage, &storeAddress); + REQUIRE(gpid.objectId == objects::INTERNAL_ERROR_REPORTER); + + ConstAccessorPair data = ipcStore->getData(storeAddress); + REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK); + CCSDSTime::CDS_short time; + // We need the object ID of the reporter here (NO_OBJECT) + InternalErrorDataset dataset(objects::INTERNAL_ERROR_REPORTER); + HousekeepingSnapshot hkSnapshot(&time, &dataset); + const uint8_t* buffer = data.second.data(); + size_t size = data.second.size(); + result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + // Test that we had one more queueHit + REQUIRE(dataset.queueHits.value == (queueHits + 1)); + REQUIRE(dataset.tmHits.value == (lostTm + 1)); + REQUIRE(dataset.storeHits.value == (storeHits + 1)); } - task.addComponent(objects::INTERNAL_ERROR_REPORTER); - MessageQueueIF* testQueue = QueueFactory::instance()->createMessageQueue(1); - MessageQueueIF* hkQueue = QueueFactory::instance()->createMessageQueue(1); - internalErrorReporter->getSubscriptionInterface()-> - subscribeForSetUpdateMessage(InternalErrorDataset::ERROR_SET_ID, objects::NO_OBJECT, hkQueue->getId(), true); - StorageManagerIF* ipcStore = ObjectManager::instance()->get(objects::IPC_STORE); - SECTION("MessageQueueFull"){ - CommandMessage message; - ActionMessage::setCompletionReply(&message, 10, true); - auto result = hkQueue->sendMessage(testQueue->getId(), &message); - REQUIRE(result == retval::CATCH_OK); - uint32_t queueHits = 0; - uint32_t lostTm = 0; - uint32_t storeHits = 0; - /* We don't know if another test caused a queue Hit so we will enforce one, - then remeber the queueHit count and force another hit */ - internalErrorReporter->queueMessageNotSent(); - internalErrorReporter->performOperation(0); - { - CommandMessage hkMessage; - result = hkQueue->receiveMessage(&hkMessage); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - REQUIRE(hkMessage.getCommand() == HousekeepingMessage::UPDATE_SNAPSHOT_SET); - store_address_t storeAddress; - gp_id_t gpid = HousekeepingMessage::getUpdateSnapshotVariableCommand(&hkMessage, &storeAddress); - REQUIRE(gpid.objectId == objects::INTERNAL_ERROR_REPORTER); - // We need the object ID of the reporter here (NO_OBJECT) - InternalErrorDataset dataset(objects::INTERNAL_ERROR_REPORTER); - CCSDSTime::CDS_short time; - ConstAccessorPair data = ipcStore->getData(storeAddress); - REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK); - HousekeepingSnapshot hkSnapshot(&time, &dataset); - const uint8_t* buffer = data.second.data(); - size_t size = data.second.size(); - result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - // Remember the amount of queueHits before to see the increase - queueHits = dataset.queueHits.value; - lostTm = dataset.tmHits.value; - storeHits = dataset.storeHits.value; - } - result = hkQueue->sendMessage(testQueue->getId(), &message); - REQUIRE(result == MessageQueueIF::FULL); - internalErrorReporter->lostTm(); - internalErrorReporter->storeFull(); - { - internalErrorReporter->performOperation(0); - CommandMessage hkMessage; - result = hkQueue->receiveMessage(&hkMessage); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - REQUIRE(hkMessage.getCommand() == HousekeepingMessage::UPDATE_SNAPSHOT_SET); - store_address_t storeAddress; - gp_id_t gpid = HousekeepingMessage::getUpdateSnapshotVariableCommand(&hkMessage, &storeAddress); - REQUIRE(gpid.objectId == objects::INTERNAL_ERROR_REPORTER); - - ConstAccessorPair data = ipcStore->getData(storeAddress); - REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK); - CCSDSTime::CDS_short time; - // We need the object ID of the reporter here (NO_OBJECT) - InternalErrorDataset dataset(objects::INTERNAL_ERROR_REPORTER); - HousekeepingSnapshot hkSnapshot(&time, &dataset); - const uint8_t* buffer = data.second.data(); - size_t size = data.second.size(); - result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE); - REQUIRE(result == HasReturnvaluesIF::RETURN_OK); - // Test that we had one more queueHit - REQUIRE(dataset.queueHits.value == (queueHits + 1)); - REQUIRE(dataset.tmHits.value == (lostTm + 1)); - REQUIRE(dataset.storeHits.value == (storeHits + 1)); - } - } - QueueFactory::instance()->deleteMessageQueue(testQueue); - QueueFactory::instance()->deleteMessageQueue(hkQueue); + } + QueueFactory::instance()->deleteMessageQueue(testQueue); + QueueFactory::instance()->deleteMessageQueue(hkQueue); } \ No newline at end of file diff --git a/tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h b/tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h index dd5bca12..ebd9a2e7 100644 --- a/tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h +++ b/tests/src/fsfw_tests/unit/mocks/PeriodicTaskIFMock.h @@ -1,14 +1,12 @@ #ifndef FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_ #define FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_ -#include #include +#include -class PeriodicTaskMock: public PeriodicTaskIF{ -public: - PeriodicTaskMock(uint32_t period = 5):period(period){ - - } +class PeriodicTaskMock : public PeriodicTaskIF { + public: + PeriodicTaskMock(uint32_t period = 5) : period(period) {} /** * @brief A virtual destructor as it is mandatory for interfaces. */ @@ -17,29 +15,23 @@ public: * @brief With the startTask method, a created task can be started * for the first time. */ - virtual ReturnValue_t startTask() override{ - return HasReturnvaluesIF::RETURN_OK; - }; + virtual ReturnValue_t startTask() override { return HasReturnvaluesIF::RETURN_OK; }; - virtual ReturnValue_t addComponent(object_id_t object) override{ - ExecutableObjectIF* executableObject = ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER); - if(executableObject == nullptr){ - return HasReturnvaluesIF::RETURN_FAILED; + virtual ReturnValue_t addComponent(object_id_t object) override { + ExecutableObjectIF* executableObject = + ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER); + if (executableObject == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; } executableObject->setTaskIF(this); executableObject->initializeAfterTaskCreation(); return HasReturnvaluesIF::RETURN_OK; }; - virtual ReturnValue_t sleepFor(uint32_t ms) override{ - return HasReturnvaluesIF::RETURN_OK; - }; + virtual ReturnValue_t sleepFor(uint32_t ms) override { return HasReturnvaluesIF::RETURN_OK; }; - virtual uint32_t getPeriodMs() const override{ - return period; - }; + virtual uint32_t getPeriodMs() const override { return period; }; uint32_t period; }; - -#endif // FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_ \ No newline at end of file +#endif // FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_ \ No newline at end of file From e5e85bcff97266f0ff46eca5bd461c323dc62424 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 22 Feb 2022 13:43:25 +0100 Subject: [PATCH 16/26] still clang --- src/fsfw/datapoollocal/LocalDataPoolManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp index cab13207..acfa23c5 100644 --- a/src/fsfw/datapoollocal/LocalDataPoolManager.cpp +++ b/src/fsfw/datapoollocal/LocalDataPoolManager.cpp @@ -84,8 +84,8 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { return result; } - printWarningOrError(sif::OutputTypes::OUT_WARNING, "initializeHousekeepingPoolEntriesOnce", HasReturnvaluesIF::RETURN_FAILED, - "The map should only be initialized once"); + printWarningOrError(sif::OutputTypes::OUT_WARNING, "initializeHousekeepingPoolEntriesOnce", + HasReturnvaluesIF::RETURN_FAILED, "The map should only be initialized once"); return HasReturnvaluesIF::RETURN_OK; } From fdc8a3d4f761dc5887e97542caf65d03645d31c0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 22 Feb 2022 14:02:03 +0100 Subject: [PATCH 17/26] display run commands in helper script --- scripts/helper.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/scripts/helper.py b/scripts/helper.py index 68693c40..09599d3d 100755 --- a/scripts/helper.py +++ b/scripts/helper.py @@ -97,11 +97,11 @@ def handle_docs_type(args, build_dir_list: list): build_directory = determine_build_dir(build_dir_list) os.chdir(build_directory) if args.build: - os.system("cmake --build . -j") + cmd_runner("cmake --build . -j") if args.open: if not os.path.isfile("docs/sphinx/index.html"): # try again.. - os.system("cmake --build . -j") + cmd_runner("cmake --build . -j") if not os.path.isfile("docs/sphinx/index.html"): print( "No Sphinx documentation file detected. " @@ -147,21 +147,21 @@ def handle_tests_type(args, build_dir_list: list): # If we are in a different directory we try to switch into it but # this might fail os.chdir(UNITTEST_FOLDER_NAME) - os.system("valgrind --leak-check=full ./fsfw-tests") + cmd_runner("valgrind --leak-check=full ./fsfw-tests") os.chdir("..") def create_tests_build_cfg(): os.mkdir(UNITTEST_FOLDER_NAME) os.chdir(UNITTEST_FOLDER_NAME) - os.system("cmake -DFSFW_OSAL=host -DFSFW_BUILD_UNITTESTS=ON ..") + cmd_runner("cmake -DFSFW_OSAL=host -DFSFW_BUILD_UNITTESTS=ON ..") os.chdir("..") def create_docs_build_cfg(): os.mkdir(DOCS_FOLDER_NAME) os.chdir(DOCS_FOLDER_NAME) - os.system("cmake -DFSFW_OSAL=host -DFSFW_BUILD_DOCS=ON ..") + cmd_runner("cmake -DFSFW_OSAL=host -DFSFW_BUILD_DOCS=ON ..") os.chdir("..") @@ -184,7 +184,7 @@ def check_for_cmake_build_dir(build_dir_list: list) -> list: def perform_lcov_operation(directory: str, chdir: bool): if chdir: os.chdir(directory) - os.system("cmake --build . -- fsfw-tests_coverage -j") + cmd_runner("cmake --build . -- fsfw-tests_coverage -j") def determine_build_dir(build_dir_list: List[str]): @@ -206,5 +206,10 @@ def determine_build_dir(build_dir_list: List[str]): return build_directory +def cmd_runner(cmd: str): + print(f"Executing command: {cmd}") + os.system(cmd) + + if __name__ == "__main__": main() From 2cb254a556b3f5da550fec9e479b56de6834274b Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Wed, 23 Feb 2022 11:53:48 +0100 Subject: [PATCH 18/26] Removed unused code --- .../internalerror/InternalErrorReporter.cpp | 24 ------------------- .../internalerror/InternalErrorReporter.h | 3 --- 2 files changed, 27 deletions(-) diff --git a/src/fsfw/internalerror/InternalErrorReporter.cpp b/src/fsfw/internalerror/InternalErrorReporter.cpp index 08d37feb..fa16ec3f 100644 --- a/src/fsfw/internalerror/InternalErrorReporter.cpp +++ b/src/fsfw/internalerror/InternalErrorReporter.cpp @@ -80,14 +80,6 @@ uint32_t InternalErrorReporter::getAndResetQueueHits() { return value; } -uint32_t InternalErrorReporter::getQueueHits() { - uint32_t value; - mutex->lockMutex(timeoutType, timeoutMs); - value = queueHits; - mutex->unlockMutex(); - return value; -} - void InternalErrorReporter::incrementQueueHits() { mutex->lockMutex(timeoutType, timeoutMs); queueHits++; @@ -103,14 +95,6 @@ uint32_t InternalErrorReporter::getAndResetTmHits() { return value; } -uint32_t InternalErrorReporter::getTmHits() { - uint32_t value; - mutex->lockMutex(timeoutType, timeoutMs); - value = tmHits; - mutex->unlockMutex(); - return value; -} - void InternalErrorReporter::incrementTmHits() { mutex->lockMutex(timeoutType, timeoutMs); tmHits++; @@ -128,14 +112,6 @@ uint32_t InternalErrorReporter::getAndResetStoreHits() { return value; } -uint32_t InternalErrorReporter::getStoreHits() { - uint32_t value; - mutex->lockMutex(timeoutType, timeoutMs); - value = storeHits; - mutex->unlockMutex(); - return value; -} - void InternalErrorReporter::incrementStoreHits() { mutex->lockMutex(timeoutType, timeoutMs); storeHits++; diff --git a/src/fsfw/internalerror/InternalErrorReporter.h b/src/fsfw/internalerror/InternalErrorReporter.h index a946b81c..549be4bd 100644 --- a/src/fsfw/internalerror/InternalErrorReporter.h +++ b/src/fsfw/internalerror/InternalErrorReporter.h @@ -74,15 +74,12 @@ class InternalErrorReporter : public SystemObject, uint32_t storeHits = 0; uint32_t getAndResetQueueHits(); - uint32_t getQueueHits(); void incrementQueueHits(); uint32_t getAndResetTmHits(); - uint32_t getTmHits(); void incrementTmHits(); uint32_t getAndResetStoreHits(); - uint32_t getStoreHits(); void incrementStoreHits(); }; From d6508e23b610dfc2541fe77e38758c28e80c6ff5 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Wed, 23 Feb 2022 12:12:49 +0100 Subject: [PATCH 19/26] Added more coverage and Documentation --- .../internalerror/InternalErrorReporterIF.h | 24 ++++++++++++++----- .../TestInternalErrorReporter.cpp | 14 +++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/fsfw/internalerror/InternalErrorReporterIF.h b/src/fsfw/internalerror/InternalErrorReporterIF.h index 9eb8e7d7..61bb52e7 100644 --- a/src/fsfw/internalerror/InternalErrorReporterIF.h +++ b/src/fsfw/internalerror/InternalErrorReporterIF.h @@ -1,22 +1,34 @@ #ifndef INTERNALERRORREPORTERIF_H_ #define INTERNALERRORREPORTERIF_H_ +/** + * @brief Interface which is used to report internal errors like full message queues or stores. + * @details + * This interface smust be used for the InteralErrorReporter object. + * It should be used to indicate that there was a Problem with Queues or Stores. + * + * It can be used to report missing Telemetry which could not be sent due to a internal problem. + * + */ class InternalErrorReporterIF { public: virtual ~InternalErrorReporterIF() {} - /** - * Thread safe + * @brief Function to be called if a message queue could not be sent. + * @details OSAL Implementations should call this function to indicate that + * a message was lost. + * + * Implementations are required to be Thread safe */ virtual void queueMessageNotSent() = 0; - /** - * Thread safe + * @brief Function to be called if Telemetry could not be sent + * @details Implementations must be Thread safe */ virtual void lostTm() = 0; - /** - * Thread safe + * @brief Function to be called if a onboard storage is full + * @details Implementations must be Thread safe */ virtual void storeFull() = 0; }; diff --git a/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp index a7f5e109..92c3ff22 100644 --- a/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp +++ b/tests/src/fsfw_tests/unit/internalerror/TestInternalErrorReporter.cpp @@ -98,6 +98,20 @@ TEST_CASE("Internal Error Reporter", "[TestInternalError]") { REQUIRE(dataset.tmHits.value == (lostTm + 1)); REQUIRE(dataset.storeHits.value == (storeHits + 1)); } + // Complete Coverage + internalErrorReporter->setDiagnosticPrintout(true); + internalErrorReporter->setMutexTimeout(MutexIF::TimeoutType::BLOCKING, 0); + { + // Message Queue Id + MessageQueueId_t id = internalErrorReporter->getCommandQueue(); + REQUIRE(id != MessageQueueIF::NO_QUEUE); + CommandMessage message; + sid_t sid(objects::INTERNAL_ERROR_REPORTER, InternalErrorDataset::ERROR_SET_ID); + HousekeepingMessage::setToggleReportingCommand(&message, sid, true, false); + result = hkQueue->sendMessage(id, &message); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + internalErrorReporter->performOperation(0); + } } QueueFactory::instance()->deleteMessageQueue(testQueue); QueueFactory::instance()->deleteMessageQueue(hkQueue); From f6357b45315a2cfbf744855d7c4676cc89d6f137 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Wed, 23 Feb 2022 18:23:22 +0100 Subject: [PATCH 20/26] WIP compiler Flags and new unit tests for fixes --- CMakeLists.txt | 18 ++++ hal/src/fsfw_hal/linux/uart/UartComIF.cpp | 2 +- src/fsfw/cfdp/tlv/FilestoreTlvBase.h | 1 + src/fsfw/globalfunctions/CRC.cpp | 86 +---------------- src/fsfw/osal/linux/BinarySemaphore.cpp | 2 + src/fsfw/rmap/RMAP.h | 8 +- src/fsfw/rmap/RMAPChannelIF.h | 14 +-- .../ServiceInterfacePrinter.h | 2 + src/fsfw/storagemanager/LocalPool.cpp | 10 +- src/fsfw/storagemanager/PoolManager.cpp | 2 +- src/fsfw/timemanager/CCSDSTime.cpp | 31 ++++--- .../unit/globalfunctions/CMakeLists.txt | 1 + .../unit/globalfunctions/testCRC.cpp | 14 +++ .../fsfw_tests/unit/testcfg/FSFWConfig.h.in | 4 +- .../unit/timemanager/CMakeLists.txt | 1 + .../unit/timemanager/TestCCSDSTime.cpp | 92 +++++++++++++++++++ 16 files changed, 171 insertions(+), 117 deletions(-) create mode 100644 tests/src/fsfw_tests/unit/globalfunctions/testCRC.cpp create mode 100644 tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 79258db2..9786d572 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -281,6 +281,24 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") -Wimplicit-fallthrough=1 -Wno-unused-parameter -Wno-psabi + -Wduplicated-cond # check for duplicate conditions + -Wduplicated-branches # check for duplicate branches + -Wlogical-op # Search for bitwise operations instead of logical + -Wnull-dereference # Search for NULL dereference + -Wundef # Warn if undefind marcos are used + -Wformat=2 # Format string problem detection + -Wformat-overflow=2 # Formatting issues in printf + -Wformat-truncation=2 # Formatting issues in printf + -Wformat-security # Search for dangerous printf operations + -Wstrict-overflow=3 # Warn if integer overflows might happen + -Warray-bounds=2 # Some array bounds violations will be found + -Wshift-overflow=2 # Search for bit left shift overflows (second.replyBuffer.data(); // Size check to prevent buffer overflow if (requestLen > uartCookie.getMaxReplyLen()) { -#if OBSW_VERBOSE_LEVEL >= 1 +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!" << std::endl; diff --git a/src/fsfw/cfdp/tlv/FilestoreTlvBase.h b/src/fsfw/cfdp/tlv/FilestoreTlvBase.h index bb9f10bb..c123f94c 100644 --- a/src/fsfw/cfdp/tlv/FilestoreTlvBase.h +++ b/src/fsfw/cfdp/tlv/FilestoreTlvBase.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include diff --git a/src/fsfw/globalfunctions/CRC.cpp b/src/fsfw/globalfunctions/CRC.cpp index 033920d0..03945612 100644 --- a/src/fsfw/globalfunctions/CRC.cpp +++ b/src/fsfw/globalfunctions/CRC.cpp @@ -28,7 +28,7 @@ const uint16_t CRC::crc16ccitt_table[256] = { // CRC implementation uint16_t CRC::crc16ccitt(uint8_t const input[], uint32_t length, uint16_t startingCrc) { - uint8_t *data = (uint8_t *)input; + const uint8_t *data = static_cast(input); unsigned int tbl_idx; while (length--) { @@ -39,88 +39,4 @@ uint16_t CRC::crc16ccitt(uint8_t const input[], uint32_t length, uint16_t starti } return startingCrc & 0xffff; - // The part below is not used! - // bool temr[16]; - // bool xor_out[16]; - // bool r[16]; - // bool d[8]; - // uint16_t crc_value = 0; - // - // - // for (int i=0; i<16 ;i++) { - // temr[i] = false; - // xor_out[i] = false; - // } - // - // - // for (int i=0; i<16 ;i++) - // r[i] = true; // initialize with 0xFFFF - // - // - // - // for (int j=0; j + BinarySemaphore::BinarySemaphore() { // Using unnamed semaphores for now initSemaphore(); diff --git a/src/fsfw/rmap/RMAP.h b/src/fsfw/rmap/RMAP.h index 7c654262..d274fb15 100644 --- a/src/fsfw/rmap/RMAP.h +++ b/src/fsfw/rmap/RMAP.h @@ -169,8 +169,8 @@ class RMAP : public HasReturnvaluesIF { * @param buffer the data to write * @param length length of data * @return - * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL - * in write command + * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == + * NULL in write command * - return codes of RMAPChannelIF::sendCommand() */ static ReturnValue_t sendWriteCommand(RMAPCookie *cookie, const uint8_t *buffer, size_t length); @@ -205,8 +205,8 @@ class RMAP : public HasReturnvaluesIF { * @param cookie to cookie to read from * @param expLength the expected maximum length of the reply * @return - * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL - * in write command, or nullpointer in read command + * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == + * NULL in write command, or nullpointer in read command * - return codes of RMAPChannelIF::sendCommand() */ static ReturnValue_t sendReadCommand(RMAPCookie *cookie, uint32_t expLength); diff --git a/src/fsfw/rmap/RMAPChannelIF.h b/src/fsfw/rmap/RMAPChannelIF.h index 7dab07c1..56ede1e2 100644 --- a/src/fsfw/rmap/RMAPChannelIF.h +++ b/src/fsfw/rmap/RMAPChannelIF.h @@ -75,11 +75,11 @@ class RMAPChannelIF { * - @c RETURN_OK * - @c COMMAND_NO_DESCRIPTORS_AVAILABLE no descriptors available for sending * command; command was not sent - * - @c COMMAND_BUFFER_FULL no receiver buffer available for expected - * len; command was not sent - * - @c COMMAND_TOO_BIG the data that was to be sent was too long for the - * hw to handle (write command) or the expected len was bigger than maximal expected len (read - * command) command was not sent + * - @c COMMAND_BUFFER_FULL no receiver buffer available for + * expected len; command was not sent + * - @c COMMAND_TOO_BIG the data that was to be sent was too long + * for the hw to handle (write command) or the expected len was bigger than maximal expected len + * (read command) command was not sent * - @c COMMAND_CHANNEL_DEACTIVATED the channel has no port set * - @c NOT_SUPPORTED if you dont feel like * implementing something... @@ -97,8 +97,8 @@ class RMAPChannelIF { * - @c REPLY_NO_REPLY no reply was received * - @c REPLY_NOT_SENT command was not sent, implies no reply * - @c REPLY_NOT_YET_SENT command is still waiting to be sent - * - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission buffer - * still being processed) + * - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission + * buffer still being processed) * - @c WRITE_REPLY_TRANSMISSION_ERROR Interface encountered errors during last * operation, data could not be processed. (transmission error) * - @c WRITE_REPLY_INVALID_DATA Invalid data (amount / value) diff --git a/src/fsfw/serviceinterface/ServiceInterfacePrinter.h b/src/fsfw/serviceinterface/ServiceInterfacePrinter.h index 89d793c3..2f3dfed5 100644 --- a/src/fsfw/serviceinterface/ServiceInterfacePrinter.h +++ b/src/fsfw/serviceinterface/ServiceInterfacePrinter.h @@ -1,6 +1,8 @@ #ifndef FSFW_SERVICEINTERFACE_SERVICEINTERFACEPRINTER #define FSFW_SERVICEINTERFACE_SERVICEINTERFACEPRINTER +#include + #if FSFW_DISABLE_PRINTOUT == 0 #include #endif diff --git a/src/fsfw/storagemanager/LocalPool.cpp b/src/fsfw/storagemanager/LocalPool.cpp index 075de4b8..9bd12b4d 100644 --- a/src/fsfw/storagemanager/LocalPool.cpp +++ b/src/fsfw/storagemanager/LocalPool.cpp @@ -2,6 +2,8 @@ #include +#include + #include "fsfw/FSFW.h" #include "fsfw/objectmanager/ObjectManager.h" @@ -110,7 +112,7 @@ ReturnValue_t LocalPool::modifyData(store_address_t storeId, uint8_t** packetPtr } ReturnValue_t LocalPool::deleteData(store_address_t storeId) { -#if FSFW_VERBOSE_PRINTOUT == 2 +#if FSFW_VERBOSE_LEVEL >= 2 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "Delete: Pool: " << std::dec << storeId.poolIndex << " Index: " << storeId.packetIndex << std::endl; @@ -148,7 +150,7 @@ ReturnValue_t LocalPool::deleteData(uint8_t* ptr, size_t size, store_address_t* // element of an object. localId.packetIndex = deltaAddress / elementSizes[n]; result = deleteData(localId); -#if FSFW_VERBOSE_PRINTOUT == 2 +#if FSFW_VERBOSE_LEVEL >= 2 if (deltaAddress % elementSizes[n] != 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "LocalPool::deleteData: Address not aligned!" << std::endl; @@ -219,7 +221,7 @@ ReturnValue_t LocalPool::reserveSpace(const size_t size, store_address_t* storeI status = findEmpty(storeId->poolIndex, &storeId->packetIndex); } if (status == RETURN_OK) { -#if FSFW_VERBOSE_PRINTOUT == 2 +#if FSFW_VERBOSE_LEVEL >= 2 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "Reserve: Pool: " << std::dec << storeId->poolIndex << " Index: " << storeId->packetIndex << std::endl; @@ -257,7 +259,7 @@ void LocalPool::setToSpillToHigherPools(bool enable) { this->spillsToHigherPools ReturnValue_t LocalPool::getSubPoolIndex(size_t packetSize, uint16_t* subpoolIndex, uint16_t startAtIndex) { for (uint16_t n = startAtIndex; n < NUMBER_OF_SUBPOOLS; n++) { -#if FSFW_VERBOSE_PRINTOUT == 2 +#if FSFW_VERBOSE_LEVEL >= 2 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "LocalPool " << getObjectId() << "::getPoolIndex: Pool: " << n << ", Element Size: " << elementSizes[n] << std::endl; diff --git a/src/fsfw/storagemanager/PoolManager.cpp b/src/fsfw/storagemanager/PoolManager.cpp index 6ff00360..92de1dfe 100644 --- a/src/fsfw/storagemanager/PoolManager.cpp +++ b/src/fsfw/storagemanager/PoolManager.cpp @@ -17,7 +17,7 @@ ReturnValue_t PoolManager::reserveSpace(const size_t size, store_address_t* addr } ReturnValue_t PoolManager::deleteData(store_address_t storeId) { -#if FSFW_VERBOSE_PRINTOUT == 2 +#if FSFW_VERBOSE_LEVEL >= 2 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "PoolManager( " << translateObject(getObjectId()) << " )::deleteData from store " << storeId.poolIndex << ". id is " << storeId.packetIndex << std::endl; diff --git a/src/fsfw/timemanager/CCSDSTime.cpp b/src/fsfw/timemanager/CCSDSTime.cpp index 4445fd24..9a92c21e 100644 --- a/src/fsfw/timemanager/CCSDSTime.cpp +++ b/src/fsfw/timemanager/CCSDSTime.cpp @@ -109,8 +109,8 @@ ReturnValue_t CCSDSTime::convertFromCCS(Clock::TimeOfDay_t* to, const uint8_t* f if (result != RETURN_OK) { return result; } - - Ccs_mseconds* temp = (Ccs_mseconds*)from; + // At this point we made sure that this is a valid ccs time + const Ccs_mseconds* temp = reinterpret_cast(from); to->year = (temp->yearMSB << 8) + temp->yearLSB; to->hour = temp->hour; @@ -118,16 +118,19 @@ ReturnValue_t CCSDSTime::convertFromCCS(Clock::TimeOfDay_t* to, const uint8_t* f to->second = temp->second; if (temp->pField & (1 << 3)) { // day of year variation - uint16_t tempDay = (temp->month << 8) + temp->day; - result = convertDaysOfYear(tempDay, to->year, &(temp->month), &(temp->day)); + uint16_t tempDayOfYear = (temp->month << 8) + temp->day; + uint8_t tempDay = 0; + uint8_t tempMonth = 0; + result = convertDaysOfYear(tempDayOfYear, to->year, &tempMonth, &tempDay); if (result != RETURN_OK) { return result; } + to->month = tempMonth; + to->day = tempDay; + }else{ + to->month = temp->month; + to->day = temp->day; } - - to->month = temp->month; - to->day = temp->day; - to->usecond = 0; if (subsecondsLength > 0) { *foundLength += 1; @@ -162,7 +165,7 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* uint16_t hour; uint16_t minute; float second; - int count = sscanf((char*)from, + int count = sscanf((const char*)from, "%4" SCNu16 "-%2" SCNu16 "-%2" SCNu16 "T%" "2" SCNu16 ":%2" SCNu16 ":%fZ", @@ -179,7 +182,7 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* } // try Code B (yyyy-ddd) - count = sscanf((char*)from, + count = sscanf((const char*)from, "%4" SCNu16 "-%3" SCNu16 "T%2" SCNu16 ":%" "2" SCNu16 ":%fZ", @@ -211,7 +214,7 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* float second; // try Code A (yyyy-mm-dd) int count = - sscanf((char*)from, "%4" SCNu16 "-%2" SCNu8 "-%2" SCNu16 "T%2" SCNu8 ":%2" SCNu8 ":%fZ", + sscanf((const char*)from, "%4" SCNu16 "-%2" SCNu8 "-%2" SCNu16 "T%2" SCNu8 ":%2" SCNu8 ":%fZ", &year, &month, &day, &hour, &minute, &second); if (count == 6) { to->year = year; @@ -225,7 +228,7 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* } // try Code B (yyyy-ddd) - count = sscanf((char*)from, "%4" SCNu16 "-%3" SCNu16 "T%2" SCNu8 ":%2" SCNu8 ":%fZ", &year, &day, + count = sscanf((const char*)from, "%4" SCNu16 "-%3" SCNu16 "T%2" SCNu8 ":%2" SCNu8 ":%fZ", &year, &day, &hour, &minute, &second); if (count == 5) { uint8_t tempDay; @@ -248,7 +251,7 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* } ReturnValue_t CCSDSTime::checkCcs(const uint8_t* time, uint8_t length) { - Ccs_mseconds* time_struct = (Ccs_mseconds*)time; + const Ccs_mseconds* time_struct = reinterpret_cast(time); uint8_t additionalBytes = time_struct->pField & 0b111; if ((additionalBytes == 0b111) || (length < (additionalBytes + 8))) { @@ -278,7 +281,7 @@ ReturnValue_t CCSDSTime::checkCcs(const uint8_t* time, uint8_t length) { return INVALID_TIME_FORMAT; } - uint8_t* additionalByte = &time_struct->secondEminus2; + const uint8_t* additionalByte = &time_struct->secondEminus2; for (; additionalBytes != 0; additionalBytes--) { if (*additionalByte++ > 99) { diff --git a/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt b/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt index 3b29f23f..79f847bf 100644 --- a/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt +++ b/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt @@ -2,4 +2,5 @@ target_sources(${FSFW_TEST_TGT} PRIVATE testDleEncoder.cpp testOpDivider.cpp testBitutil.cpp + testCRC.cpp ) diff --git a/tests/src/fsfw_tests/unit/globalfunctions/testCRC.cpp b/tests/src/fsfw_tests/unit/globalfunctions/testCRC.cpp new file mode 100644 index 00000000..b163ea1f --- /dev/null +++ b/tests/src/fsfw_tests/unit/globalfunctions/testCRC.cpp @@ -0,0 +1,14 @@ +#include + +#include "catch2/catch_test_macros.hpp" +#include "fsfw/globalfunctions/CRC.h" +#include "fsfw_tests/unit/CatchDefinitions.h" + +TEST_CASE("CRC", "[CRC]") { + std::array testData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + uint16_t crc = CRC::crc16ccitt(testData.data(), 10); + REQUIRE(crc == 49729); + for (uint8_t index = 0; index < testData.size(); index++) { + REQUIRE(testData[index] == index); + } +} \ No newline at end of file diff --git a/tests/src/fsfw_tests/unit/testcfg/FSFWConfig.h.in b/tests/src/fsfw_tests/unit/testcfg/FSFWConfig.h.in index f05ef40b..ef58f4cd 100644 --- a/tests/src/fsfw_tests/unit/testcfg/FSFWConfig.h.in +++ b/tests/src/fsfw_tests/unit/testcfg/FSFWConfig.h.in @@ -11,10 +11,12 @@ //! More FSFW related printouts depending on level. Useful for development. #define FSFW_VERBOSE_LEVEL 0 - + //! Can be used to completely disable printouts, even the C stdio ones. #if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_VERBOSE_LEVEL == 0 #define FSFW_DISABLE_PRINTOUT 1 +#else + #define FSFW_DISABLE_PRINTOUT 0 #endif #define FSFW_USE_PUS_C_TELEMETRY 1 diff --git a/tests/src/fsfw_tests/unit/timemanager/CMakeLists.txt b/tests/src/fsfw_tests/unit/timemanager/CMakeLists.txt index 6ce1c6c6..4b1693a9 100644 --- a/tests/src/fsfw_tests/unit/timemanager/CMakeLists.txt +++ b/tests/src/fsfw_tests/unit/timemanager/CMakeLists.txt @@ -1,3 +1,4 @@ target_sources(${FSFW_TEST_TGT} PRIVATE TestCountdown.cpp + TestCCSDSTime.cpp ) diff --git a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp new file mode 100644 index 00000000..783517a6 --- /dev/null +++ b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp @@ -0,0 +1,92 @@ +#include + +#include + +#include +#include + +#include "fsfw_tests/unit/CatchDefinitions.h" + +TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { + INFO("CCSDSTime Tests"); + CCSDSTime::Ccs_mseconds cssMilliSecconds; + Clock::TimeOfDay_t time; + time.year = 2020; + time.month = 2; + time.day = 29; + time.hour = 13; + time.minute = 24; + time.second = 45; + time.usecond = 123456; + SECTION("Test CCS Time") { + auto result = CCSDSTime::convertToCcsds(&cssMilliSecconds, &time); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + REQUIRE(cssMilliSecconds.pField == 0x52); // 0b01010010 + REQUIRE(cssMilliSecconds.yearMSB == 0x07); + REQUIRE(cssMilliSecconds.yearLSB == 0xe4); + REQUIRE(cssMilliSecconds.month == 2); + REQUIRE(cssMilliSecconds.day == 29); + REQUIRE(cssMilliSecconds.hour == 13); + REQUIRE(cssMilliSecconds.minute == 24); + REQUIRE(cssMilliSecconds.second == 45); + uint16_t secondsMinus4 = (static_cast(cssMilliSecconds.secondEminus2) * 100) + + cssMilliSecconds.secondEminus4; + REQUIRE(secondsMinus4 == 1234); + Clock::TimeOfDay_t timeTo; + const uint8_t* dataPtr = reinterpret_cast(&cssMilliSecconds); + size_t length = sizeof(CCSDSTime::Ccs_mseconds); + result = CCSDSTime::convertFromCCS(&timeTo, dataPtr, &length, sizeof(CCSDSTime::Ccs_mseconds)); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + REQUIRE(cssMilliSecconds.pField == 0x52); // 0b01010010 + REQUIRE(cssMilliSecconds.yearMSB == 0x07); + REQUIRE(cssMilliSecconds.yearLSB == 0xe4); + REQUIRE(cssMilliSecconds.month == 2); + REQUIRE(cssMilliSecconds.day == 29); + REQUIRE(cssMilliSecconds.hour == 13); + REQUIRE(cssMilliSecconds.minute == 24); + REQUIRE(cssMilliSecconds.second == 45); + REQUIRE(timeTo.year == 2020); + REQUIRE(timeTo.month == 2); + REQUIRE(timeTo.day == 29); + REQUIRE(timeTo.hour == 13); + REQUIRE(timeTo.minute == 24); + REQUIRE(timeTo.second == 45); + REQUIRE(timeTo.usecond == 123400); + } + SECTION("CCS_Day of Year"){ + Clock::TimeOfDay_t timeTo; + std::array ccsDayOfYear = {0b01011000, 0x07, 0xe4, 0, 60, 13, 24, 45}; + size_t length = ccsDayOfYear.size(); + auto result = CCSDSTime::convertFromCCS(&timeTo, ccsDayOfYear.data(), &length, ccsDayOfYear.size()); + REQUIRE(result == HasReturnvaluesIF::RETURN_OK); + // Check constness + REQUIRE(ccsDayOfYear[0] == 0b01011000); + REQUIRE(ccsDayOfYear[1] == 0x07); + REQUIRE(ccsDayOfYear[2] == 0xe4); + REQUIRE(ccsDayOfYear[3] == 0x0); + REQUIRE(ccsDayOfYear[4] == 60); + REQUIRE(ccsDayOfYear[5] == 13); + REQUIRE(ccsDayOfYear[6] == 24); + REQUIRE(ccsDayOfYear[7] == 45); + REQUIRE(timeTo.year == 2020); + REQUIRE(timeTo.month == 2); + REQUIRE(timeTo.day == 29); + REQUIRE(timeTo.hour == 13); + REQUIRE(timeTo.minute == 24); + REQUIRE(timeTo.second == 45); + REQUIRE(timeTo.usecond == 0); + } + SECTION("Test convertFromASCII"){ + std::string timeAscii = "2022-12-31T23:59:59.123Z"; + Clock::TimeOfDay_t timeTo; + const uint8_t* timeChar = reinterpret_cast(timeAscii.c_str()); + CCSDSTime::convertFromASCII(&timeTo, timeChar, timeAscii.length()); + REQUIRE(timeTo.year == 2022); + REQUIRE(timeTo.month == 12); + REQUIRE(timeTo.day == 31); + REQUIRE(timeTo.hour == 23); + REQUIRE(timeTo.minute == 59); + REQUIRE(timeTo.second == 59); + REQUIRE(timeTo.usecond == Catch::Approx(123000)); + } +} \ No newline at end of file From 09815f5cce17deefb9435ffc9c9b55b5b8d6f3ce Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Wed, 23 Feb 2022 18:24:07 +0100 Subject: [PATCH 21/26] Clang format --- src/fsfw/cfdp/tlv/FilestoreTlvBase.h | 2 +- src/fsfw/osal/linux/BinarySemaphore.cpp | 3 +-- src/fsfw/rmap/RMAPChannelIF.h | 6 ++--- src/fsfw/storagemanager/LocalPool.cpp | 4 ++-- src/fsfw/timemanager/CCSDSTime.cpp | 6 ++--- .../unit/timemanager/TestCCSDSTime.cpp | 22 +++++++++---------- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/fsfw/cfdp/tlv/FilestoreTlvBase.h b/src/fsfw/cfdp/tlv/FilestoreTlvBase.h index c123f94c..9a02c213 100644 --- a/src/fsfw/cfdp/tlv/FilestoreTlvBase.h +++ b/src/fsfw/cfdp/tlv/FilestoreTlvBase.h @@ -1,12 +1,12 @@ #ifndef FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTBASE_H_ #define FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTBASE_H_ +#include #include #include #include #include #include -#include #include #include diff --git a/src/fsfw/osal/linux/BinarySemaphore.cpp b/src/fsfw/osal/linux/BinarySemaphore.cpp index 536681a6..4fb67f15 100644 --- a/src/fsfw/osal/linux/BinarySemaphore.cpp +++ b/src/fsfw/osal/linux/BinarySemaphore.cpp @@ -1,6 +1,7 @@ #include "fsfw/osal/linux/BinarySemaphore.h" #include +#include #include #include @@ -9,8 +10,6 @@ #include "fsfw/serviceinterface/ServiceInterfacePrinter.h" #include "fsfw/serviceinterface/ServiceInterfaceStream.h" -#include - BinarySemaphore::BinarySemaphore() { // Using unnamed semaphores for now initSemaphore(); diff --git a/src/fsfw/rmap/RMAPChannelIF.h b/src/fsfw/rmap/RMAPChannelIF.h index 56ede1e2..9e666dfb 100644 --- a/src/fsfw/rmap/RMAPChannelIF.h +++ b/src/fsfw/rmap/RMAPChannelIF.h @@ -77,9 +77,9 @@ class RMAPChannelIF { * command; command was not sent * - @c COMMAND_BUFFER_FULL no receiver buffer available for * expected len; command was not sent - * - @c COMMAND_TOO_BIG the data that was to be sent was too long - * for the hw to handle (write command) or the expected len was bigger than maximal expected len - * (read command) command was not sent + * - @c COMMAND_TOO_BIG the data that was to be sent was too + * long for the hw to handle (write command) or the expected len was bigger than maximal expected + * len (read command) command was not sent * - @c COMMAND_CHANNEL_DEACTIVATED the channel has no port set * - @c NOT_SUPPORTED if you dont feel like * implementing something... diff --git a/src/fsfw/storagemanager/LocalPool.cpp b/src/fsfw/storagemanager/LocalPool.cpp index 9bd12b4d..6acedaca 100644 --- a/src/fsfw/storagemanager/LocalPool.cpp +++ b/src/fsfw/storagemanager/LocalPool.cpp @@ -1,9 +1,9 @@ #include "fsfw/storagemanager/LocalPool.h" -#include - #include +#include + #include "fsfw/FSFW.h" #include "fsfw/objectmanager/ObjectManager.h" diff --git a/src/fsfw/timemanager/CCSDSTime.cpp b/src/fsfw/timemanager/CCSDSTime.cpp index 9a92c21e..290d58dc 100644 --- a/src/fsfw/timemanager/CCSDSTime.cpp +++ b/src/fsfw/timemanager/CCSDSTime.cpp @@ -127,7 +127,7 @@ ReturnValue_t CCSDSTime::convertFromCCS(Clock::TimeOfDay_t* to, const uint8_t* f } to->month = tempMonth; to->day = tempDay; - }else{ + } else { to->month = temp->month; to->day = temp->day; } @@ -228,8 +228,8 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* } // try Code B (yyyy-ddd) - count = sscanf((const char*)from, "%4" SCNu16 "-%3" SCNu16 "T%2" SCNu8 ":%2" SCNu8 ":%fZ", &year, &day, - &hour, &minute, &second); + count = sscanf((const char*)from, "%4" SCNu16 "-%3" SCNu16 "T%2" SCNu8 ":%2" SCNu8 ":%fZ", &year, + &day, &hour, &minute, &second); if (count == 5) { uint8_t tempDay; ReturnValue_t result = CCSDSTime::convertDaysOfYear(day, year, &month, &tempDay); diff --git a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp index 783517a6..89713488 100644 --- a/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp +++ b/tests/src/fsfw_tests/unit/timemanager/TestCCSDSTime.cpp @@ -1,9 +1,8 @@ -#include - #include -#include +#include #include +#include #include "fsfw_tests/unit/CatchDefinitions.h" @@ -53,11 +52,12 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { REQUIRE(timeTo.second == 45); REQUIRE(timeTo.usecond == 123400); } - SECTION("CCS_Day of Year"){ + SECTION("CCS_Day of Year") { Clock::TimeOfDay_t timeTo; - std::array ccsDayOfYear = {0b01011000, 0x07, 0xe4, 0, 60, 13, 24, 45}; + std::array ccsDayOfYear = {0b01011000, 0x07, 0xe4, 0, 60, 13, 24, 45}; size_t length = ccsDayOfYear.size(); - auto result = CCSDSTime::convertFromCCS(&timeTo, ccsDayOfYear.data(), &length, ccsDayOfYear.size()); + auto result = + CCSDSTime::convertFromCCS(&timeTo, ccsDayOfYear.data(), &length, ccsDayOfYear.size()); REQUIRE(result == HasReturnvaluesIF::RETURN_OK); // Check constness REQUIRE(ccsDayOfYear[0] == 0b01011000); @@ -76,11 +76,11 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") { REQUIRE(timeTo.second == 45); REQUIRE(timeTo.usecond == 0); } - SECTION("Test convertFromASCII"){ - std::string timeAscii = "2022-12-31T23:59:59.123Z"; - Clock::TimeOfDay_t timeTo; - const uint8_t* timeChar = reinterpret_cast(timeAscii.c_str()); - CCSDSTime::convertFromASCII(&timeTo, timeChar, timeAscii.length()); + SECTION("Test convertFromASCII") { + std::string timeAscii = "2022-12-31T23:59:59.123Z"; + Clock::TimeOfDay_t timeTo; + const uint8_t* timeChar = reinterpret_cast(timeAscii.c_str()); + CCSDSTime::convertFromASCII(&timeTo, timeChar, timeAscii.length()); REQUIRE(timeTo.year == 2022); REQUIRE(timeTo.month == 12); REQUIRE(timeTo.day == 31); From 32381a78725f393b8304c4308bbbeaf0ef65f3cf Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Wed, 23 Feb 2022 21:20:22 +0100 Subject: [PATCH 22/26] Fixed an issue with wrong buffer size --- src/fsfw/globalfunctions/arrayprinter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/globalfunctions/arrayprinter.cpp b/src/fsfw/globalfunctions/arrayprinter.cpp index e0899d94..325bf247 100644 --- a/src/fsfw/globalfunctions/arrayprinter.cpp +++ b/src/fsfw/globalfunctions/arrayprinter.cpp @@ -107,7 +107,7 @@ void arrayprinter::printDec(const uint8_t *data, size_t size, size_t maxCharPerL break; } - currentPos += snprintf(printBuffer + currentPos, 3, "%d", data[i]); + currentPos += snprintf(printBuffer + currentPos, 4, "%d", data[i]); if (i < size - 1) { currentPos += sprintf(printBuffer + currentPos, ","); if (i > 0 and (i + 1) % maxCharPerLine == 0) { From 1ef3dae72e44498c7fcfab986032cabe605af319 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Wed, 23 Feb 2022 22:36:29 +0100 Subject: [PATCH 23/26] Fixed an missing include --- src/fsfw/cfdp/tlv/FilestoreTlvBase.h | 1 + src/fsfw/globalfunctions/arrayprinter.cpp | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/fsfw/cfdp/tlv/FilestoreTlvBase.h b/src/fsfw/cfdp/tlv/FilestoreTlvBase.h index 9a02c213..18eb515a 100644 --- a/src/fsfw/cfdp/tlv/FilestoreTlvBase.h +++ b/src/fsfw/cfdp/tlv/FilestoreTlvBase.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/src/fsfw/globalfunctions/arrayprinter.cpp b/src/fsfw/globalfunctions/arrayprinter.cpp index 325bf247..40dc09f5 100644 --- a/src/fsfw/globalfunctions/arrayprinter.cpp +++ b/src/fsfw/globalfunctions/arrayprinter.cpp @@ -1,6 +1,7 @@ #include "fsfw/globalfunctions/arrayprinter.h" #include +#include #include "fsfw/serviceinterface/ServiceInterface.h" @@ -68,7 +69,7 @@ void arrayprinter::printHex(const uint8_t *data, size_t size, size_t maxCharPerL currentPos += snprintf(printBuffer + currentPos, 6, "%02x", data[i]); if (i < size - 1) { currentPos += sprintf(printBuffer + currentPos, ","); - if (i > 0 and (i + 1) % maxCharPerLine == 0) { + if ((i + 1) % maxCharPerLine == 0) { currentPos += sprintf(printBuffer + currentPos, "\n"); } } @@ -97,20 +98,21 @@ void arrayprinter::printDec(const uint8_t *data, size_t size, size_t maxCharPerL } std::cout << "]" << std::endl; #else - // General format: 32, 243, -12 so it is number of chars times 5 + // General format: 32,243,-12 so it is number of chars times 4 // plus line break plus small safety margin. - char printBuffer[(size + 1) * 5 + 1] = {}; + uint16_t expectedLines = ceil((double)size / maxCharPerLine); + char printBuffer[size * 4 + 1 + expectedLines] = {}; size_t currentPos = 0; for (size_t i = 0; i < size; i++) { // To avoid buffer overflows. - if (sizeof(printBuffer) - currentPos <= 5) { + if (sizeof(printBuffer) - currentPos <= 4) { break; } currentPos += snprintf(printBuffer + currentPos, 4, "%d", data[i]); if (i < size - 1) { currentPos += sprintf(printBuffer + currentPos, ","); - if (i > 0 and (i + 1) % maxCharPerLine == 0) { + if ((i + 1) % maxCharPerLine == 0) { currentPos += sprintf(printBuffer + currentPos, "\n"); } } From 0e8328fca30a0f8e7b5e94e3362b1ade400567cf Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Thu, 24 Feb 2022 11:22:51 +0100 Subject: [PATCH 24/26] Fixed include based on Feedback --- src/fsfw/cfdp/tlv/FilestoreTlvBase.h | 3 ++- src/fsfw/serviceinterface/ServiceInterfacePrinter.h | 2 +- src/fsfw/storagemanager/LocalPool.cpp | 2 -- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/fsfw/cfdp/tlv/FilestoreTlvBase.h b/src/fsfw/cfdp/tlv/FilestoreTlvBase.h index 18eb515a..04012cda 100644 --- a/src/fsfw/cfdp/tlv/FilestoreTlvBase.h +++ b/src/fsfw/cfdp/tlv/FilestoreTlvBase.h @@ -1,7 +1,6 @@ #ifndef FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTBASE_H_ #define FSFW_SRC_FSFW_CFDP_FILESTOREREQUESTBASE_H_ -#include #include #include #include @@ -12,6 +11,8 @@ #include #include +#include "fsfw/FSFW.h" + namespace cfdp { enum FilestoreActionCode { diff --git a/src/fsfw/serviceinterface/ServiceInterfacePrinter.h b/src/fsfw/serviceinterface/ServiceInterfacePrinter.h index 2f3dfed5..65f7250a 100644 --- a/src/fsfw/serviceinterface/ServiceInterfacePrinter.h +++ b/src/fsfw/serviceinterface/ServiceInterfacePrinter.h @@ -1,7 +1,7 @@ #ifndef FSFW_SERVICEINTERFACE_SERVICEINTERFACEPRINTER #define FSFW_SERVICEINTERFACE_SERVICEINTERFACEPRINTER -#include +#include "fsfw/FSFW.h" #if FSFW_DISABLE_PRINTOUT == 0 #include diff --git a/src/fsfw/storagemanager/LocalPool.cpp b/src/fsfw/storagemanager/LocalPool.cpp index 6acedaca..cee1d407 100644 --- a/src/fsfw/storagemanager/LocalPool.cpp +++ b/src/fsfw/storagemanager/LocalPool.cpp @@ -1,7 +1,5 @@ #include "fsfw/storagemanager/LocalPool.h" -#include - #include #include "fsfw/FSFW.h" From f659f137599515995785bf768b6297eec4a1f91b Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Thu, 3 Mar 2022 16:03:06 +0100 Subject: [PATCH 25/26] Changing build to -j4 from -j to lessen load on build server --- automation/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile index 3424f986..d1459e52 100644 --- a/automation/Jenkinsfile +++ b/automation/Jenkinsfile @@ -21,14 +21,14 @@ pipeline { stage('Build') { steps { dir(BUILDDIR) { - sh 'cmake --build . -j' + sh 'cmake --build . -j4' } } } stage('Unittests') { steps { dir(BUILDDIR) { - sh 'cmake --build . -- fsfw-tests_coverage -j' + sh 'cmake --build . -- fsfw-tests_coverage -j4' } } } From 117747970d1d1e417393044e98ea404ca26676cb Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Sat, 5 Mar 2022 22:03:25 +0100 Subject: [PATCH 26/26] some forgotten size_t --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 2 +- src/fsfw/devicehandlers/DeviceHandlerBase.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index ea1fcdf1..08a15d5f 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -824,7 +824,7 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, DeviceCommandId } ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, uint8_t** data, - uint32_t* len) { + size_t* len) { size_t lenTmp; if (IPCStore == nullptr) { diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index 037f4bd7..c8b8b86d 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -673,7 +673,7 @@ class DeviceHandlerBase : public DeviceHandlerIF, //! Pointer to the raw packet that will be sent. uint8_t *rawPacket = nullptr; //! Size of the #rawPacket. - uint32_t rawPacketLen = 0; + size_t rawPacketLen = 0; /** * The mode the device handler is currently in. @@ -1250,7 +1250,7 @@ class DeviceHandlerBase : public DeviceHandlerIF, * - @c RETURN_FAILED IPCStore is nullptr * - the return value from the IPCStore if it was not @c RETURN_OK */ - ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data, uint32_t *len); + ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data, size_t *len); /** * @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW, nothing else!