mirror of
https://github.com/nasa/fprime.git
synced 2025-12-11 04:35:25 -06:00
* Initial fix for CWE-453-CmdBufferAssert * Added EVR throttle; updated ut * Updated unit tests * Updated UT to check for TLM update * Implemented finding from pull request * Removed Test Directory * Update model and SDD * Move telemetry to rate group to prevent flood * Fix Ref topology * Format * sp --------- Co-authored-by: bitWarrior <bitWarrior@protonmail.com> Co-authored-by: M Starch <LeStarch@googlemail.com>
192 lines
8.5 KiB
C++
192 lines
8.5 KiB
C++
/**
|
|
* \file
|
|
* \author T.Canham
|
|
* \brief Component responsible for dispatching incoming commands to registered components
|
|
*
|
|
* \copyright
|
|
* Copyright 2009-2015, by the California Institute of Technology.
|
|
* ALL RIGHTS RESERVED. United States Government Sponsorship
|
|
* acknowledged.
|
|
* <br /><br />
|
|
*/
|
|
|
|
#ifndef COMMANDDISPATCHERIMPL_HPP_
|
|
#define COMMANDDISPATCHERIMPL_HPP_
|
|
|
|
#include <Os/Mutex.hpp>
|
|
#include <Svc/CmdDispatcher/CommandDispatcherComponentAc.hpp>
|
|
#include <config/CommandDispatcherImplCfg.hpp>
|
|
|
|
namespace Svc {
|
|
|
|
//! \class CommandDispatcherImpl
|
|
//! \brief Command Dispatcher component class
|
|
//!
|
|
//! The command dispatcher takes incoming Fw::Com packets that contain
|
|
//! encoded commands. It extracts the opcode and looks it up in a table
|
|
//! that is populated by components at registration time. If a component
|
|
//! is connected to the seqCmdStatus port with the same number
|
|
//! as the port that submitted the command, the command status will be returned.
|
|
|
|
class CommandDispatcherImpl final : public CommandDispatcherComponentBase {
|
|
friend class CommandDispatcherTester;
|
|
|
|
public:
|
|
//! \brief Command Dispatcher constructor
|
|
//!
|
|
//! The constructor initializes the state of the component.
|
|
//! In this component, the opcode dispatch and tracking tables
|
|
//! are initialized.
|
|
//!
|
|
//! \param name the component instance name
|
|
CommandDispatcherImpl(const char* name);
|
|
//! \brief Component destructor
|
|
//!
|
|
//! The destructor for this component is empty
|
|
virtual ~CommandDispatcherImpl();
|
|
|
|
protected:
|
|
private:
|
|
//! \brief component command status handler
|
|
//!
|
|
//! The command status handler is called when a component
|
|
//! reports the completion of a command.
|
|
//!
|
|
//! \param portNum the number of the incoming port.
|
|
//! \param opCode the opcode of the completed command.
|
|
//! \param cmdSeq the sequence number assigned to the command when it was dispatched
|
|
//! \param response the completion status of the command
|
|
void compCmdStat_handler(FwIndexType portNum,
|
|
FwOpcodeType opCode,
|
|
U32 cmdSeq,
|
|
const Fw::CmdResponse& response) override;
|
|
//! \brief component command buffer handler
|
|
//!
|
|
//! The command buffer handler is called to submit a new
|
|
//! command packet to be decoded
|
|
//!
|
|
//! \param portNum the number of the incoming port.
|
|
//! \param data the buffer containing the command.
|
|
//! \param context a user value returned with the status
|
|
void seqCmdBuff_handler(FwIndexType portNum, Fw::ComBuffer& data, U32 context) override;
|
|
//! \brief component command registration handler
|
|
//!
|
|
//! The command registration handler is called to register
|
|
//! new opcodes. The port number called is used to indicate
|
|
//! which port should be used to dispatch the opcode.
|
|
//!
|
|
//! \param portNum the number of the incoming port.
|
|
//! \param opCode the opcode being registered.
|
|
void compCmdReg_handler(FwIndexType portNum, FwOpcodeType opCode) override;
|
|
//! \brief component ping handler
|
|
//!
|
|
//! The ping handler responds to messages to verify that the task
|
|
//! is still executing. Will call output ping port
|
|
//!
|
|
//! \param portNum the number of the incoming port.
|
|
//! \param opCode the opcode being registered.
|
|
//! \param key the key value that is returned with the ping response
|
|
void pingIn_handler(FwIndexType portNum, U32 key) override;
|
|
|
|
//! Handler implementation for run
|
|
//!
|
|
//! Run port used to emit telemetry. Specifically this port call emits the CommandsDropped telemetry channel.
|
|
void run_handler(FwIndexType portNum, //!< The port number
|
|
U32 context //!< The call order
|
|
) override;
|
|
|
|
//! \brief NO_OP command handler
|
|
//!
|
|
//! A test command that does nothing
|
|
//!
|
|
//! \param opCode the NO_OP opcode.
|
|
//! \param cmdSeq the assigned sequence number for the command
|
|
void CMD_NO_OP_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) override;
|
|
//! \brief NO_OP with string command handler
|
|
//!
|
|
//! A test command that receives a string and sends an event
|
|
//! with the string as an argument
|
|
//!
|
|
//! \param opCode the NO_OP_STRING opcode.
|
|
//! \param cmdSeq the assigned sequence number for the command
|
|
//! \param arg1 the string argument
|
|
void CMD_NO_OP_STRING_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdStringArg& arg1) override;
|
|
//! \brief A test command with different argument types
|
|
//!
|
|
//! A test command that receives a set of arguments of different types
|
|
//!
|
|
//! \param opCode the TEST_CMD_1 opcode.
|
|
//! \param cmdSeq the assigned sequence number for the command
|
|
//! \param arg1 the I32 argument
|
|
//! \param arg2 the F32 argument
|
|
//! \param arg3 the U8 argument
|
|
void CMD_TEST_CMD_1_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, I32 arg1, F32 arg2, U8 arg3) override;
|
|
//! \brief A command to clear the command tracking
|
|
//!
|
|
//! This command will clear the table tracking the completion of commands.
|
|
//! It is meant to be used if the tracking table has gotten full because of
|
|
//! a software failure. It is dangerous in that it can clear a command
|
|
//! that a sequencer is waiting for.
|
|
//!
|
|
//! \param opCode the CLEAR_TRACKING opcode.
|
|
//! \param cmdSeq the assigned sequence number for the command
|
|
void CMD_CLEAR_TRACKING_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) override;
|
|
|
|
//! \brief Called when the command sequence queue overflows
|
|
//!
|
|
//! Generate event to the user that the command queue overflowed and the
|
|
//! command will not be processed.
|
|
//!
|
|
//! \param portNum the number of the incoming port.
|
|
//! \param data the buffer containing the command.
|
|
//! \param context call value defined by user
|
|
void seqCmdBuff_overflowHook(FwIndexType portNum, Fw::ComBuffer& data, U32 context) override;
|
|
|
|
//! \struct DispatchEntry
|
|
//! \brief table used to store opcode to port mappings
|
|
//!
|
|
//! The DispatchEntry table is used to map incoming opcodes to the port
|
|
//! connected to the component that implements the opcode.
|
|
//! As each command opcode is registered, a new entry is found
|
|
//! in the table by checking for the "used" flag. The opcode
|
|
//! member is set to the opcode, and the port member set to the
|
|
//! port to dispatch to. When a new opcode is received for
|
|
//! execution, the table is traversed until the opcode is located.
|
|
|
|
struct DispatchEntry {
|
|
bool used; //!< if entry has been used yet
|
|
FwOpcodeType opcode; //!< opcode of entry
|
|
FwIndexType port; //!< which port the entry invokes
|
|
} m_entryTable[CMD_DISPATCHER_DISPATCH_TABLE_SIZE]; //!< table of dispatch entries
|
|
|
|
//! \struct SequenceTracker
|
|
//! \brief table used to store opcode that are being executed
|
|
//!
|
|
//! The SequenceTracker table is used to track commands that are being executed
|
|
//! but are not yet complete. When a new command opcode is received,
|
|
//! the status port that would be used to report the completion status
|
|
//! is checked. If it is connected, then an entry is placed in this table.
|
|
//! The "used" flag is set, and the "seq" member is set to the
|
|
//! assigned sequence number for the command. The "opCode" field is
|
|
//! used for the opcode, and the "callerPort" field is used to store
|
|
//! the port number of the caller so the status can be reported back to
|
|
//! correct port.
|
|
|
|
struct SequenceTracker {
|
|
bool used; //!< if this slot is used
|
|
U32 seq; //!< command sequence number
|
|
FwOpcodeType opCode; //!< opcode being tracked
|
|
U32 context; //!< context passed by user
|
|
FwIndexType callerPort; //!< port command source port
|
|
} m_sequenceTracker[CMD_DISPATCHER_SEQUENCER_TABLE_SIZE]; //!< sequence tracking port for command completions;
|
|
|
|
U32 m_seq; //!< current command sequence number
|
|
|
|
U32 m_numCmdsDispatched; //!< number of commands dispatched
|
|
U32 m_numCmdErrors; //!< number of commands with an error
|
|
U32 m_numCmdsDropped; //!< number of commands dropped due to buffer overflow
|
|
};
|
|
} // namespace Svc
|
|
|
|
#endif /* COMMANDDISPATCHERIMPL_HPP_ */
|