From ed950aa8ab88f0634eda6c374376d85ee2bc6523 Mon Sep 17 00:00:00 2001 From: Alex Mariano Date: Thu, 23 Apr 2026 16:38:19 -0500 Subject: [PATCH 1/4] Add Cancel Port --- Svc/FpySequencer/FpySequencer.cpp | 9 ++++++++ Svc/FpySequencer/FpySequencer.fpp | 4 ++++ Svc/FpySequencer/FpySequencer.hpp | 6 ++++++ .../test/ut/FpySequencerTestMain.cpp | 21 +++++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/Svc/FpySequencer/FpySequencer.cpp b/Svc/FpySequencer/FpySequencer.cpp index 4fd12c50de1..5e668abd7ac 100644 --- a/Svc/FpySequencer/FpySequencer.cpp +++ b/Svc/FpySequencer/FpySequencer.cpp @@ -390,6 +390,15 @@ void FpySequencer::cmdResponseIn_handler(FwIndexType portNum, //!< T this->m_runtime.stack.push(static_cast(response.e)); } +void FpySequencer ::seqCancelIn_handler(FwIndexType portNum) { + // only state you can't cancel in is IDLE + if (sequencer_getState() == State::IDLE) { + this->log_WARNING_HI_InvalidCommand(static_cast(sequencer_getState())); + return; + } + this->sequencer_sendSignal_cmd_CANCEL(); +} + //! Handler for input port seqRunIn void FpySequencer::seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename) { // can only run a seq while in idle diff --git a/Svc/FpySequencer/FpySequencer.fpp b/Svc/FpySequencer/FpySequencer.fpp index 8af40d3d7ce..9831ef3de5d 100644 --- a/Svc/FpySequencer/FpySequencer.fpp +++ b/Svc/FpySequencer/FpySequencer.fpp @@ -53,6 +53,10 @@ module Svc { # same priority as RUN cmd async input port seqRunIn: Svc.CmdSeqIn priority 7 assert + @ port for requesting to cancel the currently running sequence + # same priority as CANCEL cmd + async input port seqCancelIn: Svc.CmdSeqCancel priority 8 assert + @ called when a sequence begins running output port seqStartOut: Svc.CmdSeqIn diff --git a/Svc/FpySequencer/FpySequencer.hpp b/Svc/FpySequencer/FpySequencer.hpp index 703229d5b66..8b1390e387c 100644 --- a/Svc/FpySequencer/FpySequencer.hpp +++ b/Svc/FpySequencer/FpySequencer.hpp @@ -483,6 +483,12 @@ class FpySequencer : public FpySequencerComponentBase { //! Handler for input port seqRunIn void seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename) override; + //! Handler implementation for seqCancelIn + //! + //! port for requesting to cancel the currently running sequence + void seqCancelIn_handler(FwIndexType portNum //!< The port number + ) override; + //! Handler for input port pingIn void pingIn_handler(FwIndexType portNum, //!< The port number U32 key //!< Value to return to pinger diff --git a/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp b/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp index 623da92ae97..ff8e122fee6 100644 --- a/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp +++ b/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp @@ -3299,6 +3299,27 @@ TEST_F(FpySequencerTester, seqRunIn) { removeFile("test.bin"); } +TEST_F(FpySequencerTester, seqCancelIn) { + this->tester_setState(State::IDLE); + this->invoke_to_seqCancelIn(0); + this->tester_doDispatch(); + // should fail if we're in IDLE + ASSERT_EVENTS_InvalidCommand_SIZE(1); + + dispatchCurrentMessages(cmp); + ASSERT_EQ(this->tester_getState(), State::IDLE); + + this->clearHistory(); + this->tester_setState(State::RUNNING_SLEEPING); + this->invoke_to_seqCancelIn(0); + this->tester_doDispatch(); + // should go back to idle + dispatchUntilState(State::IDLE); + ASSERT_EVENTS_SequenceCancelled_SIZE(1); + ASSERT_from_seqDoneOut(0, 0, 0, Fw::CmdResponse::EXECUTION_ERROR); +} + + TEST_F(FpySequencerTester, flag_EXIT_ON_CMD_FAIL) { // test a simple seq that fails because a cmd fails this->paramSet_FLAG_DEFAULT_EXIT_ON_CMD_FAIL(true, Fw::ParamValid::VALID); From cbae2cc9d3910e038e0bab0aadf353d49cabfefc Mon Sep 17 00:00:00 2001 From: Alex Mariano Date: Thu, 23 Apr 2026 17:01:43 -0500 Subject: [PATCH 2/4] Cancel Event --- Svc/FpySequencer/FpySequencer.cpp | 2 +- Svc/FpySequencer/FpySequencerEvents.fppi | 4 +++ .../test/ut/FpySequencerTestMain.cpp | 32 +------------------ 3 files changed, 6 insertions(+), 32 deletions(-) diff --git a/Svc/FpySequencer/FpySequencer.cpp b/Svc/FpySequencer/FpySequencer.cpp index d66c13a3f33..fee6105d031 100644 --- a/Svc/FpySequencer/FpySequencer.cpp +++ b/Svc/FpySequencer/FpySequencer.cpp @@ -360,7 +360,7 @@ void FpySequencer::cmdResponseIn_handler(FwIndexType portNum, //!< T void FpySequencer ::seqCancelIn_handler(FwIndexType portNum) { // only state you can't cancel in is IDLE if (sequencer_getState() == State::IDLE) { - this->log_WARNING_HI_InvalidCommand(static_cast(sequencer_getState())); + this->log_WARNING_HI_InvalidCancel(static_cast(sequencer_getState())); return; } this->sequencer_sendSignal_cmd_CANCEL(); diff --git a/Svc/FpySequencer/FpySequencerEvents.fppi b/Svc/FpySequencer/FpySequencerEvents.fppi index 683021ab628..c012e2f94cb 100644 --- a/Svc/FpySequencer/FpySequencerEvents.fppi +++ b/Svc/FpySequencer/FpySequencerEvents.fppi @@ -6,6 +6,10 @@ event InvalidSeqRunCall($state: I32) \ severity warning high \ format "Cannot run sequence from a port in state {}" +event InvalidCancel($state: I32) \ + severity warning high \ + format "Cannot cancel sequence in state {}" + event FileOpenError( filePath: string errorCode: I32 diff --git a/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp b/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp index 979da4ccbf7..67ccc78181d 100644 --- a/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp +++ b/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp @@ -3196,7 +3196,7 @@ TEST_F(FpySequencerTester, seqCancelIn) { this->invoke_to_seqCancelIn(0); this->tester_doDispatch(); // should fail if we're in IDLE - ASSERT_EVENTS_InvalidCommand_SIZE(1); + ASSERT_EVENTS_InvalidCancel_SIZE(1); dispatchCurrentMessages(cmp); ASSERT_EQ(this->tester_getState(), State::IDLE); @@ -3211,36 +3211,6 @@ TEST_F(FpySequencerTester, seqCancelIn) { ASSERT_from_seqDoneOut(0, 0, 0, Fw::CmdResponse::EXECUTION_ERROR); } - -TEST_F(FpySequencerTester, flag_EXIT_ON_CMD_FAIL) { - // test a simple seq that fails because a cmd fails - this->paramSet_FLAG_DEFAULT_EXIT_ON_CMD_FAIL(true, Fw::ParamValid::VALID); - this->paramSend_FLAG_DEFAULT_EXIT_ON_CMD_FAIL(0, 0); - this->clearHistory(); - allocMem(); - add_CONST_CMD(123); - writeAndRun(); - dispatchUntilState(State::RUNNING_AWAITING_STATEMENT_RESPONSE); - // okay now send in a failure - invoke_to_cmdResponseIn(0, 123, 0x00010001, Fw::CmdResponse::EXECUTION_ERROR); - dispatchUntilState(State::IDLE); - ASSERT_CMD_RESPONSE_SIZE(1); - ASSERT_CMD_RESPONSE(0, 0, get_OPCODE_RUN(), Fw::CmdResponse::EXECUTION_ERROR); - - // now test that it doesn't fail if we set flag to false - this->paramSet_FLAG_DEFAULT_EXIT_ON_CMD_FAIL(false, Fw::ParamValid::VALID); - this->paramSend_FLAG_DEFAULT_EXIT_ON_CMD_FAIL(0, 0); - this->clearHistory(); - // cmd is already in seq, can just rerun - writeAndRun(); - dispatchUntilState(State::RUNNING_AWAITING_STATEMENT_RESPONSE); - // okay now send in a failure - invoke_to_cmdResponseIn(0, 123, 0x00020002, Fw::CmdResponse::EXECUTION_ERROR); - dispatchUntilState(State::IDLE); - ASSERT_CMD_RESPONSE_SIZE(1); - ASSERT_CMD_RESPONSE(0, 0, get_OPCODE_RUN(), Fw::CmdResponse::OK); -} - // ---------------------------------------------------------------------- // Stack Unit Tests // ---------------------------------------------------------------------- From 68345eb9269f1b76619e9883ba1c8aad22a602ac Mon Sep 17 00:00:00 2001 From: Alex Mariano Date: Thu, 23 Apr 2026 17:05:38 -0500 Subject: [PATCH 3/4] InvalidSeqCancelCall --- Svc/FpySequencer/FpySequencer.cpp | 2 +- Svc/FpySequencer/FpySequencerEvents.fppi | 4 ++-- Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Svc/FpySequencer/FpySequencer.cpp b/Svc/FpySequencer/FpySequencer.cpp index fee6105d031..b42759fe77a 100644 --- a/Svc/FpySequencer/FpySequencer.cpp +++ b/Svc/FpySequencer/FpySequencer.cpp @@ -360,7 +360,7 @@ void FpySequencer::cmdResponseIn_handler(FwIndexType portNum, //!< T void FpySequencer ::seqCancelIn_handler(FwIndexType portNum) { // only state you can't cancel in is IDLE if (sequencer_getState() == State::IDLE) { - this->log_WARNING_HI_InvalidCancel(static_cast(sequencer_getState())); + this->log_WARNING_HI_InvalidSeqCancelCall(static_cast(sequencer_getState())); return; } this->sequencer_sendSignal_cmd_CANCEL(); diff --git a/Svc/FpySequencer/FpySequencerEvents.fppi b/Svc/FpySequencer/FpySequencerEvents.fppi index c012e2f94cb..06c75d6a287 100644 --- a/Svc/FpySequencer/FpySequencerEvents.fppi +++ b/Svc/FpySequencer/FpySequencerEvents.fppi @@ -6,9 +6,9 @@ event InvalidSeqRunCall($state: I32) \ severity warning high \ format "Cannot run sequence from a port in state {}" -event InvalidCancel($state: I32) \ +event InvalidSeqCancelCall($state: I32) \ severity warning high \ - format "Cannot cancel sequence in state {}" + format "Cannot cancel sequence from a port in state {}" event FileOpenError( filePath: string diff --git a/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp b/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp index 67ccc78181d..d09d94f6b86 100644 --- a/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp +++ b/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp @@ -3196,7 +3196,7 @@ TEST_F(FpySequencerTester, seqCancelIn) { this->invoke_to_seqCancelIn(0); this->tester_doDispatch(); // should fail if we're in IDLE - ASSERT_EVENTS_InvalidCancel_SIZE(1); + ASSERT_EVENTS_InvalidSeqCancelCall_SIZE(1); dispatchCurrentMessages(cmp); ASSERT_EQ(this->tester_getState(), State::IDLE); From 927f6c86dd61aa6f641336b3b49a90a1878e1bb0 Mon Sep 17 00:00:00 2001 From: Brian Campuzano Date: Tue, 28 Apr 2026 11:58:45 -0600 Subject: [PATCH 4/4] Added missing brace for FpySequencer UT --- Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp b/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp index 21d6f06b24d..90e03648fca 100644 --- a/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp +++ b/Svc/FpySequencer/test/ut/FpySequencerTestMain.cpp @@ -3358,6 +3358,7 @@ TEST_F(FpySequencerTester, seqCancelIn) { dispatchUntilState(State::IDLE); ASSERT_EVENTS_SequenceCancelled_SIZE(1); ASSERT_from_seqDoneOut(0, 0, 0, Fw::CmdResponse::EXECUTION_ERROR); +} TEST_F(FpySequencerTester, seqRunInArgs) { allocMem();