Refactor TM handling #450
@ -16,6 +16,14 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
|
|
||||||
# [unreleased]
|
# [unreleased]
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Refactored TM pipeline to optimize usage of the PTME and communication downlink bandwidth.
|
||||||
|
This was done by moving the dumping of TMs to the VCs into separate threads with permanent loops.
|
||||||
|
These threads are then able to process high TM loads on demand. The PUS TM funnel will route
|
||||||
|
PUS packets to the approrpiate persisten TM stores and then demultiplex the TM to all registered
|
||||||
|
TM destinations are before.
|
||||||
|
|
||||||
# [v1.36.0] 2023-03-08
|
# [v1.36.0] 2023-03-08
|
||||||
|
|
||||||
eive-tmtc: v2.17.2
|
eive-tmtc: v2.17.2
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
#include <mission/system/objects/ImtqAssembly.h>
|
#include <mission/system/objects/ImtqAssembly.h>
|
||||||
#include <mission/system/objects/StrAssembly.h>
|
#include <mission/system/objects/StrAssembly.h>
|
||||||
#include <mission/system/objects/SyrlinksAssembly.h>
|
#include <mission/system/objects/SyrlinksAssembly.h>
|
||||||
|
#include <mission/tmtc/LiveTmTask.h>
|
||||||
|
#include <mission/tmtc/PersistentLogTmStoreTask.h>
|
||||||
|
#include <mission/tmtc/PersistentSingleTmStoreTask.h>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "bsp_q7s/boardtest/Q7STestTask.h"
|
#include "bsp_q7s/boardtest/Q7STestTask.h"
|
||||||
@ -716,9 +719,7 @@ void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF,
|
|||||||
#endif /* OBSW_ADD_RW == 1 */
|
#endif /* OBSW_ADD_RW == 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
|
ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
|
||||||
PusTmFunnel& pusFunnel,
|
|
||||||
CcsdsIpCoreHandler** ipCoreHandler) {
|
|
||||||
using namespace gpio;
|
using namespace gpio;
|
||||||
// GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core
|
// GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core
|
||||||
GpioCookie* gpioCookiePtmeIp = new GpioCookie;
|
GpioCookie* gpioCookiePtmeIp = new GpioCookie;
|
||||||
@ -739,20 +740,20 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
|
|||||||
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio);
|
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio);
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, "PAPB VC3");
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, "PAPB VC3");
|
||||||
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio);
|
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio);
|
||||||
gpioChecker(gpioComIF->addGpios(gpioCookiePtmeIp), "PTME PAPB VCs");
|
gpioChecker(args.gpioComIF.addGpios(gpioCookiePtmeIp), "PTME PAPB VCs");
|
||||||
// Creating virtual channel interfaces
|
// Creating virtual channel interfaces
|
||||||
VirtualChannelIF* vc0 =
|
VirtualChannelIF* vc0 =
|
||||||
new PapbVcInterface(gpioComIF, gpioIds::VC0_PAPB_BUSY, gpioIds::VC0_PAPB_EMPTY, q7s::UIO_PTME,
|
new PapbVcInterface(&args.gpioComIF, gpioIds::VC0_PAPB_BUSY, gpioIds::VC0_PAPB_EMPTY,
|
||||||
q7s::uiomapids::PTME_VC0);
|
q7s::UIO_PTME, q7s::uiomapids::PTME_VC0);
|
||||||
VirtualChannelIF* vc1 =
|
VirtualChannelIF* vc1 =
|
||||||
new PapbVcInterface(gpioComIF, gpioIds::VC1_PAPB_BUSY, gpioIds::VC1_PAPB_EMPTY, q7s::UIO_PTME,
|
new PapbVcInterface(&args.gpioComIF, gpioIds::VC1_PAPB_BUSY, gpioIds::VC1_PAPB_EMPTY,
|
||||||
q7s::uiomapids::PTME_VC1);
|
q7s::UIO_PTME, q7s::uiomapids::PTME_VC1);
|
||||||
VirtualChannelIF* vc2 =
|
VirtualChannelIF* vc2 =
|
||||||
new PapbVcInterface(gpioComIF, gpioIds::VC2_PAPB_BUSY, gpioIds::VC2_PAPB_EMPTY, q7s::UIO_PTME,
|
new PapbVcInterface(&args.gpioComIF, gpioIds::VC2_PAPB_BUSY, gpioIds::VC2_PAPB_EMPTY,
|
||||||
q7s::uiomapids::PTME_VC2);
|
q7s::UIO_PTME, q7s::uiomapids::PTME_VC2);
|
||||||
VirtualChannelIF* vc3 =
|
VirtualChannelIF* vc3 =
|
||||||
new PapbVcInterface(gpioComIF, gpioIds::VC3_PAPB_BUSY, gpioIds::VC3_PAPB_EMPTY, q7s::UIO_PTME,
|
new PapbVcInterface(&args.gpioComIF, gpioIds::VC3_PAPB_BUSY, gpioIds::VC3_PAPB_EMPTY,
|
||||||
q7s::uiomapids::PTME_VC3);
|
q7s::UIO_PTME, q7s::uiomapids::PTME_VC3);
|
||||||
// Creating ptme object and adding virtual channel interfaces
|
// Creating ptme object and adding virtual channel interfaces
|
||||||
Ptme* ptme = new Ptme(objects::PTME);
|
Ptme* ptme = new Ptme(objects::PTME);
|
||||||
ptme->addVcInterface(ccsds::VC0, vc0);
|
ptme->addVcInterface(ccsds::VC0, vc0);
|
||||||
@ -763,29 +764,33 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
|
|||||||
new AxiPtmeConfig(objects::AXI_PTME_CONFIG, q7s::UIO_PTME, q7s::uiomapids::PTME_CONFIG);
|
new AxiPtmeConfig(objects::AXI_PTME_CONFIG, q7s::UIO_PTME, q7s::uiomapids::PTME_CONFIG);
|
||||||
PtmeConfig* ptmeConfig = new PtmeConfig(objects::PTME_CONFIG, axiPtmeConfig);
|
PtmeConfig* ptmeConfig = new PtmeConfig(objects::PTME_CONFIG, axiPtmeConfig);
|
||||||
|
|
||||||
*ipCoreHandler = new CcsdsIpCoreHandler(objects::CCSDS_HANDLER, objects::CCSDS_PACKET_DISTRIBUTOR,
|
*args.ipCoreHandler = new CcsdsIpCoreHandler(
|
||||||
*ptmeConfig, LINK_STATE, gpioComIF,
|
objects::CCSDS_HANDLER, objects::CCSDS_PACKET_DISTRIBUTOR, *ptmeConfig, LINK_STATE,
|
||||||
gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA);
|
&args.gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA);
|
||||||
VirtualChannel* vc = new VirtualChannel(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM",
|
// This VC will receive all live TM
|
||||||
*ptme, LINK_STATE);
|
auto* vcWithQueue =
|
||||||
//(*ipCoreHandler)->addVirtualChannel(ccsds::VC0, vc);
|
new VirtualChannelWithQueue(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM", *ptme,
|
||||||
vc = new VirtualChannel(objects::PTME_VC1_LOG_TM, ccsds::VC1, "PTME VC1 LOG TM", *ptme,
|
LINK_STATE, args.tmStore, 500);
|
||||||
LINK_STATE);
|
new LiveTmTask(objects::LIVE_TM_TASK, *vcWithQueue);
|
||||||
|
|
||||||
|
// Set up log store.
|
||||||
|
auto* vc = new VirtualChannel(objects::PTME_VC1_LOG_TM, ccsds::VC1, "PTME VC1 LOG TM", *ptme,
|
||||||
|
LINK_STATE);
|
||||||
|
LogStores logStores(args.stores);
|
||||||
|
// Core task which handles the LOG store and takes care of dumping it as TM using a VC directly
|
||||||
|
new PersistentLogTmStoreTask(objects::LOG_STORE_TASK, args.ipcStore, logStores, *vc);
|
||||||
|
|
||||||
// pusFunnel.addPersistentTmStoreRouting(filters::okFilter(), vc->getReportReceptionQueue());
|
|
||||||
// pusFunnel.addPersistentTmStoreRouting(filters::notOkFilter(), vc->getReportReceptionQueue());
|
|
||||||
// pusFunnel.addPersistentTmStoreRouting(filters::miscFilter(), vc->getReportReceptionQueue());
|
|
||||||
//(*ipCoreHandler)->addVirtualChannel(ccsds::VC1, vc);
|
|
||||||
vc = new VirtualChannel(objects::PTME_VC2_HK_TM, ccsds::VC2, "PTME VC2 HK TM", *ptme, LINK_STATE);
|
vc = new VirtualChannel(objects::PTME_VC2_HK_TM, ccsds::VC2, "PTME VC2 HK TM", *ptme, LINK_STATE);
|
||||||
// auto hkTmStoreTask = new PersistentSingleTmStoreTask();
|
// Core task which handles the HK store and takes care of dumping it as TM using a VC directly
|
||||||
// pusFunnel.addPersistentTmStoreRouting(filters::hkFilter(), vc->getReportReceptionQueue());
|
new PersistentSingleTmStoreTask(objects::HK_STORE_TASK, args.ipcStore, *args.stores.hkStore, *vc);
|
||||||
//(*ipCoreHandler)->addVirtualChannel(ccsds::VC2, vc);
|
|
||||||
vc = new VirtualChannel(objects::PTME_VC3_CFDP_TM, ccsds::VC3, "PTME VC3 CFDP TM", *ptme,
|
vc = new VirtualChannel(objects::PTME_VC3_CFDP_TM, ccsds::VC3, "PTME VC3 CFDP TM", *ptme,
|
||||||
LINK_STATE);
|
LINK_STATE);
|
||||||
// TODO: Set VC destination in CFDP funnel.
|
// Core task which handles the CFDP store and takes care of dumping it as TM using a VC directly
|
||||||
//(*ipCoreHandler)->addVirtualChannel(ccsds::VC3, vc);
|
new PersistentSingleTmStoreTask(objects::CFDP_STORE_TASK, args.ipcStore, *args.stores.cfdpStore,
|
||||||
|
*vc);
|
||||||
|
|
||||||
ReturnValue_t result = (*ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
ReturnValue_t result = (*args.ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::error
|
sif::error
|
||||||
<< "ObjectFactory::createCcsdsComponents: Connecting COM subsystem to CCSDS handler failed"
|
<< "ObjectFactory::createCcsdsComponents: Connecting COM subsystem to CCSDS handler failed"
|
||||||
@ -797,14 +802,14 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
|
|||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, "PDEC Handler", Direction::OUT,
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, "PDEC Handler", Direction::OUT,
|
||||||
Levels::LOW);
|
Levels::LOW);
|
||||||
gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio);
|
gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio);
|
||||||
gpioChecker(gpioComIF->addGpios(gpioCookiePdec), "PDEC");
|
gpioChecker(args.gpioComIF.addGpios(gpioCookiePdec), "PDEC");
|
||||||
struct UioNames uioNames {};
|
struct UioNames uioNames {};
|
||||||
uioNames.configMemory = q7s::UIO_PDEC_CONFIG_MEMORY;
|
uioNames.configMemory = q7s::UIO_PDEC_CONFIG_MEMORY;
|
||||||
uioNames.ramMemory = q7s::UIO_PDEC_RAM;
|
uioNames.ramMemory = q7s::UIO_PDEC_RAM;
|
||||||
uioNames.registers = q7s::UIO_PDEC_REGISTERS;
|
uioNames.registers = q7s::UIO_PDEC_REGISTERS;
|
||||||
uioNames.irq = q7s::UIO_PDEC_IRQ;
|
uioNames.irq = q7s::UIO_PDEC_IRQ;
|
||||||
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET,
|
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, &args.gpioComIF,
|
||||||
uioNames);
|
gpioIds::PDEC_RESET, uioNames);
|
||||||
GpioCookie* gpioRS485Chip = new GpioCookie;
|
GpioCookie* gpioRS485Chip = new GpioCookie;
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver",
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver",
|
||||||
Direction::OUT, Levels::LOW);
|
Direction::OUT, Levels::LOW);
|
||||||
@ -819,7 +824,7 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
|
|||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_DATA, "RS485 Transceiver",
|
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_DATA, "RS485 Transceiver",
|
||||||
Direction::OUT, Levels::LOW);
|
Direction::OUT, Levels::LOW);
|
||||||
gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_DATA, gpio);
|
gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_DATA, gpio);
|
||||||
gpioChecker(gpioComIF->addGpios(gpioRS485Chip), "RS485 Transceiver");
|
gpioChecker(args.gpioComIF.addGpios(gpioRS485Chip), "RS485 Transceiver");
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
|
|
||||||
#include <fsfw/returnvalues/returnvalue.h>
|
#include <fsfw/returnvalues/returnvalue.h>
|
||||||
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||||
|
#include <mission/core/GenericFactory.h>
|
||||||
#include <mission/devices/HeaterHandler.h>
|
#include <mission/devices/HeaterHandler.h>
|
||||||
#include <mission/system/objects/Stack5VHandler.h>
|
#include <mission/system/objects/Stack5VHandler.h>
|
||||||
#include <mission/tmtc/CcsdsIpCoreHandler.h>
|
#include <mission/tmtc/CcsdsIpCoreHandler.h>
|
||||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||||
|
#include <mission/tmtc/PersistentLogTmStoreTask.h>
|
||||||
#include <mission/tmtc/PusTmFunnel.h>
|
#include <mission/tmtc/PusTmFunnel.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -22,6 +24,24 @@ class GpioIF;
|
|||||||
|
|
||||||
namespace ObjectFactory {
|
namespace ObjectFactory {
|
||||||
|
|
||||||
|
struct CcsdsComponentArgs {
|
||||||
|
CcsdsComponentArgs(LinuxLibgpioIF& gpioIF, PusTmFunnel& funnel, StorageManagerIF& ipcStore,
|
||||||
|
StorageManagerIF& tmStore, PersistentTmStores& stores,
|
||||||
|
CcsdsIpCoreHandler** ipCoreHandler)
|
||||||
|
: gpioComIF(gpioIF),
|
||||||
|
pusFunnel(funnel),
|
||||||
|
ipcStore(ipcStore),
|
||||||
|
tmStore(tmStore),
|
||||||
|
stores(stores),
|
||||||
|
ipCoreHandler(ipCoreHandler) {}
|
||||||
|
LinuxLibgpioIF& gpioComIF;
|
||||||
|
PusTmFunnel& pusFunnel;
|
||||||
|
StorageManagerIF& ipcStore;
|
||||||
|
StorageManagerIF& tmStore;
|
||||||
|
PersistentTmStores& stores;
|
||||||
|
CcsdsIpCoreHandler** ipCoreHandler;
|
||||||
|
};
|
||||||
|
|
||||||
void setStatics();
|
void setStatics();
|
||||||
void produce(void* args);
|
void produce(void* args);
|
||||||
|
|
||||||
@ -43,8 +63,7 @@ void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, GpioIF& gp
|
|||||||
void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher);
|
void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher);
|
||||||
void createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitcher);
|
void createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitcher);
|
||||||
void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher);
|
void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher);
|
||||||
ReturnValue_t createCcsdsComponents(LinuxLibgpioIF* gpioComIF, PusTmFunnel& pusFunnel,
|
ReturnValue_t createCcsdsComponents(CcsdsComponentArgs& args);
|
||||||
CcsdsIpCoreHandler** ipCoreHandler);
|
|
||||||
void createMiscComponents();
|
void createMiscComponents();
|
||||||
|
|
||||||
void createTestComponents(LinuxLibgpioIF* gpioComIF);
|
void createTestComponents(LinuxLibgpioIF* gpioComIF);
|
||||||
|
@ -19,9 +19,12 @@ void ObjectFactory::produce(void* args) {
|
|||||||
HealthTableIF* healthTable = nullptr;
|
HealthTableIF* healthTable = nullptr;
|
||||||
PusTmFunnel* pusFunnel = nullptr;
|
PusTmFunnel* pusFunnel = nullptr;
|
||||||
CfdpTmFunnel* cfdpFunnel = nullptr;
|
CfdpTmFunnel* cfdpFunnel = nullptr;
|
||||||
|
StorageManagerIF* ipcStore = nullptr;
|
||||||
|
StorageManagerIF* tmStore = nullptr;
|
||||||
|
|
||||||
|
PersistentTmStores stores;
|
||||||
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
|
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
|
||||||
*SdCardManager::instance());
|
*SdCardManager::instance(), &ipcStore, &tmStore, stores);
|
||||||
|
|
||||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||||
SerialComIF* uartComIF = nullptr;
|
SerialComIF* uartComIF = nullptr;
|
||||||
@ -74,7 +77,8 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
||||||
#if OBSW_ADD_CCSDS_IP_CORES == 1
|
#if OBSW_ADD_CCSDS_IP_CORES == 1
|
||||||
CcsdsIpCoreHandler* ipCoreHandler = nullptr;
|
CcsdsIpCoreHandler* ipCoreHandler = nullptr;
|
||||||
createCcsdsComponents(gpioComIF, *pusFunnel, &ipCoreHandler);
|
CcsdsComponentArgs ccsdsArgs(*gpioComIF, *pusFunnel, *ipcStore, *tmStore, stores, &ipCoreHandler);
|
||||||
|
createCcsdsComponents(ccsdsArgs);
|
||||||
#if OBSW_TM_TO_PTME == 1
|
#if OBSW_TM_TO_PTME == 1
|
||||||
// TODO: Remove this if not needed anymore
|
// TODO: Remove this if not needed anymore
|
||||||
// addTmtcIpCoresToFunnels(*ipCoreHandler, *pusFunnel, *cfdpFunnel);
|
// addTmtcIpCoresToFunnels(*ipCoreHandler, *pusFunnel, *cfdpFunnel);
|
||||||
|
@ -168,6 +168,11 @@ enum commonObjects : uint32_t {
|
|||||||
HK_TM_STORE = 0x73020004,
|
HK_TM_STORE = 0x73020004,
|
||||||
CFDP_TM_STORE = 0x73030000,
|
CFDP_TM_STORE = 0x73030000,
|
||||||
|
|
||||||
|
LIVE_TM_TASK = 0x73040000,
|
||||||
|
LOG_STORE_TASK = 0x73040001,
|
||||||
|
HK_STORE_TASK = 0x73040002,
|
||||||
|
CFDP_STORE_TASK = 0x73040003,
|
||||||
|
|
||||||
// Other stuff
|
// Other stuff
|
||||||
THERMAL_TEMP_INSERTER = 0x90000003,
|
THERMAL_TEMP_INSERTER = 0x90000003,
|
||||||
};
|
};
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <mission/system/objects/TcsBoardAssembly.h>
|
#include <mission/system/objects/TcsBoardAssembly.h>
|
||||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||||
#include <mission/tmtc/PersistentTmStore.h>
|
#include <mission/tmtc/PersistentTmStore.h>
|
||||||
|
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||||
#include <mission/tmtc/PusPacketFilter.h>
|
#include <mission/tmtc/PusPacketFilter.h>
|
||||||
#include <mission/tmtc/PusTmFunnel.h>
|
#include <mission/tmtc/PusTmFunnel.h>
|
||||||
#include <mission/tmtc/PusTmRouteByFilterHelper.h>
|
#include <mission/tmtc/PusTmRouteByFilterHelper.h>
|
||||||
@ -47,6 +48,7 @@
|
|||||||
#include "mission/system/objects/RwAssembly.h"
|
#include "mission/system/objects/RwAssembly.h"
|
||||||
#include "mission/system/tree/acsModeTree.h"
|
#include "mission/system/tree/acsModeTree.h"
|
||||||
#include "mission/system/tree/tcsModeTree.h"
|
#include "mission/system/tree/tcsModeTree.h"
|
||||||
|
#include "mission/tmtc/tmFilters.h"
|
||||||
#include "objects/systemObjectList.h"
|
#include "objects/systemObjectList.h"
|
||||||
#include "tmtc/pusIds.h"
|
#include "tmtc/pusIds.h"
|
||||||
|
|
||||||
@ -87,7 +89,9 @@ EiveFaultHandler EIVE_FAULT_HANDLER;
|
|||||||
} // namespace cfdp
|
} // namespace cfdp
|
||||||
|
|
||||||
void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFunnel** pusFunnel,
|
void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFunnel** pusFunnel,
|
||||||
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan) {
|
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan,
|
||||||
|
StorageManagerIF** ipcStore, StorageManagerIF** tmStore,
|
||||||
|
PersistentTmStores& stores) {
|
||||||
// Framework objects
|
// Framework objects
|
||||||
new EventManager(objects::EVENT_MANAGER);
|
new EventManager(objects::EVENT_MANAGER);
|
||||||
auto healthTable = new HealthTable(objects::HEALTH_TABLE);
|
auto healthTable = new HealthTable(objects::HEALTH_TABLE);
|
||||||
@ -98,8 +102,6 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
new VerificationReporter();
|
new VerificationReporter();
|
||||||
auto* timeStamper = new CdsShortTimeStamper(objects::TIME_STAMPER);
|
auto* timeStamper = new CdsShortTimeStamper(objects::TIME_STAMPER);
|
||||||
StorageManagerIF* tcStore;
|
StorageManagerIF* tcStore;
|
||||||
StorageManagerIF* tmStore;
|
|
||||||
StorageManagerIF* ipcStore;
|
|
||||||
{
|
{
|
||||||
PoolManager::LocalPoolConfig poolCfg = {{250, 16}, {250, 32}, {250, 64},
|
PoolManager::LocalPoolConfig poolCfg = {{250, 16}, {250, 32}, {250, 64},
|
||||||
{150, 128}, {120, 1024}, {120, 2048}};
|
{150, 128}, {120, 1024}, {120, 2048}};
|
||||||
@ -109,13 +111,13 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
{
|
{
|
||||||
PoolManager::LocalPoolConfig poolCfg = {{400, 32}, {400, 64}, {250, 128},
|
PoolManager::LocalPoolConfig poolCfg = {{400, 32}, {400, 64}, {250, 128},
|
||||||
{150, 512}, {150, 1024}, {150, 2048}};
|
{150, 512}, {150, 1024}, {150, 2048}};
|
||||||
tmStore = new PoolManager(objects::TM_STORE, poolCfg);
|
*tmStore = new PoolManager(objects::TM_STORE, poolCfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {200, 32}, {150, 64}, {150, 128},
|
PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {200, 32}, {150, 64}, {150, 128},
|
||||||
{100, 256}, {50, 512}, {50, 1024}, {10, 2048}};
|
{100, 256}, {50, 512}, {50, 1024}, {10, 2048}};
|
||||||
ipcStore = new PoolManager(objects::IPC_STORE, poolCfg);
|
*ipcStore = new PoolManager(objects::IPC_STORE, poolCfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OBSW_ADD_TCPIP_SERVERS == 1
|
#if OBSW_ADD_TCPIP_SERVERS == 1
|
||||||
@ -144,20 +146,71 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR);
|
new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib);
|
new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib);
|
||||||
|
|
||||||
PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, "CfdpTmFunnel", *tmStore, *ipcStore,
|
PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, "CfdpTmFunnel", **tmStore,
|
||||||
50);
|
**ipcStore, 50);
|
||||||
*cfdpFunnel = new CfdpTmFunnel(cfdpFunnelCfg, config::EIVE_CFDP_APID);
|
*cfdpFunnel = new CfdpTmFunnel(cfdpFunnelCfg, config::EIVE_CFDP_APID);
|
||||||
auto* miscStore = new PersistentTmStore(objects::MISC_TM_STORE, "tm", "misc",
|
PusTmFunnel::FunnelCfg pusFunnelCfg(objects::PUS_TM_FUNNEL, "PusTmFunnel", **tmStore, **ipcStore,
|
||||||
RolloverInterval::HOURLY, 2, *tmStore, sdcMan);
|
|
||||||
auto* okStore = new PersistentTmStore(objects::OK_TM_STORE, "tm", "ok",
|
|
||||||
RolloverInterval::MINUTELY, 30, *tmStore, sdcMan);
|
|
||||||
auto* notOkStore = new PersistentTmStore(objects::NOT_OK_TM_STORE, "tm", "nok",
|
|
||||||
RolloverInterval::MINUTELY, 30, *tmStore, sdcMan);
|
|
||||||
auto* hkStore = new PersistentTmStore(objects::HK_TM_STORE, "tm", "hk",
|
|
||||||
RolloverInterval::MINUTELY, 15, *tmStore, sdcMan);
|
|
||||||
PusTmFunnel::FunnelCfg pusFunnelCfg(objects::PUS_TM_FUNNEL, "PusTmFunnel", *tmStore, *ipcStore,
|
|
||||||
config::MAX_PUS_FUNNEL_QUEUE_DEPTH);
|
config::MAX_PUS_FUNNEL_QUEUE_DEPTH);
|
||||||
|
// The PUS funnel routes all live TM to the live destinations and to the TM stores.
|
||||||
*pusFunnel = new PusTmFunnel(pusFunnelCfg, *timeStamper, sdcMan);
|
*pusFunnel = new PusTmFunnel(pusFunnelCfg, *timeStamper, sdcMan);
|
||||||
|
|
||||||
|
// MISC store and PUS funnel to MISC store routing
|
||||||
|
// TODO: Make queue depth configurable
|
||||||
|
{
|
||||||
|
PersistentTmStoreArgs storeArgs(objects::MISC_TM_STORE, "tm", "misc",
|
||||||
|
|
||||||
|
RolloverInterval::HOURLY, 2, **tmStore, sdcMan);
|
||||||
|
stores.miscStore = new PersistentTmStoreWithTmQueue(storeArgs, "MISC STORE", 500);
|
||||||
|
(*pusFunnel)
|
||||||
|
->addPersistentTmStoreRouting(filters::miscFilter(),
|
||||||
|
stores.miscStore->getReportReceptionQueue(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK store and PUS Funnel to OK store routing
|
||||||
|
// TODO: Make queue depth configurable
|
||||||
|
{
|
||||||
|
PersistentTmStoreArgs storeArgs(objects::OK_TM_STORE, "tm", "ok", RolloverInterval::MINUTELY,
|
||||||
|
30, **tmStore, sdcMan);
|
||||||
|
stores.okStore = new PersistentTmStoreWithTmQueue(storeArgs, "OK STORE", 500);
|
||||||
|
(*pusFunnel)
|
||||||
|
->addPersistentTmStoreRouting(filters::okFilter(),
|
||||||
|
stores.okStore->getReportReceptionQueue(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOT OK store and PUS funnel to NOT OK store routing
|
||||||
|
// TODO: Make queue depth configurable
|
||||||
|
{
|
||||||
|
PersistentTmStoreArgs storeArgs(objects::NOT_OK_TM_STORE, "tm", "nok",
|
||||||
|
RolloverInterval::MINUTELY, 30, **tmStore, sdcMan);
|
||||||
|
stores.notOkStore = new PersistentTmStoreWithTmQueue(storeArgs, "NOT OK STORE", 500);
|
||||||
|
(*pusFunnel)
|
||||||
|
->addPersistentTmStoreRouting(filters::notOkFilter(),
|
||||||
|
stores.notOkStore->getReportReceptionQueue(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// HK store and PUS funnel to HK store routing
|
||||||
|
// TODO: Make queue depth configurable
|
||||||
|
{
|
||||||
|
PersistentTmStoreArgs storeArgs(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY,
|
||||||
|
15, **tmStore, sdcMan);
|
||||||
|
stores.hkStore = new PersistentTmStoreWithTmQueue(storeArgs, "HK STORE", 500);
|
||||||
|
(*pusFunnel)
|
||||||
|
->addPersistentTmStoreRouting(filters::hkFilter(),
|
||||||
|
stores.hkStore->getReportReceptionQueue(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// CFDP store and PUS funnel to CFDP store routing
|
||||||
|
// TODO: Make queue depth configurable
|
||||||
|
{
|
||||||
|
PersistentTmStoreArgs storeArgs(objects::CFDP_TM_STORE, "tm", "cfdp",
|
||||||
|
RolloverInterval::MINUTELY, 30, **tmStore, sdcMan);
|
||||||
|
stores.cfdpStore = new PersistentTmStoreWithTmQueue(storeArgs, "CFDP STORE", 500);
|
||||||
|
|
||||||
|
(*pusFunnel)
|
||||||
|
->addPersistentTmStoreRouting(filters::cfdpFilter(),
|
||||||
|
stores.cfdpStore->getReportReceptionQueue(0));
|
||||||
|
}
|
||||||
|
|
||||||
#if OBSW_ADD_TCPIP_SERVERS == 1
|
#if OBSW_ADD_TCPIP_SERVERS == 1
|
||||||
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
||||||
(*cfdpFunnel)->addLiveDestination("UDP Server", *udpBridge, 0);
|
(*cfdpFunnel)->addLiveDestination("UDP Server", *udpBridge, 0);
|
||||||
@ -208,7 +261,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
new CfdpDistributor(distribCfg);
|
new CfdpDistributor(distribCfg);
|
||||||
|
|
||||||
auto* msgQueue = QueueFactory::instance()->createMessageQueue(32);
|
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);
|
*msgQueue);
|
||||||
cfdp::IndicationCfg indicationCfg;
|
cfdp::IndicationCfg indicationCfg;
|
||||||
UnsignedByteField<uint16_t> apid(config::EIVE_LOCAL_CFDP_ENTITY_ID);
|
UnsignedByteField<uint16_t> apid(config::EIVE_LOCAL_CFDP_ENTITY_ID);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||||
#include <mission/memory/SdCardMountedIF.h>
|
#include <mission/memory/SdCardMountedIF.h>
|
||||||
|
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||||
|
|
||||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||||
#include "fsfw/power/PowerSwitchIF.h"
|
#include "fsfw/power/PowerSwitchIF.h"
|
||||||
@ -35,10 +36,20 @@ const std::array<std::pair<object_id_t, std::string>, EiveMax31855::NUM_RTDS> RT
|
|||||||
{objects::RTD_15_IC18_IMTQ, "RTD_15_IMTQ"},
|
{objects::RTD_15_IC18_IMTQ, "RTD_15_IMTQ"},
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
struct PersistentTmStores {
|
||||||
|
PersistentTmStoreWithTmQueue* okStore;
|
||||||
|
PersistentTmStoreWithTmQueue* notOkStore;
|
||||||
|
PersistentTmStoreWithTmQueue* miscStore;
|
||||||
|
PersistentTmStoreWithTmQueue* hkStore;
|
||||||
|
PersistentTmStoreWithTmQueue* cfdpStore;
|
||||||
|
};
|
||||||
|
|
||||||
namespace ObjectFactory {
|
namespace ObjectFactory {
|
||||||
|
|
||||||
void produceGenericObjects(HealthTableIF** healthTable, PusTmFunnel** pusFunnel,
|
void produceGenericObjects(HealthTableIF** healthTable, PusTmFunnel** pusFunnel,
|
||||||
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan);
|
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan,
|
||||||
|
StorageManagerIF** ipcStore, StorageManagerIF** tmStore,
|
||||||
|
PersistentTmStores& stores);
|
||||||
void createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher,
|
void createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher,
|
||||||
HeaterHandler*& heaterHandler);
|
HeaterHandler*& heaterHandler);
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ target_sources(
|
|||||||
PusLiveDemux.cpp
|
PusLiveDemux.cpp
|
||||||
PersistentSingleTmStoreTask.cpp
|
PersistentSingleTmStoreTask.cpp
|
||||||
PersistentLogTmStoreTask.cpp
|
PersistentLogTmStoreTask.cpp
|
||||||
|
TmStoreTaskBase.cpp
|
||||||
PusPacketFilter.cpp
|
PusPacketFilter.cpp
|
||||||
PusTmRouteByFilterHelper.cpp
|
PusTmRouteByFilterHelper.cpp
|
||||||
Service15TmStorage.cpp
|
Service15TmStorage.cpp
|
||||||
|
@ -1 +1,28 @@
|
|||||||
#include "PersistentLogTmStoreTask.h"
|
#include "PersistentLogTmStoreTask.h"
|
||||||
|
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
|
||||||
|
PersistentLogTmStoreTask::PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
|
||||||
|
LogStores stores, VirtualChannel& channel)
|
||||||
|
: TmStoreTaskBase(objectId, ipcStore, channel), stores(stores) {}
|
||||||
|
|
||||||
|
ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) {
|
||||||
|
while (true) {
|
||||||
|
bool someonesBusy = false;
|
||||||
|
bool busy = handleOneStore(stores.okStore);
|
||||||
|
if (busy) {
|
||||||
|
someonesBusy = true;
|
||||||
|
}
|
||||||
|
busy = handleOneStore(stores.okStore);
|
||||||
|
if (busy) {
|
||||||
|
someonesBusy = true;
|
||||||
|
}
|
||||||
|
busy = handleOneStore(stores.miscStore);
|
||||||
|
if (busy) {
|
||||||
|
someonesBusy = true;
|
||||||
|
}
|
||||||
|
if (not someonesBusy) {
|
||||||
|
TaskFactory::delayTask(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,22 +5,29 @@
|
|||||||
#include <fsfw/storagemanager/StorageManagerIF.h>
|
#include <fsfw/storagemanager/StorageManagerIF.h>
|
||||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
||||||
|
#include <mission/core/GenericFactory.h>
|
||||||
#include <mission/tmtc/PersistentTmStore.h>
|
#include <mission/tmtc/PersistentTmStore.h>
|
||||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||||
|
#include <mission/tmtc/TmStoreTaskBase.h>
|
||||||
#include <mission/tmtc/VirtualChannelWithQueue.h>
|
#include <mission/tmtc/VirtualChannelWithQueue.h>
|
||||||
|
|
||||||
struct LogStores {
|
struct LogStores {
|
||||||
|
LogStores(PersistentTmStores& stores)
|
||||||
|
: okStore(*stores.okStore), notOkStore(*stores.notOkStore), miscStore(*stores.miscStore) {}
|
||||||
PersistentTmStoreWithTmQueue& okStore;
|
PersistentTmStoreWithTmQueue& okStore;
|
||||||
PersistentTmStoreWithTmQueue& notOkStore;
|
PersistentTmStoreWithTmQueue& notOkStore;
|
||||||
PersistentTmStoreWithTmQueue& miscStore;
|
PersistentTmStoreWithTmQueue& miscStore;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PersistentLogTmStoreTask : public SystemObject, public ExecutableObjectIF {
|
class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
|
||||||
public:
|
public:
|
||||||
PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore, LogStores tmStore,
|
PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore, LogStores tmStore,
|
||||||
VirtualChannelWithQueue& channel);
|
VirtualChannel& channel);
|
||||||
|
|
||||||
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
LogStores stores;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_TMTC_PERSISTENTLOGTMSTORETASK_H_ */
|
#endif /* MISSION_TMTC_PERSISTENTLOGTMSTORETASK_H_ */
|
||||||
|
@ -5,32 +5,12 @@ PersistentSingleTmStoreTask::PersistentSingleTmStoreTask(object_id_t objectId,
|
|||||||
StorageManagerIF& ipcStore,
|
StorageManagerIF& ipcStore,
|
||||||
PersistentTmStoreWithTmQueue& tmStore,
|
PersistentTmStoreWithTmQueue& tmStore,
|
||||||
VirtualChannel& channel)
|
VirtualChannel& channel)
|
||||||
: SystemObject(objectId), ipcStore(ipcStore), storeWithQueue(tmStore), channel(channel) {}
|
: TmStoreTaskBase(objectId, ipcStore, channel), storeWithQueue(tmStore) {}
|
||||||
|
|
||||||
ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
|
ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
|
||||||
ReturnValue_t result;
|
|
||||||
auto& store = storeWithQueue.getTmStore();
|
|
||||||
bool noTmToStoreReceived = false;
|
|
||||||
bool noTcRequestReceived = false;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Store TM persistently
|
bool busy = handleOneStore(storeWithQueue);
|
||||||
result = storeWithQueue.handleNextTm();
|
if (not busy) {
|
||||||
if (result == MessageQueueIF::NO_QUEUE) {
|
|
||||||
noTmToStoreReceived = true;
|
|
||||||
}
|
|
||||||
// Handle TC requests, for example deletion or retrieval requests.
|
|
||||||
result = store.handleCommandQueue(ipcStore);
|
|
||||||
if (result == MessageQueueIF::NO_QUEUE) {
|
|
||||||
noTcRequestReceived = true;
|
|
||||||
}
|
|
||||||
// Dump TMs when applicable
|
|
||||||
if (store.getState() == PersistentTmStore::State::DUMPING) {
|
|
||||||
size_t dumpedLen;
|
|
||||||
// TODO: Maybe do a bit of a delay every 100-200 packets?
|
|
||||||
// TODO: handle returnvalue?
|
|
||||||
store.dumpNextPacket(channel, dumpedLen);
|
|
||||||
} else if (noTcRequestReceived and noTmToStoreReceived) {
|
|
||||||
// Nothng to do, so sleep for a bit.
|
|
||||||
TaskFactory::delayTask(5);
|
TaskFactory::delayTask(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
#include <fsfw/objectmanager/SystemObject.h>
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||||
|
#include <mission/tmtc/TmStoreTaskBase.h>
|
||||||
#include <mission/tmtc/VirtualChannel.h>
|
#include <mission/tmtc/VirtualChannel.h>
|
||||||
|
|
||||||
class PersistentSingleTmStoreTask : public SystemObject, public ExecutableObjectIF {
|
class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
|
||||||
public:
|
public:
|
||||||
PersistentSingleTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
|
PersistentSingleTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
|
||||||
PersistentTmStoreWithTmQueue& storeWithQueue,
|
PersistentTmStoreWithTmQueue& storeWithQueue,
|
||||||
@ -15,9 +16,7 @@ class PersistentSingleTmStoreTask : public SystemObject, public ExecutableObject
|
|||||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StorageManagerIF& ipcStore;
|
|
||||||
PersistentTmStoreWithTmQueue& storeWithQueue;
|
PersistentTmStoreWithTmQueue& storeWithQueue;
|
||||||
VirtualChannel& channel;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_TMTC_PERSISTENTSINGLETMSTORETASK_H_ */
|
#endif /* MISSION_TMTC_PERSISTENTSINGLETMSTORETASK_H_ */
|
||||||
|
@ -15,17 +15,14 @@
|
|||||||
|
|
||||||
using namespace returnvalue;
|
using namespace returnvalue;
|
||||||
|
|
||||||
PersistentTmStore::PersistentTmStore(object_id_t objectId, const char* baseDir,
|
PersistentTmStore::PersistentTmStore(PersistentTmStoreArgs args)
|
||||||
std::string baseName, RolloverInterval intervalUnit,
|
: SystemObject(args.objectId),
|
||||||
uint32_t intervalCount, StorageManagerIF& tmStore,
|
tmStore(args.tmStore),
|
||||||
SdCardMountedIF& sdcMan)
|
baseDir(args.baseDir),
|
||||||
: SystemObject(objectId),
|
baseName(std::move(args.baseName)),
|
||||||
baseDir(baseDir),
|
sdcMan(args.sdcMan) {
|
||||||
baseName(std::move(baseName)),
|
|
||||||
sdcMan(sdcMan),
|
|
||||||
tmStore(tmStore) {
|
|
||||||
tcQueue = QueueFactory::instance()->createMessageQueue();
|
tcQueue = QueueFactory::instance()->createMessageQueue();
|
||||||
calcDiffSeconds(intervalUnit, intervalCount);
|
calcDiffSeconds(args.intervalUnit, args.intervalCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PersistentTmStore::assignAndOrCreateMostRecentFile() {
|
ReturnValue_t PersistentTmStore::assignAndOrCreateMostRecentFile() {
|
||||||
|
@ -17,6 +17,27 @@
|
|||||||
|
|
||||||
enum class RolloverInterval { MINUTELY, HOURLY, DAILY };
|
enum class RolloverInterval { MINUTELY, HOURLY, DAILY };
|
||||||
|
|
||||||
|
struct PersistentTmStoreArgs {
|
||||||
|
PersistentTmStoreArgs(object_id_t objectId, const char* baseDir, std::string baseName,
|
||||||
|
RolloverInterval intervalUnit, uint32_t intervalCount,
|
||||||
|
StorageManagerIF& tmStore, SdCardMountedIF& sdcMan)
|
||||||
|
: objectId(objectId),
|
||||||
|
baseDir(baseDir),
|
||||||
|
baseName(baseName),
|
||||||
|
intervalUnit(intervalUnit),
|
||||||
|
intervalCount(intervalCount),
|
||||||
|
tmStore(tmStore),
|
||||||
|
sdcMan(sdcMan) {}
|
||||||
|
|
||||||
|
object_id_t objectId;
|
||||||
|
const char* baseDir;
|
||||||
|
std::string baseName;
|
||||||
|
RolloverInterval intervalUnit;
|
||||||
|
uint32_t intervalCount;
|
||||||
|
StorageManagerIF& tmStore;
|
||||||
|
SdCardMountedIF& sdcMan;
|
||||||
|
};
|
||||||
|
|
||||||
class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject {
|
class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject {
|
||||||
public:
|
public:
|
||||||
enum class State { IDLE, DUMPING };
|
enum class State { IDLE, DUMPING };
|
||||||
@ -36,9 +57,7 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject {
|
|||||||
static constexpr Event FILE_TOO_LARGE = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW);
|
static constexpr Event FILE_TOO_LARGE = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW);
|
||||||
static constexpr Event BUSY_DUMPING_EVENT = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO);
|
static constexpr Event BUSY_DUMPING_EVENT = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO);
|
||||||
|
|
||||||
PersistentTmStore(object_id_t objectId, const char* baseDir, std::string baseName,
|
PersistentTmStore(PersistentTmStoreArgs args);
|
||||||
RolloverInterval intervalUnit, uint32_t intervalCount,
|
|
||||||
StorageManagerIF& tmStore, SdCardMountedIF& sdcMan);
|
|
||||||
|
|
||||||
ReturnValue_t initializeTmStore();
|
ReturnValue_t initializeTmStore();
|
||||||
State getState() const;
|
State getState() const;
|
||||||
@ -52,6 +71,9 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject {
|
|||||||
// ReturnValue_t passPacket(PusTmReader& reader);
|
// ReturnValue_t passPacket(PusTmReader& reader);
|
||||||
ReturnValue_t storePacket(PusTmReader& reader);
|
ReturnValue_t storePacket(PusTmReader& reader);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
StorageManagerIF& tmStore;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint8_t MAX_FILES_IN_ONE_SECOND = 10;
|
static constexpr uint8_t MAX_FILES_IN_ONE_SECOND = 10;
|
||||||
static constexpr size_t MAX_FILESIZE = 8192;
|
static constexpr size_t MAX_FILESIZE = 8192;
|
||||||
@ -87,7 +109,6 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject {
|
|||||||
ActiveDumpParams dumpParams;
|
ActiveDumpParams dumpParams;
|
||||||
std::optional<std::filesystem::path> activeFile;
|
std::optional<std::filesystem::path> activeFile;
|
||||||
SdCardMountedIF& sdcMan;
|
SdCardMountedIF& sdcMan;
|
||||||
StorageManagerIF& tmStore;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To get the queue where commands shall be sent.
|
* To get the queue where commands shall be sent.
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
#include <fsfw/ipc/QueueFactory.h>
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
#include <fsfw/tmtcservices/TmTcMessage.h>
|
#include <fsfw/tmtcservices/TmTcMessage.h>
|
||||||
|
|
||||||
PersistentTmStoreWithTmQueue::PersistentTmStoreWithTmQueue(StorageManagerIF& tmStore,
|
PersistentTmStoreWithTmQueue::PersistentTmStoreWithTmQueue(PersistentTmStoreArgs args,
|
||||||
PersistentTmStore& persistentTmStore,
|
const char* storeName,
|
||||||
uint32_t tmQueueDepth)
|
uint32_t tmQueueDepth)
|
||||||
: tmStore(tmStore), persistentTmStore(persistentTmStore) {
|
: PersistentTmStore(args), storeName(storeName) {
|
||||||
tmQueue = QueueFactory::instance()->createMessageQueue(tmQueueDepth);
|
tmQueue = QueueFactory::instance()->createMessageQueue(tmQueueDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,8 +21,13 @@ ReturnValue_t PersistentTmStoreWithTmQueue::handleNextTm() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
PusTmReader reader(accessor.second.data(), accessor.second.size());
|
PusTmReader reader(accessor.second.data(), accessor.second.size());
|
||||||
persistentTmStore.storePacket(reader);
|
storePacket(reader);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
PersistentTmStore& PersistentTmStoreWithTmQueue::getTmStore() { return persistentTmStore; }
|
const char* PersistentTmStoreWithTmQueue::getName() const { return storeName; }
|
||||||
|
|
||||||
|
MessageQueueId_t PersistentTmStoreWithTmQueue::getReportReceptionQueue(
|
||||||
|
uint8_t virtualChannel) const {
|
||||||
|
return tmQueue->getId();
|
||||||
|
}
|
||||||
|
@ -2,18 +2,19 @@
|
|||||||
#define MISSION_TMTC_PERSISTENTTMSTOREWITHTMQUEUE_H_
|
#define MISSION_TMTC_PERSISTENTTMSTOREWITHTMQUEUE_H_
|
||||||
#include <mission/tmtc/PersistentTmStore.h>
|
#include <mission/tmtc/PersistentTmStore.h>
|
||||||
|
|
||||||
class PersistentTmStoreWithTmQueue : public AcceptsTelemetryIF {
|
class PersistentTmStoreWithTmQueue : public PersistentTmStore, public AcceptsTelemetryIF {
|
||||||
public:
|
public:
|
||||||
PersistentTmStoreWithTmQueue(StorageManagerIF& tmStore, PersistentTmStore& persistentTmStore,
|
PersistentTmStoreWithTmQueue(PersistentTmStoreArgs args, const char* storeName,
|
||||||
uint32_t tmQueueDepth);
|
uint32_t tmQueueDepth);
|
||||||
|
|
||||||
ReturnValue_t handleNextTm();
|
ReturnValue_t handleNextTm();
|
||||||
PersistentTmStore& getTmStore();
|
|
||||||
|
[[nodiscard]] const char* getName() const override;
|
||||||
|
[[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StorageManagerIF& tmStore;
|
const char* storeName;
|
||||||
MessageQueueIF* tmQueue;
|
MessageQueueIF* tmQueue;
|
||||||
PersistentTmStore& persistentTmStore;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_TMTC_PERSISTENTTMSTOREWITHTMQUEUE_H_ */
|
#endif /* MISSION_TMTC_PERSISTENTTMSTOREWITHTMQUEUE_H_ */
|
||||||
|
35
mission/tmtc/TmStoreTaskBase.cpp
Normal file
35
mission/tmtc/TmStoreTaskBase.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include "TmStoreTaskBase.h"
|
||||||
|
|
||||||
|
TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore,
|
||||||
|
VirtualChannel& channel)
|
||||||
|
: SystemObject(objectId), ipcStore(ipcStore), channel(channel) {}
|
||||||
|
|
||||||
|
bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store) {
|
||||||
|
bool tmToStoreReceived = true;
|
||||||
|
bool tcRequestReceived = true;
|
||||||
|
bool dumpsPerformed = false;
|
||||||
|
// Store TM persistently
|
||||||
|
ReturnValue_t result = store.handleNextTm();
|
||||||
|
if (result == MessageQueueIF::NO_QUEUE) {
|
||||||
|
tmToStoreReceived = false;
|
||||||
|
}
|
||||||
|
// Handle TC requests, for example deletion or retrieval requests.
|
||||||
|
result = store.handleCommandQueue(ipcStore);
|
||||||
|
if (result == MessageQueueIF::NO_QUEUE) {
|
||||||
|
tcRequestReceived = false;
|
||||||
|
}
|
||||||
|
// Dump TMs when applicable
|
||||||
|
if (store.getState() == PersistentTmStore::State::DUMPING) {
|
||||||
|
size_t dumpedLen;
|
||||||
|
// TODO: Maybe do a bit of a delay every 100-200 packets?
|
||||||
|
// TODO: handle returnvalue?
|
||||||
|
result = store.dumpNextPacket(channel, dumpedLen);
|
||||||
|
if (result == returnvalue::OK) {
|
||||||
|
dumpsPerformed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tcRequestReceived or tmToStoreReceived or dumpsPerformed) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
22
mission/tmtc/TmStoreTaskBase.h
Normal file
22
mission/tmtc/TmStoreTaskBase.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef MISSION_TMTC_TMSTORETASKBASE_H_
|
||||||
|
#define MISSION_TMTC_TMSTORETASKBASE_H_
|
||||||
|
|
||||||
|
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||||
|
#include <mission/tmtc/VirtualChannel.h>
|
||||||
|
|
||||||
|
class TmStoreTaskBase : public SystemObject {
|
||||||
|
public:
|
||||||
|
TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel);
|
||||||
|
/**
|
||||||
|
* Handling for one store. Returns if anything was done.
|
||||||
|
* @param store
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool handleOneStore(PersistentTmStoreWithTmQueue& store);
|
||||||
|
|
||||||
|
private:
|
||||||
|
StorageManagerIF& ipcStore;
|
||||||
|
VirtualChannel& channel;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MISSION_TMTC_TMSTORETASKBASE_H_ */
|
@ -3,9 +3,9 @@
|
|||||||
VirtualChannel::VirtualChannel(object_id_t objectId, uint8_t vcId, const char* vcName, PtmeIF& ptme,
|
VirtualChannel::VirtualChannel(object_id_t objectId, uint8_t vcId, const char* vcName, PtmeIF& ptme,
|
||||||
const std::atomic_bool& linkStateProvider)
|
const std::atomic_bool& linkStateProvider)
|
||||||
: SystemObject(objectId),
|
: SystemObject(objectId),
|
||||||
|
ptme(ptme),
|
||||||
vcId(vcId),
|
vcId(vcId),
|
||||||
vcName(vcName),
|
vcName(vcName),
|
||||||
ptme(ptme),
|
|
||||||
linkStateProvider(linkStateProvider) {}
|
linkStateProvider(linkStateProvider) {}
|
||||||
|
|
||||||
ReturnValue_t VirtualChannel::initialize() { return returnvalue::OK; }
|
ReturnValue_t VirtualChannel::initialize() { return returnvalue::OK; }
|
||||||
|
@ -7,15 +7,18 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
||||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
|
|
||||||
VirtualChannelWithQueue::VirtualChannelWithQueue(VirtualChannel& channel, StorageManagerIF& tmStore,
|
VirtualChannelWithQueue::VirtualChannelWithQueue(object_id_t objectId, uint8_t vcId,
|
||||||
uint32_t tmQueueDepth,
|
const char* vcName, PtmeIF& ptme,
|
||||||
const std::atomic_bool& linkStateProvider)
|
const std::atomic_bool& linkStateProvider,
|
||||||
: channel(channel) {
|
StorageManagerIF& tmStore, uint32_t tmQueueDepth)
|
||||||
auto mqArgs = MqArgs(channel.getObjectId(), reinterpret_cast<void*>(channel.getVcid()));
|
: VirtualChannel(objectId, vcId, vcName, ptme, linkStateProvider) {
|
||||||
|
auto mqArgs = MqArgs(getObjectId(), reinterpret_cast<void*>(getVcid()));
|
||||||
tmQueue = QueueFactory::instance()->createMessageQueue(
|
tmQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
tmQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
tmQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* VirtualChannelWithQueue::getName() const { return VirtualChannel::getName(); }
|
||||||
|
|
||||||
ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
|
ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
|
||||||
TmTcMessage message;
|
TmTcMessage message;
|
||||||
ReturnValue_t result = tmQueue->receiveMessage(&message);
|
ReturnValue_t result = tmQueue->receiveMessage(&message);
|
||||||
@ -33,7 +36,7 @@ ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel.write(data, size);
|
write(data, size);
|
||||||
tmStore->deleteData(storeId);
|
tmStore->deleteData(storeId);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -44,5 +47,3 @@ ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
|
|||||||
MessageQueueId_t VirtualChannelWithQueue::getReportReceptionQueue(uint8_t virtualChannel) const {
|
MessageQueueId_t VirtualChannelWithQueue::getReportReceptionQueue(uint8_t virtualChannel) const {
|
||||||
return tmQueue->getId();
|
return tmQueue->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualChannel& VirtualChannelWithQueue::vc() { return channel; }
|
|
||||||
|
@ -20,7 +20,7 @@ class StorageManagerIF;
|
|||||||
*
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class VirtualChannelWithQueue : public AcceptsTelemetryIF {
|
class VirtualChannelWithQueue : public VirtualChannel, public AcceptsTelemetryIF {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
@ -28,18 +28,15 @@ class VirtualChannelWithQueue : public AcceptsTelemetryIF {
|
|||||||
* @param vcId The virtual channel id assigned to this object
|
* @param vcId The virtual channel id assigned to this object
|
||||||
* @param tmQueueDepth Queue depth of queue receiving telemetry from other objects
|
* @param tmQueueDepth Queue depth of queue receiving telemetry from other objects
|
||||||
*/
|
*/
|
||||||
VirtualChannelWithQueue(VirtualChannel& channel, StorageManagerIF& tmStore, uint32_t tmQueueDepth,
|
VirtualChannelWithQueue(object_id_t objectId, uint8_t vcId, const char* vcName, PtmeIF& ptme,
|
||||||
const std::atomic_bool& linkStateProvider);
|
const std::atomic_bool& linkStateProvider, StorageManagerIF& tmStore,
|
||||||
|
uint32_t tmQueueDepth);
|
||||||
|
|
||||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override;
|
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override;
|
||||||
|
[[nodiscard]] const char* getName() const override;
|
||||||
ReturnValue_t sendNextTm();
|
ReturnValue_t sendNextTm();
|
||||||
|
|
||||||
VirtualChannel& vc();
|
|
||||||
|
|
||||||
const char* getName() const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VirtualChannel& channel;
|
|
||||||
MessageQueueIF* tmQueue = nullptr;
|
MessageQueueIF* tmQueue = nullptr;
|
||||||
StorageManagerIF* tmStore = nullptr;
|
StorageManagerIF* tmStore = nullptr;
|
||||||
};
|
};
|
||||||
|
@ -49,3 +49,9 @@ PusPacketFilter filters::notOkFilter() {
|
|||||||
notOkFilter.addServiceSubservice(pus::PUS_SERVICE_1, 8);
|
notOkFilter.addServiceSubservice(pus::PUS_SERVICE_1, 8);
|
||||||
return notOkFilter;
|
return notOkFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PusPacketFilter filters::cfdpFilter() {
|
||||||
|
PusPacketFilter cfdpFilter;
|
||||||
|
cfdpFilter.addApid(config::EIVE_CFDP_APID);
|
||||||
|
return cfdpFilter;
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
namespace filters {
|
namespace filters {
|
||||||
|
|
||||||
|
PusPacketFilter cfdpFilter();
|
||||||
PusPacketFilter hkFilter();
|
PusPacketFilter hkFilter();
|
||||||
PusPacketFilter miscFilter();
|
PusPacketFilter miscFilter();
|
||||||
PusPacketFilter okFilter();
|
PusPacketFilter okFilter();
|
||||||
|
Loading…
Reference in New Issue
Block a user