diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ef68b2a..91fbd0b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,16 @@ list yields a list of all related PRs for each release. # [unreleased] +- Add IRQ mode for PDEC handler + 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 +- 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 - Consistent device file naming diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index 29b1dda8..a3c94fe1 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -59,7 +59,9 @@ void Factory::setStaticFrameworkObjectIds() { void ObjectFactory::produce(void* args) { Factory::setStaticFrameworkObjectIds(); - ObjectFactory::produceGenericObjects(); + PusTmFunnel* pusFunnel; + CfdpTmFunnel* cfdpFunnel; + ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel); dummy::DummyCfg cfg; dummy::createDummies(cfg); diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index 21b9db2d..1db53d3e 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -21,6 +21,7 @@ static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio_pdec_regs"; static constexpr char UIO_PTME[] = "/dev/uio_ptme"; static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio_pdec_cfg_mem"; static constexpr char UIO_PDEC_RAM[] = "/dev/uio_pdec_ram"; +static constexpr char UIO_PDEC_IRQ[] = "/dev/uio_pdec_irq"; static constexpr int MAP_ID_PTME_CONFIG = 3; namespace uiomapids { diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 67dbfabb..4423a8fe 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -131,7 +131,7 @@ void initmission::initTasks() { // If a command has not been read before the next one arrives, the old command will be // overwritten by the PDEC. PeriodicTaskIF* pdecHandlerTask = factory->createPeriodicTask( - "PDEC_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc); + "PDEC_HANDLER", 75, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc); result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER); if (result != returnvalue::OK) { initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER); @@ -467,7 +467,7 @@ void initmission::createPusTasks(TaskFactory& factory, taskVec.push_back(pusEvents); PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask( - "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); if (result != returnvalue::OK) { initmission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS); @@ -476,6 +476,7 @@ void initmission::createPusTasks(TaskFactory& factory, if (result != returnvalue::OK) { initmission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT); } + taskVec.push_back(pusHighPrio); PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask( @@ -505,14 +506,15 @@ void initmission::createPusTasks(TaskFactory& factory, if (result != returnvalue::OK) { initmission::printAddObjectError("PUS_201", objects::PUS_SERVICE_201_HEALTH); } + // Used for connection tests, therefore use higher priority + result = pusMedPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if (result != returnvalue::OK) { + initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST); + } taskVec.push_back(pusMedPrio); PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask( "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); - result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); - if (result != returnvalue::OK) { - initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST); - } result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER); if (result != returnvalue::OK) { initmission::printAddObjectError("ERROR_REPORTER", objects::INTERNAL_ERROR_REPORTER); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 808df06b..3f6b2ac6 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -30,11 +30,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/fdir/AcsBoardFdir.h" #include "mission/system/fdir/GomspacePowerFdir.h" @@ -92,8 +92,8 @@ #include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" #include "mission/devices/devicedefinitions/payloadPcduDefinitions.h" #include "mission/system/objects/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; @@ -706,7 +706,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; @@ -769,18 +770,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; @@ -789,8 +791,13 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) { Levels::LOW); gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio); gpioChecker(gpioComIF->addGpios(gpioCookiePdec), "PDEC"); + struct UioNames uioNames {}; + uioNames.configMemory = q7s::UIO_PDEC_CONFIG_MEMORY; + uioNames.ramMemory = q7s::UIO_PDEC_RAM; + uioNames.registers = q7s::UIO_PDEC_REGISTERS; + uioNames.irq = q7s::UIO_PDEC_IRQ; new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET, - q7s::UIO_PDEC_CONFIG_MEMORY, q7s::UIO_PDEC_RAM, q7s::UIO_PDEC_REGISTERS); + uioNames); GpioCookie* gpioRS485Chip = new GpioCookie; gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver", Direction::OUT, Levels::LOW); 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..8667154b 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; @@ -33,6 +35,9 @@ void ObjectFactory::produce(void* args) { // level components. dummy::DummyCfg dummyCfg; dummyCfg.addCoreCtrlCfg = false; +#if OBSW_ADD_SYRLINKS == 1 + dummyCfg.addSyrlinksDummies = false; +#endif dummy::createDummies(dummyCfg); new CoreController(objects::CORE_CONTROLLER); @@ -63,6 +68,10 @@ void ObjectFactory::produce(void* args) { createImtqComponents(pwrSwitcher); #endif +#if OBSW_ADD_SYRLINKS == 1 + createSyrlinksComponents(pwrSwitcher); +#endif /* OBSW_ADD_SYRLINKS == 1 */ + #if OBSW_ADD_RW == 1 createReactionWheelComponents(gpioComIF, pwrSwitcher); #endif @@ -75,7 +84,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 @@ -85,5 +98,5 @@ void ObjectFactory::produce(void* args) { createScexComponents(q7s::UART_SCEX_DEV, pwrSwitcher, *SdCardManager::instance(), true, std::nullopt); #endif - createAcsController(); + createAcsController(true); } diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index 53bbb7ba..ac5037ec 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -16,7 +16,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; @@ -62,7 +64,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/dummies/CoreControllerDummy.cpp b/dummies/CoreControllerDummy.cpp index fd2e3f63..8a027dbf 100644 --- a/dummies/CoreControllerDummy.cpp +++ b/dummies/CoreControllerDummy.cpp @@ -6,8 +6,7 @@ #include #include -CoreControllerDummy::CoreControllerDummy(object_id_t objectId) - : ExtendedControllerBase(objectId, objects::NO_OBJECT) {} +CoreControllerDummy::CoreControllerDummy(object_id_t objectId) : ExtendedControllerBase(objectId) {} ReturnValue_t CoreControllerDummy::initialize() { static bool done = false; diff --git a/dummies/SusDummy.cpp b/dummies/SusDummy.cpp index 2a2a1bda..6d02ba69 100644 --- a/dummies/SusDummy.cpp +++ b/dummies/SusDummy.cpp @@ -5,8 +5,7 @@ #include #include -SusDummy::SusDummy() - : ExtendedControllerBase(objects::SUS_0_N_LOC_XFYFZM_PT_XF, objects::NO_OBJECT), susSet(this) { +SusDummy::SusDummy() : ExtendedControllerBase(objects::SUS_0_N_LOC_XFYFZM_PT_XF), susSet(this) { ObjectManager::instance()->insert(objects::SUS_6_R_LOC_XFYBZM_PT_XF, this); ObjectManager::instance()->insert(objects::SUS_1_N_LOC_XBYFZM_PT_XB, this); ObjectManager::instance()->insert(objects::SUS_7_R_LOC_XBYBZM_PT_XB, this); diff --git a/dummies/TemperatureSensorsDummy.cpp b/dummies/TemperatureSensorsDummy.cpp index 49194e91..c580473a 100644 --- a/dummies/TemperatureSensorsDummy.cpp +++ b/dummies/TemperatureSensorsDummy.cpp @@ -6,7 +6,7 @@ #include TemperatureSensorsDummy::TemperatureSensorsDummy() - : ExtendedControllerBase(objects::RTD_0_IC3_PLOC_HEATSPREADER, objects::NO_OBJECT), + : ExtendedControllerBase(objects::RTD_0_IC3_PLOC_HEATSPREADER), max31865Set(this, MAX31865::MAX31865_SET_ID) { ObjectManager::instance()->insert(objects::RTD_1_IC4_PLOC_MISSIONBOARD, this); ObjectManager::instance()->insert(objects::RTD_2_IC5_4K_CAMERA, this); diff --git a/dummies/helpers.cpp b/dummies/helpers.cpp index 2b18cffd..495d6f6c 100644 --- a/dummies/helpers.cpp +++ b/dummies/helpers.cpp @@ -38,7 +38,9 @@ void dummy::createDummies(DummyCfg cfg) { new RwDummy(objects::RW4, objects::DUMMY_COM_IF, comCookieDummy); new SaDeplDummy(objects::SOLAR_ARRAY_DEPL_HANDLER); new StarTrackerDummy(objects::STAR_TRACKER, objects::DUMMY_COM_IF, comCookieDummy); - new SyrlinksDummy(objects::SYRLINKS_HK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); + if (cfg.addSyrlinksDummies) { + new SyrlinksDummy(objects::SYRLINKS_HK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); + } new ImtqDummy(objects::IMTQ_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); if (cfg.addPowerDummies) { new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); diff --git a/dummies/helpers.h b/dummies/helpers.h index 680f97c1..f509f316 100644 --- a/dummies/helpers.h +++ b/dummies/helpers.h @@ -5,6 +5,7 @@ namespace dummy { struct DummyCfg { bool addCoreCtrlCfg = true; bool addPowerDummies = true; + bool addSyrlinksDummies = true; bool addAcsBoardDummies = true; bool addSusDummies = true; bool addTempSensorDummies = true; diff --git a/fsfw b/fsfw index 7600ed1e..84b9d1ce 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 7600ed1ea70ef2998739800f84722dd7cadb7552 +Subproject commit 84b9d1ce216c076bdfeeaf1663aa873c7f1c9cff diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 05354cdc..7dace6d3 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -132,12 +132,13 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/devices/ploc/PlocMemoryDumper.h 12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/devices/ploc/PlocMemoryDumper.h 12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/devices/ploc/PlocMemoryDumper.h -12401;0x3071;INVALID_TC_FRAME;HIGH;;linux/obc/PdecHandler.h -12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/obc/PdecHandler.h -12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/obc/PdecHandler.h -12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/obc/PdecHandler.h -12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/obc/PdecHandler.h -12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/obc/PdecHandler.h +12401;0x3071;INVALID_TC_FRAME;HIGH;;linux/ipcore/PdecHandler.h +12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/PdecHandler.h +12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/PdecHandler.h +12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/PdecHandler.h +12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/PdecHandler.h +12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/PdecHandler.h +12407;0x3077;POLL_ERROR_PDEC;MEDIUM;;linux/ipcore/PdecHandler.h 12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/devices/startracker/StrHelper.h 12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/devices/startracker/StrHelper.h 12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/devices/startracker/StrHelper.h diff --git a/generators/bsp_q7s_returnvalues.csv b/generators/bsp_q7s_returnvalues.csv index fe4c5cfc..72c0868f 100644 --- a/generators/bsp_q7s_returnvalues.csv +++ b/generators/bsp_q7s_returnvalues.csv @@ -1,7 +1,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x0000;OK;System-wide code for ok.;0;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h 0x0001;Failed;Unspecified system-wide code for failed.;1;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h -0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/tmtc/CCSDSHandler.h +0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/tmtc/CcsdsIpCoreHandler.h 0x5d00;GOMS_PacketTooLong;;0;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h 0x5d01;GOMS_InvalidTableId;;1;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h 0x5d02;GOMS_InvalidAddress;;2;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 435474e8..dfaec6e0 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 233 translations. + * @brief Auto-generated event translation file. Contains 234 translations. * @details - * Generated on: 2022-10-27 09:17:50 + * Generated on: 2022-11-03 16:11:14 */ #include "translateEvents.h" @@ -144,6 +144,7 @@ const char *CARRIER_LOCK_STRING = "CARRIER_LOCK"; const char *BIT_LOCK_PDEC_STRING = "BIT_LOCK_PDEC"; const char *LOST_CARRIER_LOCK_PDEC_STRING = "LOST_CARRIER_LOCK_PDEC"; const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC"; +const char *POLL_ERROR_PDEC_STRING = "POLL_ERROR_PDEC"; const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED"; const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED"; const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL"; @@ -515,6 +516,8 @@ const char *translateEvents(Event event) { return LOST_CARRIER_LOCK_PDEC_STRING; case (12406): return LOST_BIT_LOCK_PDEC_STRING; + case (12407): + return POLL_ERROR_PDEC_STRING; case (12500): return IMAGE_UPLOAD_FAILED_STRING; case (12501): diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 2fca9350..1e676cbc 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 142 translations. - * Generated on: 2022-10-27 09:17:50 + * Generated on: 2022-11-03 16:11:14 */ #include "translateObjects.h" 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 831f8c17..24bb6254 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -18,13 +18,14 @@ #include #include #include -#include -#include #include "OBSWConfig.h" #include "devConf.h" #include "devices/addresses.h" #include "devices/gpioIds.h" +#include "eive/definitions.h" +#include "mission/system/objects/SusAssembly.h" +#include "mission/system/objects/TcsBoardAssembly.h" #include "mission/system/tree/acsModeTree.h" void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, @@ -354,3 +355,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 9c4ac63e..3704e9bd 100644 --- a/linux/ObjectFactory.h +++ b/linux/ObjectFactory.h @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #include #include @@ -29,4 +32,7 @@ void gpioChecker(ReturnValue_t result, std::string output); void createThermalController(); AcsController* createAcsController(bool connectSubsystem); +void addTmtcIpCoresToFunnels(CcsdsIpCoreHandler& ipCoreHandler, PusTmFunnel& pusFunnel, + CfdpTmFunnel& cfdpFunnel); + } // namespace ObjectFactory 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/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/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 435474e8..dfaec6e0 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 233 translations. + * @brief Auto-generated event translation file. Contains 234 translations. * @details - * Generated on: 2022-10-27 09:17:50 + * Generated on: 2022-11-03 16:11:14 */ #include "translateEvents.h" @@ -144,6 +144,7 @@ const char *CARRIER_LOCK_STRING = "CARRIER_LOCK"; const char *BIT_LOCK_PDEC_STRING = "BIT_LOCK_PDEC"; const char *LOST_CARRIER_LOCK_PDEC_STRING = "LOST_CARRIER_LOCK_PDEC"; const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC"; +const char *POLL_ERROR_PDEC_STRING = "POLL_ERROR_PDEC"; const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED"; const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED"; const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL"; @@ -515,6 +516,8 @@ const char *translateEvents(Event event) { return LOST_CARRIER_LOCK_PDEC_STRING; case (12406): return LOST_BIT_LOCK_PDEC_STRING; + case (12407): + return POLL_ERROR_PDEC_STRING; case (12500): return IMAGE_UPLOAD_FAILED_STRING; case (12501): diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 2fca9350..1e676cbc 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 142 translations. - * Generated on: 2022-10-27 09:17:50 + * Generated on: 2022-11-03 16:11:14 */ #include "translateObjects.h" 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 82% rename from linux/obc/PdecConfig.cpp rename to linux/ipcore/PdecConfig.cpp index ac762a6c..321e5940 100644 --- a/linux/obc/PdecConfig.cpp +++ b/linux/ipcore/PdecConfig.cpp @@ -31,3 +31,8 @@ uint32_t PdecConfig::getConfigWord(uint8_t wordNo) { } return configWords[wordNo]; } + +uint32_t PdecConfig::getImrReg() { + return static_cast(enableNewFarIrq << 2) | + static_cast(enableTcAbortIrq << 1) | static_cast(enableTcNewIrq); +} diff --git a/linux/obc/PdecConfig.h b/linux/ipcore/PdecConfig.h similarity index 92% rename from linux/obc/PdecConfig.h rename to linux/ipcore/PdecConfig.h index e037dd56..284af6ef 100644 --- a/linux/obc/PdecConfig.h +++ b/linux/ipcore/PdecConfig.h @@ -23,6 +23,7 @@ class PdecConfig { * @brief Returns the configuration word by specifying the position. */ uint32_t getConfigWord(uint8_t wordNo); + uint32_t getImrReg(); private: // TC transfer frame configuration parameters @@ -45,6 +46,9 @@ class PdecConfig { static const uint8_t CONFIG_WORDS_NUM = 2; uint32_t configWords[CONFIG_WORDS_NUM]; + bool enableTcNewIrq = true; + bool enableTcAbortIrq = true; + bool enableNewFarIrq = true; void initialize(); }; diff --git a/linux/obc/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp similarity index 82% rename from linux/obc/PdecHandler.cpp rename to linux/ipcore/PdecHandler.cpp index ebd17957..bc33a220 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -1,7 +1,9 @@ #include "PdecHandler.h" #include +#include #include +#include #include #include @@ -12,18 +14,21 @@ #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/tmtcservices/TmTcMessage.h" #include "fsfw_hal/linux/uio/UioMapper.h" +#include "pdec.h" + +using namespace pdec; + +// If this is ever shared, protect it with a mutex! +uint32_t PdecHandler::CURRENT_FAR = 0; PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId, - LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioConfigMemory, - std::string uioRamMemory, std::string uioRegisters) + LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names) : SystemObject(objectId), tcDestinationId(tcDestinationId), gpioComIF(gpioComIF), pdecReset(pdecReset), - uioConfigMemory(uioConfigMemory), - uioRamMemory(uioRamMemory), - uioRegisters(uioRegisters), - actionHelper(this, nullptr) { + actionHelper(this, nullptr), + uioNames(names) { auto mqArgs = MqArgs(objectId, static_cast(this)); commandQueue = QueueFactory::instance()->createMessageQueue( QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); @@ -47,29 +52,39 @@ ReturnValue_t PdecHandler::initialize() { ReturnValue_t result = returnvalue::OK; - UioMapper regMapper(uioRegisters); + UioMapper regMapper(uioNames.registers); result = regMapper.getMappedAdress(®isterBaseAddress, UioMapper::Permissions::READ_WRITE); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } - UioMapper configMemMapper(uioConfigMemory); + UioMapper configMemMapper(uioNames.configMemory); result = configMemMapper.getMappedAdress(&memoryBaseAddress, UioMapper::Permissions::READ_WRITE); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } - UioMapper ramMapper(uioRamMemory); + UioMapper ramMapper(uioNames.ramMemory); result = ramMapper.getMappedAdress(&ramBaseAddress, UioMapper::Permissions::READ_WRITE); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } - writePdecConfig(); + if (OP_MODE == Modes::IRQ and uioNames.irq == nullptr) { + sif::error << "Can not use IRQ mode if IRQ UIO name is invalid" << std::endl; + return returnvalue::FAILED; + } + PdecConfig pdecConfig; + writePdecConfigDuringReset(pdecConfig); result = releasePdec(); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } + // This configuration must be done while the PDEC is not held in reset. + if (OP_MODE == Modes::IRQ) { + // Configure interrupt mask register to enable interrupts + *(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); + } result = actionHelper.initialize(commandQueue); if (result != returnvalue::OK) { return result; @@ -78,59 +93,16 @@ ReturnValue_t PdecHandler::initialize() { return returnvalue::OK; } -MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); } - -void PdecHandler::writePdecConfig() { - PdecConfig pdecConfig; - - *(memoryBaseAddress + FRAME_HEADER_OFFSET) = pdecConfig.getConfigWord(0); - *(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1); - - // Configure all MAP IDs as invalid - for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { - *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx / 4) = - NO_DESTINATION << 24 | NO_DESTINATION << 16 | NO_DESTINATION << 8 | NO_DESTINATION; - } - - // All TCs with MAP ID 7 will be routed to the PM module (can then be read from memory) - uint8_t routeToPm = calcMapAddrEntry(PM_BUFFER); - *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + 1) = - (NO_DESTINATION << 24) | (NO_DESTINATION << 16) | (NO_DESTINATION << 8) | routeToPm; - - // Write map id clock frequencies - for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { - *(memoryBaseAddress + MAP_CLK_FREQ_OFFSET + idx / 4) = - MAP_CLK_FREQ << 24 | MAP_CLK_FREQ << 16 | MAP_CLK_FREQ << 8 | MAP_CLK_FREQ; - } -} - -ReturnValue_t PdecHandler::resetFarStatFlag() { - uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); - if (pdecFar != FAR_RESET) { - sif::warning << "PdecHandler::resetFarStatFlag: FAR register did not match expected value." - << " Read value: 0x" << std::hex << static_cast(pdecFar) - << std::endl; - return returnvalue::FAILED; - } -#if OBSW_DEBUG_PDEC_HANDLER == 1 - sif::debug << "PdecHandler::resetFarStatFlag: read FAR with value: 0x" << std::hex << pdecFar - << std::endl; -#endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */ - return returnvalue::OK; -} - -ReturnValue_t PdecHandler::releasePdec() { - ReturnValue_t result = returnvalue::OK; - result = gpioComIF->pullHigh(pdecReset); - if (result != returnvalue::OK) { - sif::error << "PdecHandler::releasePdec: Failed to release PDEC reset signal" << std::endl; - } - return result; -} - ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { - ReturnValue_t result = returnvalue::OK; + if (OP_MODE == Modes::POLLED) { + return polledOperation(); + } else if (OP_MODE == Modes::IRQ) { + return irqOperation(); + } +} +ReturnValue_t PdecHandler::polledOperation() { + ReturnValue_t result = returnvalue::OK; readCommandQueue(); switch (state) { @@ -153,13 +125,94 @@ ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { case State::WAIT_FOR_RECOVERY: break; default: - sif::debug << "PdecHandler::performOperation: Invalid state" << std::endl; + sif::error << "PdecHandler::performOperation: Invalid state" << std::endl; break; } return returnvalue::OK; } +ReturnValue_t PdecHandler::irqOperation() { + ReturnValue_t result = returnvalue::OK; + int fd = open(uioNames.irq, O_RDWR); + if (fd < 0) { + sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed" + << std::endl; + return returnvalue::FAILED; + } + + struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0}; + // Used to unmask IRQ + uint32_t info = 1; + ssize_t nb = 0; + int ret = 0; + // Clear interrupts with dummy read before unmasking the interrupt + ret = *(registerBaseAddress + PDEC_PIR_OFFSET); + + while (true) { + readCommandQueue(); + switch (state) { + case State::INIT: + resetFarStatFlag(); + if (result != returnvalue::OK) { + // Requires reconfiguration and reinitialization of PDEC + triggerEvent(INVALID_FAR); + state = State::WAIT_FOR_RECOVERY; + return result; + } + state = State::RUNNING; + break; + case State::RUNNING: { + nb = write(fd, &info, sizeof(info)); + if (nb != static_cast(sizeof(info))) { + sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl; + close(fd); + } + + ret = poll(&fds, 1, IRQ_TIMEOUT_MS); + if (ret == 0) { + // No TCs for timeout period + checkLocks(); + lockCheckCd.resetTimer(); + } else if (ret >= 1) { + nb = read(fd, &info, sizeof(info)); + if (nb == static_cast(sizeof(info))) { + uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET); + if ((pisr & TC_NEW_MASK) == TC_NEW_MASK) { + // handle TC + handleNewTc(); + } + if ((pisr & TC_ABORT_MASK) == TC_ABORT_MASK) { + tcAbortCounter += 1; + } + if ((pisr & NEW_FAR_MASK) == NEW_FAR_MASK) { + // Read FAR here + CURRENT_FAR = readFar(); + } + if (lockCheckCd.hasTimedOut()) { + checkLocks(); + lockCheckCd.resetTimer(); + } + // Clear interrupts with dummy read + ret = *(registerBaseAddress + PDEC_PIR_OFFSET); + } + } else { + sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": " + << strerror(errno) << std::endl; + triggerEvent(POLL_ERROR_PDEC, errno); + } + break; + } + case State::WAIT_FOR_RECOVERY: + break; + default: + sif::error << "PdecHandler::performOperation: Invalid state" << std::endl; + break; + } + } + return returnvalue::OK; +} + void PdecHandler::readCommandQueue(void) { CommandMessage commandMessage; ReturnValue_t result = returnvalue::FAILED; @@ -177,13 +230,65 @@ void PdecHandler::readCommandQueue(void) { } } +MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); } + +void PdecHandler::writePdecConfigDuringReset(PdecConfig& pdecConfig) { + *(memoryBaseAddress + FRAME_HEADER_OFFSET) = pdecConfig.getConfigWord(0); + *(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1); + + // Configure all MAP IDs as invalid + for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { + *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx / 4) = + NO_DESTINATION << 24 | NO_DESTINATION << 16 | NO_DESTINATION << 8 | NO_DESTINATION; + } + + // All TCs with MAP ID 7 will be routed to the PM module (can then be read from memory) + uint8_t routeToPm = calcMapAddrEntry(PM_BUFFER); + *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + 1) = + (NO_DESTINATION << 24) | (NO_DESTINATION << 16) | (NO_DESTINATION << 8) | routeToPm; + + // Write map id clock frequencies + for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { + *(memoryBaseAddress + MAP_CLK_FREQ_OFFSET + idx / 4) = + MAP_CLK_FREQ << 24 | MAP_CLK_FREQ << 16 | MAP_CLK_FREQ << 8 | MAP_CLK_FREQ; + } +} + +ReturnValue_t PdecHandler::resetFarStatFlag() { + uint32_t pdecFar = readFar(); + if ((pdecFar & FAR_STAT_MASK) != 0) { + sif::warning << "PdecHandler::resetFarStatFlag: FAR register stat bit is not 0." + << " Read value for FAR: 0x" << std::hex << static_cast(pdecFar) + << std::endl; + CURRENT_FAR = pdecFar; + return returnvalue::FAILED; + } +#if OBSW_DEBUG_PDEC_HANDLER == 1 + sif::debug << "PdecHandler::resetFarStatFlag: read FAR with value: 0x" << std::hex << pdecFar + << std::endl; +#endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */ + CURRENT_FAR = pdecFar; + return returnvalue::OK; +} + +ReturnValue_t PdecHandler::releasePdec() { + ReturnValue_t result = returnvalue::OK; + result = gpioComIF->pullHigh(pdecReset); + if (result != returnvalue::OK) { + sif::error << "PdecHandler::releasePdec: Failed to release PDEC reset signal" << std::endl; + } + return result; +} + bool PdecHandler::newTcReceived() { - uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); + uint32_t pdecFar = readFar(); if (pdecFar >> STAT_POSITION != NEW_FAR_RECEIVED) { + CURRENT_FAR = pdecFar; return false; } if (!checkFrameAna(pdecFar)) { + CURRENT_FAR = pdecFar; return false; } return true; @@ -331,7 +436,6 @@ void PdecHandler::handleNewTc() { printTC(tcLength); #endif /* OBSW_DEBUG_PDEC_HANDLER */ -#if OBSW_TC_FROM_PDEC == 1 store_address_t storeId; result = tcStore->addData(&storeId, tcSegment + 1, tcLength - 1); if (result != returnvalue::OK) { @@ -349,7 +453,6 @@ void PdecHandler::handleNewTc() { tcStore->deleteData(storeId); return; } -#endif /* OBSW_TC_FROM_PDEC == 1 */ return; } @@ -500,6 +603,8 @@ void PdecHandler::printPdecMon() { sif::info << std::setw(30) << std::left << "Start sequence lock: " << lock << std::endl; } +uint32_t PdecHandler::readFar() { return *(registerBaseAddress + PDEC_FAR_OFFSET); } + std::string PdecHandler::getMonStatusString(uint32_t status) { switch (status) { case TC_CHANNEL_INACTIVE: diff --git a/linux/obc/PdecHandler.h b/linux/ipcore/PdecHandler.h similarity index 84% rename from linux/obc/PdecHandler.h rename to linux/ipcore/PdecHandler.h index 57adfa9f..b7089999 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -1,6 +1,8 @@ #ifndef LINUX_OBC_PDECHANDLER_H_ #define LINUX_OBC_PDECHANDLER_H_ +#include + #include "OBSWConfig.h" #include "PdecConfig.h" #include "fsfw/action/ActionHelper.h" @@ -13,6 +15,13 @@ #include "fsfw_hal/common/gpio/gpioDefinitions.h" #include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" +struct UioNames { + const char* configMemory; + const char* ramMemory; + const char* registers; + const char* irq; +}; + /** * @brief This class controls the PDEC IP Core implemented in the programmable logic of the * Zynq-7020. All registers and memories of the PDEC IP Core are accessed via UIO @@ -33,6 +42,10 @@ */ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasActionsIF { public: + static constexpr dur_millis_t IRQ_TIMEOUT_MS = 500; + + enum class Modes { POLLED, IRQ }; + /** * @brief Constructor * @param objectId Object ID of PDEC handler system object @@ -43,8 +56,7 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc * @param uioregsiters String of uio device file same mapped to the PDEC register space */ PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF, - gpioId_t pdecReset, std::string uioConfigMemory, std::string uioRamMemory, - std::string uioRegisters); + gpioId_t pdecReset, UioNames names); virtual ~PdecHandler(); @@ -74,10 +86,13 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO); //! [EXPORT] : [COMMENT] Lost bit lock static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO); + static constexpr Event POLL_ERROR_PDEC = event::makeEvent(SUBSYSTEM_ID, 7, severity::MEDIUM); private: static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; + static constexpr Modes OP_MODE = Modes::IRQ; + static const ReturnValue_t ABANDONED_CLTU = MAKE_RETURN_CODE(0xA0); static const ReturnValue_t FRAME_DIRTY = MAKE_RETURN_CODE(0xA1); static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2); @@ -112,48 +127,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc // Print PDEC monitor register static const ActionId_t PRINT_PDEC_MON = 1; - static const uint8_t STAT_POSITION = 31; - static const uint8_t FRAME_ANA_POSITION = 28; - static const uint8_t IREASON_POSITION = 25; - - static const uint8_t NEW_FAR_RECEIVED = 0; - - static const uint32_t FRAME_ANA_MASK = 0x70000000; - static const uint32_t IREASON_MASK = 0x0E000000; - - static const uint32_t TC_CHANNEL_INACTIVE = 0x0; - static const uint32_t TC_CHANNEL_ACTIVE = 0x1; - static const uint32_t TC_CHANNEL_TIMEDOUT = 0x2; - - static const uint32_t TC0_STATUS_MASK = 0x3; - static const uint32_t TC1_STATUS_MASK = 0xC; - static const uint32_t TC2_STATUS_MASK = 0x300; - static const uint32_t TC3_STATUS_MASK = 0xC00; - static const uint32_t TC4_STATUS_MASK = 0x30000; - static const uint32_t TC5_STATUS_MASK = 0xc00000; - // Lock register set to 1 when start sequence has been found (CLTU is beeing processed) - static const uint32_t LOCK_MASK = 0xc00000; - - static const uint32_t TC0_STATUS_POS = 0; - static const uint32_t TC1_STATUS_POS = 2; - static const uint32_t TC2_STATUS_POS = 4; - static const uint32_t TC3_STATUS_POS = 6; - static const uint32_t TC4_STATUS_POS = 8; - static const uint32_t TC5_STATUS_POS = 10; - // Lock register set to 1 when start sequence has been found (CLTU is beeing processed) - static const uint32_t LOCK_POS = 12; - - /** - * UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4 - * Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10 - */ - static const uint32_t PDEC_FAR_OFFSET = 0xA10; - static const uint32_t PDEC_CLCW_OFFSET = 0xA12; - static const uint32_t PDEC_BFREE_OFFSET = 0xA24; - static const uint32_t PDEC_BPTR_OFFSET = 0xA25; - static const uint32_t PDEC_SLEN_OFFSET = 0xA26; - static const uint32_t PDEC_MON_OFFSET = 0xA27; - #ifdef TE0720_1CFA static const int CONFIG_MEMORY_MAP_SIZE = 0x400; static const int RAM_MAP_SIZE = 0x4000; @@ -227,16 +200,69 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc enum class State : uint8_t { INIT, RUNNING, WAIT_FOR_RECOVERY }; + static uint32_t CURRENT_FAR; + + Countdown lockCheckCd = Countdown(IRQ_TIMEOUT_MS); + object_id_t tcDestinationId; + + AcceptsTelecommandsIF* tcDestination = nullptr; + + LinuxLibgpioIF* gpioComIF = nullptr; + + /** + * Reset signal is required to hold PDEC in reset state until the configuration has been + * written to the appropriate memory space. + * Can also be used to reboot PDEC in case of erros. + */ + gpioId_t pdecReset = gpio::NO_GPIO; + + uint32_t tcAbortCounter = 0; + + ActionHelper actionHelper; + + StorageManagerIF* tcStore = nullptr; + + MessageQueueIF* commandQueue = nullptr; + + State state = State::INIT; + + /** + * Pointer pointing to base address of the PDEC memory space. + * This address is equivalent with the base address of the section named configuration area in + * the PDEC datasheet. + */ + uint32_t* memoryBaseAddress = nullptr; + + uint32_t* ramBaseAddress = nullptr; + + // Pointer pointing to base address of register space + uint32_t* registerBaseAddress = nullptr; + + uint8_t tcSegment[TC_SEGMENT_LEN]; + + // Used to check carrier and bit lock changes (default set to no rf and no bitlock) + uint32_t lastClcw = 0xC000; + + bool carrierLock = false; + bool bitLock = false; + + UioNames uioNames; + /** * @brief Reads and handles messages stored in the commandQueue */ void readCommandQueue(void); + ReturnValue_t polledOperation(); + ReturnValue_t irqOperation(); + + uint32_t readFar(); + /** * @brief This functions writes the configuration parameters to the configuration * section of the PDEC. */ - void writePdecConfig(); + void writePdecConfigDuringReset(PdecConfig& config); /** * @brief Reading the FAR resets the set stat flag which signals a new TC. Without clearing @@ -343,58 +369,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc void printPdecMon(); std::string getMonStatusString(uint32_t status); - - object_id_t tcDestinationId; - - AcceptsTelecommandsIF* tcDestination = nullptr; - - LinuxLibgpioIF* gpioComIF = nullptr; - - /** - * Reset signal is required to hold PDEC in reset state until the configuration has been - * written to the appropriate memory space. - * Can also be used to reboot PDEC in case of erros. - */ - gpioId_t pdecReset = gpio::NO_GPIO; - - // UIO device file giving access to the PDEC configuration memory section - std::string uioConfigMemory; - - // UIO device file giving access to the PDEC RAM section - std::string uioRamMemory; - - // UIO device file giving access to the PDEC register space - std::string uioRegisters; - - ActionHelper actionHelper; - - StorageManagerIF* tcStore = nullptr; - - MessageQueueIF* commandQueue = nullptr; - - State state = State::INIT; - - /** - * Pointer pointing to base address of the PDEC memory space. - * This address is equivalent with the base address of the section named configuration area in - * the PDEC datasheet. - */ - uint32_t* memoryBaseAddress = nullptr; - - uint32_t* ramBaseAddress = nullptr; - - // Pointer pointing to base address of register space - uint32_t* registerBaseAddress = nullptr; - - uint32_t pdecFar = 0; - - uint8_t tcSegment[TC_SEGMENT_LEN]; - - // Used to check carrier and bit lock changes (default set to no rf and no bitlock) - uint32_t lastClcw = 0xC000; - - bool carrierLock = false; - bool bitLock = false; }; #endif /* LINUX_OBC_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/linux/ipcore/pdec.h b/linux/ipcore/pdec.h new file mode 100644 index 00000000..16b0c2e6 --- /dev/null +++ b/linux/ipcore/pdec.h @@ -0,0 +1,61 @@ +#ifndef LINUX_OBC_PDEC_H_ +#define LINUX_OBC_PDEC_H_ + +#include + +namespace pdec { + +static const uint8_t STAT_POSITION = 31; +static const uint8_t FRAME_ANA_POSITION = 28; +static const uint8_t IREASON_POSITION = 25; + +static const uint8_t NEW_FAR_RECEIVED = 0; + +static constexpr uint32_t NEW_FAR_MASK = 1 << 2; +static constexpr uint32_t TC_ABORT_MASK = 1 << 1; +static constexpr uint32_t TC_NEW_MASK = 1 << 0; + +static constexpr uint32_t FAR_STAT_MASK = 1 << 31; + +static const uint32_t FRAME_ANA_MASK = 0x70000000; +static const uint32_t IREASON_MASK = 0x0E000000; + +static const uint32_t TC_CHANNEL_INACTIVE = 0x0; +static const uint32_t TC_CHANNEL_ACTIVE = 0x1; +static const uint32_t TC_CHANNEL_TIMEDOUT = 0x2; + +static const uint32_t TC0_STATUS_MASK = 0x3; +static const uint32_t TC1_STATUS_MASK = 0xC; +static const uint32_t TC2_STATUS_MASK = 0x300; +static const uint32_t TC3_STATUS_MASK = 0xC00; +static const uint32_t TC4_STATUS_MASK = 0x30000; +static const uint32_t TC5_STATUS_MASK = 0xc00000; +// Lock register set to 1 when start sequence has been found (CLTU is beeing processed) +static const uint32_t LOCK_MASK = 0xc00000; + +static const uint32_t TC0_STATUS_POS = 0; +static const uint32_t TC1_STATUS_POS = 2; +static const uint32_t TC2_STATUS_POS = 4; +static const uint32_t TC3_STATUS_POS = 6; +static const uint32_t TC4_STATUS_POS = 8; +static const uint32_t TC5_STATUS_POS = 10; +// Lock register set to 1 when start sequence has been found (CLTU is beeing processed) +static const uint32_t LOCK_POS = 12; + +/** + * UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4 + * Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10 + */ +static constexpr uint32_t PDEC_PISR_OFFSET = 0xA02; +static constexpr uint32_t PDEC_PIR_OFFSET = 0xA03; +static constexpr uint32_t PDEC_IMR_OFFSET = 0xA04; +static const uint32_t PDEC_FAR_OFFSET = 0xA10; +static const uint32_t PDEC_CLCW_OFFSET = 0xA12; +static const uint32_t PDEC_BFREE_OFFSET = 0xA24; +static const uint32_t PDEC_BPTR_OFFSET = 0xA25; +static const uint32_t PDEC_SLEN_OFFSET = 0xA26; +static const uint32_t PDEC_MON_OFFSET = 0xA27; + +} // namespace pdec + +#endif /* LINUX_OBC_PDEC_H_ */ diff --git a/mission/controller/ThermalController.cpp b/mission/controller/ThermalController.cpp index 5beccb4e..66fa2187 100644 --- a/mission/controller/ThermalController.cpp +++ b/mission/controller/ThermalController.cpp @@ -573,369 +573,344 @@ void ThermalController::copySus() { void ThermalController::copyDevices() { lp_var_t tempQ7s = lp_var_t(objects::CORE_CONTROLLER, core::PoolIds::TEMPERATURE); - ReturnValue_t result = tempQ7s.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read Q7S temperature" << std::endl; - deviceTemperatures.q7s.setValid(false); - deviceTemperatures.q7s = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.q7s = tempQ7s; - deviceTemperatures.q7s.setValid(tempQ7s.isValid()); + { + PoolReadGuard pg(&tempQ7s, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() == returnvalue::OK) { + deviceTemperatures.q7s = tempQ7s; + deviceTemperatures.q7s.setValid(tempQ7s.isValid()); + } else { + deviceTemperatures.q7s.setValid(false); + deviceTemperatures.q7s = static_cast(INVALID_TEMPERATURE); + } } - result = tempQ7s.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t battTemp1 = + lp_var_t(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_1); + PoolReadGuard pg(&battTemp1, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read battery temperature 1" << std::endl; + deviceTemperatures.batteryTemp1.setValid(false); + deviceTemperatures.batteryTemp1 = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.batteryTemp1 = battTemp1; + deviceTemperatures.batteryTemp1.setValid(battTemp1.isValid()); + } } - lp_var_t battTemp1 = - lp_var_t(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_1); - result = battTemp1.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read battery temperature 1" << std::endl; - deviceTemperatures.batteryTemp1.setValid(false); - deviceTemperatures.batteryTemp1 = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.batteryTemp1 = battTemp1; - deviceTemperatures.batteryTemp1.setValid(battTemp1.isValid()); + + { + lp_var_t battTemp2 = + lp_var_t(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_2); + PoolReadGuard pg(&battTemp2, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read battery temperature 2" << std::endl; + deviceTemperatures.batteryTemp2.setValid(false); + deviceTemperatures.batteryTemp2 = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.batteryTemp2 = battTemp2; + deviceTemperatures.batteryTemp2.setValid(battTemp2.isValid()); + } } - result = battTemp1.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t battTemp3 = + lp_var_t(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_3); + PoolReadGuard pg(&battTemp3, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read battery temperature 3" << std::endl; + deviceTemperatures.batteryTemp3.setValid(false); + deviceTemperatures.batteryTemp3 = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.batteryTemp3 = battTemp3; + deviceTemperatures.batteryTemp3.setValid(battTemp3.isValid()); + } } - lp_var_t battTemp2 = - lp_var_t(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_2); - result = battTemp2.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read battery temperature 2" << std::endl; - deviceTemperatures.batteryTemp2.setValid(false); - deviceTemperatures.batteryTemp2 = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.batteryTemp2 = battTemp2; - deviceTemperatures.batteryTemp2.setValid(battTemp2.isValid()); + + { + lp_var_t battTemp4 = + lp_var_t(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_4); + PoolReadGuard pg(&battTemp4, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read battery temperature 4" << std::endl; + deviceTemperatures.batteryTemp4.setValid(false); + deviceTemperatures.batteryTemp4 = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.batteryTemp4 = battTemp4; + deviceTemperatures.batteryTemp4.setValid(battTemp4.isValid()); + } } - result = battTemp2.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t tempRw1 = lp_var_t(objects::RW1, RwDefinitions::TEMPERATURE_C); + PoolReadGuard pg(&tempRw1, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read reaction wheel 1 temperature" << std::endl; + deviceTemperatures.rw1.setValid(false); + deviceTemperatures.rw1 = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.rw1.setValid(tempRw1.isValid()); + deviceTemperatures.rw1 = tempRw1; + } } - lp_var_t battTemp3 = - lp_var_t(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_3); - result = battTemp3.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read battery temperature 3" << std::endl; - deviceTemperatures.batteryTemp3.setValid(false); - deviceTemperatures.batteryTemp3 = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.batteryTemp3 = battTemp3; - deviceTemperatures.batteryTemp3.setValid(battTemp3.isValid()); + + { + lp_var_t tempRw2 = lp_var_t(objects::RW2, RwDefinitions::TEMPERATURE_C); + PoolReadGuard pg(&tempRw2, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read reaction wheel 2 temperature" << std::endl; + deviceTemperatures.rw2.setValid(false); + deviceTemperatures.rw2 = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.rw2.setValid(tempRw2.isValid()); + deviceTemperatures.rw2 = tempRw2; + } } - result = battTemp3.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t tempRw3 = lp_var_t(objects::RW3, RwDefinitions::TEMPERATURE_C); + PoolReadGuard pg(&tempRw3, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read reaction wheel 3 temperature" << std::endl; + deviceTemperatures.rw3.setValid(false); + deviceTemperatures.rw3 = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.rw3.setValid(tempRw3.isValid()); + deviceTemperatures.rw3 = tempRw3; + } } - lp_var_t battTemp4 = - lp_var_t(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_4); - result = battTemp4.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read battery temperature 4" << std::endl; - deviceTemperatures.batteryTemp4.setValid(false); - deviceTemperatures.batteryTemp4 = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.batteryTemp4 = battTemp4; - deviceTemperatures.batteryTemp4.setValid(battTemp4.isValid()); + + { + lp_var_t tempRw4 = lp_var_t(objects::RW4, RwDefinitions::TEMPERATURE_C); + PoolReadGuard pg(&tempRw4, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read reaction wheel 4 temperature" << std::endl; + deviceTemperatures.rw4.setValid(false); + deviceTemperatures.rw4 = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.rw4.setValid(tempRw4.isValid()); + deviceTemperatures.rw4 = tempRw4; + } } - result = battTemp4.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t tempStartracker = + lp_var_t(objects::STAR_TRACKER, startracker::MCU_TEMPERATURE); + PoolReadGuard pg(&tempStartracker, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read startracker temperature" << std::endl; + deviceTemperatures.startracker.setValid(false); + deviceTemperatures.startracker = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.startracker.setValid(tempStartracker.isValid()); + deviceTemperatures.startracker = tempStartracker; + } } - lp_var_t tempRw1 = lp_var_t(objects::RW1, RwDefinitions::TEMPERATURE_C); - result = tempRw1.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read reaction wheel 1 temperature" << std::endl; - deviceTemperatures.rw1.setValid(false); - deviceTemperatures.rw1 = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.rw1.setValid(tempRw1.isValid()); - deviceTemperatures.rw1 = tempRw1; + + { + lp_var_t tempSyrlinksPowerAmplifier = + lp_var_t(objects::SYRLINKS_HK_HANDLER, syrlinks::TEMP_POWER_AMPLIFIER); + PoolReadGuard pg(&tempSyrlinksPowerAmplifier, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read syrlinks power amplifier temperature" + << std::endl; + deviceTemperatures.syrlinksPowerAmplifier.setValid(false); + deviceTemperatures.syrlinksPowerAmplifier = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.syrlinksPowerAmplifier.setValid(tempSyrlinksPowerAmplifier.isValid()); + deviceTemperatures.syrlinksPowerAmplifier = tempSyrlinksPowerAmplifier; + } } - result = tempRw1.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t tempSyrlinksBasebandBoard = + lp_var_t(objects::SYRLINKS_HK_HANDLER, syrlinks::TEMP_BASEBAND_BOARD); + PoolReadGuard pg(&tempSyrlinksBasebandBoard, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read syrlinks baseband board temperature" + << std::endl; + deviceTemperatures.syrlinksBasebandBoard.setValid(false); + deviceTemperatures.syrlinksBasebandBoard = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.syrlinksBasebandBoard.setValid(tempSyrlinksBasebandBoard.isValid()); + deviceTemperatures.syrlinksBasebandBoard = tempSyrlinksBasebandBoard; + } } - lp_var_t tempRw2 = lp_var_t(objects::RW2, RwDefinitions::TEMPERATURE_C); - result = tempRw2.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read reaction wheel 2 temperature" << std::endl; - deviceTemperatures.rw2.setValid(false); - deviceTemperatures.rw2 = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.rw2.setValid(tempRw2.isValid()); - deviceTemperatures.rw2 = tempRw2; + + { + lp_var_t tempMgt = lp_var_t(objects::IMTQ_HANDLER, IMTQ::MCU_TEMPERATURE); + PoolReadGuard pg(&tempMgt, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read MGT temperature" << std::endl; + deviceTemperatures.mgt.setValid(false); + deviceTemperatures.mgt = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.mgt.setValid(tempMgt.isValid()); + deviceTemperatures.mgt = tempMgt; + } } - result = tempRw2.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_vec_t tempAcu = + lp_vec_t(objects::ACU_HANDLER, ACU::pool::ACU_TEMPERATURES); + PoolReadGuard pg(&tempAcu, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read ACU temperatures" << std::endl; + deviceTemperatures.acu.setValid(false); + deviceTemperatures.acu[0] = static_cast(INVALID_TEMPERATURE); + deviceTemperatures.acu[1] = static_cast(INVALID_TEMPERATURE); + deviceTemperatures.acu[2] = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.acu.setValid(tempAcu.isValid()); + deviceTemperatures.acu = tempAcu; + } } - lp_var_t tempRw3 = lp_var_t(objects::RW3, RwDefinitions::TEMPERATURE_C); - result = tempRw3.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read reaction wheel 3 temperature" << std::endl; - deviceTemperatures.rw3.setValid(false); - deviceTemperatures.rw3 = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.rw3.setValid(tempRw3.isValid()); - deviceTemperatures.rw3 = tempRw3; + + { + lp_var_t tempPdu1 = lp_var_t(objects::PDU1_HANDLER, PDU::pool::PDU_TEMPERATURE); + PoolReadGuard pg(&tempPdu1, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read PDU1 temperature" << std::endl; + deviceTemperatures.pdu1.setValid(false); + deviceTemperatures.pdu1 = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.pdu1.setValid(tempPdu1.isValid()); + deviceTemperatures.pdu1 = tempPdu1; + } } - result = tempRw3.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t tempPdu2 = lp_var_t(objects::PDU2_HANDLER, PDU::pool::PDU_TEMPERATURE); + PoolReadGuard pg(&tempPdu2, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read PDU2 temperature" << std::endl; + deviceTemperatures.pdu2.setValid(false); + deviceTemperatures.pdu2 = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.pdu2.setValid(tempPdu2.isValid()); + deviceTemperatures.pdu2 = tempPdu2; + } } - lp_var_t tempRw4 = lp_var_t(objects::RW4, RwDefinitions::TEMPERATURE_C); - result = tempRw4.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read reaction wheel 4 temperature" << std::endl; - deviceTemperatures.rw4.setValid(false); - deviceTemperatures.rw4 = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.rw4.setValid(tempRw4.isValid()); - deviceTemperatures.rw4 = tempRw4; + + { + lp_var_t temp1P60dock = + lp_var_t(objects::P60DOCK_HANDLER, P60Dock::pool::P60DOCK_TEMPERATURE_1); + PoolReadGuard pg(&temp1P60dock, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read P60 dock temperature 1" << std::endl; + deviceTemperatures.temp1P60dock.setValid(false); + deviceTemperatures.temp1P60dock = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.temp1P60dock.setValid(temp1P60dock.isValid()); + deviceTemperatures.temp1P60dock = temp1P60dock; + } } - result = tempRw4.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t temp2P60dock = + lp_var_t(objects::P60DOCK_HANDLER, P60Dock::pool::P60DOCK_TEMPERATURE_2); + PoolReadGuard pg(&temp2P60dock, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read P60 dock temperature 2" << std::endl; + deviceTemperatures.temp2P60dock.setValid(false); + deviceTemperatures.temp2P60dock = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.temp2P60dock.setValid(temp2P60dock.isValid()); + deviceTemperatures.temp2P60dock = temp2P60dock; + } } - lp_var_t tempStartracker = - lp_var_t(objects::STAR_TRACKER, startracker::MCU_TEMPERATURE); - result = tempStartracker.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read startracker temperature" << std::endl; - deviceTemperatures.startracker.setValid(false); - deviceTemperatures.startracker = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.startracker.setValid(tempStartracker.isValid()); - deviceTemperatures.startracker = tempStartracker; + + { + lp_var_t tempGyro0 = + lp_var_t(objects::GYRO_0_ADIS_HANDLER, ADIS1650X::TEMPERATURE); + PoolReadGuard pg(&tempGyro0, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read gyro 0 temperature" << std::endl; + deviceTemperatures.gyro0SideA.setValid(false); + deviceTemperatures.gyro0SideA = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.gyro0SideA.setValid(tempGyro0.isValid()); + deviceTemperatures.gyro0SideA = tempGyro0; + } } - result = tempStartracker.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t tempGyro1 = lp_var_t(objects::GYRO_1_L3G_HANDLER, L3GD20H::TEMPERATURE); + PoolReadGuard pg(&tempGyro1, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read gyro 1 temperature" << std::endl; + deviceTemperatures.gyro1SideA.setValid(false); + deviceTemperatures.gyro1SideA = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.gyro1SideA.setValid(tempGyro1.isValid()); + deviceTemperatures.gyro1SideA = tempGyro1; + } } - lp_var_t tempSyrlinksPowerAmplifier = - lp_var_t(objects::SYRLINKS_HK_HANDLER, syrlinks::TEMP_POWER_AMPLIFIER); - result = tempSyrlinksPowerAmplifier.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read syrlinks power amplifier temperature" - << std::endl; - deviceTemperatures.syrlinksPowerAmplifier.setValid(false); - deviceTemperatures.syrlinksPowerAmplifier = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.syrlinksPowerAmplifier.setValid(tempSyrlinksPowerAmplifier.isValid()); - deviceTemperatures.syrlinksPowerAmplifier = tempSyrlinksPowerAmplifier; + + { + lp_var_t tempGyro2 = + lp_var_t(objects::GYRO_2_ADIS_HANDLER, ADIS1650X::TEMPERATURE); + PoolReadGuard pg(&tempGyro2, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read gyro 2 temperature" << std::endl; + deviceTemperatures.gyro2SideB.setValid(false); + deviceTemperatures.gyro2SideB = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.gyro2SideB.setValid(tempGyro2.isValid()); + deviceTemperatures.gyro2SideB = tempGyro2; + } } - result = tempSyrlinksPowerAmplifier.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t tempGyro3 = lp_var_t(objects::GYRO_3_L3G_HANDLER, L3GD20H::TEMPERATURE); + PoolReadGuard pg(&tempGyro3, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read gyro 3 temperature" << std::endl; + deviceTemperatures.gyro3SideB.setValid(false); + deviceTemperatures.gyro3SideB = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.gyro3SideB.setValid(tempGyro3.isValid()); + deviceTemperatures.gyro3SideB = tempGyro3; + } } - lp_var_t tempSyrlinksBasebandBoard = - lp_var_t(objects::SYRLINKS_HK_HANDLER, syrlinks::TEMP_BASEBAND_BOARD); - result = tempSyrlinksBasebandBoard.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read syrlinks baseband board temperature" - << std::endl; - deviceTemperatures.syrlinksBasebandBoard.setValid(false); - deviceTemperatures.syrlinksBasebandBoard = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.syrlinksBasebandBoard.setValid(tempSyrlinksBasebandBoard.isValid()); - deviceTemperatures.syrlinksBasebandBoard = tempSyrlinksBasebandBoard; + + { + lp_var_t tempMgm0 = + lp_var_t(objects::MGM_0_LIS3_HANDLER, MGMLIS3MDL::TEMPERATURE_CELCIUS); + PoolReadGuard pg(&tempMgm0, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read MGM 0 temperature" << std::endl; + deviceTemperatures.mgm0SideA.setValid(false); + deviceTemperatures.mgm0SideA = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.mgm0SideA.setValid(tempMgm0.isValid()); + deviceTemperatures.mgm0SideA = tempMgm0; + } } - result = tempSyrlinksBasebandBoard.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t tempMgm2 = + lp_var_t(objects::MGM_2_LIS3_HANDLER, MGMLIS3MDL::TEMPERATURE_CELCIUS); + PoolReadGuard pg(&tempMgm2, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read MGM 2 temperature" << std::endl; + deviceTemperatures.mgm2SideB.setValid(false); + deviceTemperatures.mgm2SideB = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.mgm2SideB.setValid(tempMgm2.isValid()); + deviceTemperatures.mgm2SideB = tempMgm2; + } } - lp_var_t tempMgt = lp_var_t(objects::IMTQ_HANDLER, IMTQ::MCU_TEMPERATURE); - result = tempMgt.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read MGT temperature" << std::endl; - deviceTemperatures.mgt.setValid(false); - deviceTemperatures.mgt = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.mgt.setValid(tempMgt.isValid()); - deviceTemperatures.mgt = tempMgt; - } - result = tempMgt.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_vec_t tempAcu = - lp_vec_t(objects::ACU_HANDLER, ACU::pool::ACU_TEMPERATURES); - result = tempAcu.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read ACU temperatures" << std::endl; - deviceTemperatures.acu.setValid(false); - deviceTemperatures.acu[0] = static_cast(INVALID_TEMPERATURE); - deviceTemperatures.acu[1] = static_cast(INVALID_TEMPERATURE); - deviceTemperatures.acu[2] = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.acu.setValid(tempAcu.isValid()); - deviceTemperatures.acu = tempAcu; - } - result = tempAcu.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_var_t tempPdu1 = lp_var_t(objects::PDU1_HANDLER, PDU::pool::PDU_TEMPERATURE); - result = tempPdu1.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read PDU1 temperature" << std::endl; - deviceTemperatures.pdu1.setValid(false); - deviceTemperatures.pdu1 = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.pdu1.setValid(tempPdu1.isValid()); - deviceTemperatures.pdu1 = tempPdu1; - } - result = tempPdu1.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_var_t tempPdu2 = lp_var_t(objects::PDU2_HANDLER, PDU::pool::PDU_TEMPERATURE); - result = tempPdu2.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read PDU2 temperature" << std::endl; - deviceTemperatures.pdu2.setValid(false); - deviceTemperatures.pdu2 = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.pdu2.setValid(tempPdu1.isValid()); - deviceTemperatures.pdu2 = tempPdu1; - } - result = tempPdu2.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_var_t temp1P60dock = - lp_var_t(objects::P60DOCK_HANDLER, P60Dock::pool::P60DOCK_TEMPERATURE_1); - result = temp1P60dock.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read P60 dock temperature 1" << std::endl; - deviceTemperatures.temp1P60dock.setValid(false); - deviceTemperatures.temp1P60dock = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.temp1P60dock.setValid(temp1P60dock.isValid()); - deviceTemperatures.temp1P60dock = temp1P60dock; - } - result = temp1P60dock.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_var_t temp2P60dock = - lp_var_t(objects::P60DOCK_HANDLER, P60Dock::pool::P60DOCK_TEMPERATURE_2); - result = temp2P60dock.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read P60 dock temperature 2" << std::endl; - deviceTemperatures.temp2P60dock.setValid(false); - deviceTemperatures.temp2P60dock = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.temp2P60dock.setValid(temp2P60dock.isValid()); - deviceTemperatures.temp2P60dock = temp2P60dock; - } - result = temp2P60dock.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_var_t tempGyro0 = lp_var_t(objects::GYRO_0_ADIS_HANDLER, ADIS1650X::TEMPERATURE); - result = tempGyro0.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read gyro 0 temperature" << std::endl; - deviceTemperatures.gyro0SideA.setValid(false); - deviceTemperatures.gyro0SideA = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.gyro0SideA.setValid(tempGyro0.isValid()); - deviceTemperatures.gyro0SideA = tempGyro0; - } - result = tempGyro0.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_var_t tempGyro1 = lp_var_t(objects::GYRO_1_L3G_HANDLER, L3GD20H::TEMPERATURE); - result = tempGyro1.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read gyro 1 temperature" << std::endl; - deviceTemperatures.gyro1SideA.setValid(false); - deviceTemperatures.gyro1SideA = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.gyro1SideA.setValid(tempGyro1.isValid()); - deviceTemperatures.gyro1SideA = tempGyro1; - } - result = tempGyro1.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_var_t tempGyro2 = lp_var_t(objects::GYRO_2_ADIS_HANDLER, ADIS1650X::TEMPERATURE); - result = tempGyro2.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read gyro 2 temperature" << std::endl; - deviceTemperatures.gyro2SideB.setValid(false); - deviceTemperatures.gyro2SideB = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.gyro2SideB.setValid(tempGyro2.isValid()); - deviceTemperatures.gyro2SideB = tempGyro2; - } - result = tempGyro2.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_var_t tempGyro3 = lp_var_t(objects::GYRO_3_L3G_HANDLER, L3GD20H::TEMPERATURE); - result = tempGyro3.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read gyro 3 temperature" << std::endl; - deviceTemperatures.gyro3SideB.setValid(false); - deviceTemperatures.gyro3SideB = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.gyro3SideB.setValid(tempGyro3.isValid()); - deviceTemperatures.gyro3SideB = tempGyro3; - } - result = tempGyro3.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_var_t tempMgm0 = - lp_var_t(objects::MGM_0_LIS3_HANDLER, MGMLIS3MDL::TEMPERATURE_CELCIUS); - result = tempMgm0.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read MGM 0 temperature" << std::endl; - deviceTemperatures.mgm0SideA.setValid(false); - deviceTemperatures.mgm0SideA = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.mgm0SideA.setValid(tempMgm0.isValid()); - deviceTemperatures.mgm0SideA = tempMgm0; - } - result = tempMgm0.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_var_t tempMgm2 = - lp_var_t(objects::MGM_2_LIS3_HANDLER, MGMLIS3MDL::TEMPERATURE_CELCIUS); - result = tempMgm2.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read MGM 2 temperature" << std::endl; - deviceTemperatures.mgm2SideB.setValid(false); - deviceTemperatures.mgm2SideB = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.mgm2SideB.setValid(tempMgm2.isValid()); - deviceTemperatures.mgm2SideB = tempMgm2; - } - result = tempMgm2.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; - } - lp_var_t tempAdcPayloadPcdu = lp_var_t(objects::PLPCDU_HANDLER, plpcdu::TEMP); - result = tempAdcPayloadPcdu.read(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to read payload PCDU ADC temperature" << std::endl; - deviceTemperatures.adcPayloadPcdu.setValid(false); - deviceTemperatures.adcPayloadPcdu = static_cast(INVALID_TEMPERATURE); - } else { - deviceTemperatures.adcPayloadPcdu.setValid(tempAdcPayloadPcdu.isValid()); - deviceTemperatures.adcPayloadPcdu = tempAdcPayloadPcdu; - } - result = tempAdcPayloadPcdu.commit(); - if (result != returnvalue::OK) { - sif::warning << "ThermalController: Failed to commit" << std::endl; + + { + lp_var_t tempAdcPayloadPcdu = lp_var_t(objects::PLPCDU_HANDLER, plpcdu::TEMP); + PoolReadGuard pg(&tempAdcPayloadPcdu, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); + if (pg.getReadResult() != returnvalue::OK) { + sif::warning << "ThermalController: Failed to read payload PCDU ADC temperature" << std::endl; + deviceTemperatures.adcPayloadPcdu.setValid(false); + deviceTemperatures.adcPayloadPcdu = static_cast(INVALID_TEMPERATURE); + } else { + deviceTemperatures.adcPayloadPcdu.setValid(tempAdcPayloadPcdu.isValid()); + deviceTemperatures.adcPayloadPcdu = tempAdcPayloadPcdu; + } } } diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index e81818e9..0e1926f4 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); @@ -79,14 +80,14 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_) { StorageManagerIF* tcStore; StorageManagerIF* tmStore; { - PoolManager::LocalPoolConfig poolCfg = {{200, 16}, {200, 32}, {150, 64}, - {100, 128}, {100, 1024}, {100, 2048}}; + PoolManager::LocalPoolConfig poolCfg = {{250, 16}, {250, 32}, {250, 64}, + {150, 128}, {120, 1024}, {120, 2048}}; tcStore = new PoolManager(objects::TC_STORE, poolCfg); } { - PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {300, 32}, {100, 64}, - {100, 128}, {100, 1024}, {100, 2048}}; + PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {350, 32}, {350, 64}, + {200, 128}, {150, 1024}, {150, 2048}}; tmStore = new PoolManager(objects::TM_STORE, poolCfg); } @@ -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(150); #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, 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); #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..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() { mode = MODE_NORMAL; } +void GomspaceDeviceHandler::setModeNormal() { setMode(_MODE_TO_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..db6f5a83 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); } } @@ -104,7 +101,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 +122,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,12 +142,17 @@ 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; } + 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/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..aff7c95d 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, uint32_t messageDepth) + : TmFunnelBase(objectId, tmStore, messageDepth), 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,34 @@ 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 (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); + if (result == returnvalue::OK) { + msg.setStorageId(storeId); + } else { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "CfdpTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; + sif::error << "PusTmFunnel::handlePacket: Store too full to create data copy" + << std::endl; #endif + } + } else { + msg.setStorageId(origStoreId); + } + } + result = tmQueue->sendMessage(destVcidPair.first, &msg); + if (result != returnvalue::OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + 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..e294956a 100644 --- a/mission/tmtc/CfdpTmFunnel.h +++ b/mission/tmtc/CfdpTmFunnel.h @@ -1,19 +1,20 @@ #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, + uint32_t messageDepth); [[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 +23,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..5d6bbb4d 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,33 @@ 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 (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); + if (result == returnvalue::OK) { + message.setStorageId(storeId); + } else { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PusTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; + sif::error << "PusTmFunnel::handlePacket: Store too full to create data copy" + << std::endl; #endif + } + } 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; +#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..b0f9391d 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" @@ -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; 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" diff --git a/tmtc b/tmtc index f3609b81..f62c67a1 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit f3609b81799790578c095262f33c11add3c0b078 +Subproject commit f62c67a11e54b99fdb60dab13e55456f16450951