Refactor TM handling #450

Merged
muellerr merged 47 commits from refactor_tm_handling into develop 2023-03-11 15:05:22 +01:00
23 changed files with 330 additions and 125 deletions
Showing only changes of commit b2fd2f5d83 - Show all commits

View File

@ -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

View File

@ -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;
} }

View File

@ -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);

View File

@ -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);

View File

@ -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,
}; };

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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_ */

View File

@ -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);
} }
} }

View File

@ -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_ */

View File

@ -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() {

View File

@ -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.

View File

@ -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();
}

View File

@ -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_ */

View 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;
}

View 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_ */

View File

@ -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; }

View File

@ -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; }

View File

@ -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;
}; };

View File

@ -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;
}

View File

@ -4,6 +4,7 @@
namespace filters { namespace filters {
PusPacketFilter cfdpFilter();
PusPacketFilter hkFilter(); PusPacketFilter hkFilter();
PusPacketFilter miscFilter(); PusPacketFilter miscFilter();
PusPacketFilter okFilter(); PusPacketFilter okFilter();