From bc525ab2eb3079de23260efca5dd366a4e68418d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 16 Sep 2020 16:22:36 +0200 Subject: [PATCH] linux working --- .gitignore | 9 + Makefile | 5 - bsp_linux/InitMission.cpp | 168 ++++++++++++ bsp_linux/boardconfig/etl_profile.h | 38 +++ bsp_linux/boardconfig/gcov.h | 14 + bsp_linux/boardconfig/print.c | 14 + bsp_linux/boardconfig/print.h | 8 + bsp_linux/bsp_linux.mk | 4 + bsp_linux/main.cpp | 39 +++ config/cdatapool/dataPoolInit.cpp | 48 ++++ config/cdatapool/dataPoolInit.h | 29 ++ config/config.mk | 15 ++ config/devices/logicalAddresses.cpp | 11 + config/devices/logicalAddresses.h | 26 ++ config/devices/powerSwitcherList.cpp | 10 + config/devices/powerSwitcherList.h | 22 ++ config/events/translateEvents.cpp | 254 ++++++++++++++++++ config/events/translateEvents.h | 16 ++ config/ipc/MissionMessageTypes.cpp | 11 + config/ipc/MissionMessageTypes.h | 22 ++ config/objects/Factory.cpp | 116 ++++++++ config/objects/Factory.h | 16 ++ config/objects/systemObjectList.h | 37 +++ config/objects/translateObjects.cpp | 242 +++++++++++++++++ config/objects/translateObjects.h | 16 ++ .../PollingSequenceFactory.cpp | 31 +++ .../pollingsequence/PollingSequenceFactory.h | 31 +++ config/returnvalues/classIds.h | 28 ++ config/tmtc/apid.h | 19 ++ config/tmtc/pusIds.h | 23 ++ config/tmtc/subsystemIdRanges.h | 36 +++ config/tmtc/tmTcSize.h | 10 + config/version.h | 9 + fsfw | 2 +- mission/mission.mk | 2 + mission/utility/TimeStamper.cpp | 23 ++ mission/utility/TimeStamper.h | 18 ++ mission/utility/TmFunnel.cpp | 112 ++++++++ mission/utility/TmFunnel.h | 52 ++++ test/test.mk | 3 + test/testtasks/MutextestTask.cpp | 41 +++ test/testtasks/MutextestTask.h | 32 +++ test/testtasks/PusTcInjector.cpp | 67 +++++ test/testtasks/PusTcInjector.h | 72 +++++ test/testtasks/TestTask.cpp | 74 +++++ test/testtasks/TestTask.h | 57 ++++ unittest/unittest.mk | 0 47 files changed, 1926 insertions(+), 6 deletions(-) create mode 100644 .gitignore create mode 100644 bsp_linux/InitMission.cpp create mode 100644 bsp_linux/boardconfig/etl_profile.h create mode 100644 bsp_linux/boardconfig/gcov.h create mode 100644 bsp_linux/boardconfig/print.c create mode 100644 bsp_linux/boardconfig/print.h create mode 100644 bsp_linux/main.cpp create mode 100644 config/cdatapool/dataPoolInit.cpp create mode 100644 config/cdatapool/dataPoolInit.h create mode 100644 config/devices/logicalAddresses.cpp create mode 100644 config/devices/logicalAddresses.h create mode 100644 config/devices/powerSwitcherList.cpp create mode 100644 config/devices/powerSwitcherList.h create mode 100644 config/events/translateEvents.cpp create mode 100644 config/events/translateEvents.h create mode 100644 config/ipc/MissionMessageTypes.cpp create mode 100644 config/ipc/MissionMessageTypes.h create mode 100644 config/objects/Factory.cpp create mode 100644 config/objects/Factory.h create mode 100644 config/objects/systemObjectList.h create mode 100644 config/objects/translateObjects.cpp create mode 100644 config/objects/translateObjects.h create mode 100644 config/pollingsequence/PollingSequenceFactory.cpp create mode 100644 config/pollingsequence/PollingSequenceFactory.h create mode 100644 config/returnvalues/classIds.h create mode 100644 config/tmtc/apid.h create mode 100644 config/tmtc/pusIds.h create mode 100644 config/tmtc/subsystemIdRanges.h create mode 100644 config/tmtc/tmTcSize.h create mode 100644 config/version.h create mode 100644 mission/utility/TimeStamper.cpp create mode 100644 mission/utility/TimeStamper.h create mode 100644 mission/utility/TmFunnel.cpp create mode 100644 mission/utility/TmFunnel.h create mode 100644 test/testtasks/MutextestTask.cpp create mode 100644 test/testtasks/MutextestTask.h create mode 100644 test/testtasks/PusTcInjector.cpp create mode 100644 test/testtasks/PusTcInjector.h create mode 100644 test/testtasks/TestTask.cpp create mode 100644 test/testtasks/TestTask.h create mode 100644 unittest/unittest.mk diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f6adc50a --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +_obj +_bin +_dep + +.settings +.metadata +.project +.cproject +__pycache__ diff --git a/Makefile b/Makefile index a9ccccf0..1e089c5e 100644 --- a/Makefile +++ b/Makefile @@ -19,11 +19,6 @@ OS_FSFW = linux CUSTOM_DEFINES += -D$(OS_FSFW) CUSTOM_DEFINES += -DLINUX -SW_VERSION = 1 -SW_SUBVERSION = 6 -CUSTOM_DEFINES += -DSW_VERSION=$(SW_VERSION) -CUSTOM_DEFINES += -DSW_SUBVERSION=$(SW_SUBVERSION) - # General folder paths FRAMEWORK_PATH = fsfw MISSION_PATH = mission diff --git a/bsp_linux/InitMission.cpp b/bsp_linux/InitMission.cpp new file mode 100644 index 00000000..bc3d1f83 --- /dev/null +++ b/bsp_linux/InitMission.cpp @@ -0,0 +1,168 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/* Declare global object manager */ +ObjectManagerIF* objectManager; + +/* Initialize Data Pool */ +DataPool dataPool(datapool::dataPoolInit); + +/* Set up output streams */ +namespace sif { +ServiceInterfaceStream debug("DEBUG"); +ServiceInterfaceStream info("INFO"); +ServiceInterfaceStream warning("WARNING"); +ServiceInterfaceStream error("ERROR", false, true, true); +} + + +void initTask(); + + +void initMission() { + sif::info << "Initiating mission specific code." << std::endl; + // Allocate object manager here, as global constructors might not be + // executed, depending on buildchain + sif::info << "Creating objects" << std::endl; + objectManager = new ObjectManager(Factory::produce); + objectManager -> initialize(); + + initTask(); + +} + +void initTask() { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + + /* Packet Distributor Taks */ + PeriodicTaskIF* PacketDistributorTask = + TaskFactory::instance()-> createPeriodicTask( + "PACKET_DIST_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 0.4, nullptr); + result = PacketDistributorTask-> + addComponent(objects::CCSDS_PACKET_DISTRIBUTOR); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Add component CCSDS Packet Distributor failed" + << std::endl; + } + result = PacketDistributorTask-> + addComponent(objects::PUS_PACKET_DISTRIBUTOR); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Add component PUS Packet Distributor failed" + << std::endl; + } + result = PacketDistributorTask->addComponent(objects::PUS_FUNNEL); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Add component PUS Funnel failed" << std::endl; + } + + /* UDP bridge */ + PeriodicTaskIF* UdpBridgeTask = TaskFactory::instance()->createPeriodicTask( + "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 0.2, nullptr); + result = UdpBridgeTask->addComponent(objects::UDP_BRIDGE); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component UDP Unix Bridge failed" << std::endl; + } + + PeriodicTaskIF* UdpPollingTask = TaskFactory::instance()-> + createPeriodicTask("UDP_POLLING", 80, + PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); + result = UdpPollingTask->addComponent(objects::UDP_POLLING_TASK); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component UDP Polling failed" << std::endl; + } + + /* PUS Services */ + PeriodicTaskIF* PusService1 = TaskFactory::instance()->createPeriodicTask( + "PUS_SRV_1", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 0.4, nullptr); + result = PusService1->addComponent(objects::PUS_SERVICE_1); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component Verification Reporter failed" << std::endl; + } + + PeriodicTaskIF* PusService2 = TaskFactory::instance()->createPeriodicTask( + "PUS_SRV_2", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 0.2, nullptr); + result = PusService2->addComponent(objects::PUS_SERVICE_2); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component Device Access failed" << std::endl; + } + + PeriodicTaskIF* PusService5 = TaskFactory::instance()->createPeriodicTask( + "PUS_SRV_5", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 0.4, nullptr); + result = PusService5->addComponent(objects::PUS_SERVICE_5); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component Event Service failed" << std::endl; + } + + PeriodicTaskIF* PusService8 = TaskFactory::instance()->createPeriodicTask( + "PUS_SRV_8", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 0.4, nullptr); + result = PusService2->addComponent(objects::PUS_SERVICE_8); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component Function MGMT failed" << std::endl; + } + + PeriodicTaskIF* PusService17 = TaskFactory::instance()->createPeriodicTask( + "PUS_SRV_17", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 0.4, nullptr); + result = PusService17->addComponent(objects::PUS_SERVICE_17); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component Test Service failed" << std::endl; + } + + PeriodicTaskIF* PusService200 = TaskFactory::instance()->createPeriodicTask( + "PUS_SRV_200", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 0.4, nullptr); + result = PusService200->addComponent(objects::PUS_SERVICE_200); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Add component Mode MGMT failed" << std::endl; + } + + + /* Test Task */ +// PeriodicTaskIF* TestTask = TaskFactory::instance()-> +// createPeriodicTask("TEST_TASK", 80, +// PeriodicTaskIF::MINIMUM_STACK_SIZE, 5.0, nullptr); +// result = TestTask->addComponent(objects::TEST_TASK); +// if (result != HasReturnvaluesIF::RETURN_OK) { +// sif::error << "Add component Test Task failed" << std::endl; +// } + + + /* Polling Sequence Table Default */ +// FixedTimeslotTaskIF * PollingSequenceTableTaskDefault = +// TaskFactory::instance()-> createFixedTimeslotTask( +// "PST_DEFAULT", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, +// nullptr); +// result = pst::pollingSequenceInitDefault(PollingSequenceTableTaskDefault); +// if (result != HasReturnvaluesIF::RETURN_OK) { +// sif::error << "creating PST failed" << std::endl; +// } + + //TestTask->startTask(); + PacketDistributorTask->startTask(); + //PollingSequenceTableTaskDefault->startTask(); + UdpBridgeTask->startTask(); + UdpPollingTask->startTask(); + + PusService1->startTask(); + PusService2->startTask(); + PusService5->startTask(); + PusService8->startTask(); + PusService17->startTask(); + PusService200->startTask(); +} diff --git a/bsp_linux/boardconfig/etl_profile.h b/bsp_linux/boardconfig/etl_profile.h new file mode 100644 index 00000000..c35ffb46 --- /dev/null +++ b/bsp_linux/boardconfig/etl_profile.h @@ -0,0 +1,38 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2019 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ +#ifndef __ETL_PROFILE_H__ +#define __ETL_PROFILE_H__ + +#define ETL_CHECK_PUSH_POP + +#define ETL_CPP11_SUPPORTED 1 +#define ETL_NO_NULLPTR_SUPPORT 0 + +#endif diff --git a/bsp_linux/boardconfig/gcov.h b/bsp_linux/boardconfig/gcov.h new file mode 100644 index 00000000..491d24c6 --- /dev/null +++ b/bsp_linux/boardconfig/gcov.h @@ -0,0 +1,14 @@ +#ifndef LINUX_GCOV_H_ +#define LINUX_GCOV_H_ +#include + +#ifdef GCOV +extern "C" void __gcov_flush(); +#else +void __gcov_flush() { + sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if " + "coverage information is desired.\n" << std::flush; +} +#endif + +#endif /* LINUX_GCOV_H_ */ diff --git a/bsp_linux/boardconfig/print.c b/bsp_linux/boardconfig/print.c new file mode 100644 index 00000000..f409ee1b --- /dev/null +++ b/bsp_linux/boardconfig/print.c @@ -0,0 +1,14 @@ +#include "print.h" +#include + +void printChar(const char* character, bool errStream) { + if(errStream) { + putc(*character, stderr); + return; + } + putc(*character, stdout); +} + + + + diff --git a/bsp_linux/boardconfig/print.h b/bsp_linux/boardconfig/print.h new file mode 100644 index 00000000..8e7e2e5d --- /dev/null +++ b/bsp_linux/boardconfig/print.h @@ -0,0 +1,8 @@ +#ifndef HOSTED_BOARDCONFIG_PRINT_H_ +#define HOSTED_BOARDCONFIG_PRINT_H_ + +#include + +void printChar(const char* character, bool errStream); + +#endif /* HOSTED_BOARDCONFIG_PRINT_H_ */ diff --git a/bsp_linux/bsp_linux.mk b/bsp_linux/bsp_linux.mk index e69de29b..f7f9a469 100644 --- a/bsp_linux/bsp_linux.mk +++ b/bsp_linux/bsp_linux.mk @@ -0,0 +1,4 @@ +CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp) +CSRC += $(wildcard $(CURRENTPATH)/*.c) + +CSRC += $(wildcard $(CURRENTPATH)/boardconfig/*.c) \ No newline at end of file diff --git a/bsp_linux/main.cpp b/bsp_linux/main.cpp new file mode 100644 index 00000000..4c34e501 --- /dev/null +++ b/bsp_linux/main.cpp @@ -0,0 +1,39 @@ +#if defined(GCOV) +#include +#endif + +#include +#include +#include + +// This will be the entry to the mission specific code +void initMission(); + +#ifndef SW_VERSION +#define SW_VERSION 0 +#endif + +#ifndef SW_SUBVERSION +#define SW_SUBVERSION 0 +#endif + +/** + * @brief This is the main program for the hosted build. It can be run for + * Linux and Windows. + * @return + */ +int main(void) +{ + std::cout << "-- EIVE OBSW --" << std::endl; + std::cout << "-- Compiled for Linux " << " --" << std::endl; + std::cout << "-- Software version v" << SW_VERSION << "." << SW_SUBVERSION + << " -- " << std::endl; + std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; + initMission(); + for(;;) { + // suspend main thread by sleeping it. + sleep(5); + } +} + + diff --git a/config/cdatapool/dataPoolInit.cpp b/config/cdatapool/dataPoolInit.cpp new file mode 100644 index 00000000..b37ed0ac --- /dev/null +++ b/config/cdatapool/dataPoolInit.cpp @@ -0,0 +1,48 @@ +#include "dataPoolInit.h" + +void datapool::dataPoolInit(std::map* poolMap) { + uint8_t UINT8T_INIT[1] = {0}; + uint16_t UINT16T_INIT[1] = {0}; + uint32_t UINT32T_INIT[1] = {0}; + float FLOAT_INIT[2] = {0.0, 0.0}; + /* FSFW */ + poolMap->emplace(datapool::INTERNAL_ERROR_STORE_FULL, + new PoolEntry(UINT32T_INIT,1)); + poolMap->emplace(datapool::INTERNAL_ERROR_MISSED_LIVE_TM, + new PoolEntry(UINT32T_INIT,1)); + poolMap->emplace(datapool::INTERNAL_ERROR_FULL_MSG_QUEUES, + new PoolEntry(UINT32T_INIT,1)); + + /* TEST */ + poolMap->emplace(datapool::TEST_UINT8, + new PoolEntry(UINT8T_INIT,1)); + poolMap->emplace(datapool::TEST_UINT16, + new PoolEntry(UINT16T_INIT,1)); + poolMap->emplace(datapool::TEST_UINT32, + new PoolEntry(UINT32T_INIT,1)); + poolMap->emplace(datapool::TEST_FLOAT_VECTOR, + new PoolEntry(FLOAT_INIT,2)); + + // With new initializer list feature and boolean entries. + +// /* FSFW */ +// poolMap->emplace(datapool::INTERNAL_ERROR_STORE_FULL, +// new PoolEntry({0},1)); +// poolMap->emplace(datapool::INTERNAL_ERROR_MISSED_LIVE_TM, +// new PoolEntry({0},1)); +// poolMap->emplace(datapool::INTERNAL_ERROR_FULL_MSG_QUEUES, +// new PoolEntry({0},1)); +// +// /* TEST */ +// poolMap->emplace(datapool::TEST_BOOLEAN, +// new PoolEntry({0},1)); +// poolMap->emplace(datapool::TEST_UINT8, +// new PoolEntry({0},1)); +// poolMap->emplace(datapool::TEST_UINT16, +// new PoolEntry({0},1)); +// poolMap->emplace(datapool::TEST_UINT32, +// new PoolEntry({0},1)); +// poolMap->emplace(datapool::TEST_FLOAT_VECTOR, +// new PoolEntry({0, 0},2)); + +} diff --git a/config/cdatapool/dataPoolInit.h b/config/cdatapool/dataPoolInit.h new file mode 100644 index 00000000..9da940b5 --- /dev/null +++ b/config/cdatapool/dataPoolInit.h @@ -0,0 +1,29 @@ +#ifndef HOSTED_CONFIG_CDATAPOOL_DATAPOOLINIT_H_ +#define HOSTED_CONFIG_CDATAPOOL_DATAPOOLINIT_H_ + +#include +#include +#include +#include + + +namespace datapool { + void dataPoolInit(std::map* poolMap); + + enum datapoolvariables { + NO_PARAMETER = 0, + + /** [EXPORT] : [GROUP] FSFW */ + INTERNAL_ERROR_STORE_FULL = 0xEE000001, //!< [EXPORT] : [NAME] Internal Error Store Entry [UNIT] (-) [SIZE] 1 [TYPE] uint32_t + INTERNAL_ERROR_MISSED_LIVE_TM = 0xEE000001, //!< [EXPORT] : [NAME] Internal Error Missed Live Tm [UNIT] (-) [SIZE] 1 [TYPE] uint32_t + INTERNAL_ERROR_FULL_MSG_QUEUES = 0xEE000001, //!< [EXPORT] : [NAME] Internal Error Full Msg Queue [UNIT] (-) [SIZE] 1 [TYPE] uint32_t + + /** [EXPORT] : [GROUP] TEST */ + TEST_BOOLEAN = 0x01010102, //!< [EXPORT] : [NAME] Test Boolean [UNIT] (-) [SIZE] 1 [TYPE] bool + TEST_UINT8 = 0x02020204, //!< [EXPORT] : [NAME] Test Byte [UNIT] (-) [SIZE] 1 [TYPE] uint8_t + TEST_UINT16 = 0x03030306, //!< [EXPORT] : [NAME] Test UINT16 [UNIT] (-) [SIZE] 1 [TYPE] uint16_t + TEST_UINT32 = 0x04040408, //!< [EXPORT] : [NAME] Test UINT32 [UNIT] (-) [SIZE] 1 [TYPE] uint32_t + TEST_FLOAT_VECTOR = 0x05050510, //!< [EXPORT] : [NAME] Test Float [UNIT] (-) [SIZE] 2 [TYPE] float + }; +} +#endif /* CONFIG_CDATAPOOL_DATAPOOLINIT_H_ */ diff --git a/config/config.mk b/config/config.mk index e69de29b..105c3fba 100644 --- a/config/config.mk +++ b/config/config.mk @@ -0,0 +1,15 @@ +CXXSRC += $(wildcard $(CURRENTPATH)/cdatapool/*.cpp) +CXXSRC += $(wildcard $(CURRENTPATH)/ipc/*.cpp) +CXXSRC += $(wildcard $(CURRENTPATH)/objects/*.cpp) +CXXSRC += $(wildcard $(CURRENTPATH)/pollingsequence/*.cpp) +CXXSRC += $(wildcard $(CURRENTPATH)/events/*.cpp) + +INCLUDES += $(CURRENTPATH) +INCLUDES += $(CURRENTPATH)/objects +INCLUDES += $(CURRENTPATH)/ipc +INCLUDES += $(CURRENTPATH)/pollingsequence +INCLUDES += $(CURRENTPATH)/returnvalues +INCLUDES += $(CURRENTPATH)/tmtc +INCLUDES += $(CURRENTPATH)/events +INCLUDES += $(CURRENTPATH)/devices +INCLUDES += $(CURRENTPATH)/cdatapool \ No newline at end of file diff --git a/config/devices/logicalAddresses.cpp b/config/devices/logicalAddresses.cpp new file mode 100644 index 00000000..20cabdb1 --- /dev/null +++ b/config/devices/logicalAddresses.cpp @@ -0,0 +1,11 @@ +/** + * \file logicalAddresses.cpp + * + * \date 06.11.2019 + */ + +#include "logicalAddresses.h" + + + + diff --git a/config/devices/logicalAddresses.h b/config/devices/logicalAddresses.h new file mode 100644 index 00000000..58683bee --- /dev/null +++ b/config/devices/logicalAddresses.h @@ -0,0 +1,26 @@ +/** + * \file logicalAddresses.cpp + * + * \date 07.11.2019 + */ + +#ifndef CONFIG_DEVICES_LOGICALADDRESSES_H_ +#define CONFIG_DEVICES_LOGICALADDRESSES_H_ +#include +#include +#include + +namespace addresses { + /* Logical addresses have uint32_t datatype */ + enum logicalAddresses: address_t { + PCDU, + + /* Dummy and Test Addresses */ + DUMMY_ECHO = 129, + DUMMY_GPS0 = 130, + DUMMY_GPS1 = 131, + }; +} + + +#endif /* CONFIG_DEVICES_LOGICALADDRESSES_H_ */ diff --git a/config/devices/powerSwitcherList.cpp b/config/devices/powerSwitcherList.cpp new file mode 100644 index 00000000..24679907 --- /dev/null +++ b/config/devices/powerSwitcherList.cpp @@ -0,0 +1,10 @@ +/** + * @file switcherList.cpp + * + * @date 28.11.2019 + */ + +#include "powerSwitcherList.h" + + + diff --git a/config/devices/powerSwitcherList.h b/config/devices/powerSwitcherList.h new file mode 100644 index 00000000..2d10ae8d --- /dev/null +++ b/config/devices/powerSwitcherList.h @@ -0,0 +1,22 @@ +/** + * @file switcherList.h + * + * @date 28.11.2019 + */ + +#ifndef CONFIG_DEVICES_POWERSWITCHERLIST_H_ +#define CONFIG_DEVICES_POWERSWITCHERLIST_H_ + +namespace switches { + /* Switches are uint8_t datatype and go from 0 to 255 */ + enum switcherList { + PCDU, + GPS0, + GPS1, + DUMMY = 129 + }; + +} + + +#endif /* CONFIG_DEVICES_POWERSWITCHERLIST_H_ */ diff --git a/config/events/translateEvents.cpp b/config/events/translateEvents.cpp new file mode 100644 index 00000000..f955a56f --- /dev/null +++ b/config/events/translateEvents.cpp @@ -0,0 +1,254 @@ +/** + * @brief Auto-generated event translation file. Contains 80 translations. + * Generated on: 2020-05-02 20:13:41 + */ +#include "translateEvents.h" + +const char *GPS_STARTUP_FAILED_STRING = "GPS_STARTUP_FAILED"; +const char *GPS_FIX_STRING = "GPS_FIX"; +const char *GPS_LOST_FIX_STRING = "GPS_LOST_FIX"; +const char *STORE_SEND_WRITE_FAILED_STRING = "STORE_SEND_WRITE_FAILED"; +const char *STORE_WRITE_FAILED_STRING = "STORE_WRITE_FAILED"; +const char *STORE_SEND_READ_FAILED_STRING = "STORE_SEND_READ_FAILED"; +const char *STORE_READ_FAILED_STRING = "STORE_READ_FAILED"; +const char *UNEXPECTED_MSG_STRING = "UNEXPECTED_MSG"; +const char *STORING_FAILED_STRING = "STORING_FAILED"; +const char *TM_DUMP_FAILED_STRING = "TM_DUMP_FAILED"; +const char *STORE_INIT_FAILED_STRING = "STORE_INIT_FAILED"; +const char *STORE_INIT_EMPTY_STRING = "STORE_INIT_EMPTY"; +const char *STORE_CONTENT_CORRUPTED_STRING = "STORE_CONTENT_CORRUPTED"; +const char *STORE_INITIALIZE_STRING = "STORE_INITIALIZE"; +const char *INIT_DONE_STRING = "INIT_DONE"; +const char *DUMP_FINISHED_STRING = "DUMP_FINISHED"; +const char *DELETION_FINISHED_STRING = "DELETION_FINISHED"; +const char *DELETION_FAILED_STRING = "DELETION_FAILED"; +const char *AUTO_CATALOGS_SENDING_FAILED_STRING = "AUTO_CATALOGS_SENDING_FAILED"; +const char *GET_DATA_FAILED_STRING = "GET_DATA_FAILED"; +const char *STORE_DATA_FAILED_STRING = "STORE_DATA_FAILED"; +const char *DEVICE_BUILDING_COMMAND_FAILED_STRING = "DEVICE_BUILDING_COMMAND_FAILED"; +const char *DEVICE_SENDING_COMMAND_FAILED_STRING = "DEVICE_SENDING_COMMAND_FAILED"; +const char *DEVICE_REQUESTING_REPLY_FAILED_STRING = "DEVICE_REQUESTING_REPLY_FAILED"; +const char *DEVICE_READING_REPLY_FAILED_STRING = "DEVICE_READING_REPLY_FAILED"; +const char *DEVICE_INTERPRETING_REPLY_FAILED_STRING = "DEVICE_INTERPRETING_REPLY_FAILED"; +const char *DEVICE_MISSED_REPLY_STRING = "DEVICE_MISSED_REPLY"; +const char *DEVICE_UNKNOWN_REPLY_STRING = "DEVICE_UNKNOWN_REPLY"; +const char *DEVICE_UNREQUESTED_REPLY_STRING = "DEVICE_UNREQUESTED_REPLY"; +const char *INVALID_DEVICE_COMMAND_STRING = "INVALID_DEVICE_COMMAND"; +const char *MONITORING_LIMIT_EXCEEDED_STRING = "MONITORING_LIMIT_EXCEEDED"; +const char *MONITORING_AMBIGUOUS_STRING = "MONITORING_AMBIGUOUS"; +const char *FUSE_CURRENT_HIGH_STRING = "FUSE_CURRENT_HIGH"; +const char *FUSE_WENT_OFF_STRING = "FUSE_WENT_OFF"; +const char *POWER_ABOVE_HIGH_LIMIT_STRING = "POWER_ABOVE_HIGH_LIMIT"; +const char *POWER_BELOW_LOW_LIMIT_STRING = "POWER_BELOW_LOW_LIMIT"; +const char *SWITCH_WENT_OFF_STRING = "SWITCH_WENT_OFF"; +const char *HEATER_ON_STRING = "HEATER_ON"; +const char *HEATER_OFF_STRING = "HEATER_OFF"; +const char *HEATER_TIMEOUT_STRING = "HEATER_TIMEOUT"; +const char *HEATER_STAYED_ON_STRING = "HEATER_STAYED_ON"; +const char *HEATER_STAYED_OFF_STRING = "HEATER_STAYED_OFF"; +const char *TEMP_SENSOR_HIGH_STRING = "TEMP_SENSOR_HIGH"; +const char *TEMP_SENSOR_LOW_STRING = "TEMP_SENSOR_LOW"; +const char *TEMP_SENSOR_GRADIENT_STRING = "TEMP_SENSOR_GRADIENT"; +const char *COMPONENT_TEMP_LOW_STRING = "COMPONENT_TEMP_LOW"; +const char *COMPONENT_TEMP_HIGH_STRING = "COMPONENT_TEMP_HIGH"; +const char *COMPONENT_TEMP_OOL_LOW_STRING = "COMPONENT_TEMP_OOL_LOW"; +const char *COMPONENT_TEMP_OOL_HIGH_STRING = "COMPONENT_TEMP_OOL_HIGH"; +const char *TEMP_NOT_IN_OP_RANGE_STRING = "TEMP_NOT_IN_OP_RANGE"; +const char *FDIR_CHANGED_STATE_STRING = "FDIR_CHANGED_STATE"; +const char *FDIR_STARTS_RECOVERY_STRING = "FDIR_STARTS_RECOVERY"; +const char *FDIR_TURNS_OFF_DEVICE_STRING = "FDIR_TURNS_OFF_DEVICE"; +const char *MONITOR_CHANGED_STATE_STRING = "MONITOR_CHANGED_STATE"; +const char *VALUE_BELOW_LOW_LIMIT_STRING = "VALUE_BELOW_LOW_LIMIT"; +const char *VALUE_ABOVE_HIGH_LIMIT_STRING = "VALUE_ABOVE_HIGH_LIMIT"; +const char *VALUE_OUT_OF_RANGE_STRING = "VALUE_OUT_OF_RANGE"; +const char *SWITCHING_TM_FAILED_STRING = "SWITCHING_TM_FAILED"; +const char *CHANGING_MODE_STRING = "CHANGING_MODE"; +const char *MODE_INFO_STRING = "MODE_INFO"; +const char *FALLBACK_FAILED_STRING = "FALLBACK_FAILED"; +const char *MODE_TRANSITION_FAILED_STRING = "MODE_TRANSITION_FAILED"; +const char *CANT_KEEP_MODE_STRING = "CANT_KEEP_MODE"; +const char *OBJECT_IN_INVALID_MODE_STRING = "OBJECT_IN_INVALID_MODE"; +const char *FORCING_MODE_STRING = "FORCING_MODE"; +const char *MODE_CMD_REJECTED_STRING = "MODE_CMD_REJECTED"; +const char *HEALTH_INFO_STRING = "HEALTH_INFO"; +const char *CHILD_CHANGED_HEALTH_STRING = "CHILD_CHANGED_HEALTH"; +const char *CHILD_PROBLEMS_STRING = "CHILD_PROBLEMS"; +const char *OVERWRITING_HEALTH_STRING = "OVERWRITING_HEALTH"; +const char *TRYING_RECOVERY_STRING = "TRYING_RECOVERY"; +const char *RECOVERY_STEP_STRING = "RECOVERY_STEP"; +const char *RECOVERY_DONE_STRING = "RECOVERY_DONE"; +const char *RF_AVAILABLE_STRING = "RF_AVAILABLE"; +const char *RF_LOST_STRING = "RF_LOST"; +const char *BIT_LOCK_STRING = "BIT_LOCK"; +const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST"; +const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED"; +const char *TEST_EVENT_SERVICE_1_STRING = "TEST_EVENT_SERVICE_1"; +const char *TEST2_STRING = "TEST2"; + +const char * translateEvents(Event event){ + switch((event&0xFFFF)){ + case 1000: + return GPS_STARTUP_FAILED_STRING; + case 1001: + return GPS_FIX_STRING; + case 1002: + return GPS_LOST_FIX_STRING; + case 2200: + return STORE_SEND_WRITE_FAILED_STRING; + case 2201: + return STORE_WRITE_FAILED_STRING; + case 2202: + return STORE_SEND_READ_FAILED_STRING; + case 2203: + return STORE_READ_FAILED_STRING; + case 2204: + return UNEXPECTED_MSG_STRING; + case 2205: + return STORING_FAILED_STRING; + case 2206: + return TM_DUMP_FAILED_STRING; + case 2207: + return STORE_INIT_FAILED_STRING; + case 2208: + return STORE_INIT_EMPTY_STRING; + case 2209: + return STORE_CONTENT_CORRUPTED_STRING; + case 2210: + return STORE_INITIALIZE_STRING; + case 2211: + return INIT_DONE_STRING; + case 2212: + return DUMP_FINISHED_STRING; + case 2213: + return DELETION_FINISHED_STRING; + case 2214: + return DELETION_FAILED_STRING; + case 2215: + return AUTO_CATALOGS_SENDING_FAILED_STRING; + case 2600: + return GET_DATA_FAILED_STRING; + case 2601: + return STORE_DATA_FAILED_STRING; + case 2800: + return DEVICE_BUILDING_COMMAND_FAILED_STRING; + case 2801: + return DEVICE_SENDING_COMMAND_FAILED_STRING; + case 2802: + return DEVICE_REQUESTING_REPLY_FAILED_STRING; + case 2803: + return DEVICE_READING_REPLY_FAILED_STRING; + case 2804: + return DEVICE_INTERPRETING_REPLY_FAILED_STRING; + case 2805: + return DEVICE_MISSED_REPLY_STRING; + case 2806: + return DEVICE_UNKNOWN_REPLY_STRING; + case 2807: + return DEVICE_UNREQUESTED_REPLY_STRING; + case 2808: + return INVALID_DEVICE_COMMAND_STRING; + case 2809: + return MONITORING_LIMIT_EXCEEDED_STRING; + case 2810: + return MONITORING_AMBIGUOUS_STRING; + case 4201: + return FUSE_CURRENT_HIGH_STRING; + case 4202: + return FUSE_WENT_OFF_STRING; + case 4204: + return POWER_ABOVE_HIGH_LIMIT_STRING; + case 4205: + return POWER_BELOW_LOW_LIMIT_STRING; + case 4300: + return SWITCH_WENT_OFF_STRING; + case 5000: + return HEATER_ON_STRING; + case 5001: + return HEATER_OFF_STRING; + case 5002: + return HEATER_TIMEOUT_STRING; + case 5003: + return HEATER_STAYED_ON_STRING; + case 5004: + return HEATER_STAYED_OFF_STRING; + case 5200: + return TEMP_SENSOR_HIGH_STRING; + case 5201: + return TEMP_SENSOR_LOW_STRING; + case 5202: + return TEMP_SENSOR_GRADIENT_STRING; + case 5901: + return COMPONENT_TEMP_LOW_STRING; + case 5902: + return COMPONENT_TEMP_HIGH_STRING; + case 5903: + return COMPONENT_TEMP_OOL_LOW_STRING; + case 5904: + return COMPONENT_TEMP_OOL_HIGH_STRING; + case 5905: + return TEMP_NOT_IN_OP_RANGE_STRING; + case 7101: + return FDIR_CHANGED_STATE_STRING; + case 7102: + return FDIR_STARTS_RECOVERY_STRING; + case 7103: + return FDIR_TURNS_OFF_DEVICE_STRING; + case 7201: + return MONITOR_CHANGED_STATE_STRING; + case 7202: + return VALUE_BELOW_LOW_LIMIT_STRING; + case 7203: + return VALUE_ABOVE_HIGH_LIMIT_STRING; + case 7204: + return VALUE_OUT_OF_RANGE_STRING; + case 7301: + return SWITCHING_TM_FAILED_STRING; + case 7400: + return CHANGING_MODE_STRING; + case 7401: + return MODE_INFO_STRING; + case 7402: + return FALLBACK_FAILED_STRING; + case 7403: + return MODE_TRANSITION_FAILED_STRING; + case 7404: + return CANT_KEEP_MODE_STRING; + case 7405: + return OBJECT_IN_INVALID_MODE_STRING; + case 7406: + return FORCING_MODE_STRING; + case 7407: + return MODE_CMD_REJECTED_STRING; + case 7506: + return HEALTH_INFO_STRING; + case 7507: + return CHILD_CHANGED_HEALTH_STRING; + case 7508: + return CHILD_PROBLEMS_STRING; + case 7509: + return OVERWRITING_HEALTH_STRING; + case 7510: + return TRYING_RECOVERY_STRING; + case 7511: + return RECOVERY_STEP_STRING; + case 7512: + return RECOVERY_DONE_STRING; + case 7900: + return RF_AVAILABLE_STRING; + case 7901: + return RF_LOST_STRING; + case 7902: + return BIT_LOCK_STRING; + case 7903: + return BIT_LOCK_LOST_STRING; + case 7905: + return FRAME_PROCESSING_FAILED_STRING; + case 8000: + return TEST_EVENT_SERVICE_1_STRING; + case 9100: + return TEST2_STRING; + default: + return "UNKNOWN_EVENT"; + } + return 0; +} diff --git a/config/events/translateEvents.h b/config/events/translateEvents.h new file mode 100644 index 00000000..0e40ef8b --- /dev/null +++ b/config/events/translateEvents.h @@ -0,0 +1,16 @@ +/* + * translateEvent.h + * + * Created on: 28 May 2019 + * Author: Robin + */ + +#ifndef CONFIG_EVENTS_TRANSLATEEVENTS_H_ +#define CONFIG_EVENTS_TRANSLATEEVENTS_H_ + +#include + +const char * translateEvents(Event event); + + +#endif /* CONFIG_EVENTS_TRANSLATEEVENTS_H_ */ diff --git a/config/ipc/MissionMessageTypes.cpp b/config/ipc/MissionMessageTypes.cpp new file mode 100644 index 00000000..3eef97fc --- /dev/null +++ b/config/ipc/MissionMessageTypes.cpp @@ -0,0 +1,11 @@ +#include "MissionMessageTypes.h" +#include + +void messagetypes::clearMissionMessage(CommandMessage* message) { +// switch(message->getMessageType()) { +// default: +// break; +// } +} + + diff --git a/config/ipc/MissionMessageTypes.h b/config/ipc/MissionMessageTypes.h new file mode 100644 index 00000000..832d8e58 --- /dev/null +++ b/config/ipc/MissionMessageTypes.h @@ -0,0 +1,22 @@ +#ifndef CONFIG_IPC_MISSIONMESSAGETYPES_H_ +#define CONFIG_IPC_MISSIONMESSAGETYPES_H_ + +#include + +class CommandMessage; + +/** + * Custom command messages are specified here. + * Most messages needed to use FSFW are already located in + * + * @param message Generic Command Message + */ +namespace messagetypes{ +enum MESSAGE_TYPE { + MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT, +}; + +void clearMissionMessage(CommandMessage* message); +} + +#endif /* CONFIG_IPC_MISSIONMESSAGETYPES_H_ */ diff --git a/config/objects/Factory.cpp b/config/objects/Factory.cpp new file mode 100644 index 00000000..be709414 --- /dev/null +++ b/config/objects/Factory.cpp @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * @brief Produces system objects. + * @details + * Build tasks by using SystemObject Interface (Interface). + * Header files of all tasks must be included + * Please note that an object has to implement the system object interface + * if the interface validity is checked or retrieved later by using the + * get(object_id) function from the ObjectManagerIF. + * + * Framework objects are created first. + * + * @ingroup init + */ +void Factory::produce(void) { + setStaticFrameworkObjectIds(); + new EventManager(objects::EVENT_MANAGER); + new HealthTable(objects::HEALTH_TABLE); + new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER, + datapool::INTERNAL_ERROR_FULL_MSG_QUEUES, + datapool::INTERNAL_ERROR_MISSED_LIVE_TM, + datapool::INTERNAL_ERROR_STORE_FULL); + + /* Pool manager handles storage und mutexes */ + /* Data Stores. Currently reserving 9600 bytes of memory */ + uint16_t numberOfElements[4] = {100, 30, 20, 10}; + uint16_t sizeOfElements[4] = {32, 64, 128, 256}; + new PoolManager<4>(objects::IPC_STORE, sizeOfElements, numberOfElements); + new PoolManager<4>(objects::TM_STORE, sizeOfElements, numberOfElements); + new PoolManager<4>(objects::TC_STORE, sizeOfElements, numberOfElements); + + new TimeStamper(objects::PUS_TIME); + + /* Distributor Tasks */ + new CCSDSDistributor(apid::EIVE_OBSW, objects::CCSDS_PACKET_DISTRIBUTOR); + new PUSDistributor(apid::EIVE_OBSW, objects::PUS_PACKET_DISTRIBUTOR, + objects::CCSDS_PACKET_DISTRIBUTOR); + + /* TM Destination */ + new TmFunnel(objects::PUS_FUNNEL); + + new TmTcUnixUdpBridge(objects::UDP_BRIDGE, + objects::CCSDS_PACKET_DISTRIBUTOR, objects::TM_STORE, + objects::TC_STORE); + new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, + objects::UDP_BRIDGE); + + /* PUS Service Base Services */ + new Service1TelecommandVerification(objects::PUS_SERVICE_1, + apid::EIVE_OBSW, pus::PUS_SERVICE_1, objects::PUS_FUNNEL); + new Service5EventReporting(objects::PUS_SERVICE_5, apid::EIVE_OBSW, + pus::PUS_SERVICE_5); + new Service17Test(objects::PUS_SERVICE_17, apid::EIVE_OBSW, + pus::PUS_SERVICE_17); + + /* Commanding Service Base Services */ + new Service2DeviceAccess(objects::PUS_SERVICE_2, apid::EIVE_OBSW, + pus::PUS_SERVICE_2); + new Service8FunctionManagement(objects::PUS_SERVICE_8, apid::EIVE_OBSW, + pus::PUS_SERVICE_8); + new CService200ModeCommanding(objects::PUS_SERVICE_200, apid::EIVE_OBSW, + pus::PUS_SERVICE_200); + + /* Test Tasks */ +// CookieIF* dummyCookie = new DummyCookie(0); +// new DummyEchoComIF(objects::DUMMY_INTERFACE); +// new TestDevice(objects::DUMMY_HANDLER, objects::DUMMY_INTERFACE, +// dummyCookie, true); + new TestTask(objects::TEST_TASK); +} + +void Factory::setStaticFrameworkObjectIds() { + PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; + PusServiceBase::packetDestination = objects::PUS_FUNNEL; + + CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; + CommandingServiceBase::defaultPacketDestination = objects::PUS_FUNNEL; + + VerificationReporter::messageReceiver = objects::PUS_SERVICE_1; + //DeviceHandlerBase::rawDataReceiverId = objects::PUS_SERVICE_2; + //DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; + + TmPacketStored::timeStamperId = objects::PUS_TIME; + TmFunnel::downlinkDestination = objects::UDP_BRIDGE; +} + + diff --git a/config/objects/Factory.h b/config/objects/Factory.h new file mode 100644 index 00000000..84f9207e --- /dev/null +++ b/config/objects/Factory.h @@ -0,0 +1,16 @@ +#ifndef FACTORY_H_ +#define FACTORY_H_ + +#include + +namespace Factory { + /** + * @brief Creates all SystemObject elements which are persistent + * during execution. + */ + void produce(); + void setStaticFrameworkObjectIds(); + +} + +#endif /* FACTORY_H_ */ diff --git a/config/objects/systemObjectList.h b/config/objects/systemObjectList.h new file mode 100644 index 00000000..e2a76311 --- /dev/null +++ b/config/objects/systemObjectList.h @@ -0,0 +1,37 @@ +#ifndef HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ +#define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ + +#include + +// The objects will be instantiated in the ID order +namespace objects { + enum sourceObjects: uint32_t { + /* First Byte 0x50-0x52 reserved for PUS Services **/ + CCSDS_PACKET_DISTRIBUTOR = 0x50000100, + PUS_PACKET_DISTRIBUTOR = 0x50000200, + UDP_BRIDGE = 0x50000300, + UDP_POLLING_TASK = 0x50000400, + + PUS_SERVICE_1 = 0x51000100, + PUS_SERVICE_2 = 0x51000200, + PUS_SERVICE_3 = 0x51000300, + PUS_SERVICE_5 = 0x51000400, + PUS_SERVICE_6 = 0x51000500, + PUS_SERVICE_8 = 0x51000800, + PUS_SERVICE_9 = 0x51000900, + PUS_SERVICE_17 = 0x51001700, + PUS_SERVICE_23 = 0x51002300, + PUS_SERVICE_200 = 0x51020000, + PUS_SERVICE_201 = 0x51020100, + + PUS_TIME = 0x52000001, + PUS_FUNNEL = 0x52000002, + + /* Test Task */ + TEST_TASK = 0x42694269, + DUMMY_INTERFACE = 0xCAFECAFE, + DUMMY_HANDLER = 0x4400AFFE, + }; +} + +#endif /* BSP_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */ diff --git a/config/objects/translateObjects.cpp b/config/objects/translateObjects.cpp new file mode 100644 index 00000000..84e4011c --- /dev/null +++ b/config/objects/translateObjects.cpp @@ -0,0 +1,242 @@ +/* Auto-generated event translation file. Contains 77 translations. */ +#include + +const char *AT91_UART2_TEST_TASK_STRING = "AT91_UART2_TEST_TASK"; +const char *ARDUINO_0_STRING = "ARDUINO_0"; +const char *ARDUINO_1_STRING = "ARDUINO_1"; +const char *ARDUINO_2_STRING = "ARDUINO_2"; +const char *ARDUINO_3_STRING = "ARDUINO_3"; +const char *ARDUINO_4_STRING = "ARDUINO_4"; +const char *AT91_I2C_TEST_TASK_STRING = "AT91_I2C_TEST_TASK"; +const char *TEST_TASK_STRING = "TEST_TASK"; +const char *PCDU_HANDLER_STRING = "PCDU_HANDLER"; +const char *DUMMY_HANDLER_STRING = "DUMMY_HANDLER"; +const char *S_ADC1_DEC2_STRING = "S_ADC1_DEC2"; +const char *GPS0_HANDLER_STRING = "GPS0_HANDLER"; +const char *DLR_PVCH_STRING = "DLR_PVCH"; +const char *GYRO1_STRING = "GYRO1"; +const char *DLR_IRAS_STRING = "DLR_IRAS"; +const char *_DEC1_O1_STRING = "_DEC1_O1"; +const char *_DEC1_O2_STRING = "_DEC1_O2"; +const char *S1_DEC1_O3_STRING = "S1_DEC1_O3"; +const char *S2_DEC1_O4_STRING = "S2_DEC1_O4"; +const char *S3_DEC1_O5_STRING = "S3_DEC1_O5"; +const char *PT1000_PVHC_DEC1_O6_STRING = "PT1000_PVHC_DEC1_O6"; +const char *PT1000_CCSDS1_DEC2_STRING = "PT1000_CCSDS1_DEC2"; +const char *PT1000_MGT1_DEC2_STRING = "PT1000_MGT1_DEC2"; +const char *S4_DEC2_STRING = "S4_DEC2"; +const char *S5_DEC2_STRING = "S5_DEC2"; +const char *S6_DEC2_STRING = "S6_DEC2"; +const char *PT1000_PVCH_DEC2_STRING = "PT1000_PVCH_DEC2"; +const char *_DEC3_STRING = "_DEC3"; +const char *PT1000_CCSDS2_DEC3_STRING = "PT1000_CCSDS2_DEC3"; +const char *S7_DEC3_STRING = "S7_DEC3"; +const char *S8_DEC3_STRING = "S8_DEC3"; +const char *PT1000_PVCH_DEC3_STRING = "PT1000_PVCH_DEC3"; +const char *GYRO2_STRING = "GYRO2"; +const char *PT1000_PLOC_DEC4_STRING = "PT1000_PLOC_DEC4"; +const char *S9_DEC4_STRING = "S9_DEC4"; +const char *S10_DEC4_STRING = "S10_DEC4"; +const char *PT1000_PVHC_DEC4_STRING = "PT1000_PVHC_DEC4"; +const char *S_ADC_DEC4_STRING = "S_ADC_DEC4"; +const char *GPS1_HANDLER_STRING = "GPS1_HANDLER"; +const char *DUMMY_GPS_COM_IF_STRING = "DUMMY_GPS_COM_IF"; +const char *RS232_DEVICE_COM_IF_STRING = "RS232_DEVICE_COM_IF"; +const char *I2C_DEVICE_COM_IF_STRING = "I2C_DEVICE_COM_IF"; +const char *GPIO_DEVICE_COM_IF_STRING = "GPIO_DEVICE_COM_IF"; +const char *SPI_POLLING_TASK_STRING = "SPI_POLLING_TASK"; +const char *SPI_DEVICE_COM_IF_STRING = "SPI_DEVICE_COM_IF"; +const char *DUMMY_ECHO_COM_IF_STRING = "DUMMY_ECHO_COM_IF"; +const char *SD_CARD_HANDLER_STRING = "SD_CARD_HANDLER"; +const char *CCSDS_PACKET_DISTRIBUTOR_STRING = "CCSDS_PACKET_DISTRIBUTOR"; +const char *PUS_PACKET_DISTRIBUTOR_STRING = "PUS_PACKET_DISTRIBUTOR"; +const char *UDP_TMTC_BRIDGE_STRING = "UDP_TMTC_BRIDGE"; +const char *EMAC_POLLING_TASK_STRING = "EMAC_POLLING_TASK"; +const char *SERIAL_POLLING_TASK_STRING = "SERIAL_POLLING_TASK"; +const char *UART_TMTC_BRIDGE_STRING = "UART_TMTC_BRIDGE"; +const char *PUS_SERVICE_1_STRING = "PUS_SERVICE_1"; +const char *PUS_SERVICE_2_STRING = "PUS_SERVICE_2"; +const char *PUS_SERVICE_3_STRING = "PUS_SERVICE_3"; +const char *PUS_SERVICE_5_STRING = "PUS_SERVICE_5"; +const char *PUS_SERVICE_6_STRING = "PUS_SERVICE_6"; +const char *PUS_SERVICE_8_STRING = "PUS_SERVICE_8"; +const char *PUS_SERVICE_9_STRING = "PUS_SERVICE_9"; +const char *PUS_SERVICE_17_STRING = "PUS_SERVICE_17"; +const char *PUS_SERVICE_23_STRING = "PUS_SERVICE_23"; +const char *PUS_SERVICE_200_STRING = "PUS_SERVICE_200"; +const char *PUS_SERVICE_201_STRING = "PUS_SERVICE_201"; +const char *PUS_TIME_STRING = "PUS_TIME"; +const char *PUS_FUNNEL_STRING = "PUS_FUNNEL"; +const char *HEALTH_TABLE_STRING = "HEALTH_TABLE"; +const char *MODE_STORE_STRING = "MODE_STORE"; +const char *EVENT_MANAGER_STRING = "EVENT_MANAGER"; +const char *INTERNAL_ERROR_REPORTER_STRING = "INTERNAL_ERROR_REPORTER"; +const char *TC_STORE_STRING = "TC_STORE"; +const char *TM_STORE_STRING = "TM_STORE"; +const char *IPC_STORE_STRING = "IPC_STORE"; +const char *AT91_SPI_TEST_TASK_STRING = "AT91_SPI_TEST_TASK"; +const char *STM32_TEST_TASK_STRING = "STM32_TEST_TASK"; +const char *AT91_UART0_TEST_TASK_STRING = "AT91_UART0_TEST_TASK"; +const char *NO_OBJECT_STRING = "NO_OBJECT"; + +const char* translateObject(object_id_t object){ + switch((object&0xFFFFFFFF)){ + case 0x000123336: + return AT91_UART2_TEST_TASK_STRING; + case 0x01010100: + return ARDUINO_0_STRING; + case 0x01010101: + return ARDUINO_1_STRING; + case 0x01010102: + return ARDUINO_2_STRING; + case 0x01010103: + return ARDUINO_3_STRING; + case 0x01010104: + return ARDUINO_4_STRING; + case 0x12345678: + return AT91_I2C_TEST_TASK_STRING; + case 0x42694269: + return TEST_TASK_STRING; + case 0x44003200: + return PCDU_HANDLER_STRING; + case 0x4400AFFE: + return DUMMY_HANDLER_STRING; + case 0x44020108: + return S_ADC1_DEC2_STRING; + case 0x44101F00: + return GPS0_HANDLER_STRING; + case 0x44104000: + return DLR_PVCH_STRING; + case 0x44105000: + return GYRO1_STRING; + case 0x44106000: + return DLR_IRAS_STRING; + case 0x44115401: + return _DEC1_O1_STRING; + case 0x44115402: + return _DEC1_O2_STRING; + case 0x44115404: + return S1_DEC1_O3_STRING; + case 0x44115405: + return S2_DEC1_O4_STRING; + case 0x44115406: + return S3_DEC1_O5_STRING; + case 0x44115407: + return PT1000_PVHC_DEC1_O6_STRING; + case 0x44125401: + return PT1000_CCSDS1_DEC2_STRING; + case 0x44125403: + return PT1000_MGT1_DEC2_STRING; + case 0x44125404: + return S4_DEC2_STRING; + case 0x44125405: + return S5_DEC2_STRING; + case 0x44125406: + return S6_DEC2_STRING; + case 0x44125407: + return PT1000_PVCH_DEC2_STRING; + case 0x44130301: + return _DEC3_STRING; + case 0x44130302: + return PT1000_CCSDS2_DEC3_STRING; + case 0x44130305: + return S7_DEC3_STRING; + case 0x44130306: + return S8_DEC3_STRING; + case 0x44130307: + return PT1000_PVCH_DEC3_STRING; + case 0x44130308: + return GYRO2_STRING; + case 0x44145401: + return PT1000_PLOC_DEC4_STRING; + case 0x44145404: + return S9_DEC4_STRING; + case 0x44145405: + return S10_DEC4_STRING; + case 0x44145406: + return PT1000_PVHC_DEC4_STRING; + case 0x44145407: + return S_ADC_DEC4_STRING; + case 0x44202000: + return GPS1_HANDLER_STRING; + case 0x49001F00: + return DUMMY_GPS_COM_IF_STRING; + case 0x49005200: + return RS232_DEVICE_COM_IF_STRING; + case 0x49005300: + return I2C_DEVICE_COM_IF_STRING; + case 0x49005400: + return GPIO_DEVICE_COM_IF_STRING; + case 0x49005410: + return SPI_POLLING_TASK_STRING; + case 0x49005600: + return SPI_DEVICE_COM_IF_STRING; + case 0x4900AFFE: + return DUMMY_ECHO_COM_IF_STRING; + case 0x4D0073AD: + return SD_CARD_HANDLER_STRING; + case 0x50000100: + return CCSDS_PACKET_DISTRIBUTOR_STRING; + case 0x50000200: + return PUS_PACKET_DISTRIBUTOR_STRING; + case 0x50000300: + return UDP_TMTC_BRIDGE_STRING; + case 0x50000400: + return EMAC_POLLING_TASK_STRING; + case 0x50000600: + return SERIAL_POLLING_TASK_STRING; + case 0x5000500: + return UART_TMTC_BRIDGE_STRING; + case 0x51000100: + return PUS_SERVICE_1_STRING; + case 0x51000200: + return PUS_SERVICE_2_STRING; + case 0x51000300: + return PUS_SERVICE_3_STRING; + case 0x51000400: + return PUS_SERVICE_5_STRING; + case 0x51000500: + return PUS_SERVICE_6_STRING; + case 0x51000800: + return PUS_SERVICE_8_STRING; + case 0x51000900: + return PUS_SERVICE_9_STRING; + case 0x51001700: + return PUS_SERVICE_17_STRING; + case 0x51002300: + return PUS_SERVICE_23_STRING; + case 0x51020000: + return PUS_SERVICE_200_STRING; + case 0x51020100: + return PUS_SERVICE_201_STRING; + case 0x52000001: + return PUS_TIME_STRING; + case 0x52000002: + return PUS_FUNNEL_STRING; + case 0x53010000: + return HEALTH_TABLE_STRING; + case 0x53010100: + return MODE_STORE_STRING; + case 0x53030000: + return EVENT_MANAGER_STRING; + case 0x53040000: + return INTERNAL_ERROR_REPORTER_STRING; + case 0x534f0100: + return TC_STORE_STRING; + case 0x534f0200: + return TM_STORE_STRING; + case 0x534f0300: + return IPC_STORE_STRING; + case 0x66666666: + return AT91_SPI_TEST_TASK_STRING; + case 0x77777777: + return STM32_TEST_TASK_STRING; + case 0x87654321: + return AT91_UART0_TEST_TASK_STRING; + case 0xFFFFFFFF: + return NO_OBJECT_STRING; + default: + return "UNKNOWN_OBJECT"; + } + return 0; +} diff --git a/config/objects/translateObjects.h b/config/objects/translateObjects.h new file mode 100644 index 00000000..18c237eb --- /dev/null +++ b/config/objects/translateObjects.h @@ -0,0 +1,16 @@ +/* + * translateObjects.h + * + * Created on: 28 May 2019 + * Author: Robin + */ + +#ifndef CONFIG_OBJECTS_TRANSLATEOBJECTS_H_ +#define CONFIG_OBJECTS_TRANSLATEOBJECTS_H_ + +#include + +const char* translateObject(object_id_t object); + + +#endif /* CONFIG_OBJECTS_TRANSLATEOBJECTS_H_ */ diff --git a/config/pollingsequence/PollingSequenceFactory.cpp b/config/pollingsequence/PollingSequenceFactory.cpp new file mode 100644 index 00000000..dbe13add --- /dev/null +++ b/config/pollingsequence/PollingSequenceFactory.cpp @@ -0,0 +1,31 @@ +#include +#include + +#include +#include +#include +#include + +ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) +{ + /* Length of a communication cycle */ + uint32_t length = thisSequence->getPeriodMs(); + + thisSequence->addSlot(objects::DUMMY_HANDLER, + length * 0, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::DUMMY_HANDLER, + length * 0.25, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::DUMMY_HANDLER, + length * 0.5, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::DUMMY_HANDLER, + length * 0.75, DeviceHandlerIF::GET_READ); + + if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) { + return HasReturnvaluesIF::RETURN_OK; + } + else { + sif::error << "PollingSequence::initialize has errors!" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } +} + diff --git a/config/pollingsequence/PollingSequenceFactory.h b/config/pollingsequence/PollingSequenceFactory.h new file mode 100644 index 00000000..b6cc2f1e --- /dev/null +++ b/config/pollingsequence/PollingSequenceFactory.h @@ -0,0 +1,31 @@ +#ifndef POLLINGSEQUENCEFACTORY_H_ +#define POLLINGSEQUENCEFACTORY_H_ +#include + +class FixedTimeslotTaskIF; + +/** + * All device handlers are scheduled by adding them into + * Polling Sequence Tables (PST) to satisfy stricter timing requirements of + * device communication, a device handler has four different communication steps: + * 1. DeviceHandlerIF::SEND_WRITE -> Send write via interface + * 2. DeviceHandlerIF::GET_WRITE -> Get confirmation for write + * 3. DeviceHandlerIF::SEND_READ -> Send read request + * 4. DeviceHandlerIF::GET_READ -> Read from interface + * The PST specifies precisely when the respective ComIF functions are called + * during the communication cycle time. + * The task is created using the FixedTimeslotTaskIF, + * which utilises the underlying Operating System Abstraction Layer (OSAL) + * + * @param thisSequence FixedTimeslotTaskIF * object is passed inside the + * Factory class when creating the PST + * @return + */ +namespace pst { + +/* 0.4 second period init*/ +ReturnValue_t pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence); + +} + +#endif /* POLLINGSEQUENCEINIT_H_ */ diff --git a/config/returnvalues/classIds.h b/config/returnvalues/classIds.h new file mode 100644 index 00000000..a024e3d7 --- /dev/null +++ b/config/returnvalues/classIds.h @@ -0,0 +1,28 @@ +/* + * classIds.h + * + * Created on: 16.07.2018 + * Author: mohr + */ + +#ifndef CONFIG_RETURNVALUES_CLASSIDS_H_ +#define CONFIG_RETURNVALUES_CLASSIDS_H_ + +/** + * Source IDs starts at 73 for now + * Framework IDs for ReturnValues run from 0 to 56 + * and are located inside + */ +namespace CLASS_ID { +enum { + MISSION_CLASS_ID_START = FW_CLASS_ID_COUNT, + RS232_CHANNEL, //!< RS232 + I2C_CHANNEL, //!< I2C + SPI_CHANNEL, //!< SPI + GPS_HANDLER, //!< GPS + PUS_SERVICE_3 //!< HKS +}; +} + + +#endif /* CONFIG_RETURNVALUES_CLASSIDS_H_ */ diff --git a/config/tmtc/apid.h b/config/tmtc/apid.h new file mode 100644 index 00000000..64d3763c --- /dev/null +++ b/config/tmtc/apid.h @@ -0,0 +1,19 @@ +#ifndef CONFIG_TMTC_APID_H_ +#define CONFIG_TMTC_APID_H_ + +#include + +/** + * Application Process Definition: entity, uniquely identified by an + * application process ID (APID), capable of generating telemetry source + * packets and receiving telecommand packets + * + * SOURCE APID: 0x73 / 115 / s + * APID is a 11 bit number + */ +namespace apid { + static const uint16_t EIVE_OBSW = 0x65; +} + + +#endif /* CONFIG_TMTC_APID_H_ */ diff --git a/config/tmtc/pusIds.h b/config/tmtc/pusIds.h new file mode 100644 index 00000000..a2dd7575 --- /dev/null +++ b/config/tmtc/pusIds.h @@ -0,0 +1,23 @@ +#ifndef CONFIG_TMTC_PUSIDS_HPP_ +#define CONFIG_TMTC_PUSIDS_HPP_ + +namespace pus { +enum Ids{ + PUS_SERVICE_1 = 1, + PUS_SERVICE_2 = 2, + PUS_SERVICE_3 = 3, + PUS_SERVICE_3_PSB = 3, + PUS_SERVICE_5 = 5, + PUS_SERVICE_6 = 6, + PUS_SERVICE_8 = 8, + PUS_SERVICE_9 = 9, + PUS_SERVICE_17 = 17, + PUS_SERVICE_19 = 19, + PUS_SERVICE_20 = 20, + PUS_SERVICE_23 = 23, + PUS_SERVICE_200 = 200, + PUS_SERVICE_201 = 201, +}; +}; + +#endif /* CONFIG_TMTC_PUSIDS_HPP_ */ diff --git a/config/tmtc/subsystemIdRanges.h b/config/tmtc/subsystemIdRanges.h new file mode 100644 index 00000000..10d34250 --- /dev/null +++ b/config/tmtc/subsystemIdRanges.h @@ -0,0 +1,36 @@ +#ifndef CONFIG_TMTC_SUBSYSTEMIDRANGES_H_ +#define CONFIG_TMTC_SUBSYSTEMIDRANGES_H_ + +#include +#include + +/** + * These IDs are part of the ID for an event thrown by a subsystem. + * Numbers 0-80 are reserved for FSFW Subsystem IDs (framework/events/) + */ +namespace SUBSYSTEM_ID { +enum: uint8_t { + SUBSYSTE_ID_START = FW_SUBSYSTEM_ID_RANGE, + /** + * 80-105: PUS Services + */ + PUS_SERVICE_2 = 82, + PUS_SERVICE_3 = 83, + PUS_SERVICE_5 = 85, + PUS_SERVICE_6 = 86, + PUS_SERVICE_8 = 88, + PUS_SERVICE_9 = 89, + PUS_SERVICE_17 = 82, + PUS_SERVICE_23 = 91, + DUMMY_DEVICE = 90, + /** + * 105-115: AOCS + */ + GPS_DEVICE = 105, + + SPI_COM_IF = 128, + I2C_COM_IF = 138 +}; +} + +#endif /* CONFIG_TMTC_SUBSYSTEMIDRANGES_H_ */ diff --git a/config/tmtc/tmTcSize.h b/config/tmtc/tmTcSize.h new file mode 100644 index 00000000..de7f4adc --- /dev/null +++ b/config/tmtc/tmTcSize.h @@ -0,0 +1,10 @@ +#ifndef CONFIG_TMTC_TMTCSIZE_H_ +#define CONFIG_TMTC_TMTCSIZE_H_ + +#include + +namespace tmtcsize { +static const uint32_t MAX_TM_PACKET = 50; +} + +#endif /* CONFIG_TMTC_TMTCSIZE_H_ */ diff --git a/config/version.h b/config/version.h new file mode 100644 index 00000000..386cbc09 --- /dev/null +++ b/config/version.h @@ -0,0 +1,9 @@ +#ifndef CONFIG_VERSION_H_ +#define CONFIG_VERSION_H_ + +#define SW_VERSION 0 +#define SW_SUBVERSION 1 + + + +#endif /* CONFIG_VERSION_H_ */ diff --git a/fsfw b/fsfw index 42bfedd3..62508132 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 42bfedd36c517d00d0be6321d1d828f429813ef1 +Subproject commit 62508132c0c248d6851fd88207828c7f12c38e50 diff --git a/mission/mission.mk b/mission/mission.mk index e69de29b..c3399b0f 100644 --- a/mission/mission.mk +++ b/mission/mission.mk @@ -0,0 +1,2 @@ +CXXSRC += $(wildcard $(CURRENTPATH)/utility/*.cpp) +CSRC += $(wildcard $(CURRENTPATH)/utility/*.c) \ No newline at end of file diff --git a/mission/utility/TimeStamper.cpp b/mission/utility/TimeStamper.cpp new file mode 100644 index 00000000..c0cccbd6 --- /dev/null +++ b/mission/utility/TimeStamper.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +TimeStamper::TimeStamper(object_id_t objectId): SystemObject(objectId) {} + + +ReturnValue_t TimeStamper::addTimeStamp(uint8_t* buffer, + const uint8_t maxSize) { + if(maxSize < TimeStamperIF::MISSION_TIMESTAMP_SIZE) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + timeval now; + Clock::getClock_timeval(&now); + CCSDSTime::CDS_short cds; + ReturnValue_t result = CCSDSTime::convertToCcsds(&cds,&now); + if(result != HasReturnvaluesIF::RETURN_OK){ + return result; + } + std::memcpy(buffer,&cds,sizeof(cds)); + return result; +} diff --git a/mission/utility/TimeStamper.h b/mission/utility/TimeStamper.h new file mode 100644 index 00000000..d2122546 --- /dev/null +++ b/mission/utility/TimeStamper.h @@ -0,0 +1,18 @@ +#ifndef MISSION_UTILITY_TIMESTAMPER_H_ +#define MISSION_UTILITY_TIMESTAMPER_H_ + +#include +#include +#include + +/** + * @brief + * @ingroup utility + */ +class TimeStamper: public TimeStamperIF, public SystemObject { +public: + TimeStamper(object_id_t objectId); + virtual ReturnValue_t addTimeStamp(uint8_t* buffer, const uint8_t maxSize); +}; + +#endif /* MISSION_UTILITY_TIMESTAMPER_H_ */ diff --git a/mission/utility/TmFunnel.cpp b/mission/utility/TmFunnel.cpp new file mode 100644 index 00000000..16753b36 --- /dev/null +++ b/mission/utility/TmFunnel.cpp @@ -0,0 +1,112 @@ +#include + +#include +#include +#include +#include + +object_id_t TmFunnel::downlinkDestination = objects::NO_OBJECT; +object_id_t TmFunnel::storageDestination = objects::NO_OBJECT; + +TmFunnel::TmFunnel(object_id_t objectId_): SystemObject(objectId_), + sourceSequenceCount(0), storageTargetSet(false) { + tmQueue = QueueFactory::instance()->createMessageQueue(messageDepth, + MessageQueueMessage::MAX_MESSAGE_SIZE); + storageQueue = QueueFactory::instance()->createMessageQueue(messageDepth, + MessageQueueMessage::MAX_MESSAGE_SIZE); +} + +TmFunnel::~TmFunnel() { +} + +MessageQueueId_t TmFunnel::getReportReceptionQueue(uint8_t virtualChannel) { + return tmQueue->getId(); +} + +ReturnValue_t TmFunnel::performOperation(uint8_t operationCode) { + TmTcMessage currentMessage; + ReturnValue_t status = tmQueue->receiveMessage(¤tMessage); + while(status == HasReturnvaluesIF::RETURN_OK) + { + status = handlePacket(¤tMessage); + if(status != HasReturnvaluesIF::RETURN_OK){ + break; + } + status = tmQueue->receiveMessage(¤tMessage); + } + + if (status == MessageQueueIF::EMPTY) { + return HasReturnvaluesIF::RETURN_OK; + } + else { + return status; + } +} + +ReturnValue_t TmFunnel::handlePacket(TmTcMessage* message) { + uint8_t* packetData = nullptr; + size_t size = 0; + ReturnValue_t result = tmPool->modifyData(message->getStorageId(), + &packetData, &size); + if(result != HasReturnvaluesIF::RETURN_OK){ + return result; + } + TmPacketBase packet(packetData); + packet.setPacketSequenceCount(this->sourceSequenceCount); + sourceSequenceCount++; + sourceSequenceCount = sourceSequenceCount % + SpacePacketBase::LIMIT_SEQUENCE_COUNT; + packet.setErrorControl(); + + result = tmQueue->sendToDefault(message); + if(result != HasReturnvaluesIF::RETURN_OK){ + tmPool->deleteData(message->getStorageId()); + sif::error << "TmFunnel::handlePacket: Error sending to downlink " + "handler" << std::endl; + return result; + } + + if(storageTargetSet) { + result = storageQueue->sendToDefault(message); + if(result != HasReturnvaluesIF::RETURN_OK){ + tmPool->deleteData(message->getStorageId()); + sif::error << "TmFunnel::handlePacket: Error sending to storage " + "handler" << std::endl; + return result; + } + } + return result; +} + +ReturnValue_t TmFunnel::initialize() { + + tmPool = objectManager->get(objects::TM_STORE); + if(tmPool == nullptr) { + sif::error << "TmFunnel::initialize: TM store not set." + << std::endl; + sif::error << "Make sure the tm store is set up properly" + " and implements StorageManagerIF" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + AcceptsTelemetryIF* tmTarget = + objectManager->get(downlinkDestination); + if(tmTarget == nullptr){ + sif::error << "TmFunnel::initialize: Downlink Destination not set." + << std::endl; + sif::error << "Make sure the downlink destination object is set up " + "properly and implements AcceptsTelemetryIF" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + tmQueue->setDefaultDestination(tmTarget->getReportReceptionQueue()); + + AcceptsTelemetryIF* storageTarget = + objectManager->get(storageDestination); + if(storageTarget != nullptr) { + storageTargetSet = true; + storageQueue->setDefaultDestination( + storageTarget->getReportReceptionQueue()); + } + + return SystemObject::initialize(); +} diff --git a/mission/utility/TmFunnel.h b/mission/utility/TmFunnel.h new file mode 100644 index 00000000..0490b194 --- /dev/null +++ b/mission/utility/TmFunnel.h @@ -0,0 +1,52 @@ +#ifndef MISSION_UTILITY_TMFUNNEL_H_ +#define MISSION_UTILITY_TMFUNNEL_H_ + +#include +#include +#include +#include +#include + +namespace Factory{ +void setStaticFrameworkObjectIds(); +} + +/** + * @brief TM Recipient. + * @details + * Main telemetry receiver. All generated telemetry is funneled into + * this object. + * @ingroup utility + * @author J. Meier + */ +class TmFunnel: public AcceptsTelemetryIF, + public ExecutableObjectIF, + public SystemObject { + friend void (Factory::setStaticFrameworkObjectIds)(); +public: + TmFunnel(object_id_t objectId); + virtual ~TmFunnel(); + + virtual MessageQueueId_t getReportReceptionQueue( + uint8_t virtualChannel = 0) override; + virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override; + virtual ReturnValue_t initialize() override; + +protected: + static object_id_t downlinkDestination; + static object_id_t storageDestination; + +private: + + uint16_t sourceSequenceCount; + bool storageTargetSet; + MessageQueueIF* tmQueue = nullptr; + MessageQueueIF* storageQueue = nullptr; + + StorageManagerIF* tmPool = nullptr; + uint32_t messageDepth = 10; + + ReturnValue_t handlePacket(TmTcMessage* message); +}; + +#endif /* MISSION_UTILITY_TMFUNNEL_H_ */ diff --git a/test/test.mk b/test/test.mk index e69de29b..701ec2d1 100644 --- a/test/test.mk +++ b/test/test.mk @@ -0,0 +1,3 @@ +CXXSRC += $(wildcard $(CURRENTPATH)/testdevices/*.cpp) +CXXSRC += $(wildcard $(CURRENTPATH)/testinterfaces/*.cpp) +CXXSRC += $(wildcard $(CURRENTPATH)/testtasks/*.cpp) \ No newline at end of file diff --git a/test/testtasks/MutextestTask.cpp b/test/testtasks/MutextestTask.cpp new file mode 100644 index 00000000..325d0029 --- /dev/null +++ b/test/testtasks/MutextestTask.cpp @@ -0,0 +1,41 @@ +/* + * MutextestTask.cpp + * + * Created on: 19.07.2018 + * Author: mohr + */ + +#include + +#include + +MutexIF * MutextestTask::mutex = nullptr; + +MutextestTask::MutextestTask(const char *name, object_id_t setObjectId) : + SystemObject(setObjectId), name(name), locked(false) { + if (mutex == NULL) { + mutex = MutexFactory::instance()->createMutex(); + } +} + +ReturnValue_t MutextestTask::performOperation(uint8_t operationCode) { + if (!locked){ + sif::info << name << ": locking..." << std::endl; + ReturnValue_t result = mutex->lockMutex(MutexIF::BLOCKING); + sif::info << name << ": locked with " << (int) result << std::endl; + if (result == HasReturnvaluesIF::RETURN_OK){ + locked = true; + } + } else { + sif::info << name << ": releasing" << std::endl; + mutex->unlockMutex(); + locked = false; + } + + return HasReturnvaluesIF::RETURN_OK; +} + +MutextestTask::~MutextestTask() { +// TODO Auto-generated destructor stub +} + diff --git a/test/testtasks/MutextestTask.h b/test/testtasks/MutextestTask.h new file mode 100644 index 00000000..14b81028 --- /dev/null +++ b/test/testtasks/MutextestTask.h @@ -0,0 +1,32 @@ +/* + * MutextestTask.h + * + * Created on: 19.07.2018 + * Author: mohr + */ + +#ifndef MISSION_MUTEXTESTTASK_H_ +#define MISSION_MUTEXTESTTASK_H_ + +#include +#include +#include + +/** + * Start two of them with a little time difference and different periods to see mutex in action + */ + +class MutextestTask: public SystemObject, public ExecutableObjectIF { +public: + + virtual ReturnValue_t performOperation(uint8_t operationCode = 0); + + MutextestTask(const char *name, object_id_t setObjectId); + virtual ~MutextestTask(); +private: + static MutexIF *mutex; + const char * name; + bool locked; +}; + +#endif /* MISSION_MUTEXTESTTASK_H_ */ diff --git a/test/testtasks/PusTcInjector.cpp b/test/testtasks/PusTcInjector.cpp new file mode 100644 index 00000000..b7884cfd --- /dev/null +++ b/test/testtasks/PusTcInjector.cpp @@ -0,0 +1,67 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +PusTcInjector::PusTcInjector(object_id_t objectId, object_id_t destination, + object_id_t tcStore, uint16_t defaultApid): SystemObject(objectId), + defaultApid(defaultApid), destination(destination), tcStoreId(tcStore) { +} + +PusTcInjector::~PusTcInjector() { +} + +//ReturnValue_t PusTcInjector::injectPusTelecommand(uint8_t service, +// uint8_t subservice,const uint8_t* appData, size_t appDataLen) { +// return injectPusTelecommand(service, subservice, defaultApid, appData, +// appDataLen); +//} + +// TODO: ACK flags +//ReturnValue_t PusTcInjector::injectPusTelecommand(uint8_t service, +// uint8_t subservice,uint16_t apid, const uint8_t* appData, +// size_t appDataLen) { +// // Prepare TC packet. Store into TC store immediately. +// TcPacketStored tcPacket(service, subservice, apid, sequenceCount++); +// +// const uint8_t* packetPtr = nullptr; +// size_t packetSize = 0; +// tcPacket.getData(&packetPtr, &packetSize); +// //arrayprinter::print(packetPtr, packetSize, OutputType::BIN); +// +// // Send TC packet. +// TmTcMessage tcMessage(tcPacket.getStoreAddress()); +// ReturnValue_t result = injectionQueue->sendToDefault(&tcMessage); +// if(result != HasReturnvaluesIF::RETURN_OK) { +// sif::warning << "PusTcInjector: Sending TMTC message failed!" << std::endl; +// } +// return result; +//} + +ReturnValue_t PusTcInjector::initialize() { + // Prepare message queue which is used to send telecommands. + injectionQueue = QueueFactory::instance()-> + createMessageQueue(INJECTION_QUEUE_DEPTH); + AcceptsTelecommandsIF* targetQueue = objectManager-> + get(destination); + if(targetQueue == nullptr) { + sif::error << "PusTcInjector: CCSDS distributor not initialized yet!" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + else { + injectionQueue->setDefaultDestination(targetQueue->getRequestQueue()); + } + + // Prepare store used to store TC messages + tcStore = objectManager->get(tcStoreId); + if(tcStore == nullptr) { + sif::error << "PusTcInjector: TC Store not initialized!" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/test/testtasks/PusTcInjector.h b/test/testtasks/PusTcInjector.h new file mode 100644 index 00000000..df67e403 --- /dev/null +++ b/test/testtasks/PusTcInjector.h @@ -0,0 +1,72 @@ +#ifndef TEST_TESTTASKS_PUSTCINJECTOR_H_ +#define TEST_TESTTASKS_PUSTCINJECTOR_H_ +#include +#include +#include +#include + +class PusTcInjector: public SystemObject { +public: + static constexpr uint8_t INJECTION_QUEUE_DEPTH = 10; + const uint16_t defaultApid; + + /** + * Initialize a software telecommand injector by supplying object IDs to + * various helper objects which must exist before calling initialiez() + * @param objectId ID of PUS telecommand injector + * @param destination ID of destination, which has to implement + * AcceptsTelecommandIF. + * @param tcStore ID of telecommand store, which has to implement + * StorageManagerIF. + * @param defaultApid Default APID which will be used if an injection + * without an APID is requested. + */ + PusTcInjector(object_id_t objectId, object_id_t destination, + object_id_t tcStore, uint16_t defaultApid); + /** + * This has to be called before using the PusTcInjector. + * Call Not necessary when using a factory and the object manager. + * @return -@c RETURN_OK for successfull init + * -@c ObjectManagerIF::CHILD_INIT_FAILED otherwise + */ + ReturnValue_t initialize() override; + + virtual~ PusTcInjector(); + + /** + * Can be used to inject a telecommand by supplying service, subservice + * and optional application data and its length. + * Default APID will be used. + * @param service PUS service type + * @param subservice PUS subservice type + * @param appData Pointer to application data + * @param appDataLen Length of application data + * @return + */ + //ReturnValue_t injectPusTelecommand(uint8_t service, uint8_t subservice, + // const uint8_t* appData = nullptr, size_t appDataLen = 0); + + /** + * Provides the same functionality while also setting a user defined APID. + * @param service PUS service type + * @param subservice PUS subservice type + * @param apid Custom APID to, + * @param appData Pointer to application data + * @param appDataLen Length of application data + * @return + */ + //ReturnValue_t injectPusTelecommand(uint8_t service, uint8_t subservice, + // uint16_t apid, const uint8_t* appData = nullptr, + // size_t appDataLen = 0); +private: + MessageQueueIF* injectionQueue = nullptr; + StorageManagerIF *tcStore = nullptr; + + /* Cached for initialize function */ + object_id_t destination = 0; + object_id_t tcStoreId = 0; + + uint16_t sequenceCount = 0; +}; + +#endif /* TEST_TESTTASKS_PUSTCINJECTOR_H_ */ diff --git a/test/testtasks/TestTask.cpp b/test/testtasks/TestTask.cpp new file mode 100644 index 00000000..a9d6626b --- /dev/null +++ b/test/testtasks/TestTask.cpp @@ -0,0 +1,74 @@ +#include "logicalAddresses.h" +#include "apid.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +bool TestTask::oneShotAction = true; +MutexIF* TestTask::testLock = nullptr; + +TestTask::TestTask(object_id_t objectId_): + SystemObject(objectId_), testMode(testModes::A) { + if(testLock == nullptr) { + testLock = MutexFactory::instance()->createMutex(); + } + IPCStore = objectManager->get(objects::IPC_STORE); +} + +TestTask::~TestTask() { +} + +ReturnValue_t TestTask::performOperation(uint8_t operationCode) { + ReturnValue_t result = RETURN_OK; + testLock ->lockMutex(MutexIF::TimeoutType::WAITING, 20); + if(oneShotAction) { + // Add code here which should only be run once + performOneShotAction(); + oneShotAction = false; + } + testLock->unlockMutex(); + + // Add code here which should only be run once per performOperation + performPeriodicAction(); + + // Add code here which should only be run on alternating cycles. + if(testMode == testModes::A) { + performActionA(); + testMode = testModes::B; + } + else if(testMode == testModes::B) { + performActionB(); + testMode = testModes::A; + } + return result; +} + +ReturnValue_t TestTask::performOneShotAction() { + // Everything here will only be performed once. + return HasReturnvaluesIF::RETURN_OK; +} + + +ReturnValue_t TestTask::performPeriodicAction() { + ReturnValue_t result = RETURN_OK; + return result; +} + +ReturnValue_t TestTask::performActionA() { + ReturnValue_t result = RETURN_OK; + // Add periodically executed code here + return result; +} + +ReturnValue_t TestTask::performActionB() { + ReturnValue_t result = RETURN_OK; + // Add periodically executed code here + return result; +} diff --git a/test/testtasks/TestTask.h b/test/testtasks/TestTask.h new file mode 100644 index 00000000..24e62af1 --- /dev/null +++ b/test/testtasks/TestTask.h @@ -0,0 +1,57 @@ +#ifndef TEST_TESTTASK_H_ +#define TEST_TESTTASK_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include + + +/** + * @brief Test class for general C++ testing. + * @details + * Should not be used for board specific + * tests. Instead, a derived board test class should be used. + */ +class TestTask : public SystemObject, + public ExecutableObjectIF, + public HasReturnvaluesIF { +public: + TestTask(object_id_t objectId); + virtual ~TestTask(); + virtual ReturnValue_t performOperation(uint8_t operationCode = 0); + +protected: + virtual ReturnValue_t performOneShotAction(); + virtual ReturnValue_t performPeriodicAction(); + virtual ReturnValue_t performActionA(); + virtual ReturnValue_t performActionB(); + + enum testModes: uint8_t { + A, + B + }; + + testModes testMode; + + bool testFlag = false; + uint8_t counter { 1 }; + uint8_t counterTrigger { 3 }; + + void performPusInjectorTest(); + void examplePacketTest(); +private: + // Actually, to be really thread-safe, a mutex should be used as well + // Let's keep it simple for now. + static bool oneShotAction; + static MutexIF* testLock; + StorageManagerIF* IPCStore; +}; + + +#endif /* TESTTASK_H_ */ diff --git a/unittest/unittest.mk b/unittest/unittest.mk new file mode 100644 index 00000000..e69de29b