Skip to content
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions Svc/CmdSequencer/CmdSequencerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ void CmdSequencerComponentImpl::CS_RUN_cmdHandler(FwOpcodeType opCode,
if (AUTO == this->m_stepMode) {
this->m_runMode = RUNNING;
if (this->isConnected_seqStartOut_OutputPort(0)) {
this->seqStartOut_out(0, this->m_sequence->getStringFileName());
// Create empty SeqArgs as placeholder
// Use parameterized constructor to ensure m_size is initialized to 0
Svc::SeqArgs emptyArgs{0, 0};
this->seqStartOut_out(0, this->m_sequence->getStringFileName(), emptyArgs);
}
this->performCmd_Step();
}
Expand Down Expand Up @@ -162,15 +165,19 @@ void CmdSequencerComponentImpl::doSequenceRun(const Fw::StringBase& filename) {
if (AUTO == this->m_stepMode) {
this->m_runMode = RUNNING;
if (this->isConnected_seqStartOut_OutputPort(0)) {
this->seqStartOut_out(0, this->m_sequence->getStringFileName());
// Create empty SeqArgs as placeholder
// Use parameterized constructor to ensure m_size is initialized to 0
Svc::SeqArgs emptyArgs{0, 0};
this->seqStartOut_out(0, this->m_sequence->getStringFileName(), emptyArgs);
}
this->performCmd_Step();
}

this->log_ACTIVITY_HI_CS_PortSequenceStarted(this->m_sequence->getLogFileName());
}

void CmdSequencerComponentImpl::seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename) {
void CmdSequencerComponentImpl::seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename, const Svc::SeqArgs& args) {
(void)args; // Suppress unused parameter warning
this->doSequenceRun(filename);
}

