fprime/Ref/Top/RefTopology.cpp
Rob Bocchino dcfc109b5b
Update Ref to use FPP telemetry packets (#3440)
* Revise Ref app

Convert Ref packets to FPP

* Remove header include for XML packets

* Remove trailing spaces

* Delete RefPackets.xml

* Update Ref packets

* Update fpp version

* Update fpp version

---------

Co-authored-by: M Starch <LeStarch@googlemail.com>
2025-04-03 10:36:00 -07:00

206 lines
8.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ======================================================================
// \title Topology.cpp
// \author mstarch
// \brief cpp file containing the topology instantiation code
//
// \copyright
// Copyright 2009-2022, by the California Institute of Technology.
// ALL RIGHTS RESERVED. United States Government Sponsorship
// acknowledged.
// ======================================================================
// Provides access to autocoded functions
#include <Ref/Top/RefTopologyAc.hpp>
// Necessary project-specified types
#include <Fw/Types/MallocAllocator.hpp>
#include <Os/Console.hpp>
#include <Svc/FramingProtocol/FprimeProtocol.hpp>
#include <Svc/FrameAccumulator/FrameDetector/FprimeFrameDetector.hpp>
// Used for 1Hz synthetic cycling
#include <Os/Mutex.hpp>
// Allows easy reference to objects in FPP/autocoder required namespaces
using namespace Ref;
// Instantiate a system logger that will handle Fw::Logger::log calls
Os::Console logger;
// The reference topology uses a malloc-based allocator for components that need to allocate memory during the
// initialization phase.
Fw::MallocAllocator mallocator;
// The reference topology uses the F´ packet protocol when communicating with the ground and therefore uses the F´
// framing and deframing implementations.
Svc::FprimeFraming framing;
Svc::FrameDetectors::FprimeFrameDetector frameDetector;
// The reference topology divides the incoming clock signal (1Hz) into sub-signals: 1Hz, 1/2Hz, and 1/4Hz and
// zero offset for all the dividers
Svc::RateGroupDriver::DividerSet rateGroupDivisorsSet{{{1, 0}, {2, 0}, {4, 0}}};
// Rate groups may supply a context token to each of the attached children whose purpose is set by the project. The
// reference topology sets each token to zero as these contexts are unused in this project.
U32 rateGroup1Context[Svc::ActiveRateGroup::CONNECTION_COUNT_MAX] = {};
U32 rateGroup2Context[Svc::ActiveRateGroup::CONNECTION_COUNT_MAX] = {};
U32 rateGroup3Context[Svc::ActiveRateGroup::CONNECTION_COUNT_MAX] = {};
// A number of constants are needed for construction of the topology. These are specified here.
enum TopologyConstants {
CMD_SEQ_BUFFER_SIZE = 5 * 1024,
FILE_DOWNLINK_TIMEOUT = 1000,
FILE_DOWNLINK_COOLDOWN = 1000,
FILE_DOWNLINK_CYCLE_TIME = 1000,
FILE_DOWNLINK_FILE_QUEUE_DEPTH = 10,
HEALTH_WATCHDOG_CODE = 0x123,
COMM_PRIORITY = 100,
// Buffer manager for Uplink/Downlink
COMMS_BUFFER_MANAGER_STORE_SIZE = 2048,
COMMS_BUFFER_MANAGER_STORE_COUNT = 20,
COMMS_BUFFER_MANAGER_FILE_STORE_SIZE = 3000,
COMMS_BUFFER_MANAGER_FILE_QUEUE_SIZE = 30,
COMMS_BUFFER_MANAGER_ID = 200,
// Buffer manager for Data Products
DP_BUFFER_MANAGER_STORE_SIZE = 10000,
DP_BUFFER_MANAGER_STORE_COUNT = 10,
DP_BUFFER_MANAGER_ID = 300,
};
/**
* \brief configure/setup components in project-specific way
*
* This is a *helper* function which configures/sets up each component requiring project specific input. This includes
* allocating resources, passing-in arguments, etc. This function may be inlined into the topology setup function if
* desired, but is extracted here for clarity.
*/
void configureTopology() {
// Command sequencer needs to allocate memory to hold contents of command sequences
cmdSeq.allocateBuffer(0, mallocator, CMD_SEQ_BUFFER_SIZE);
// Rate group driver needs a divisor list
rateGroupDriverComp.configure(rateGroupDivisorsSet);
// Rate groups require context arrays. Empty for Reference example.
rateGroup1Comp.configure(rateGroup1Context, FW_NUM_ARRAY_ELEMENTS(rateGroup1Context));
rateGroup2Comp.configure(rateGroup2Context, FW_NUM_ARRAY_ELEMENTS(rateGroup2Context));
rateGroup3Comp.configure(rateGroup3Context, FW_NUM_ARRAY_ELEMENTS(rateGroup3Context));
// File downlink requires some project-derived properties.
fileDownlink.configure(FILE_DOWNLINK_TIMEOUT, FILE_DOWNLINK_COOLDOWN, FILE_DOWNLINK_CYCLE_TIME,
FILE_DOWNLINK_FILE_QUEUE_DEPTH);
// Parameter database is configured with a database file name, and that file must be initially read.
prmDb.configure("PrmDb.dat");
prmDb.readParamFile();
// Health is supplied a set of ping entires.
health.setPingEntries(ConfigObjects::Ref_health::pingEntries,
FW_NUM_ARRAY_ELEMENTS(ConfigObjects::Ref_health::pingEntries), HEALTH_WATCHDOG_CODE);
// Buffer managers need a configured set of buckets and an allocator used to allocate memory for those buckets.
Svc::BufferManager::BufferBins commsBuffMgrBins;
memset(&commsBuffMgrBins, 0, sizeof(commsBuffMgrBins));
commsBuffMgrBins.bins[0].bufferSize = COMMS_BUFFER_MANAGER_STORE_SIZE;
commsBuffMgrBins.bins[0].numBuffers = COMMS_BUFFER_MANAGER_STORE_COUNT;
commsBuffMgrBins.bins[1].bufferSize = COMMS_BUFFER_MANAGER_FILE_STORE_SIZE;
commsBuffMgrBins.bins[1].numBuffers = COMMS_BUFFER_MANAGER_FILE_QUEUE_SIZE;
commsBufferManager.setup(COMMS_BUFFER_MANAGER_ID, 0, mallocator, commsBuffMgrBins);
Svc::BufferManager::BufferBins dpBuffMgrBins;
memset(&dpBuffMgrBins, 0, sizeof(dpBuffMgrBins));
dpBuffMgrBins.bins[0].bufferSize = DP_BUFFER_MANAGER_STORE_SIZE;
dpBuffMgrBins.bins[0].numBuffers = DP_BUFFER_MANAGER_STORE_COUNT;
dpBufferManager.setup(DP_BUFFER_MANAGER_ID, 0, mallocator, dpBuffMgrBins);
// Framer and Deframer components need to be passed a protocol handler
framer.setup(framing);
frameAccumulator.configure(frameDetector, 1, mallocator, 2048);
Fw::FileNameString dpDir("./DpCat");
Fw::FileNameString dpState("./DpCat/DpState.dat");
// create the DP directory if it doesn't exist
Os::FileSystem::createDirectory(dpDir.toChar());
dpCat.configure(&dpDir,1,dpState,0,mallocator);
dpWriter.configure(dpDir);
// Note: Uncomment when using Svc:TlmPacketizer
// tlmSend.setPacketList(Ref::Ref_RefPacketsTlmPackets::packetList, Ref::Ref_RefPacketsTlmPackets::omittedChannels, 1);
}
// Public functions for use in main program are namespaced with deployment name Ref
namespace Ref {
void setupTopology(const TopologyState& state) {
// Autocoded initialization. Function provided by autocoder.
initComponents(state);
// Autocoded id setup. Function provided by autocoder.
setBaseIds();
// Autocoded connection wiring. Function provided by autocoder.
connectComponents();
// Autocoded command registration. Function provided by autocoder.
regCommands();
// Autocoded configuration. Function provided by autocoder.
configComponents(state);
if (state.hostname != nullptr && state.port != 0) {
comm.configure(state.hostname, state.port);
}
// Project-specific component configuration. Function provided above. May be inlined, if desired.
configureTopology();
// Autocoded parameter loading. Function provided by autocoder.
loadParameters();
// Autocoded task kick-off (active components). Function provided by autocoder.
startTasks(state);
// Startup TLM and Config verbosity for Versions
version.config(true);
// Initialize socket client communication if and only if there is a valid specification
if (state.hostname != nullptr && state.port != 0) {
Os::TaskString name("ReceiveTask");
// Uplink is configured for receive so a socket task is started
comm.start(name, COMM_PRIORITY, Default::STACK_SIZE);
}
}
// Variables used for cycle simulation
Os::Mutex cycleLock;
volatile bool cycleFlag = true;
void startSimulatedCycle(Fw::TimeInterval interval) {
cycleLock.lock();
bool cycling = cycleFlag;
cycleLock.unLock();
// Main loop
while (cycling) {
Ref::blockDrv.callIsr();
Os::Task::delay(interval);
cycleLock.lock();
cycling = cycleFlag;
cycleLock.unLock();
}
}
void stopSimulatedCycle() {
cycleLock.lock();
cycleFlag = false;
cycleLock.unLock();
}
void teardownTopology(const TopologyState& state) {
// Autocoded (active component) task clean-up. Functions provided by topology autocoder.
stopTasks(state);
freeThreads(state);
// Other task clean-up.
comm.stop();
(void)comm.join();
// Resource deallocation
cmdSeq.deallocateBuffer(mallocator);
commsBufferManager.cleanup();
frameAccumulator.cleanup();
}
} // namespace Ref