From 191d5f126820d06389cb071bef7de7850e287cac Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Nov 2022 10:20:14 +0100 Subject: [PATCH 01/14] refactored TM funnels to allow multiple TM recipients --- bsp_q7s/core/ObjectFactory.cpp | 28 +++--- bsp_q7s/core/ObjectFactory.h | 5 +- bsp_q7s/em/emObjectFactory.cpp | 10 ++- bsp_q7s/fmObjectFactory.cpp | 10 ++- linux/CMakeLists.txt | 2 +- linux/ObjectFactory.cpp | 7 ++ linux/ObjectFactory.h | 6 ++ .../startracker/StarTrackerHandler.cpp | 24 +++--- linux/{obc => ipcore}/AxiPtmeConfig.cpp | 0 linux/{obc => ipcore}/AxiPtmeConfig.h | 0 linux/{obc => ipcore}/CMakeLists.txt | 0 linux/{obc => ipcore}/PapbVcInterface.cpp | 2 +- linux/{obc => ipcore}/PapbVcInterface.h | 2 +- linux/{obc => ipcore}/PdecConfig.cpp | 0 linux/{obc => ipcore}/PdecConfig.h | 0 linux/{obc => ipcore}/PdecHandler.cpp | 0 linux/{obc => ipcore}/PdecHandler.h | 0 linux/{obc => ipcore}/Ptme.cpp | 2 +- linux/{obc => ipcore}/Ptme.h | 4 +- linux/{obc => ipcore}/PtmeConfig.cpp | 0 linux/{obc => ipcore}/PtmeConfig.h | 2 +- linux/{obc => ipcore}/PtmeIF.h | 0 linux/{obc => ipcore}/VcInterfaceIF.h | 0 mission/core/GenericFactory.cpp | 27 +++--- mission/core/GenericFactory.h | 5 +- mission/devices/BpxBatteryHandler.cpp | 2 +- mission/devices/GomspaceDeviceHandler.cpp | 2 +- mission/devices/Max31865EiveHandler.cpp | 8 +- mission/devices/Max31865PT1000Handler.cpp | 4 +- mission/devices/PayloadPcduHandler.cpp | 29 ++++--- mission/devices/SusHandler.cpp | 2 +- mission/devices/SyrlinksHkHandler.cpp | 2 +- mission/devices/Tmp1075Handler.cpp | 2 +- mission/tmtc/CMakeLists.txt | 5 +- ...CSDSHandler.cpp => CcsdsIpCoreHandler.cpp} | 86 ++++++++++--------- .../{CCSDSHandler.h => CcsdsIpCoreHandler.h} | 22 ++--- mission/tmtc/CfdpTmFunnel.cpp | 37 ++++---- mission/tmtc/CfdpTmFunnel.h | 14 ++- mission/tmtc/PusTmFunnel.cpp | 36 ++++---- mission/tmtc/PusTmFunnel.h | 14 +-- mission/tmtc/TmFunnel.cpp | 16 ---- mission/tmtc/TmFunnelBase.cpp | 19 ++++ mission/tmtc/TmFunnelBase.h | 24 ++++++ mission/tmtc/TmFunnelHandler.cpp | 17 ++++ .../tmtc/{TmFunnel.h => TmFunnelHandler.h} | 6 +- mission/tmtc/VirtualChannel.cpp | 2 +- mission/tmtc/VirtualChannel.h | 2 +- 47 files changed, 287 insertions(+), 200 deletions(-) rename linux/{obc => ipcore}/AxiPtmeConfig.cpp (100%) rename linux/{obc => ipcore}/AxiPtmeConfig.h (100%) rename linux/{obc => ipcore}/CMakeLists.txt (100%) rename linux/{obc => ipcore}/PapbVcInterface.cpp (98%) rename linux/{obc => ipcore}/PapbVcInterface.h (98%) rename linux/{obc => ipcore}/PdecConfig.cpp (100%) rename linux/{obc => ipcore}/PdecConfig.h (100%) rename linux/{obc => ipcore}/PdecHandler.cpp (100%) rename linux/{obc => ipcore}/PdecHandler.h (100%) rename linux/{obc => ipcore}/Ptme.cpp (98%) rename linux/{obc => ipcore}/Ptme.h (96%) rename linux/{obc => ipcore}/PtmeConfig.cpp (100%) rename linux/{obc => ipcore}/PtmeConfig.h (98%) rename linux/{obc => ipcore}/PtmeIF.h (100%) rename linux/{obc => ipcore}/VcInterfaceIF.h (100%) rename mission/tmtc/{CCSDSHandler.cpp => CcsdsIpCoreHandler.cpp} (73%) rename mission/tmtc/{CCSDSHandler.h => CcsdsIpCoreHandler.h} (90%) delete mode 100644 mission/tmtc/TmFunnel.cpp create mode 100644 mission/tmtc/TmFunnelBase.cpp create mode 100644 mission/tmtc/TmFunnelBase.h create mode 100644 mission/tmtc/TmFunnelHandler.cpp rename mission/tmtc/{TmFunnel.h => TmFunnelHandler.h} (80%) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index fdc263de..949fb1db 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -31,11 +31,11 @@ #include "linux/devices/ploc/PlocSupervisorHandler.h" #include "linux/devices/startracker/StarTrackerHandler.h" #include "linux/devices/startracker/StrHelper.h" -#include "linux/obc/AxiPtmeConfig.h" -#include "linux/obc/PapbVcInterface.h" -#include "linux/obc/PdecHandler.h" -#include "linux/obc/Ptme.h" -#include "linux/obc/PtmeConfig.h" +#include "linux/ipcore/AxiPtmeConfig.h" +#include "linux/ipcore/PapbVcInterface.h" +#include "linux/ipcore/PdecHandler.h" +#include "linux/ipcore/Ptme.h" +#include "linux/ipcore/PtmeConfig.h" #include "mission/csp/CspCookie.h" #include "mission/system/RwAssembly.h" #include "mission/system/fdir/AcsBoardFdir.h" @@ -90,8 +90,8 @@ #include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" #include "mission/devices/devicedefinitions/payloadPcduDefinitions.h" #include "mission/system/AcsBoardAssembly.h" -#include "mission/tmtc/CCSDSHandler.h" -#include "mission/tmtc/TmFunnel.h" +#include "mission/tmtc/CcsdsIpCoreHandler.h" +#include "mission/tmtc/TmFunnelHandler.h" #include "mission/tmtc/VirtualChannel.h" ResetArgs RESET_ARGS_GNSS; @@ -690,7 +690,8 @@ void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, #endif /* OBSW_ADD_RW == 1 */ } -ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) { +ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF, + CcsdsIpCoreHandler** ipCoreHandler) { using namespace gpio; // GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core GpioCookie* gpioCookiePtmeIp = new GpioCookie; @@ -753,18 +754,19 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) { #else static const uint32_t TRANSMITTER_TIMEOUT = 900000; // 15 minutes #endif - CCSDSHandler* ccsdsHandler = new CCSDSHandler( + *ipCoreHandler = new CcsdsIpCoreHandler( objects::CCSDS_HANDLER, objects::PTME, objects::CCSDS_PACKET_DISTRIBUTOR, ptmeConfig, gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA, TRANSMITTER_TIMEOUT); VirtualChannel* vc = nullptr; vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE, objects::CCSDS_HANDLER); - ccsdsHandler->addVirtualChannel(ccsds::VC0, vc); + (*ipCoreHandler)->addVirtualChannel(ccsds::VC0, vc); vc = new VirtualChannel(ccsds::VC1, common::VC1_QUEUE_SIZE, objects::CCSDS_HANDLER); - ccsdsHandler->addVirtualChannel(ccsds::VC1, vc); + (*ipCoreHandler)->addVirtualChannel(ccsds::VC1, vc); vc = new VirtualChannel(ccsds::VC2, common::VC2_QUEUE_SIZE, objects::CCSDS_HANDLER); - ccsdsHandler->addVirtualChannel(ccsds::VC2, vc); + (*ipCoreHandler)->addVirtualChannel(ccsds::VC2, vc); vc = new VirtualChannel(ccsds::VC3, common::VC3_QUEUE_SIZE, objects::CCSDS_HANDLER); - ccsdsHandler->addVirtualChannel(ccsds::VC3, vc); + (*ipCoreHandler)->addVirtualChannel(ccsds::VC3, vc); + GpioCookie* gpioCookiePdec = new GpioCookie; consumer.str(""); consumer << "0x" << std::hex << objects::PDEC_HANDLER; diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index 2947d786..3737db92 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -2,6 +2,9 @@ #define BSP_Q7S_OBJECTFACTORY_H_ #include +#include +#include +#include #include @@ -37,7 +40,7 @@ void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, GpioIF& gp void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher); void createPayloadComponents(LinuxLibgpioIF* gpioComIF); void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher); -ReturnValue_t createCcsdsComponents(LinuxLibgpioIF* gpioComIF); +ReturnValue_t createCcsdsComponents(LinuxLibgpioIF* gpioComIF, CcsdsIpCoreHandler** ipCoreHandler); void createMiscComponents(); void createTestComponents(LinuxLibgpioIF* gpioComIF); diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 13ae55d6..ff3b57bb 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -17,7 +17,9 @@ void ObjectFactory::produce(void* args) { ObjectFactory::setStatics(); HealthTableIF* healthTable = nullptr; - ObjectFactory::produceGenericObjects(&healthTable); + PusTmFunnel* pusFunnel = nullptr; + CfdpTmFunnel* cfdpFunnel = nullptr; + ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel); LinuxLibgpioIF* gpioComIF = nullptr; UartComIF* uartComIF = nullptr; @@ -75,7 +77,11 @@ void ObjectFactory::produce(void* args) { createStrComponents(pwrSwitcher); #endif /* OBSW_ADD_STAR_TRACKER == 1 */ #if OBSW_ADD_CCSDS_IP_CORES == 1 - createCcsdsComponents(gpioComIF); + CcsdsIpCoreHandler* ipCoreHandler = nullptr; + createCcsdsComponents(gpioComIF, &ipCoreHandler); +#if OBSW_TM_TO_PTME == 1 + ObjectFactory::addTmtcIpCoresToFunnels(*ipCoreHandler, *pusFunnel, *cfdpFunnel); +#endif #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ /* Test Task */ #if OBSW_ADD_TEST_CODE == 1 diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index 57023c3c..b38d1274 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -15,7 +15,9 @@ void ObjectFactory::produce(void* args) { ObjectFactory::setStatics(); HealthTableIF* healthTable = nullptr; - ObjectFactory::produceGenericObjects(&healthTable); + PusTmFunnel* pusFunnel = nullptr; + CfdpTmFunnel* cfdpFunnel = nullptr; + ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel); LinuxLibgpioIF* gpioComIF = nullptr; UartComIF* uartComIF = nullptr; @@ -61,7 +63,11 @@ void ObjectFactory::produce(void* args) { createStrComponents(pwrSwitcher); #endif /* OBSW_ADD_STAR_TRACKER == 1 */ #if OBSW_ADD_CCSDS_IP_CORES == 1 - createCcsdsComponents(gpioComIF); + CcsdsIpCoreHandler* ipCoreHandler = nullptr; + createCcsdsComponents(gpioComIF, &ipCoreHandler); +#if OBSW_TM_TO_PTME == 1 + ObjectFactory::addTmtcIpCoresToFunnels(*ipCoreHandler, *pusFunnel, *cfdpFunnel); +#endif #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ #if OBSW_ADD_SCEX_DEVICE == 1 diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 861dfb5c..d7e6ca93 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -4,6 +4,6 @@ add_subdirectory(callbacks) add_subdirectory(boardtest) add_subdirectory(devices) add_subdirectory(fsfwconfig) -add_subdirectory(obc) +add_subdirectory(ipcore) target_sources(${OBSW_NAME} PUBLIC ObjectFactory.cpp InitMission.cpp) diff --git a/linux/ObjectFactory.cpp b/linux/ObjectFactory.cpp index ff7060fb..a573d345 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -24,6 +24,7 @@ #include "devConf.h" #include "devices/addresses.h" #include "devices/gpioIds.h" +#include "eive/definitions.h" void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, PowerSwitchIF* pwrSwitcher, std::string spiDev) { @@ -350,3 +351,9 @@ void ObjectFactory::gpioChecker(ReturnValue_t result, std::string output) { sif::error << "ObjectFactory: Adding GPIOs failed for " << output << std::endl; } } + +void ObjectFactory::addTmtcIpCoresToFunnels(CcsdsIpCoreHandler& ipCoreHandler, + PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel) { + cfdpFunnel.addDestination(ipCoreHandler, config::LIVE_TM); + pusFunnel.addDestination(ipCoreHandler, config::LIVE_TM); +} diff --git a/linux/ObjectFactory.h b/linux/ObjectFactory.h index f4ecc6e3..d0fd62e9 100644 --- a/linux/ObjectFactory.h +++ b/linux/ObjectFactory.h @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #include #include @@ -28,4 +31,7 @@ void gpioChecker(ReturnValue_t result, std::string output); void createThermalController(); void createAcsController(); +void addTmtcIpCoresToFunnels(CcsdsIpCoreHandler& ipCoreHandler, PusTmFunnel& pusFunnel, + CfdpTmFunnel& cfdpFunnel); + } // namespace ObjectFactory diff --git a/linux/devices/startracker/StarTrackerHandler.cpp b/linux/devices/startracker/StarTrackerHandler.cpp index a4cd432c..ff632c99 100644 --- a/linux/devices/startracker/StarTrackerHandler.cpp +++ b/linux/devices/startracker/StarTrackerHandler.cpp @@ -240,13 +240,12 @@ void StarTrackerHandler::doStartUp() { // the device handler's submode to the star tracker's mode return; case StartupState::DONE: - submode = SUBMODE_BOOTLOADER; startupState = StartupState::IDLE; break; default: return; } - setMode(_MODE_TO_ON); + setMode(_MODE_TO_ON, SUBMODE_BOOTLOADER); } void StarTrackerHandler::doShutDown() { @@ -654,7 +653,7 @@ void StarTrackerHandler::fillCommandAndReplyMap() { } ReturnValue_t StarTrackerHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) { - if (this->mode == MODE_NORMAL && mode == MODE_ON) { + if (getMode() == MODE_NORMAL && mode == MODE_ON) { return TRANS_NOT_ALLOWED; } switch (mode) { @@ -678,7 +677,7 @@ ReturnValue_t StarTrackerHandler::isModeCombinationValid(Mode_t mode, Submode_t } void StarTrackerHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { - switch (mode) { + switch (getMode()) { case _MODE_TO_ON: doOnTransition(subModeFrom); break; @@ -698,17 +697,18 @@ void StarTrackerHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { } void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) { - if (submode == SUBMODE_BOOTLOADER && subModeFrom == SUBMODE_FIRMWARE) { + uint8_t dhbSubmode = getSubmode(); + if (dhbSubmode == SUBMODE_BOOTLOADER && subModeFrom == SUBMODE_FIRMWARE) { bootBootloader(); - } else if (submode == SUBMODE_FIRMWARE && subModeFrom == SUBMODE_FIRMWARE) { + } else if (dhbSubmode == SUBMODE_FIRMWARE && subModeFrom == SUBMODE_FIRMWARE) { setMode(MODE_ON); - } else if (submode == SUBMODE_FIRMWARE && subModeFrom == SUBMODE_BOOTLOADER) { + } else if (dhbSubmode == SUBMODE_FIRMWARE && subModeFrom == SUBMODE_BOOTLOADER) { bootFirmware(MODE_ON); - } else if (submode == SUBMODE_BOOTLOADER && subModeFrom == SUBMODE_BOOTLOADER) { + } else if (dhbSubmode == SUBMODE_BOOTLOADER && subModeFrom == SUBMODE_BOOTLOADER) { setMode(MODE_ON); - } else if (submode == SUBMODE_BOOTLOADER && subModeFrom == SUBMODE_NONE) { + } else if (dhbSubmode == SUBMODE_BOOTLOADER && subModeFrom == SUBMODE_NONE) { setMode(MODE_ON); - } else if (submode == SUBMODE_FIRMWARE && subModeFrom == SUBMODE_NONE) { + } else if (dhbSubmode == SUBMODE_FIRMWARE && subModeFrom == SUBMODE_NONE) { setMode(MODE_ON); } } @@ -2067,13 +2067,13 @@ ReturnValue_t StarTrackerHandler::checkCommand(ActionId_t actionId) { case startracker::REQ_SUBSCRIPTION: case startracker::REQ_LOG_SUBSCRIPTION: case startracker::REQ_DEBUG_CAMERA: - if (not(mode == MODE_ON && submode == startracker::Program::FIRMWARE)) { + if (not(getMode() == MODE_ON && getSubmode() == startracker::Program::FIRMWARE)) { return STARTRACKER_RUNNING_BOOTLOADER; } break; case startracker::FIRMWARE_UPDATE: case startracker::FLASH_READ: - if (not(mode == MODE_ON && submode == startracker::Program::BOOTLOADER)) { + if (not(getMode() == MODE_ON && getSubmode() == startracker::Program::BOOTLOADER)) { return STARTRACKER_RUNNING_FIRMWARE; } break; diff --git a/linux/obc/AxiPtmeConfig.cpp b/linux/ipcore/AxiPtmeConfig.cpp similarity index 100% rename from linux/obc/AxiPtmeConfig.cpp rename to linux/ipcore/AxiPtmeConfig.cpp diff --git a/linux/obc/AxiPtmeConfig.h b/linux/ipcore/AxiPtmeConfig.h similarity index 100% rename from linux/obc/AxiPtmeConfig.h rename to linux/ipcore/AxiPtmeConfig.h diff --git a/linux/obc/CMakeLists.txt b/linux/ipcore/CMakeLists.txt similarity index 100% rename from linux/obc/CMakeLists.txt rename to linux/ipcore/CMakeLists.txt diff --git a/linux/obc/PapbVcInterface.cpp b/linux/ipcore/PapbVcInterface.cpp similarity index 98% rename from linux/obc/PapbVcInterface.cpp rename to linux/ipcore/PapbVcInterface.cpp index 1fbbe2ba..b8b12c7a 100644 --- a/linux/obc/PapbVcInterface.cpp +++ b/linux/ipcore/PapbVcInterface.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include "fsfw/serviceinterface/ServiceInterface.h" diff --git a/linux/obc/PapbVcInterface.h b/linux/ipcore/PapbVcInterface.h similarity index 98% rename from linux/obc/PapbVcInterface.h rename to linux/ipcore/PapbVcInterface.h index 6162765e..83081d9d 100644 --- a/linux/obc/PapbVcInterface.h +++ b/linux/ipcore/PapbVcInterface.h @@ -6,7 +6,7 @@ #include "OBSWConfig.h" #include "fsfw/returnvalues/returnvalue.h" -#include "linux/obc/VcInterfaceIF.h" +#include "linux/ipcore/VcInterfaceIF.h" /** * @brief This class handles the transmission of data to a virtual channel of the PTME IP Core diff --git a/linux/obc/PdecConfig.cpp b/linux/ipcore/PdecConfig.cpp similarity index 100% rename from linux/obc/PdecConfig.cpp rename to linux/ipcore/PdecConfig.cpp diff --git a/linux/obc/PdecConfig.h b/linux/ipcore/PdecConfig.h similarity index 100% rename from linux/obc/PdecConfig.h rename to linux/ipcore/PdecConfig.h diff --git a/linux/obc/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp similarity index 100% rename from linux/obc/PdecHandler.cpp rename to linux/ipcore/PdecHandler.cpp diff --git a/linux/obc/PdecHandler.h b/linux/ipcore/PdecHandler.h similarity index 100% rename from linux/obc/PdecHandler.h rename to linux/ipcore/PdecHandler.h diff --git a/linux/obc/Ptme.cpp b/linux/ipcore/Ptme.cpp similarity index 98% rename from linux/obc/Ptme.cpp rename to linux/ipcore/Ptme.cpp index 65705c2e..0c475236 100644 --- a/linux/obc/Ptme.cpp +++ b/linux/ipcore/Ptme.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/linux/obc/Ptme.h b/linux/ipcore/Ptme.h similarity index 96% rename from linux/obc/Ptme.h rename to linux/ipcore/Ptme.h index f76f7fd1..2de85a38 100644 --- a/linux/obc/Ptme.h +++ b/linux/ipcore/Ptme.h @@ -9,8 +9,8 @@ #include "OBSWConfig.h" #include "fsfw/returnvalues/returnvalue.h" -#include "linux/obc/PtmeIF.h" -#include "linux/obc/VcInterfaceIF.h" +#include "linux/ipcore/PtmeIF.h" +#include "linux/ipcore/VcInterfaceIF.h" /** * @brief This class handles the interfacing to the telemetry (PTME) IP core responsible for the diff --git a/linux/obc/PtmeConfig.cpp b/linux/ipcore/PtmeConfig.cpp similarity index 100% rename from linux/obc/PtmeConfig.cpp rename to linux/ipcore/PtmeConfig.cpp diff --git a/linux/obc/PtmeConfig.h b/linux/ipcore/PtmeConfig.h similarity index 98% rename from linux/obc/PtmeConfig.h rename to linux/ipcore/PtmeConfig.h index 9c5a85af..f57f6fb5 100644 --- a/linux/obc/PtmeConfig.h +++ b/linux/ipcore/PtmeConfig.h @@ -4,7 +4,7 @@ #include "AxiPtmeConfig.h" #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/returnvalues/returnvalue.h" -#include "linux/obc/PtmeConfig.h" +#include "linux/ipcore/PtmeConfig.h" #include "returnvalues/classIds.h" /** diff --git a/linux/obc/PtmeIF.h b/linux/ipcore/PtmeIF.h similarity index 100% rename from linux/obc/PtmeIF.h rename to linux/ipcore/PtmeIF.h diff --git a/linux/obc/VcInterfaceIF.h b/linux/ipcore/VcInterfaceIF.h similarity index 100% rename from linux/obc/VcInterfaceIF.h rename to linux/ipcore/VcInterfaceIF.h diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index e81818e9..8f4924f1 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "OBSWConfig.h" #include "eive/definitions.h" @@ -66,7 +66,8 @@ EiveFaultHandler EIVE_FAULT_HANDLER; } // namespace cfdp -void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_) { +void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFunnel** pusFunnel, + CfdpTmFunnel** cfdpFunnel) { // Framework objects new EventManager(objects::EVENT_MANAGER); auto healthTable = new HealthTable(objects::HEALTH_TABLE); @@ -98,12 +99,12 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_) { #if OBSW_ADD_TCPIP_BRIDGE == 1 #if OBSW_USE_TMTC_TCP_BRIDGE == 0 - auto tmtcBridge = new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + auto tcpIpTmtcBridge = new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); sif::info << "Created UDP server for TMTC commanding with listener port " << udpBridge->getUdpPort() << std::endl; #else - auto tmtcBridge = new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + auto tcpIpTmtcBridge = new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); auto tcpServer = new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); // TCP is stream based. Use packet ID as start marker when parsing for space packets tcpServer->setSpacePacketParsingOptions({common::PUS_PACKET_ID, common::CFDP_PACKET_ID}); @@ -113,23 +114,21 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_) { tcpServer->enableWiretapping(true); #endif /* OBSW_TCP_SERVER_WIRETAPPING == 1 */ #endif /* OBSW_USE_TMTC_TCP_BRIDGE == 0 */ - tmtcBridge->setMaxNumberOfPacketsStored(300); + tcpIpTmtcBridge->setMaxNumberOfPacketsStored(300); #endif /* OBSW_ADD_TCPIP_BRIDGE == 1 */ auto* ccsdsDistrib = new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR); new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib); - uint8_t vc = 0; -#if OBSW_TM_TO_PTME == 1 - vc = config::LIVE_TM; + *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore); + *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore); +#if OBSW_ADD_TCPIP_BRIDGE == 1 + (*cfdpFunnel)->addDestination(*tcpIpTmtcBridge, 0); + (*pusFunnel)->addDestination(*tcpIpTmtcBridge, 0); #endif - auto* cfdpFunnel = - new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmtcBridge, *tmStore, vc); - auto* pusFunnel = - new PusTmFunnel(objects::PUS_TM_FUNNEL, *tmtcBridge, *timeStamper, *tmStore, vc); // Every TM packet goes through this funnel - new TmFunnel(objects::TM_FUNNEL, *pusFunnel, *cfdpFunnel); + new TmFunnelHandler(objects::TM_FUNNEL, **pusFunnel, **cfdpFunnel); // PUS service stack new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION, config::EIVE_PUS_APID, @@ -165,7 +164,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_) { new CfdpDistributor(distribCfg); auto* msgQueue = QueueFactory::instance()->createMessageQueue(32); - FsfwHandlerParams params(objects::CFDP_HANDLER, HOST_FS, *cfdpFunnel, *tcStore, *tmStore, + FsfwHandlerParams params(objects::CFDP_HANDLER, HOST_FS, **cfdpFunnel, *tcStore, *tmStore, *msgQueue); cfdp::IndicationCfg indicationCfg; UnsignedByteField apid(config::EIVE_LOCAL_CFDP_ENTITY_ID); diff --git a/mission/core/GenericFactory.h b/mission/core/GenericFactory.h index 4bc6695d..2e2b0748 100644 --- a/mission/core/GenericFactory.h +++ b/mission/core/GenericFactory.h @@ -2,10 +2,13 @@ #define MISSION_CORE_GENERICFACTORY_H_ class HealthTableIF; +class PusTmFunnel; +class CfdpTmFunnel; namespace ObjectFactory { -void produceGenericObjects(HealthTableIF** healthTable = nullptr); +void produceGenericObjects(HealthTableIF** healthTable, PusTmFunnel** pusFunnel, + CfdpTmFunnel** cfdpFunnel); } diff --git a/mission/devices/BpxBatteryHandler.cpp b/mission/devices/BpxBatteryHandler.cpp index 02eea4fe..4e49bebe 100644 --- a/mission/devices/BpxBatteryHandler.cpp +++ b/mission/devices/BpxBatteryHandler.cpp @@ -216,7 +216,7 @@ ReturnValue_t BpxBatteryHandler::interpretDeviceReply(DeviceCommandId_t id, cons if (packet[2] != sentPingByte) { return DeviceHandlerIF::INVALID_DATA; } - if (mode == _MODE_START_UP) { + if (getMode() == _MODE_START_UP) { commandExecuted = true; } break; diff --git a/mission/devices/GomspaceDeviceHandler.cpp b/mission/devices/GomspaceDeviceHandler.cpp index 254b6993..d1749e4c 100644 --- a/mission/devices/GomspaceDeviceHandler.cpp +++ b/mission/devices/GomspaceDeviceHandler.cpp @@ -570,7 +570,7 @@ ReturnValue_t GomspaceDeviceHandler::generateRequestFullCfgTableCmd(DeviceType d uint32_t GomspaceDeviceHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 0; } -void GomspaceDeviceHandler::setModeNormal() { mode = MODE_NORMAL; } +void GomspaceDeviceHandler::setModeNormal() { setMode(MODE_NORMAL); } ReturnValue_t GomspaceDeviceHandler::printStatus(DeviceCommandId_t cmd) { sif::info << "No printHkTable implementation given.." << std::endl; diff --git a/mission/devices/Max31865EiveHandler.cpp b/mission/devices/Max31865EiveHandler.cpp index 8858cf38..90e4b933 100644 --- a/mission/devices/Max31865EiveHandler.cpp +++ b/mission/devices/Max31865EiveHandler.cpp @@ -104,7 +104,7 @@ void Max31865EiveHandler::simpleCommand(EiveMax31855::RtdCommands cmd) { rawPacketLen = 1; } void Max31865EiveHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { - if (mode == _MODE_TO_NORMAL) { + if (getMode() == _MODE_TO_NORMAL) { if (state != InternalState::ACTIVE) { state = InternalState::ACTIVE; transitionOk = false; @@ -125,7 +125,7 @@ void Max31865EiveHandler::fillCommandAndReplyMap() { ReturnValue_t Max31865EiveHandler::scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId, size_t* foundLen) { - if (mode == _MODE_POWER_ON or mode == _MODE_WAIT_ON) { + if (getMode() == _MODE_POWER_ON or getMode() == _MODE_WAIT_ON) { return IGNORE_FULL_PACKET; } if (remainingSize != structLen) { @@ -145,10 +145,10 @@ ReturnValue_t Max31865EiveHandler::interpretDeviceReply(DeviceCommandId_t id, if (result != returnvalue::OK) { return result; } - if (mode == _MODE_TO_NORMAL and exchangeStruct.active and state == InternalState::ACTIVE) { + if (getMode() == _MODE_TO_NORMAL and exchangeStruct.active and state == InternalState::ACTIVE) { transitionOk = true; } - if (mode == _MODE_START_UP and exchangeStruct.configured and state == InternalState::ON) { + if (getMode() == _MODE_START_UP and exchangeStruct.configured and state == InternalState::ON) { transitionOk = true; } // Calculate resistance diff --git a/mission/devices/Max31865PT1000Handler.cpp b/mission/devices/Max31865PT1000Handler.cpp index 30e19d0e..75588cbd 100644 --- a/mission/devices/Max31865PT1000Handler.cpp +++ b/mission/devices/Max31865PT1000Handler.cpp @@ -302,7 +302,7 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r } else if (internalState == InternalState::CLEAR_FAULT_BYTE) { *foundId = MAX31865::CLEAR_FAULT_BYTE; *foundLen = 2; - if (mode == _MODE_START_UP) { + if (getMode() == _MODE_START_UP) { commandExecuted = true; } else { internalState = InternalState::RUNNING; @@ -524,7 +524,7 @@ void Max31865PT1000Handler::setInstantNormal(bool instantNormal) { } void Max31865PT1000Handler::modeChanged() { - if (mode == MODE_OFF) { + if (getMode() == MODE_OFF) { lastFaultStatus = 0; currentFaultStatus = 0; sameFaultStatusCounter = 0; diff --git a/mission/devices/PayloadPcduHandler.cpp b/mission/devices/PayloadPcduHandler.cpp index 725e05df..7b4353e4 100644 --- a/mission/devices/PayloadPcduHandler.cpp +++ b/mission/devices/PayloadPcduHandler.cpp @@ -66,7 +66,7 @@ void PayloadPcduHandler::doShutDown() { } void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { - if (mode == _MODE_TO_NORMAL) { + if (getMode() == _MODE_TO_NORMAL) { stateMachineToNormal(modeFrom, subModeFrom); return; } @@ -76,7 +76,7 @@ void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_t subModeFrom) { using namespace plpcdu; bool doFinish = true; - if (((submode >> SOLID_STATE_RELAYS_ADC_ON) & 0b1) == 1) { + if (((getSubmode() >> SOLID_STATE_RELAYS_ADC_ON) & 0b1) == 1) { if (state == States::PL_PCDU_OFF) { sif::error << "PayloadPcduHandler::stateMachineToNormal: Unexpected state PL_PCDU_OFF" << "detected" << std::endl; @@ -129,7 +129,7 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_ auto switchHandler = [&](NormalSubmodeBits bit, gpioId_t id, std::string info) { if (((diffMask >> bit) & 1) == 1) { - if (((submode >> bit) & 1) == 1) { + if (((getSubmode() >> bit) & 1) == 1) { #if OBSW_VERBOSE_LEVEL >= 1 sif::info << "Enabling PL PCDU " << info << " module" << std::endl; #endif @@ -150,7 +150,7 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_ switchHandler(MPA_ON, gpioIds::PLPCDU_ENB_MPA, "MPA"); switchHandler(HPA_ON, gpioIds::PLPCDU_ENB_HPA, "HPA"); if (doFinish) { - setMode(MODE_NORMAL, submode); + setMode(MODE_NORMAL); } return returnvalue::OK; } @@ -177,7 +177,7 @@ ReturnValue_t PayloadPcduHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id = plpcdu::SETUP_CMD; return buildCommandFromCommand(*id, nullptr, 0); } - if (mode == _MODE_TO_NORMAL) { + if (getMode() == _MODE_TO_NORMAL) { return buildNormalDeviceCommand(id); } return NOTHING_TO_SEND; @@ -248,7 +248,7 @@ ReturnValue_t PayloadPcduHandler::interpretDeviceReply(DeviceCommandId_t id, using namespace plpcdu; switch (id) { case (SETUP_CMD): { - if (mode == _MODE_TO_NORMAL) { + if (getMode() == _MODE_TO_NORMAL) { adcCmdExecuted = true; } break; @@ -540,33 +540,34 @@ bool PayloadPcduHandler::checkCurrent(float val, float upperBound, Event event) ReturnValue_t PayloadPcduHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) { using namespace plpcdu; if (mode == MODE_NORMAL) { - diffMask = submode ^ this->submode; + uint8_t dhbSubmode = getSubmode(); + diffMask = submode ^ dhbSubmode; // Also deals with the case where the mode is MODE_ON, submode should be 0 here if ((((submode >> SOLID_STATE_RELAYS_ADC_ON) & 0b1) == SOLID_STATE_RELAYS_ADC_ON) and - (this->mode == MODE_NORMAL and this->submode != ALL_OFF_SUBMODE)) { + (getMode() == MODE_NORMAL and dhbSubmode != ALL_OFF_SUBMODE)) { return TRANS_NOT_ALLOWED; } if (((((submode >> DRO_ON) & 1) == 1) and - ((this->submode & 0b1) != (1 << SOLID_STATE_RELAYS_ADC_ON)))) { + ((dhbSubmode & 0b1) != (1 << SOLID_STATE_RELAYS_ADC_ON)))) { return TRANS_NOT_ALLOWED; } if ((((submode >> X8_ON) & 1) == 1) and - ((this->submode & 0b11) != ((1 << SOLID_STATE_RELAYS_ADC_ON) | (1 << DRO_ON)))) { + ((dhbSubmode & 0b11) != ((1 << SOLID_STATE_RELAYS_ADC_ON) | (1 << DRO_ON)))) { return TRANS_NOT_ALLOWED; } if (((((submode >> TX_ON) & 1) == 1) and - ((this->submode & 0b111) != + ((dhbSubmode & 0b111) != ((1 << X8_ON) | (1 << DRO_ON) | (1 << SOLID_STATE_RELAYS_ADC_ON))))) { return TRANS_NOT_ALLOWED; } if ((((submode >> MPA_ON) & 1) == 1 and - ((this->submode & 0b1111) != + ((dhbSubmode & 0b1111) != ((1 << TX_ON) | (1 << X8_ON) | (1 << DRO_ON) | (1 << SOLID_STATE_RELAYS_ADC_ON))))) { return TRANS_NOT_ALLOWED; } if ((((submode >> HPA_ON) & 1) == 1 and - ((this->submode & 0b11111) != ((1 << MPA_ON) | (1 << TX_ON) | (1 << X8_ON) | - (1 << DRO_ON) | (1 << SOLID_STATE_RELAYS_ADC_ON))))) { + ((dhbSubmode & 0b11111) != ((1 << MPA_ON) | (1 << TX_ON) | (1 << X8_ON) | (1 << DRO_ON) | + (1 << SOLID_STATE_RELAYS_ADC_ON))))) { return TRANS_NOT_ALLOWED; } return returnvalue::OK; diff --git a/mission/devices/SusHandler.cpp b/mission/devices/SusHandler.cpp index 73a8344f..0b053e99 100644 --- a/mission/devices/SusHandler.cpp +++ b/mission/devices/SusHandler.cpp @@ -150,7 +150,7 @@ ReturnValue_t SusHandler::scanForReply(const uint8_t *start, size_t remainingSiz ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { switch (id) { case SUS::WRITE_SETUP: { - if (mode == _MODE_START_UP) { + if (getMode() == _MODE_START_UP) { commandExecuted = true; } return returnvalue::OK; diff --git a/mission/devices/SyrlinksHkHandler.cpp b/mission/devices/SyrlinksHkHandler.cpp index 1b4af19f..b07d665e 100644 --- a/mission/devices/SyrlinksHkHandler.cpp +++ b/mission/devices/SyrlinksHkHandler.cpp @@ -630,7 +630,7 @@ ReturnValue_t SyrlinksHkHandler::initializeLocalDataPool(localpool::DataPool& lo return returnvalue::OK; } -void SyrlinksHkHandler::setModeNormal() { mode = MODE_NORMAL; } +void SyrlinksHkHandler::setModeNormal() { setMode(MODE_NORMAL); } float SyrlinksHkHandler::calcTempVal(uint16_t raw) { return 0.126984 * raw - 67.87; } diff --git a/mission/devices/Tmp1075Handler.cpp b/mission/devices/Tmp1075Handler.cpp index 83a4643b..22d72999 100644 --- a/mission/devices/Tmp1075Handler.cpp +++ b/mission/devices/Tmp1075Handler.cpp @@ -12,7 +12,7 @@ Tmp1075Handler::Tmp1075Handler(object_id_t objectId, object_id_t comIF, CookieIF Tmp1075Handler::~Tmp1075Handler() {} void Tmp1075Handler::doStartUp() { - if (mode == _MODE_START_UP) { + if (getMode() == _MODE_START_UP) { setMode(MODE_ON); } } diff --git a/mission/tmtc/CMakeLists.txt b/mission/tmtc/CMakeLists.txt index f34f9ccc..bb92a84e 100644 --- a/mission/tmtc/CMakeLists.txt +++ b/mission/tmtc/CMakeLists.txt @@ -1,3 +1,4 @@ target_sources( - ${LIB_EIVE_MISSION} PRIVATE CCSDSHandler.cpp VirtualChannel.cpp TmFunnel.cpp - CfdpTmFunnel.cpp PusTmFunnel.cpp) + ${LIB_EIVE_MISSION} + PRIVATE CcsdsIpCoreHandler.cpp VirtualChannel.cpp TmFunnelHandler.cpp + TmFunnelBase.cpp CfdpTmFunnel.cpp PusTmFunnel.cpp) diff --git a/mission/tmtc/CCSDSHandler.cpp b/mission/tmtc/CcsdsIpCoreHandler.cpp similarity index 73% rename from mission/tmtc/CCSDSHandler.cpp rename to mission/tmtc/CcsdsIpCoreHandler.cpp index 26abec25..c65a12a8 100644 --- a/mission/tmtc/CCSDSHandler.cpp +++ b/mission/tmtc/CcsdsIpCoreHandler.cpp @@ -1,7 +1,7 @@ -#include "CCSDSHandler.h" +#include "CcsdsIpCoreHandler.h" -#include -#include +#include +#include #include "fsfw/events/EventManagerIF.h" #include "fsfw/ipc/QueueFactory.h" @@ -11,9 +11,10 @@ #include "fsfw/serviceinterface/serviceInterfaceDefintions.h" #include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" -CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination, - PtmeConfig* ptmeConfig, GpioIF* gpioIF, gpioId_t enTxClock, - gpioId_t enTxData, uint32_t transmitterTimeout) +CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t ptmeId, + object_id_t tcDestination, PtmeConfig* ptmeConfig, + GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData, + uint32_t transmitterTimeout) : SystemObject(objectId), ptmeId(ptmeId), tcDestination(tcDestination), @@ -30,9 +31,9 @@ CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs); } -CCSDSHandler::~CCSDSHandler() {} +CcsdsIpCoreHandler::~CcsdsIpCoreHandler() {} -ReturnValue_t CCSDSHandler::performOperation(uint8_t operationCode) { +ReturnValue_t CcsdsIpCoreHandler::performOperation(uint8_t operationCode) { checkEvents(); readCommandQueue(); handleTelemetry(); @@ -41,16 +42,16 @@ ReturnValue_t CCSDSHandler::performOperation(uint8_t operationCode) { return returnvalue::OK; } -void CCSDSHandler::handleTelemetry() { +void CcsdsIpCoreHandler::handleTelemetry() { VirtualChannelMapIter iter; for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) { iter->second->performOperation(); } } -void CCSDSHandler::handleTelecommands() {} +void CcsdsIpCoreHandler::handleTelecommands() {} -ReturnValue_t CCSDSHandler::initialize() { +ReturnValue_t CcsdsIpCoreHandler::initialize() { ReturnValue_t result = returnvalue::OK; PtmeIF* ptme = ObjectManager::instance()->get(ptmeId); if (ptme == nullptr) { @@ -62,7 +63,7 @@ ReturnValue_t CCSDSHandler::initialize() { ObjectManager::instance()->get(tcDestination); if (tcDistributor == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "CCSDSHandler::initialize: Invalid TC Distributor object" << std::endl; + sif::error << "CcsdsHandler::initialize: Invalid TC Distributor object" << std::endl; #endif return ObjectManagerIF::CHILD_INIT_FAILED; } @@ -91,14 +92,14 @@ ReturnValue_t CCSDSHandler::initialize() { EventManagerIF* manager = ObjectManager::instance()->get(objects::EVENT_MANAGER); if (manager == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "CCSDSHandler::initialize: Invalid event manager" << std::endl; + sif::error << "CcsdsHandler::initialize: Invalid event manager" << std::endl; #endif return ObjectManagerIF::CHILD_INIT_FAILED; } result = manager->registerListener(eventQueue->getId()); if (result != returnvalue::OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "CCSDSHandler::initialize: Failed to register CCSDS handler as event " + sif::warning << "CcsdsHandler::initialize: Failed to register CCSDS handler as event " "listener" << std::endl; #endif @@ -110,7 +111,7 @@ ReturnValue_t CCSDSHandler::initialize() { event::getEventId(PdecHandler::BIT_LOCK_PDEC)); if (result != returnvalue::OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "CCSDSHandler::initialize: Failed to subscribe to events from PDEC " + sif::error << "CcsdsHandler::initialize: Failed to subscribe to events from PDEC " "handler" << std::endl; #endif @@ -136,7 +137,7 @@ ReturnValue_t CCSDSHandler::initialize() { return result; } -void CCSDSHandler::readCommandQueue(void) { +void CcsdsIpCoreHandler::readCommandQueue(void) { CommandMessage commandMessage; ReturnValue_t result = returnvalue::FAILED; @@ -157,61 +158,62 @@ void CCSDSHandler::readCommandQueue(void) { } } -MessageQueueId_t CCSDSHandler::getCommandQueue() const { return commandQueue->getId(); } +MessageQueueId_t CcsdsIpCoreHandler::getCommandQueue() const { return commandQueue->getId(); } -void CCSDSHandler::addVirtualChannel(VcId_t vcId, VirtualChannel* virtualChannel) { +void CcsdsIpCoreHandler::addVirtualChannel(VcId_t vcId, VirtualChannel* virtualChannel) { if (vcId > common::NUMBER_OF_VIRTUAL_CHANNELS) { - sif::warning << "CCSDSHandler::addVirtualChannel: Invalid virtual channel ID" << std::endl; + sif::warning << "CcsdsHandler::addVirtualChannel: Invalid virtual channel ID" << std::endl; return; } if (virtualChannel == nullptr) { - sif::warning << "CCSDSHandler::addVirtualChannel: Invalid virtual channel interface" + sif::warning << "CcsdsHandler::addVirtualChannel: Invalid virtual channel interface" << std::endl; return; } auto status = virtualChannelMap.emplace(vcId, virtualChannel); if (status.second == false) { - sif::warning << "CCSDSHandler::addVirtualChannel: Failed to add virtual channel to " + sif::warning << "CcsdsHandler::addVirtualChannel: Failed to add virtual channel to " "virtual channel map" << std::endl; return; } } -MessageQueueId_t CCSDSHandler::getReportReceptionQueue(uint8_t virtualChannel) const { +MessageQueueId_t CcsdsIpCoreHandler::getReportReceptionQueue(uint8_t virtualChannel) const { if (virtualChannel < common::NUMBER_OF_VIRTUAL_CHANNELS) { auto iter = virtualChannelMap.find(virtualChannel); if (iter != virtualChannelMap.end()) { return iter->second->getReportReceptionQueue(); } else { - sif::warning << "CCSDSHandler::getReportReceptionQueue: Virtual channel with ID " + sif::warning << "CcsdsHandler::getReportReceptionQueue: Virtual channel with ID " << static_cast(virtualChannel) << " not in virtual channel map" << std::endl; return MessageQueueIF::NO_QUEUE; } } else { - sif::debug << "CCSDSHandler::getReportReceptionQueue: Invalid virtual channel requested"; + sif::debug << "CcsdsHandler::getReportReceptionQueue: Invalid virtual channel requested"; } return MessageQueueIF::NO_QUEUE; } -ReturnValue_t CCSDSHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifier, - ParameterWrapper* parameterWrapper, - const ParameterWrapper* newValues, uint16_t startAtIndex) { +ReturnValue_t CcsdsIpCoreHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifier, + ParameterWrapper* parameterWrapper, + const ParameterWrapper* newValues, + uint16_t startAtIndex) { return returnvalue::OK; } -uint32_t CCSDSHandler::getIdentifier() const { return 0; } +uint32_t CcsdsIpCoreHandler::getIdentifier() const { return 0; } -MessageQueueId_t CCSDSHandler::getRequestQueue() const { +MessageQueueId_t CcsdsIpCoreHandler::getRequestQueue() const { // Forward packets directly to TC distributor return tcDistributorQueueId; } -ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, - const uint8_t* data, size_t size) { +ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) { ReturnValue_t result = returnvalue::OK; switch (actionId) { case SET_LOW_RATE: { @@ -261,7 +263,7 @@ ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId, MessageQueueId_t return EXECUTION_FINISHED; } -void CCSDSHandler::checkEvents() { +void CcsdsIpCoreHandler::checkEvents() { EventMessage event; for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == returnvalue::OK; result = eventQueue->receiveMessage(&event)) { @@ -270,14 +272,14 @@ void CCSDSHandler::checkEvents() { handleEvent(&event); break; default: - sif::debug << "CCSDSHandler::checkEvents: Did not subscribe to this event message" + sif::debug << "CcsdsHandler::checkEvents: Did not subscribe to this event message" << std::endl; break; } } } -void CCSDSHandler::handleEvent(EventMessage* eventMessage) { +void CcsdsIpCoreHandler::handleEvent(EventMessage* eventMessage) { Event event = eventMessage->getEvent(); switch (event) { case PdecHandler::BIT_LOCK_PDEC: { @@ -289,12 +291,12 @@ void CCSDSHandler::handleEvent(EventMessage* eventMessage) { break; } default: - sif::debug << "CCSDSHandler::handleEvent: Did not subscribe to this event" << std::endl; + sif::debug << "CcsdsHandler::handleEvent: Did not subscribe to this event" << std::endl; break; } } -void CCSDSHandler::handleBitLockEvent() { +void CcsdsIpCoreHandler::handleBitLockEvent() { if (transmitterCountdown.isBusy()) { // Transmitter already enabled return; @@ -302,21 +304,21 @@ void CCSDSHandler::handleBitLockEvent() { enableTransmit(); } -void CCSDSHandler::handleCarrierLockEvent() { +void CcsdsIpCoreHandler::handleCarrierLockEvent() { if (!enableTxWhenCarrierLock) { return; } enableTransmit(); } -void CCSDSHandler::forwardLinkstate() { +void CcsdsIpCoreHandler::forwardLinkstate() { VirtualChannelMapIter iter; for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) { iter->second->setLinkState(linkState); } } -void CCSDSHandler::enableTransmit() { +void CcsdsIpCoreHandler::enableTransmit() { if (transmitterCountdown.isBusy()) { // Transmitter already enabled return; @@ -327,7 +329,7 @@ void CCSDSHandler::enableTransmit() { #endif } -void CCSDSHandler::checkTxTimer() { +void CcsdsIpCoreHandler::checkTxTimer() { if (linkState == DOWN) { return; } @@ -336,7 +338,7 @@ void CCSDSHandler::checkTxTimer() { } } -void CCSDSHandler::disableTransmit() { +void CcsdsIpCoreHandler::disableTransmit() { #ifndef TE0720_1CFA gpioIF->pullLow(enTxClock); gpioIF->pullLow(enTxData); @@ -346,4 +348,4 @@ void CCSDSHandler::disableTransmit() { transmitterCountdown.setTimeout(0); } -const char* CCSDSHandler::getName() const { return "CCSDS Handler"; } +const char* CcsdsIpCoreHandler::getName() const { return "CCSDS Handler"; } diff --git a/mission/tmtc/CCSDSHandler.h b/mission/tmtc/CcsdsIpCoreHandler.h similarity index 90% rename from mission/tmtc/CCSDSHandler.h rename to mission/tmtc/CcsdsIpCoreHandler.h index d76dbdaf..942b73cb 100644 --- a/mission/tmtc/CCSDSHandler.h +++ b/mission/tmtc/CcsdsIpCoreHandler.h @@ -17,7 +17,7 @@ #include "fsfw/tmtcservices/AcceptsTelemetryIF.h" #include "fsfw_hal/common/gpio/GpioIF.h" #include "fsfw_hal/common/gpio/gpioDefinitions.h" -#include "linux/obc/PtmeConfig.h" +#include "linux/ipcore/PtmeConfig.h" /** * @brief This class handles the data exchange with the CCSDS IP cores implemented in the @@ -28,12 +28,12 @@ * * @author J. Meier */ -class CCSDSHandler : public SystemObject, - public ExecutableObjectIF, - public AcceptsTelemetryIF, - public AcceptsTelecommandsIF, - public ReceivesParameterMessagesIF, - public HasActionsIF { +class CcsdsIpCoreHandler : public SystemObject, + public ExecutableObjectIF, + public AcceptsTelemetryIF, + public AcceptsTelecommandsIF, + public ReceivesParameterMessagesIF, + public HasActionsIF { public: using VcId_t = uint8_t; @@ -49,11 +49,11 @@ class CCSDSHandler : public SystemObject, * @param enTxClock GPIO ID of RS485 tx clock enable * @param enTxData GPIO ID of RS485 tx data enable */ - CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination, - PtmeConfig* ptmeConfig, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData, - uint32_t transmitterTimeout = 900000); + CcsdsIpCoreHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination, + PtmeConfig* ptmeConfig, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData, + uint32_t transmitterTimeout = 900000); - ~CCSDSHandler(); + ~CcsdsIpCoreHandler(); ReturnValue_t performOperation(uint8_t operationCode = 0) override; ReturnValue_t initialize(); diff --git a/mission/tmtc/CfdpTmFunnel.cpp b/mission/tmtc/CfdpTmFunnel.cpp index 7969961b..0c003881 100644 --- a/mission/tmtc/CfdpTmFunnel.cpp +++ b/mission/tmtc/CfdpTmFunnel.cpp @@ -5,29 +5,21 @@ #include "fsfw/tmtcservices/TmTcMessage.h" CfdpTmFunnel::CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid, - const AcceptsTelemetryIF& downlinkDestination, StorageManagerIF& tmStore, - uint8_t vc) - : SystemObject(objectId), cfdpInCcsdsApid(cfdpInCcsdsApid), tmStore(tmStore) { - msgQueue = QueueFactory::instance()->createMessageQueue(5); - msgQueue->setDefaultDestination(downlinkDestination.getReportReceptionQueue(vc)); -} + StorageManagerIF& tmStore) + : TmFunnelBase(objectId, tmStore, 10), cfdpInCcsdsApid(cfdpInCcsdsApid) {} const char* CfdpTmFunnel::getName() const { return "CFDP TM Funnel"; } -MessageQueueId_t CfdpTmFunnel::getReportReceptionQueue(uint8_t virtualChannel) const { - return msgQueue->getId(); -} - ReturnValue_t CfdpTmFunnel::performOperation(uint8_t) { TmTcMessage currentMessage; - ReturnValue_t status = msgQueue->receiveMessage(¤tMessage); + ReturnValue_t status = tmQueue->receiveMessage(¤tMessage); while (status == returnvalue::OK) { status = handlePacket(currentMessage); if (status != returnvalue::OK) { sif::warning << "CfdpTmFunnel packet handling failed" << std::endl; break; } - status = msgQueue->receiveMessage(¤tMessage); + status = tmQueue->receiveMessage(¤tMessage); } if (status == MessageQueueIF::EMPTY) { @@ -74,12 +66,25 @@ ReturnValue_t CfdpTmFunnel::handlePacket(TmTcMessage& msg) { // Delete old packet tmStore.deleteData(msg.getStorageId()); msg.setStorageId(newStoreId); - result = msgQueue->sendToDefault(&msg); - if (result != returnvalue::OK) { - tmStore.deleteData(msg.getStorageId()); + store_address_t origStoreId = newStoreId; + for (unsigned int idx = 0; idx < destinations.size(); idx++) { + const auto& destVcidPair = destinations[idx]; + if (idx <= destinations.size() - 1) { + // Create copy of data to ensure each TM recipient has its own copy. That way, we don't need + // to bother with send order and where the data is deleted. + store_address_t storeId; + result = tmStore.addData(&storeId, newPacketData, serSize); + msg.setStorageId(storeId); + } else { + msg.setStorageId(origStoreId); + } + result = tmQueue->sendMessage(destVcidPair.first, &msg); + if (result != returnvalue::OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "CfdpTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; + sif::error << "PusTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; #endif + tmStore.deleteData(msg.getStorageId()); + } } return result; } diff --git a/mission/tmtc/CfdpTmFunnel.h b/mission/tmtc/CfdpTmFunnel.h index fe2d664d..a6d947fd 100644 --- a/mission/tmtc/CfdpTmFunnel.h +++ b/mission/tmtc/CfdpTmFunnel.h @@ -1,19 +1,19 @@ #ifndef FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H #define FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H +#include + +#include + #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/storagemanager/StorageManagerIF.h" #include "fsfw/tmtcservices/AcceptsTelemetryIF.h" #include "fsfw/tmtcservices/TmTcMessage.h" -class CfdpTmFunnel : public AcceptsTelemetryIF, public SystemObject { +class CfdpTmFunnel : public TmFunnelBase { public: - CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid, - const AcceptsTelemetryIF& downlinkDestination, StorageManagerIF& tmStore, - uint8_t vc); + CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid, StorageManagerIF& tmStore); [[nodiscard]] const char* getName() const override; - [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; - ReturnValue_t performOperation(uint8_t opCode); ReturnValue_t initialize() override; @@ -22,7 +22,5 @@ class CfdpTmFunnel : public AcceptsTelemetryIF, public SystemObject { uint16_t sourceSequenceCount = 0; uint16_t cfdpInCcsdsApid; - MessageQueueIF* msgQueue; - StorageManagerIF& tmStore; }; #endif // FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index f4072f0f..dcf56f18 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -4,21 +4,12 @@ #include "fsfw/objectmanager.h" #include "fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h" -PusTmFunnel::PusTmFunnel(object_id_t objectId, const AcceptsTelemetryIF &downlinkDestination, - TimeReaderIF &timeReader, StorageManagerIF &tmStore, uint8_t vcId, +PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, StorageManagerIF &tmStore, uint32_t messageDepth) - : SystemObject(objectId), timeReader(timeReader), tmStore(tmStore) { - tmQueue = QueueFactory::instance()->createMessageQueue(messageDepth, - MessageQueueMessage::MAX_MESSAGE_SIZE); - tmQueue->setDefaultDestination(downlinkDestination.getReportReceptionQueue(vcId)); -} + : TmFunnelBase(objectId, tmStore, messageDepth), timeReader(timeReader) {} PusTmFunnel::~PusTmFunnel() = default; -MessageQueueId_t PusTmFunnel::getReportReceptionQueue(uint8_t virtualChannel) const { - return tmQueue->getId(); -} - ReturnValue_t PusTmFunnel::performOperation(uint8_t) { TmTcMessage currentMessage; ReturnValue_t status = tmQueue->receiveMessage(¤tMessage); @@ -40,7 +31,8 @@ ReturnValue_t PusTmFunnel::performOperation(uint8_t) { ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { uint8_t *packetData = nullptr; size_t size = 0; - ReturnValue_t result = tmStore.modifyData(message.getStorageId(), &packetData, &size); + store_address_t origStoreId = message.getStorageId(); + ReturnValue_t result = tmStore.modifyData(origStoreId, &packetData, &size); if (result != returnvalue::OK) { return result; } @@ -56,12 +48,24 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT; packet.updateErrorControl(); - result = tmQueue->sendToDefault(&message); - if (result != returnvalue::OK) { - tmStore.deleteData(message.getStorageId()); + for (unsigned int idx = 0; idx < destinations.size(); idx++) { + const auto &destVcidPair = destinations[idx]; + if (idx <= destinations.size() - 1) { + // Create copy of data to ensure each TM recipient has its own copy. That way, we don't need + // to bother with send order and where the data is deleted. + store_address_t storeId; + result = tmStore.addData(&storeId, packetData, size); + message.setStorageId(storeId); + } else { + message.setStorageId(origStoreId); + } + result = tmQueue->sendMessage(destVcidPair.first, &message); + if (result != returnvalue::OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PusTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; + sif::error << "PusTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; #endif + tmStore.deleteData(message.getStorageId()); + } } return result; } diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index ae0390b3..ca9a6016 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -6,6 +6,9 @@ #include #include #include +#include + +#include #include "fsfw/timemanager/TimeReaderIF.h" @@ -20,22 +23,19 @@ * @ingroup utility * @author J. Meier, R. Mueller */ -class PusTmFunnel : public AcceptsTelemetryIF, public SystemObject { +class PusTmFunnel : public TmFunnelBase { public: - explicit PusTmFunnel(object_id_t objectId, const AcceptsTelemetryIF &downlinkDestination, - TimeReaderIF &timeReader, StorageManagerIF &tmStore, uint8_t vdId, - uint32_t messageDepth = 20); + explicit PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, StorageManagerIF &tmStore, + uint32_t messageDepth = 10); [[nodiscard]] const char *getName() const override; ~PusTmFunnel() override; - [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; ReturnValue_t performOperation(uint8_t operationCode); private: uint16_t sourceSequenceCount = 0; TimeReaderIF &timeReader; - StorageManagerIF &tmStore; - MessageQueueIF *tmQueue = nullptr; + ReturnValue_t handlePacket(TmTcMessage &message); }; diff --git a/mission/tmtc/TmFunnel.cpp b/mission/tmtc/TmFunnel.cpp deleted file mode 100644 index 01bf0437..00000000 --- a/mission/tmtc/TmFunnel.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "TmFunnel.h" - -#include - -TmFunnel::TmFunnel(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel) - : SystemObject(objectId), pusFunnel(pusFunnel), cfdpFunnel(cfdpFunnel) {} - -TmFunnel::~TmFunnel() = default; - -ReturnValue_t TmFunnel::performOperation(uint8_t operationCode) { - pusFunnel.performOperation(operationCode); - cfdpFunnel.performOperation(operationCode); - return returnvalue::OK; -} - -ReturnValue_t TmFunnel::initialize() { return returnvalue::OK; } diff --git a/mission/tmtc/TmFunnelBase.cpp b/mission/tmtc/TmFunnelBase.cpp new file mode 100644 index 00000000..fa0062e6 --- /dev/null +++ b/mission/tmtc/TmFunnelBase.cpp @@ -0,0 +1,19 @@ +#include "TmFunnelBase.h" + +#include "fsfw/ipc/QueueFactory.h" + +TmFunnelBase::TmFunnelBase(object_id_t objectId, StorageManagerIF &tmStore, uint32_t tmMsgDepth) + : SystemObject(objectId), tmStore(tmStore) { + tmQueue = QueueFactory::instance()->createMessageQueue(tmMsgDepth); +} + +TmFunnelBase::~TmFunnelBase() { QueueFactory::instance()->deleteMessageQueue(tmQueue); } + +MessageQueueId_t TmFunnelBase::getReportReceptionQueue(uint8_t virtualChannel) const { + return tmQueue->getId(); +} + +void TmFunnelBase::addDestination(const AcceptsTelemetryIF &downlinkDestination, uint8_t vcid) { + auto queueId = downlinkDestination.getReportReceptionQueue(vcid); + destinations.emplace_back(queueId, vcid); +} diff --git a/mission/tmtc/TmFunnelBase.h b/mission/tmtc/TmFunnelBase.h new file mode 100644 index 00000000..c630fefd --- /dev/null +++ b/mission/tmtc/TmFunnelBase.h @@ -0,0 +1,24 @@ +#ifndef MISSION_TMTC_TMFUNNELBASE_H_ +#define MISSION_TMTC_TMFUNNELBASE_H_ + +#include +#include +#include + +#include + +class TmFunnelBase : public AcceptsTelemetryIF, public SystemObject { + public: + TmFunnelBase(object_id_t objectId, StorageManagerIF& tmStore, uint32_t tmMsgDepth); + void addDestination(const AcceptsTelemetryIF& downlinkDestination, uint8_t vcid = 0); + [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; + + virtual ~TmFunnelBase(); + + protected: + StorageManagerIF& tmStore; + std::vector> destinations; + MessageQueueIF* tmQueue = nullptr; +}; + +#endif /* MISSION_TMTC_TMFUNNELBASE_H_ */ diff --git a/mission/tmtc/TmFunnelHandler.cpp b/mission/tmtc/TmFunnelHandler.cpp new file mode 100644 index 00000000..33f8addc --- /dev/null +++ b/mission/tmtc/TmFunnelHandler.cpp @@ -0,0 +1,17 @@ +#include "TmFunnelHandler.h" + +#include + +TmFunnelHandler::TmFunnelHandler(object_id_t objectId, PusTmFunnel& pusFunnel, + CfdpTmFunnel& cfdpFunnel) + : SystemObject(objectId), pusFunnel(pusFunnel), cfdpFunnel(cfdpFunnel) {} + +TmFunnelHandler::~TmFunnelHandler() = default; + +ReturnValue_t TmFunnelHandler::performOperation(uint8_t operationCode) { + pusFunnel.performOperation(operationCode); + cfdpFunnel.performOperation(operationCode); + return returnvalue::OK; +} + +ReturnValue_t TmFunnelHandler::initialize() { return returnvalue::OK; } diff --git a/mission/tmtc/TmFunnel.h b/mission/tmtc/TmFunnelHandler.h similarity index 80% rename from mission/tmtc/TmFunnel.h rename to mission/tmtc/TmFunnelHandler.h index 5441db2b..a101f361 100644 --- a/mission/tmtc/TmFunnel.h +++ b/mission/tmtc/TmFunnelHandler.h @@ -19,10 +19,10 @@ * @ingroup utility * @author J. Meier, R. Mueller */ -class TmFunnel : public ExecutableObjectIF, public SystemObject { +class TmFunnelHandler : public ExecutableObjectIF, public SystemObject { public: - TmFunnel(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel); - ~TmFunnel() override; + TmFunnelHandler(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel); + ~TmFunnelHandler() override; ReturnValue_t performOperation(uint8_t operationCode) override; ReturnValue_t initialize() override; diff --git a/mission/tmtc/VirtualChannel.cpp b/mission/tmtc/VirtualChannel.cpp index 96a37b3b..9fe47b1c 100644 --- a/mission/tmtc/VirtualChannel.cpp +++ b/mission/tmtc/VirtualChannel.cpp @@ -1,6 +1,6 @@ #include "VirtualChannel.h" -#include "CCSDSHandler.h" +#include "CcsdsIpCoreHandler.h" #include "OBSWConfig.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/objectmanager/ObjectManager.h" diff --git a/mission/tmtc/VirtualChannel.h b/mission/tmtc/VirtualChannel.h index 024ccee6..96d7ba9d 100644 --- a/mission/tmtc/VirtualChannel.h +++ b/mission/tmtc/VirtualChannel.h @@ -2,7 +2,7 @@ #define VIRTUALCHANNEL_H_ #include -#include +#include #include "OBSWConfig.h" #include "fsfw/returnvalues/returnvalue.h" -- 2.34.1 From 97fd35fe7bde1037ead217ff90adc79ea4aecbf0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 2 Nov 2022 10:25:42 +0100 Subject: [PATCH 02/14] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 24612091..033676ad 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 24612091690f191d799f30ba38b5f750d0617fa3 +Subproject commit 033676ad3b5136c4e2fb9d41309d2f0883f5f2de -- 2.34.1 From 772e18904052622636b47be46ab74e3b887cac89 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 10:11:14 +0100 Subject: [PATCH 03/14] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index a38279f8..8a61af77 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit a38279f8131370bda6ba21af64aef13689da8526 +Subproject commit 8a61af779d7f212f93e0bfe024e35051c0e47430 -- 2.34.1 From 23684710e72baab0a25b11130cef14ff28fdf3bd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 10:12:25 +0100 Subject: [PATCH 04/14] bump fsfw again --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 8a61af77..9a0cc64b 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 8a61af779d7f212f93e0bfe024e35051c0e47430 +Subproject commit 9a0cc64be3236b2ce7497cc482aade9225b5d0b3 -- 2.34.1 From d5a908ab75424417b61172f289de118271c17b94 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 10:15:44 +0100 Subject: [PATCH 05/14] remove stray info printout --- linux/ipcore/PdecHandler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index 8f5be22d..7fda509a 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -135,7 +135,6 @@ ReturnValue_t PdecHandler::polledOperation() { ReturnValue_t PdecHandler::irqOperation() { ReturnValue_t result = returnvalue::OK; int fd = open(uioNames.irq, O_RDWR); - sif::info << uioNames.irq << std::endl; if (fd < 0) { sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed" << std::endl; -- 2.34.1 From 264a34d2279523f8f00dd7382ef4fd75bcd6f35a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 10:24:55 +0100 Subject: [PATCH 06/14] tweak for gomspace to normal function --- mission/devices/GomspaceDeviceHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/devices/GomspaceDeviceHandler.cpp b/mission/devices/GomspaceDeviceHandler.cpp index d1749e4c..389b08c7 100644 --- a/mission/devices/GomspaceDeviceHandler.cpp +++ b/mission/devices/GomspaceDeviceHandler.cpp @@ -570,7 +570,7 @@ ReturnValue_t GomspaceDeviceHandler::generateRequestFullCfgTableCmd(DeviceType d uint32_t GomspaceDeviceHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 0; } -void GomspaceDeviceHandler::setModeNormal() { setMode(MODE_NORMAL); } +void GomspaceDeviceHandler::setModeNormal() { setMode(_MODE_TO_NORMAL); } ReturnValue_t GomspaceDeviceHandler::printStatus(DeviceCommandId_t cmd) { sif::info << "No printHkTable implementation given.." << std::endl; -- 2.34.1 From caa81e3b8e88c34c63d31581a187c5412b977c27 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 10:34:19 +0100 Subject: [PATCH 07/14] larger queues --- fsfw | 2 +- mission/core/GenericFactory.cpp | 4 ++-- mission/tmtc/CfdpTmFunnel.cpp | 4 ++-- mission/tmtc/CfdpTmFunnel.h | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/fsfw b/fsfw index 9a0cc64b..e5b5c7d2 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 9a0cc64be3236b2ce7497cc482aade9225b5d0b3 +Subproject commit e5b5c7d2533cd25dbe53d33be540babf15a3c70b diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index f00c4007..d93c06b4 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -121,8 +121,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR); new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib); - *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore); - *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore); + *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 30); + *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, 60); #if OBSW_ADD_TCPIP_BRIDGE == 1 (*cfdpFunnel)->addDestination(*tcpIpTmtcBridge, 0); (*pusFunnel)->addDestination(*tcpIpTmtcBridge, 0); diff --git a/mission/tmtc/CfdpTmFunnel.cpp b/mission/tmtc/CfdpTmFunnel.cpp index 33ecc034..f62e68e3 100644 --- a/mission/tmtc/CfdpTmFunnel.cpp +++ b/mission/tmtc/CfdpTmFunnel.cpp @@ -5,8 +5,8 @@ #include "fsfw/tmtcservices/TmTcMessage.h" CfdpTmFunnel::CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid, - StorageManagerIF& tmStore) - : TmFunnelBase(objectId, tmStore, 10), cfdpInCcsdsApid(cfdpInCcsdsApid) {} + StorageManagerIF& tmStore, uint32_t messageDepth) + : TmFunnelBase(objectId, tmStore, messageDepth), cfdpInCcsdsApid(cfdpInCcsdsApid) {} const char* CfdpTmFunnel::getName() const { return "CFDP TM Funnel"; } diff --git a/mission/tmtc/CfdpTmFunnel.h b/mission/tmtc/CfdpTmFunnel.h index a6d947fd..e294956a 100644 --- a/mission/tmtc/CfdpTmFunnel.h +++ b/mission/tmtc/CfdpTmFunnel.h @@ -12,7 +12,8 @@ class CfdpTmFunnel : public TmFunnelBase { public: - CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid, StorageManagerIF& tmStore); + CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid, StorageManagerIF& tmStore, + uint32_t messageDepth); [[nodiscard]] const char* getName() const override; ReturnValue_t performOperation(uint8_t opCode); ReturnValue_t initialize() override; -- 2.34.1 From 9044a5476c909a73c9d656086a0c92e8d3be2cc4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 13:38:41 +0100 Subject: [PATCH 08/14] even larger queues --- mission/core/GenericFactory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index d93c06b4..06627886 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -121,8 +121,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR); new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib); - *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 30); - *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, 60); + *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 50); + *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, 80); #if OBSW_ADD_TCPIP_BRIDGE == 1 (*cfdpFunnel)->addDestination(*tcpIpTmtcBridge, 0); (*pusFunnel)->addDestination(*tcpIpTmtcBridge, 0); -- 2.34.1 From 8e26ad2871657b02abff776a1b703b479844f657 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 15:10:42 +0100 Subject: [PATCH 09/14] simplify max RTD low level handler --- linux/devices/Max31865RtdLowlevelHandler.cpp | 24 ++++++++------------ linux/devices/Max31865RtdLowlevelHandler.h | 2 -- mission/core/GenericFactory.cpp | 6 ++--- mission/devices/Max31865EiveHandler.cpp | 13 +++++++---- mission/tmtc/VirtualChannel.cpp | 2 +- 5 files changed, 22 insertions(+), 25 deletions(-) diff --git a/linux/devices/Max31865RtdLowlevelHandler.cpp b/linux/devices/Max31865RtdLowlevelHandler.cpp index 1be2b1c2..38a9ac11 100644 --- a/linux/devices/Max31865RtdLowlevelHandler.cpp +++ b/linux/devices/Max31865RtdLowlevelHandler.cpp @@ -50,7 +50,7 @@ ReturnValue_t Max31865RtdReader::performOperation(uint8_t operationCode) { } bool Max31865RtdReader::rtdIsActive(uint8_t idx) { - if (rtds[idx]->on and rtds[idx]->active and rtds[idx]->configured) { + if (rtds[idx]->on and rtds[idx]->db.active and rtds[idx]->db.configured) { return true; } return false; @@ -69,7 +69,7 @@ bool Max31865RtdReader::periodicInitHandling() { if (rtd == nullptr) { continue; } - if ((rtd->on or rtd->active) and not rtd->configured and rtd->cd.hasTimedOut()) { + if ((rtd->on or rtd->db.active) and not rtd->db.configured and rtd->cd.hasTimedOut()) { ManualCsLockWrapper mg(csLock, gpioIF, rtd->spiCookie, csTimeoutType, csTimeoutMs); if (mg.lockResult != returnvalue::OK or mg.gpioResult != returnvalue::OK) { sif::error << "Max31865RtdReader::periodicInitHandling: Manual CS lock failed" << std::endl; @@ -95,13 +95,7 @@ bool Max31865RtdReader::periodicInitHandling() { if (result != returnvalue::OK) { handleSpiError(rtd, result, "clearFaultStatus"); } - rtd->configured = true; rtd->db.configured = true; - if (rtd->active) { - rtd->db.active = true; - } - } - if (rtd->active and rtd->configured and not rtd->db.active) { rtd->db.active = true; } } @@ -241,8 +235,8 @@ ReturnValue_t Max31865RtdReader::sendMessage(CookieIF* cookie, const uint8_t* se rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS); rtdCookie->cd.resetTimer(); rtdCookie->on = true; - rtdCookie->active = false; - rtdCookie->configured = false; + rtdCookie->db.active = false; + rtdCookie->db.configured = false; if (sendLen == 5) { thresholdHandler(rtdCookie, sendData); } @@ -254,10 +248,10 @@ ReturnValue_t Max31865RtdReader::sendMessage(CookieIF* cookie, const uint8_t* se rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS); rtdCookie->cd.resetTimer(); rtdCookie->on = true; - rtdCookie->active = true; - rtdCookie->configured = false; + rtdCookie->db.active = true; + rtdCookie->db.configured = false; } else { - rtdCookie->active = true; + rtdCookie->db.active = true; } if (sendLen == 5) { thresholdHandler(rtdCookie, sendData); @@ -266,8 +260,8 @@ ReturnValue_t Max31865RtdReader::sendMessage(CookieIF* cookie, const uint8_t* se } case (EiveMax31855::RtdCommands::OFF): { rtdCookie->on = false; - rtdCookie->active = false; - rtdCookie->configured = false; + rtdCookie->db.active = false; + rtdCookie->db.configured = false; break; } case (EiveMax31855::RtdCommands::HIGH_TRESHOLD): { diff --git a/linux/devices/Max31865RtdLowlevelHandler.h b/linux/devices/Max31865RtdLowlevelHandler.h index d3845bd5..89d66350 100644 --- a/linux/devices/Max31865RtdLowlevelHandler.h +++ b/linux/devices/Max31865RtdLowlevelHandler.h @@ -23,8 +23,6 @@ struct Max31865ReaderCookie : public CookieIF { Countdown cd = Countdown(MAX31865::WARMUP_MS); bool on = false; - bool configured = false; - bool active = false; bool writeLowThreshold = false; bool writeHighThreshold = false; uint16_t lowThreshold = 0; diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index 06627886..0e1926f4 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -86,8 +86,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun } { - PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {300, 32}, {250, 64}, - {150, 128}, {120, 1024}, {120, 2048}}; + PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {350, 32}, {350, 64}, + {200, 128}, {150, 1024}, {150, 2048}}; tmStore = new PoolManager(objects::TM_STORE, poolCfg); } @@ -114,7 +114,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun tcpServer->enableWiretapping(true); #endif /* OBSW_TCP_SERVER_WIRETAPPING == 1 */ #endif /* OBSW_USE_TMTC_TCP_BRIDGE == 0 */ - tcpIpTmtcBridge->setMaxNumberOfPacketsStored(300); + tcpIpTmtcBridge->setMaxNumberOfPacketsStored(150); #endif /* OBSW_ADD_TCPIP_BRIDGE == 1 */ auto* ccsdsDistrib = diff --git a/mission/devices/Max31865EiveHandler.cpp b/mission/devices/Max31865EiveHandler.cpp index 90e4b933..45f3a8d1 100644 --- a/mission/devices/Max31865EiveHandler.cpp +++ b/mission/devices/Max31865EiveHandler.cpp @@ -30,16 +30,13 @@ void Max31865EiveHandler::doStartUp() { } void Max31865EiveHandler::doShutDown() { - updatePeriodicReply(false, EiveMax31855::RtdCommands::EXCHANGE_SET_ID); if (state == InternalState::NONE or state == InternalState::ACTIVE or state == InternalState::ON) { state = InternalState::INACTIVE; transitionOk = false; - } else { - transitionOk = true; } if (state == InternalState::INACTIVE and transitionOk) { - setMode(_MODE_POWER_DOWN); + setMode(MODE_OFF); } } @@ -151,6 +148,14 @@ ReturnValue_t Max31865EiveHandler::interpretDeviceReply(DeviceCommandId_t id, if (getMode() == _MODE_START_UP and exchangeStruct.configured and state == InternalState::ON) { transitionOk = true; } + if (getMode() == _MODE_SHUT_DOWN) { + uint32_t dummy = 0; + } + if (getMode() == _MODE_SHUT_DOWN and not exchangeStruct.active) { + transitionOk = true; + return returnvalue::OK; + } + // Calculate resistance float rtdValue = exchangeStruct.adcCode * EiveMax31855::RTD_RREF_PT1000 / INT16_MAX; // calculate approximation diff --git a/mission/tmtc/VirtualChannel.cpp b/mission/tmtc/VirtualChannel.cpp index 9fe47b1c..b0f9391d 100644 --- a/mission/tmtc/VirtualChannel.cpp +++ b/mission/tmtc/VirtualChannel.cpp @@ -34,7 +34,7 @@ ReturnValue_t VirtualChannel::performOperation() { size_t size = 0; result = tmStore->getData(storeId, &data, &size); if (result != returnvalue::OK) { - sif::warning << "VirtualChannel::performOperation: Failed to read data from IPC store" + sif::warning << "VirtualChannel::performOperation: Failed to read data from TM store" << std::endl; tmStore->deleteData(storeId); return result; -- 2.34.1 From b742f91ea82bdf28187d52456d9bf961a35447bc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 15:11:19 +0100 Subject: [PATCH 10/14] remove debug dummy --- mission/devices/Max31865EiveHandler.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/mission/devices/Max31865EiveHandler.cpp b/mission/devices/Max31865EiveHandler.cpp index 45f3a8d1..db6f5a83 100644 --- a/mission/devices/Max31865EiveHandler.cpp +++ b/mission/devices/Max31865EiveHandler.cpp @@ -148,9 +148,6 @@ ReturnValue_t Max31865EiveHandler::interpretDeviceReply(DeviceCommandId_t id, if (getMode() == _MODE_START_UP and exchangeStruct.configured and state == InternalState::ON) { transitionOk = true; } - if (getMode() == _MODE_SHUT_DOWN) { - uint32_t dummy = 0; - } if (getMode() == _MODE_SHUT_DOWN and not exchangeStruct.active) { transitionOk = true; return returnvalue::OK; -- 2.34.1 From 89083cdbc8886bb445ecae922f6ac3f09e9ea49d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 15:29:54 +0100 Subject: [PATCH 11/14] important bugfix --- mission/tmtc/CfdpTmFunnel.cpp | 11 +++++++++-- mission/tmtc/PusTmFunnel.cpp | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/mission/tmtc/CfdpTmFunnel.cpp b/mission/tmtc/CfdpTmFunnel.cpp index f62e68e3..aff7c95d 100644 --- a/mission/tmtc/CfdpTmFunnel.cpp +++ b/mission/tmtc/CfdpTmFunnel.cpp @@ -70,12 +70,19 @@ ReturnValue_t CfdpTmFunnel::handlePacket(TmTcMessage& msg) { for (unsigned int idx = 0; idx < destinations.size(); idx++) { const auto& destVcidPair = destinations[idx]; if (destinations.size() > 1) { - if (idx <= destinations.size() - 1) { + if (idx < destinations.size() - 1) { // Create copy of data to ensure each TM recipient has its own copy. That way, we don't need // to bother with send order and where the data is deleted. store_address_t storeId; result = tmStore.addData(&storeId, newPacketData, serSize); - msg.setStorageId(storeId); + if (result == returnvalue::OK) { + msg.setStorageId(storeId); + } else { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "PusTmFunnel::handlePacket: Store too full to create data copy" + << std::endl; +#endif + } } else { msg.setStorageId(origStoreId); } diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index a776e6b9..5d6bbb4d 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -51,12 +51,19 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { for (unsigned int idx = 0; idx < destinations.size(); idx++) { const auto &destVcidPair = destinations[idx]; if (destinations.size() > 1) { - if (idx <= destinations.size() - 1) { + if (idx < destinations.size() - 1) { // Create copy of data to ensure each TM recipient has its own copy. That way, we don't need // to bother with send order and where the data is deleted. store_address_t storeId; result = tmStore.addData(&storeId, packetData, size); - message.setStorageId(storeId); + if (result == returnvalue::OK) { + message.setStorageId(storeId); + } else { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "PusTmFunnel::handlePacket: Store too full to create data copy" + << std::endl; +#endif + } } else { message.setStorageId(origStoreId); } -- 2.34.1 From 7ce9bbf2e8e63aa934210e6eed8ffc8f6c969670 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 15:33:29 +0100 Subject: [PATCH 12/14] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index e5b5c7d2..84b9d1ce 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit e5b5c7d2533cd25dbe53d33be540babf15a3c70b +Subproject commit 84b9d1ce216c076bdfeeaf1663aa873c7f1c9cff -- 2.34.1 From 60d81fac4176aead95145f596e0b61e8f227ebc7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 15:34:07 +0100 Subject: [PATCH 13/14] bump changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a449a030..8781ab5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ list yields a list of all related PRs for each release. PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/310 - Extended TM funnels to allow multiple TM recipients. PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/312 +- DHB: Transitions to normal mode now possible directly, which simplifies subsystem implementations + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/313 # [v1.15.0] 27.10.2022 -- 2.34.1 From 6069948b4e352c3e6ecf66463fb121c4171897ba Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Nov 2022 15:35:32 +0100 Subject: [PATCH 14/14] bump changelog again --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8781ab5f..146628b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,9 @@ list yields a list of all related PRs for each release. PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/312 - DHB: Transitions to normal mode now possible directly, which simplifies subsystem implementations PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/313 +- MAX3185 Low Level Handler and Device Handler: Simplifications and bugfixes to allow switching + off without triggering unrequested replies + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/313 # [v1.15.0] 27.10.2022 -- 2.34.1