Expand Down Expand Up @@ -322,7 +329,9 @@ void CmdSequencerComponentImpl ::CS_START_cmdHandler(FwOpcodeType opcode, U32 cm
this->performCmd_Step();
this->log_ACTIVITY_HI_CS_CmdStarted(this->m_sequence->getLogFileName());
if (this->isConnected_seqStartOut_OutputPort(0)) {
this->seqStartOut_out(0, this->m_sequence->getStringFileName());
// Create empty SeqArgs as placeholder
Svc::SeqArgs emptyArgs{0, 0};
this->seqStartOut_out(0, this->m_sequence->getStringFileName(), emptyArgs);
}
this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::OK);
}
Expand Down
3 changes: 2 additions & 1 deletion Svc/CmdSequencer/CmdSequencerImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,8 @@ class CmdSequencerComponentImpl final : public CmdSequencerComponentBase {

//! Handler for input port seqRunIn
void seqRunIn_handler(FwIndexType portNum, //!< The port number
const Fw::StringBase& filename //!< The sequence file
const Fw::StringBase& filename, //!< The sequence file
const Svc::SeqArgs& args //!< Sequence arguments (not currently used)
) override;

//! Handler implementation for seqDispatchIn
Expand Down
4 changes: 2 additions & 2 deletions Svc/CmdSequencer/Commands.fppi
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

@ Run a command sequence file
async command CS_RUN(
fileName: string size 240 @< The name of the sequence file
fileName: string size FileNameStringSize @< The name of the sequence file
$block: BlockState @< Return command status when complete or not
) \
opcode 0

@ Validate a command sequence file
async command CS_VALIDATE(
fileName: string size 240 @< The name of the sequence file
fileName: string size FileNameStringSize @< The name of the sequence file
) \
opcode 1

Expand Down
12 changes: 8 additions & 4 deletions Svc/CmdSequencer/test/ut/CmdSequencerTester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ void CmdSequencerTester ::parameterizedDataReadErrors(SequenceFiles::File& file)
void CmdSequencerTester ::parameterizedNeverLoaded() {
// Try to run a sequence
Fw::String fArg("");
this->invoke_to_seqRunIn(0, fArg);
Svc::SeqArgs emptyArgs{0, 0};
this->invoke_to_seqRunIn(0, fArg, emptyArgs);
this->clearAndDispatch();
// Assert seqDone response
ASSERT_from_seqDone_SIZE(1);
Expand Down Expand Up @@ -474,7 +475,8 @@ void CmdSequencerTester ::runSequence(const U32 cmdSeq, const char* const fileNa
void CmdSequencerTester ::runSequenceByPortCall(const char* const fileName) {
// Invoke the seqRun port
Fw::String fArg(fileName);
this->invoke_to_seqRunIn(0, fArg);
Svc::SeqArgs emptyArgs{0, 0};
this->invoke_to_seqRunIn(0, fArg, emptyArgs);
this->clearAndDispatch();
// Assert no command response
ASSERT_CMD_RESPONSE_SIZE(0);
Expand All @@ -500,7 +502,8 @@ void CmdSequencerTester ::runSequenceByFileDispatcherPortCall(const char* const
void CmdSequencerTester ::runLoadedSequence() {
// Invoke the port
Fw::String fArg("");
this->invoke_to_seqRunIn(0, fArg);
Svc::SeqArgs emptyArgs{0, 0};
this->invoke_to_seqRunIn(0, fArg, emptyArgs);
this->clearAndDispatch();
// Assert no command response
ASSERT_CMD_RESPONSE_SIZE(0);
Expand Down Expand Up @@ -530,7 +533,8 @@ void CmdSequencerTester ::startNewSequence(const char* const fileName) {
ASSERT_EVENTS_CS_InvalidMode_SIZE(1);
// Invoke sequence port
Fw::String fArg(fileName);
this->invoke_to_seqRunIn(0, fArg);
Svc::SeqArgs emptyArgs{0, 0};
this->invoke_to_seqRunIn(0, fArg, emptyArgs);
this->clearAndDispatch();
// Assert response on seqDone
ASSERT_from_seqDone_SIZE(1);
Expand Down
3 changes: 2 additions & 1 deletion Svc/CmdSequencer/test/ut/ImmediateBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ void CmdSequencerTester ::parameterizedLoadRunRun(SequenceFiles::File& file, con
this->parameterizedAutoByPort(file, numCommands, bound);
// Try to run a loaded sequence
Fw::String fArg("");
this->invoke_to_seqRunIn(0, fArg);
Svc::SeqArgs emptyArgs{0, 0};
this->invoke_to_seqRunIn(0, fArg, emptyArgs);
this->clearAndDispatch();
// Assert seqDone response
ASSERT_from_seqDone_SIZE(1);
Expand Down
3 changes: 2 additions & 1 deletion Svc/CmdSequencer/test/ut/InvalidFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ void CmdSequencerTester ::MissingCRC() {
ASSERT_TLM_CS_Errors(0, 2);
// Run the sequence by port call
Fw::String fArg(file.getName());
this->invoke_to_seqRunIn(0, fArg);
Svc::SeqArgs emptyArgs{0, 0};
this->invoke_to_seqRunIn(0, fArg, emptyArgs);
this->clearAndDispatch();
// Assert seqDone response
ASSERT_from_seqDone_SIZE(1);
Expand Down
39 changes: 30 additions & 9 deletions Svc/FpySequencer/FpySequencer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ void FpySequencer::RUN_cmdHandler(FwOpcodeType opCode, //!< The op
U32 cmdSeq, //!< The command sequence number
const Fw::CmdStringArg& fileName, //!< The name of the sequence file
FpySequencer_BlockState block //!< Return command status when complete or not
) {
// Empty args and delegate to RUN_ARGS handler
this->RUN_ARGS_cmdHandler(opCode, cmdSeq, fileName, block, Svc::SeqArgs{0, 0});
}

void FpySequencer ::RUN_ARGS_cmdHandler(FwOpcodeType opCode, //!< The opcode
U32 cmdSeq, //!< The command sequence number
const Fw::CmdStringArg& fileName, //!< The name of the sequence file
Svc::FpySequencer_BlockState block, //!< Return command status when complete or not
Svc::SeqArgs args //!< Arguments to pass to the sequencer
) {
// can only run a seq while in idle
if (sequencer_getState() != State::IDLE) {
Expand All @@ -53,7 +63,8 @@ void FpySequencer::RUN_cmdHandler(FwOpcodeType opCode, //!< The op
this->m_savedCmdSeq = cmdSeq;
}

this->sequencer_sendSignal_cmd_RUN(FpySequencer_SequenceExecutionArgs(fileName, block));
// Store args for pushArgsToStack action
this->sequencer_sendSignal_cmd_RUN(FpySequencer_SequenceExecutionArgs(fileName, block, args));

// only respond if the user doesn't want us to block further execution
if (block == FpySequencer_BlockState::NO_BLOCK) {
Expand All @@ -68,6 +79,16 @@ void FpySequencer::VALIDATE_cmdHandler(FwOpcodeType opCode, //!< Th
U32 cmdSeq, //!< The command sequence number
const Fw::CmdStringArg& fileName //!< The name of the sequence file
) {
this->VALIDATE_ARGS_cmdHandler(opCode, cmdSeq, fileName, Svc::SeqArgs{0, 0});
}

//! Handler implementation for command VALIDATE_ARGS
//!
//! Loads and validates a sequence with arguments
void FpySequencer ::VALIDATE_ARGS_cmdHandler(FwOpcodeType opCode,
U32 cmdSeq,
const Fw::CmdStringArg& fileName,
Svc::SeqArgs buffer) {
// can only validate a seq while in idle
if (sequencer_getState() != State::IDLE) {
this->log_WARNING_HI_InvalidCommand(static_cast<I32>(sequencer_getState()));
Expand All @@ -80,13 +101,12 @@ void FpySequencer::VALIDATE_cmdHandler(FwOpcodeType opCode, //!< Th
this->m_savedOpCode = opCode;
this->m_savedCmdSeq = cmdSeq;

// VALIDATE_ARGS receives args via command interface
// Store args for pushArgsToStack action when RUN_VALIDATED is called
this->sequencer_sendSignal_cmd_VALIDATE(
FpySequencer_SequenceExecutionArgs(fileName, FpySequencer_BlockState::BLOCK));
FpySequencer_SequenceExecutionArgs(fileName, FpySequencer_BlockState::BLOCK, buffer));
}

//! Handler for command RUN_VALIDATED
//!
//! Runs a previously validated sequence
void FpySequencer::RUN_VALIDATED_cmdHandler(
FwOpcodeType opCode, //!< The opcode
U32 cmdSeq, //!< The command sequence number
Expand All @@ -105,7 +125,7 @@ void FpySequencer::RUN_VALIDATED_cmdHandler(
this->m_savedCmdSeq = cmdSeq;
}

this->sequencer_sendSignal_cmd_RUN_VALIDATED(FpySequencer_SequenceExecutionArgs(this->m_sequenceFilePath, block));
this->sequencer_sendSignal_cmd_RUN_VALIDATED(FpySequencer_SequenceExecutionArgs(this->m_sequenceFilePath, block, this->m_sequenceArgs));

// only respond if the user doesn't want us to block further execution
if (block == FpySequencer_BlockState::NO_BLOCK) {
Expand Down Expand Up @@ -358,15 +378,16 @@ void FpySequencer::cmdResponseIn_handler(FwIndexType portNum, //!< T
}

//! Handler for input port seqRunIn
void FpySequencer::seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename) {
void FpySequencer::seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename, const Svc::SeqArgs& args) {
// can only run a seq while in idle
if (sequencer_getState() != State::IDLE) {
this->log_WARNING_HI_InvalidSeqRunCall(static_cast<I32>(sequencer_getState()));
return;
}

// seqRunIn is never blocking
this->sequencer_sendSignal_cmd_RUN(FpySequencer_SequenceExecutionArgs(filename, FpySequencer_BlockState::NO_BLOCK));
// seqRunIn is never blocking - store args for pushArgsToStack action
// Args must be serialized in F' big-endian format by the caller before being sent
this->sequencer_sendSignal_cmd_RUN(FpySequencer_SequenceExecutionArgs(filename, FpySequencer_BlockState::NO_BLOCK, args));
}

//! Handler for input port tlmWrite
Expand Down
66 changes: 59 additions & 7 deletions Svc/FpySequencer/FpySequencer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class FpySequencer : public FpySequencerComponentBase {
// pushes a byte array to the top of the stack from the source array
// leaves the source array unmodified
// does not convert endianness
void push(U8* src, Fpy::StackSizeType size);
void push(const U8* src, Fpy::StackSizeType size);

// pushes zero bytes to the stack
void pushZeroes(Fpy::StackSizeType byteCount);
Expand Down Expand Up @@ -145,6 +145,14 @@ class FpySequencer : public FpySequencerComponentBase {
const Fw::CmdStringArg& fileName, //!< The name of the sequence file
FpySequencer_BlockState block //!< Return command status when complete or not
) override;

//! Handler implementation for command RUN_ARGS
void RUN_ARGS_cmdHandler(FwOpcodeType opCode, //!< The opcode
U32 cmdSeq, //!< The command sequence number
const Fw::CmdStringArg& fileName, //!< The name of the sequence file
Svc::FpySequencer_BlockState block, //!< Return command status when complete or not
Svc::SeqArgs args //!< Arguments to pass to the sequencer
) override;

//! Handler for command VALIDATE
//!
Expand All @@ -153,13 +161,22 @@ class FpySequencer : public FpySequencerComponentBase {
U32 cmdSeq, //!< The command sequence number
const Fw::CmdStringArg& fileName //!< The name of the sequence file
) override;

//! Handler implementation for command VALIDATE_ARGS
//!
//! Loads and validates a sequence with arguments
void VALIDATE_ARGS_cmdHandler(FwOpcodeType opCode, //!< The opcode
U32 cmdSeq, //!< The command sequence number
const Fw::CmdStringArg& fileName, //!< The name of the sequence file
Svc::SeqArgs buffer //!< Arguments to pass to the sequencer
) override;

//! Handler for command RUN_VALIDATED
//! Handler implementation for command RUN_VALIDATED
//!
//! Runs a previously validated sequence
void RUN_VALIDATED_cmdHandler(FwOpcodeType opCode, //!< The opcode
U32 cmdSeq, //!< The command sequence number
FpySequencer_BlockState block //!< Return command status when complete or not
//! Must be called after VALIDATE. Runs the sequence that was validated.
void RUN_VALIDATED_cmdHandler(FwOpcodeType opCode, //!< The opcode
U32 cmdSeq, //!< The command sequence number
Svc::FpySequencer_BlockState block //!< Return command status when complete or not
) override;

//! Handler for command CANCEL
Expand Down Expand Up @@ -252,6 +269,15 @@ class FpySequencer : public FpySequencerComponentBase {
Svc_FpySequencer_SequencerStateMachine::Signal signal, //!< The signal
const Svc::FpySequencer_SequenceExecutionArgs& value //!< The value
) override;

//! Implementation for action setSequenceArguments of state machine Svc_FpySequencer_SequencerStateMachine
//!
//! sets the arguments to pass to the sequence
void Svc_FpySequencer_SequencerStateMachine_action_setSequenceArguments(
SmId smId, //!< The state machine id
Svc_FpySequencer_SequencerStateMachine::Signal signal, //!< The signal
const Svc::FpySequencer_SequenceExecutionArgs& value //!< The value
) override;

//! Implementation for action validate of state machine Svc_FpySequencer_SequencerStateMachine
//!
Expand Down Expand Up @@ -333,6 +359,14 @@ class FpySequencer : public FpySequencerComponentBase {
SmId smId, //!< The state machine id
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
) override;

//! Implementation for action clearSequenceArguments of state machine Svc_FpySequencer_SequencerStateMachine
//!
//! clears arguments
void Svc_FpySequencer_SequencerStateMachine_action_clearSequenceArguments(
SmId smId, //!< The state machine id
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
) override;

//! Implementation for action checkShouldWake of state machine Svc_FpySequencer_SequencerStateMachine
//!
Expand Down Expand Up @@ -366,6 +400,14 @@ class FpySequencer : public FpySequencerComponentBase {
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
) override;

//! Implementation for action pushArgsToStack of state machine Svc_FpySequencer_SequencerStateMachine
//!
//! pushes sequence arguments to the stack
void Svc_FpySequencer_SequencerStateMachine_action_pushArgsToStack(
SmId smId, //!< The state machine id
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
) override;

//! Implementation for action clearBreakpoint of state machine Svc_FpySequencer_SequencerStateMachine
//!
//! clears the breakpoint, allowing execution of the sequence to continue
Expand Down Expand Up @@ -470,7 +512,7 @@ class FpySequencer : public FpySequencerComponentBase {
) override;

//! Handler for input port seqRunIn
void seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename) override;
void seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename, const Svc::SeqArgs& args) override;

//! Handler for input port pingIn
void pingIn_handler(FwIndexType portNum, //!< The port number
Expand Down Expand Up @@ -592,6 +634,10 @@ class FpySequencer : public FpySequencerComponentBase {
// live running computation of CRC (updated as we read)
U32 m_computedCRC;

// Size of arguments read in current sequence. Used for validation between
// User provided arguments and what is requested of the sequence.
Fpy::StackSizeType m_totalReadArgumentSize{0};
Comment thread
Lex-ari marked this conversation as resolved.
Outdated

// whether or not the sequence we're about to run should return immediately or
// block on completion
FpySequencer_BlockState m_sequenceBlockState;
Expand All @@ -600,6 +646,9 @@ class FpySequencer : public FpySequencerComponentBase {
FwOpcodeType m_savedOpCode;
U32 m_savedCmdSeq;

// sequence arguments to push to stack when entering RUNNING state
Svc::SeqArgs m_sequenceArgs{};

// the goal state is the state that we're trying to reach in the sequencer
// if it's RUNNING, then we should promptly go to RUNNING once we validate the
// sequence. if it's VALID, we should wait after VALIDATING
Expand Down Expand Up @@ -701,6 +750,9 @@ class FpySequencer : public FpySequencerComponentBase {
// reads and validates the header from the m_sequenceBuffer
// return SUCCESS if sequence is valid, FAILURE otherwise
Fw::Success readHeader();
// helper function to read and deserialize a variable-length string field (length byte + string bytes)
Comment thread
Lex-ari marked this conversation as resolved.
Outdated
// returns the length via outLength parameter and writes string data to buffer
Fw::Success deserializeStringField(Os::File& file, U8* buffer, U8& outLength);
// reads and validates the body from the m_sequenceBuffer
// return SUCCESS if sequence is valid, FAILURE otherwise
Fw::Success readBody();
Expand Down
Loading
Loading