| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // ====================================================================== | ||
| 2 | // \title FpySequencer.cpp | ||
| 3 | // \author zimri.leisher | ||
| 4 | // \brief cpp file for FpySequencer component implementation class | ||
| 5 | // ====================================================================== | ||
| 6 | |||
| 7 | #include <Fw/Prm/ParamValid.hpp> | ||
| 8 | #include <Svc/FpySequencer/FpySequencer.hpp> | ||
| 9 | #include <config/CommandDispatcherImplCfg.hpp> | ||
| 10 | #include <new> | ||
| 11 | |||
| 12 | namespace Svc { | ||
| 13 | |||
| 14 | // ---------------------------------------------------------------------- | ||
| 15 | // Construction, initialization, and destruction | ||
| 16 | // ---------------------------------------------------------------------- | ||
| 17 | |||
| 18 | 347 | FpySequencer ::FpySequencer(const char* const compName) | |
| 19 | : FpySequencerComponentBase(compName), | ||
| 20 |
1/1✓ Branch 4 taken 347 times.
|
347 | m_sequenceBuffer(), |
| 21 | 347 | m_allocatorId(0), | |
| 22 |
1/1✓ Branch 4 taken 347 times.
|
347 | m_sequenceFilePath("<invalid_seq>"), |
| 23 |
1/1✓ Branch 5 taken 347 times.
|
347 | m_sequenceObj(), |
| 24 |
1/1✓ Branch 5 taken 347 times.
|
347 | m_computedCRC(), |
| 25 | 347 | m_totalExpectedArgSize(0), | |
| 26 |
1/1✓ Branch 5 taken 347 times.
|
347 | m_sequenceBlockState(), |
| 27 | 347 | m_savedOpCode(0), | |
| 28 | 347 | m_savedCmdSeq(0), | |
| 29 |
1/1✓ Branch 4 taken 347 times.
|
347 | m_sequenceArgs(0, 0), |
| 30 |
1/1✓ Branch 5 taken 347 times.
|
347 | m_goalState(), |
| 31 | 347 | m_sequencesStarted(0), | |
| 32 | 347 | m_statementsDispatched(0), | |
| 33 | 347 | m_checkTimersQueued(false), | |
| 34 | 347 | m_tlmWriteQueued(false), | |
| 35 |
1/1✓ Branch 7 taken 347 times.
|
347 | m_runtime(), |
| 36 | 347 | m_breakpoint(), | |
| 37 | 347 | m_debug(), | |
| 38 |
1/1✓ Branch 7 taken 347 times.
|
347 | m_tlm(), |
| 39 |
2/2✓ Branch 4 taken 83280 times.
✓ Branch 5 taken 347 times.
|
83627 | m_sandboxDir(), |
| 40 |
1/1✓ Branch 11 taken 347 times.
|
1041 | m_sandboxConfigured(false) {} |
| 41 | |||
| 42 | 694 | FpySequencer ::~FpySequencer() {} | |
| 43 | |||
| 44 | 4 | void FpySequencer::configureSandbox(const char* directory) { | |
| 45 | 4 | FW_ASSERT(directory != nullptr); | |
| 46 | const Os::FilePathUtils::Status status = | ||
| 47 | 4 | Os::FilePathUtils::resolveDirectoryFromCwd(directory, this->m_sandboxDir, sizeof(this->m_sandboxDir)); | |
| 48 | 4 | FW_ASSERT(status == Os::FilePathUtils::VALID, static_cast<FwAssertArgType>(status)); | |
| 49 | 4 | this->m_sandboxConfigured = true; | |
| 50 | 4 | } | |
| 51 | |||
| 52 | 81 | bool FpySequencer::checkSandbox(const Fw::StringBase& fileName) { | |
| 53 |
3/4✗ Branch 3 not taken.
✓ Branch 4 taken 81 times.
✓ Branch 5 taken 76 times.
✓ Branch 6 taken 5 times.
|
81 | if (!this->m_sandboxConfigured) { |
| 54 | 76 | return true; | |
| 55 | } | ||
| 56 | 5 | char resolved[Os::FilePathUtils::MAX_PATH_LENGTH]; | |
| 57 | const bool contained = | ||
| 58 |
2/2✓ Branch 11 taken 5 times.
✓ Branch 14 taken 5 times.
|
5 | (Os::FilePathUtils::resolveFromCwd(fileName.toChar(), resolved, sizeof(resolved)) == |
| 59 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
10 | Os::FilePathUtils::VALID) && |
| 60 |
3/3✓ Branch 3 taken 5 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 3 times.
|
5 | (Os::FilePathUtils::checkContainment(resolved, this->m_sandboxDir) == Os::FilePathUtils::VALID); |
| 61 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
|
5 | if (!contained) { |
| 62 |
2/2✓ Branch 8 taken 3 times.
✓ Branch 12 taken 3 times.
|
3 | this->log_WARNING_HI_FileOutsideSandbox(fileName, Fw::LogStringArg(this->m_sandboxDir)); |
| 63 | } | ||
| 64 | 5 | return contained; | |
| 65 | } | ||
| 66 | |||
| 67 | //! Handler for command RUN | ||
| 68 | //! | ||
| 69 | //! Loads, validates and runs a sequence | ||
| 70 | 47 | void FpySequencer::RUN_cmdHandler(FwOpcodeType opCode, //!< The opcode | |
| 71 | U32 cmdSeq, //!< The command sequence number | ||
| 72 | const Fw::CmdStringArg& fileName, //!< The name of the sequence file | ||
| 73 | const BlockState& block //!< Return command status when complete or not | ||
| 74 | ) { | ||
| 75 | // Empty args and delegate to RUN_ARGS handler | ||
| 76 |
2/2✓ Branch 8 taken 47 times.
✓ Branch 12 taken 47 times.
|
47 | this->RUN_ARGS_cmdHandler(opCode, cmdSeq, fileName, block, Svc::SeqArgs{0, 0}); |
| 77 | 47 | } | |
| 78 | |||
| 79 | 50 | void FpySequencer ::RUN_ARGS_cmdHandler(FwOpcodeType opCode, //!< The opcode | |
| 80 | U32 cmdSeq, //!< The command sequence number | ||
| 81 | const Fw::CmdStringArg& fileName, //!< The name of the sequence file | ||
| 82 | const Svc::BlockState& block, //!< Return command status when complete or not | ||
| 83 | const Svc::SeqArgs& args //!< Arguments to pass to the sequencer | ||
| 84 | ) { | ||
| 85 | // can only run a seq while in idle | ||
| 86 |
3/3✓ Branch 3 taken 50 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 49 times.
|
50 | if (sequencer_getState() != State::IDLE) { |
| 87 |
2/2✓ Branch 7 taken 1 times.
✓ Branch 14 taken 1 times.
|
1 | this->log_WARNING_HI_InvalidCommand(static_cast<I32>(sequencer_getState())); |
| 88 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
| 89 | 1 | return; | |
| 90 | } | ||
| 91 | |||
| 92 |
2/2✓ Branch 4 taken 48 times.
✓ Branch 5 taken 1 times.
|
49 | if (block == BlockState::BLOCK) { |
| 93 | // save the opCode and cmdSeq so we can respond later | ||
| 94 | 48 | this->m_savedOpCode = opCode; | |
| 95 | 48 | this->m_savedCmdSeq = cmdSeq; | |
| 96 | } | ||
| 97 | |||
| 98 | // Store args for pushArgsToStack action | ||
| 99 |
2/2✓ Branch 13 taken 49 times.
✓ Branch 17 taken 49 times.
|
49 | this->sequencer_sendSignal_cmd_RUN(FpySequencer_SequenceExecutionArgs(fileName, block, args)); |
| 100 | |||
| 101 | // only respond if the user doesn't want us to block further execution | ||
| 102 |
2/2✓ Branch 4 taken 1 times.
✓ Branch 5 taken 48 times.
|
49 | if (block == BlockState::NO_BLOCK) { |
| 103 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | //! Handler for command VALIDATE | ||
| 108 | //! | ||
| 109 | //! Loads and validates a sequence | ||
| 110 | 10 | void FpySequencer::VALIDATE_cmdHandler(FwOpcodeType opCode, //!< The opcode | |
| 111 | U32 cmdSeq, //!< The command sequence number | ||
| 112 | const Fw::CmdStringArg& fileName //!< The name of the sequence file | ||
| 113 | ) { | ||
| 114 |
2/2✓ Branch 8 taken 10 times.
✓ Branch 12 taken 10 times.
|
10 | this->VALIDATE_ARGS_cmdHandler(opCode, cmdSeq, fileName, Svc::SeqArgs{0, 0}); |
| 115 | 10 | } | |
| 116 | |||
| 117 | //! Handler implementation for command VALIDATE_ARGS | ||
| 118 | //! | ||
| 119 | //! Loads and validates a sequence with arguments | ||
| 120 | 18 | void FpySequencer ::VALIDATE_ARGS_cmdHandler(FwOpcodeType opCode, | |
| 121 | U32 cmdSeq, | ||
| 122 | const Fw::CmdStringArg& fileName, | ||
| 123 | const Svc::SeqArgs& buffer) { | ||
| 124 | // can only validate a seq while in idle | ||
| 125 |
3/3✓ Branch 3 taken 18 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 17 times.
|
18 | if (sequencer_getState() != State::IDLE) { |
| 126 |
2/2✓ Branch 7 taken 1 times.
✓ Branch 14 taken 1 times.
|
1 | this->log_WARNING_HI_InvalidCommand(static_cast<I32>(sequencer_getState())); |
| 127 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
| 128 | 1 | return; | |
| 129 | } | ||
| 130 | |||
| 131 | // validate always blocks until finished, so save opcode/cmdseq | ||
| 132 | // so we can respond once done | ||
| 133 | 17 | this->m_savedOpCode = opCode; | |
| 134 | 17 | this->m_savedCmdSeq = cmdSeq; | |
| 135 | |||
| 136 | // VALIDATE_ARGS receives args via command interface | ||
| 137 | // Store args for pushArgsToStack action when RUN_VALIDATED is called | ||
| 138 |
2/2✓ Branch 9 taken 17 times.
✓ Branch 13 taken 17 times.
|
17 | this->sequencer_sendSignal_cmd_VALIDATE(FpySequencer_SequenceExecutionArgs(fileName, BlockState::BLOCK, buffer)); |
| 139 | } | ||
| 140 | |||
| 141 | 5 | void FpySequencer::RUN_VALIDATED_cmdHandler(FwOpcodeType opCode, //!< The opcode | |
| 142 | U32 cmdSeq, //!< The command sequence number | ||
| 143 | const BlockState& block //!< Return command status when complete or not | ||
| 144 | ) { | ||
| 145 | // can only RUN_VALIDATED if we have validated and are awaiting this exact cmd | ||
| 146 |
3/3✓ Branch 3 taken 5 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 4 times.
|
5 | if (sequencer_getState() != State::AWAITING_CMD_RUN_VALIDATED) { |
| 147 |
2/2✓ Branch 7 taken 1 times.
✓ Branch 14 taken 1 times.
|
1 | this->log_WARNING_HI_InvalidCommand(static_cast<I32>(sequencer_getState())); |
| 148 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
| 149 | 1 | return; | |
| 150 | } | ||
| 151 | |||
| 152 |
2/2✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
|
4 | if (block == BlockState::BLOCK) { |
| 153 | // save the opCode and cmdSeq so we can respond later | ||
| 154 | 2 | this->m_savedOpCode = opCode; | |
| 155 | 2 | this->m_savedCmdSeq = cmdSeq; | |
| 156 | } | ||
| 157 | |||
| 158 |
1/1✓ Branch 5 taken 4 times.
|
8 | this->sequencer_sendSignal_cmd_RUN_VALIDATED( |
| 159 |
1/1✓ Branch 12 taken 4 times.
|
8 | FpySequencer_SequenceExecutionArgs(this->m_sequenceFilePath, block, this->m_sequenceArgs)); |
| 160 | |||
| 161 | // only respond if the user doesn't want us to block further execution | ||
| 162 |
2/2✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
|
4 | if (block == BlockState::NO_BLOCK) { |
| 163 |
2/2✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
|
2 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | //! Handler for command CANCEL | ||
| 168 | //! | ||
| 169 | //! Cancels a running or validated sequence | ||
| 170 | 5 | void FpySequencer::CANCEL_cmdHandler(FwOpcodeType opCode, //!< The opcode | |
| 171 | U32 cmdSeq //!< The command sequence number | ||
| 172 | ) { | ||
| 173 | // only state you can't cancel in is IDLE | ||
| 174 |
3/3✓ Branch 3 taken 5 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 4 times.
|
5 | if (sequencer_getState() == State::IDLE) { |
| 175 |
2/2✓ Branch 7 taken 1 times.
✓ Branch 14 taken 1 times.
|
1 | this->log_WARNING_HI_InvalidCommand(static_cast<I32>(sequencer_getState())); |
| 176 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
| 177 | 1 | return; | |
| 178 | } | ||
| 179 | |||
| 180 | 4 | this->sequencer_sendSignal_cmd_CANCEL(); | |
| 181 | |||
| 182 | // cancel returns immediately and always succeeds | ||
| 183 |
2/2✓ Branch 6 taken 4 times.
✓ Branch 9 taken 4 times.
|
4 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 184 | } | ||
| 185 | |||
| 186 | //! Handler for command SET_BREAKPOINT | ||
| 187 | //! | ||
| 188 | //! Sets the breakpoint which will pause the execution of the sequencer when | ||
| 189 | //! reached, until unpaused by the CONTINUE command. Will pause just before | ||
| 190 | //! dispatching the specified statement. This command is valid in all states. Breakpoint | ||
| 191 | //! settings are cleared after a sequence ends execution. | ||
| 192 | 1 | void FpySequencer::SET_BREAKPOINT_cmdHandler(FwOpcodeType opCode, //!< The opcode | |
| 193 | U32 cmdSeq, //!< The command sequence number | ||
| 194 | U32 stmtIdx, //!< The statement index to pause execution before. | ||
| 195 | bool breakOnce //!< Whether or not to break only once at this breakpoint | ||
| 196 | ) { | ||
| 197 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
|
1 | this->sequencer_sendSignal_cmd_SET_BREAKPOINT(FpySequencer_BreakpointArgs(true, breakOnce, stmtIdx)); |
| 198 | |||
| 199 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 200 | 1 | } | |
| 201 | |||
| 202 | //! Handler for command BREAK | ||
| 203 | //! | ||
| 204 | //! Pauses the execution of the sequencer, just before it is about to dispatch the next statement, | ||
| 205 | //! until unpaused by the CONTINUE command, or stepped by the STEP command. This command is only valid | ||
| 206 | //! in substates of the RUNNING state that are not RUNNING.PAUSED. | ||
| 207 | 3 | void FpySequencer::BREAK_cmdHandler(FwOpcodeType opCode, //!< The opcode | |
| 208 | U32 cmdSeq //!< The command sequence number | ||
| 209 | ) { | ||
| 210 |
14/24✓ Branch 6 taken 3 times.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 1 times.
✓ Branch 14 taken 2 times.
✓ Branch 20 taken 1 times.
✓ Branch 21 taken 1 times.
✓ Branch 22 taken 2 times.
✓ Branch 23 taken 1 times.
✓ Branch 26 taken 2 times.
✓ Branch 27 taken 1 times.
✓ Branch 29 taken 3 times.
✗ Branch 30 not taken.
✓ Branch 33 taken 3 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 2 times.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
|
3 | if (!this->isRunningState(this->sequencer_getState()) || this->sequencer_getState() == State::RUNNING_PAUSED) { |
| 211 | // can only break while running, and not paused | ||
| 212 |
2/2✓ Branch 7 taken 2 times.
✓ Branch 14 taken 2 times.
|
2 | this->log_WARNING_HI_InvalidCommand(static_cast<I32>(sequencer_getState())); |
| 213 |
2/2✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
|
2 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
| 214 | 2 | return; | |
| 215 | } | ||
| 216 | 1 | this->sequencer_sendSignal_cmd_BREAK(); | |
| 217 | |||
| 218 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 219 | } | ||
| 220 | |||
| 221 | //! Handler for command CONTINUE | ||
| 222 | //! | ||
| 223 | //! Continues the automatic execution of the sequence after it has been paused. If a breakpoint is still | ||
| 224 | //! set, it may pause again on that breakpoint. This command is only valid in the RUNNING.PAUSED state. | ||
| 225 | 2 | void FpySequencer::CONTINUE_cmdHandler(FwOpcodeType opCode, //!< The opcode | |
| 226 | U32 cmdSeq //!< The command sequence number | ||
| 227 | ) { | ||
| 228 |
3/3✓ Branch 3 taken 2 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 1 times.
|
2 | if (this->sequencer_getState() != State::RUNNING_PAUSED) { |
| 229 |
2/2✓ Branch 7 taken 1 times.
✓ Branch 14 taken 1 times.
|
1 | this->log_WARNING_HI_InvalidCommand(static_cast<I32>(sequencer_getState())); |
| 230 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
| 231 | 1 | return; | |
| 232 | } | ||
| 233 | |||
| 234 | 1 | this->sequencer_sendSignal_cmd_CONTINUE(); | |
| 235 | |||
| 236 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 237 | } | ||
| 238 | |||
| 239 | //! Handler for command CLEAR_BREAKPOINT | ||
| 240 | //! | ||
| 241 | //! Clears the breakpoint, but does not continue executing the sequence. This command | ||
| 242 | //! is valid in all states. This happens automatically when a sequence ends execution. | ||
| 243 | 1 | void FpySequencer::CLEAR_BREAKPOINT_cmdHandler(FwOpcodeType opCode, //!< The opcode | |
| 244 | U32 cmdSeq //!< The command sequence number | ||
| 245 | ) { | ||
| 246 | 1 | this->sequencer_sendSignal_cmd_CLEAR_BREAKPOINT(); | |
| 247 | 1 | this->log_ACTIVITY_HI_BreakpointCleared(); | |
| 248 | |||
| 249 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 250 | 1 | } | |
| 251 | |||
| 252 | //! Handler for command STEP | ||
| 253 | //! | ||
| 254 | //! Dispatches and awaits the result of the next directive, or ends the sequence if no more directives remain. | ||
| 255 | //! Returns to the RUNNING.PAUSED state if the directive executes successfully. This command is only valid in the | ||
| 256 | //! RUNNING.PAUSED state. | ||
| 257 | 4 | void FpySequencer::STEP_cmdHandler(FwOpcodeType opCode, //!< The opcode | |
| 258 | U32 cmdSeq //!< The command sequence number | ||
| 259 | ) { | ||
| 260 |
3/3✓ Branch 3 taken 4 times.
✓ Branch 12 taken 2 times.
✓ Branch 13 taken 2 times.
|
4 | if (this->sequencer_getState() != State::RUNNING_PAUSED) { |
| 261 |
2/2✓ Branch 7 taken 2 times.
✓ Branch 14 taken 2 times.
|
2 | this->log_WARNING_HI_InvalidCommand(static_cast<I32>(sequencer_getState())); |
| 262 |
2/2✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
|
2 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
| 263 | 2 | return; | |
| 264 | } | ||
| 265 | |||
| 266 | 2 | this->sequencer_sendSignal_cmd_STEP(); | |
| 267 |
2/2✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
|
2 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 268 | } | ||
| 269 | |||
| 270 | //! Handler for command DUMP_STACK_TO_FILE | ||
| 271 | //! | ||
| 272 | //! Writes the contents of the stack to a file. This command is only valid in the RUNNING.PAUSED state. | ||
| 273 | 5 | void FpySequencer::DUMP_STACK_TO_FILE_cmdHandler(FwOpcodeType opCode, //!< The opcode | |
| 274 | U32 cmdSeq, //!< The command sequence number | ||
| 275 | const Fw::CmdStringArg& fileName //!< The name of the output file | ||
| 276 | ) { | ||
| 277 |
3/3✓ Branch 3 taken 5 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 4 times.
|
5 | if (this->sequencer_getState() != State::RUNNING_PAUSED) { |
| 278 |
2/2✓ Branch 7 taken 1 times.
✓ Branch 14 taken 1 times.
|
1 | this->log_WARNING_HI_InvalidCommand(static_cast<I32>(sequencer_getState())); |
| 279 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
| 280 | 1 | return; | |
| 281 | } | ||
| 282 |
3/3✓ Branch 7 taken 4 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 3 times.
|
4 | if (!this->checkSandbox(fileName)) { |
| 283 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
| 284 | 1 | return; | |
| 285 | } | ||
| 286 |
1/1✓ Branch 2 taken 3 times.
|
3 | Os::File sequenceFile; |
| 287 |
1/1✓ Branch 6 taken 3 times.
|
3 | Os::File::Status status = sequenceFile.open(fileName.toChar(), Os::File::OPEN_WRITE); |
| 288 | |||
| 289 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if (status != Os::File::Status::OP_OK) { |
| 290 |
1/1✓ Branch 8 taken 1 times.
|
1 | this->log_WARNING_HI_FileOpenError(fileName, static_cast<I32>(status)); |
| 291 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
| 292 | 1 | return; | |
| 293 | } | ||
| 294 | |||
| 295 | 2 | FwSizeType writeSize = static_cast<FwSizeType>(this->m_runtime.stack.size); | |
| 296 |
1/1✓ Branch 4 taken 2 times.
|
2 | status = sequenceFile.write(this->m_runtime.stack.bytes, writeSize); |
| 297 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
|
2 | if (status != Os::File::Status::OP_OK || writeSize != this->m_runtime.stack.size) { |
| 298 | ✗ | this->log_WARNING_HI_FileWriteError(writeSize, fileName, static_cast<I32>(status)); | |
| 299 | ✗ | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); | |
| 300 | ✗ | return; | |
| 301 | } | ||
| 302 |
2/2✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
|
2 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 303 | 2 | return; | |
| 304 | 3 | } | |
| 305 | //! Handler for input port checkTimers | ||
| 306 | 9 | void FpySequencer::checkTimers_handler(FwIndexType portNum, //!< The port number | |
| 307 | U32 context //!< The call order | ||
| 308 | ) { | ||
| 309 | // only enqueue if a checkTimersInternal message is not already on the queue | ||
| 310 | 9 | bool expected = false; | |
| 311 |
2/2✓ Branch 4 taken 6 times.
✓ Branch 5 taken 3 times.
|
9 | if (this->m_checkTimersQueued.compare_exchange_strong(expected, true)) { |
| 312 |
1/1✓ Branch 5 taken 6 times.
|
6 | this->checkTimersInternal_internalInterfaceInvoke(); |
| 313 | } | ||
| 314 | 9 | } | |
| 315 | |||
| 316 | //! Internal interface handler for checkTimersInternal | ||
| 317 | 5 | void FpySequencer::checkTimersInternal_internalInterfaceHandler() { | |
| 318 | 5 | FW_ASSERT(this->m_checkTimersQueued); | |
| 319 | 5 | this->m_checkTimersQueued = false; | |
| 320 | 5 | this->sequencer_sendSignal_checkTimersIn(); | |
| 321 | 5 | } | |
| 322 | |||
| 323 | 1 | void FpySequencer::pingIn_handler(FwIndexType portNum, /*!< The port number*/ | |
| 324 | U32 key /*!< Value to return to pinger*/ | ||
| 325 | ) { | ||
| 326 | // send ping response | ||
| 327 | 1 | this->pingOut_out(0, key); | |
| 328 | 1 | } | |
| 329 | |||
| 330 | //! Handler for input port cmdResponseIn | ||
| 331 | 8 | void FpySequencer::cmdResponseIn_handler(FwIndexType portNum, //!< The port number | |
| 332 | FwOpcodeType opCode, //!< Command Op Code | ||
| 333 | U32 cmdSeq, //!< Command Sequence | ||
| 334 | const Fw::CmdResponse& response //!< The command response argument | ||
| 335 | ) { | ||
| 336 | // if we aren't in the RUNNING state: | ||
| 337 |
3/3✓ Branch 6 taken 8 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 7 times.
|
8 | if (!this->isRunningState(sequencer_getState())) { |
| 338 | // must be a coding error from an outside component (off nom), or due to CANCEL while running a command (nom). | ||
| 339 | // because we can't be sure that it wasn't a nominal sequence of events leading to this, don't fail the | ||
| 340 | // sequence, just report it | ||
| 341 |
2/2✓ Branch 8 taken 1 times.
✓ Branch 15 taken 1 times.
|
1 | this->log_WARNING_LO_CmdResponseWhileNotRunningSequence(static_cast<I32>(this->sequencer_getState()), |
| 342 | CmdDispatcherCfg::getEventOpcode(opCode), response); | ||
| 343 | 1 | return; | |
| 344 | } | ||
| 345 | |||
| 346 | // okay, we're running a sequence. now let's use the cmdUid to check if the response was for a cmd | ||
| 347 | // from this sequence | ||
| 348 | |||
| 349 | // the cmdSeq arg is confusingly not the cmdSeq in this case, according to the current implementation | ||
| 350 | // of the CmdDisp. instead, it is the context that we passed in when we originally sent the cmd out. | ||
| 351 | // this context is in turn the cmdUid that we calculated just before sending it. rename the variable for | ||
| 352 | // clarity's sake | ||
| 353 | 7 | U32 cmdUid = cmdSeq; | |
| 354 | |||
| 355 | // pull the sequence index (modulo 2^16) out of the cmdUid. see the comment in FpySequencer::dispatchCommand | ||
| 356 | // for info on the binary format of this cmdUid. as a reminder, this should be equal to the first 16 bits of | ||
| 357 | // the m_sequencesStarted variable | ||
| 358 | 7 | U16 sequenceIndex = static_cast<U16>((cmdUid & 0xFFFF0000) >> 16); | |
| 359 | 7 | U16 currentSequenceIndex = static_cast<U16>(this->m_sequencesStarted & 0xFFFF); | |
| 360 | |||
| 361 | // if it was from a different sequence: | ||
| 362 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
|
7 | if (sequenceIndex != currentSequenceIndex) { |
| 363 | 1 | this->log_WARNING_LO_CmdResponseFromOldSequence(CmdDispatcherCfg::getEventOpcode(opCode), response, | |
| 364 | sequenceIndex, currentSequenceIndex); | ||
| 365 | 1 | return; | |
| 366 | } | ||
| 367 | |||
| 368 | // okay, it was from this sequence. now if anything's wrong from this point on we should fail the sequence | ||
| 369 | |||
| 370 | // first, make sure we're actually awaiting a statement response | ||
| 371 |
3/3✓ Branch 3 taken 6 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 5 times.
|
6 | if (this->sequencer_getState() != State::RUNNING_AWAITING_STATEMENT_RESPONSE) { |
| 372 | // okay, crap. something from this sequence responded, and we weren't awaiting anything. end it all | ||
| 373 | 1 | this->log_WARNING_HI_CmdResponseWhileNotAwaiting(CmdDispatcherCfg::getEventOpcode(opCode), response); | |
| 374 | 1 | this->sequencer_sendSignal_stmtResponse_unexpected(); | |
| 375 | 1 | return; | |
| 376 | } | ||
| 377 | |||
| 378 |
2/2✓ Branch 4 taken 1 times.
✓ Branch 5 taken 4 times.
|
5 | if (this->m_runtime.currentStatementOpcode != Fpy::DirectiveId::CONST_CMD && |
| 379 |
1/2✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
1 | this->m_runtime.currentStatementOpcode != Fpy::DirectiveId::STACK_CMD) { |
| 380 | // we were not awaiting a cmd response, we were waiting for a directive | ||
| 381 | ✗ | this->log_WARNING_HI_CmdResponseWhileAwaitingDirective(CmdDispatcherCfg::getEventOpcode(opCode), response, | |
| 382 | ✗ | this->m_runtime.currentStatementOpcode); | |
| 383 | ✗ | this->sequencer_sendSignal_stmtResponse_unexpected(); | |
| 384 | ✗ | return; | |
| 385 | } | ||
| 386 | |||
| 387 | // okay, we were awaiting a cmd response. were we awaiting this opcode? | ||
| 388 |
2/2✓ Branch 4 taken 1 times.
✓ Branch 5 taken 4 times.
|
5 | if (opCode != this->m_runtime.currentCmdOpcode) { |
| 389 | // we were not awaiting this opcode. coding error, likely on the part of the responding component or cmd | ||
| 390 | // dispatcher | ||
| 391 | 2 | this->log_WARNING_HI_WrongCmdResponseOpcode(CmdDispatcherCfg::getEventOpcode(opCode), response, | |
| 392 | 1 | CmdDispatcherCfg::getEventOpcode(this->m_runtime.currentCmdOpcode)); | |
| 393 | 1 | this->sequencer_sendSignal_stmtResponse_unexpected(); | |
| 394 | 1 | return; | |
| 395 | } | ||
| 396 | |||
| 397 | // okay, we were awaiting this opcode. but was it from this exact statement, or a different one with the same opcode | ||
| 398 | // in the same file? | ||
| 399 | |||
| 400 | // pull the cmd index (modulo 2^16) out of cmdUid. this should be equal to the first 16 bits of the | ||
| 401 | // m_statementsDispatched variable | ||
| 402 | 4 | U16 cmdIndex = static_cast<U16>(cmdUid & 0xFFFF); | |
| 403 | // check for coding errors. at this point in the function, we have definitely dispatched a stmt | ||
| 404 | 4 | FW_ASSERT(this->m_statementsDispatched > 0); | |
| 405 | 4 | U16 currentCmdIndex = static_cast<U16>((this->m_statementsDispatched) & 0xFFFF); | |
| 406 | |||
| 407 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (cmdIndex != currentCmdIndex) { |
| 408 | // we were not awaiting this exact statement, it was a different one with the same opcode. coding error | ||
| 409 | 2 | this->log_WARNING_HI_WrongCmdResponseIndex(CmdDispatcherCfg::getEventOpcode(opCode), response, cmdIndex, | |
| 410 | currentCmdIndex); | ||
| 411 | 2 | this->sequencer_sendSignal_stmtResponse_unexpected(); | |
| 412 | 2 | return; | |
| 413 | } | ||
| 414 | |||
| 415 | // okay, got the right cmd back. we have verified: | ||
| 416 | // 1) we are in the RUNNING state | ||
| 417 | // 2) the response is from this sequence | ||
| 418 | // 3) the response is from the correct opcode | ||
| 419 | // 4) the response is from the correct instance of that opcode in the sequence | ||
| 420 | |||
| 421 | // always succeed; the cmd response value is pushed to the stack so the sequence | ||
| 422 | // can branch on it if desired | ||
| 423 | 2 | this->sequencer_sendSignal_stmtResponse_success(); | |
| 424 | |||
| 425 | // push the cmd response to the stack so we can branch off of it | ||
| 426 | // the constCmd/stackCmd directive handlers guarantee there is room for this push | ||
| 427 |
1/2✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
|
2 | this->m_runtime.stack.push(static_cast<Fw::CmdResponse::SerialType>(response.e)); |
| 428 | } | ||
| 429 | |||
| 430 | 2 | void FpySequencer ::seqCancelIn_handler(FwIndexType portNum) { | |
| 431 | // only state you can't cancel in is IDLE | ||
| 432 |
3/3✓ Branch 3 taken 2 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 1 times.
|
2 | if (sequencer_getState() == State::IDLE) { |
| 433 |
2/2✓ Branch 7 taken 1 times.
✓ Branch 14 taken 1 times.
|
1 | this->log_WARNING_HI_InvalidSeqCancelCall(static_cast<I32>(sequencer_getState())); |
| 434 | 1 | return; | |
| 435 | } | ||
| 436 | 1 | this->sequencer_sendSignal_cmd_CANCEL(); | |
| 437 | } | ||
| 438 | |||
| 439 | //! Handler for input port seqRunIn | ||
| 440 | 3 | void FpySequencer::seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename, const Svc::SeqArgs& args) { | |
| 441 | // can only run a seq while in idle | ||
| 442 |
3/3✓ Branch 3 taken 3 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 2 times.
|
3 | if (sequencer_getState() != State::IDLE) { |
| 443 |
2/2✓ Branch 7 taken 1 times.
✓ Branch 14 taken 1 times.
|
1 | this->log_WARNING_HI_InvalidSeqRunCall(static_cast<I32>(sequencer_getState())); |
| 444 | 1 | return; | |
| 445 | } | ||
| 446 | |||
| 447 | // seqRunIn is never blocking - store args for pushArgsToStack action | ||
| 448 | // Args must be serialized in F' big-endian format by the caller before being sent | ||
| 449 |
2/2✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
|
2 | this->sequencer_sendSignal_cmd_RUN(FpySequencer_SequenceExecutionArgs(filename, BlockState::NO_BLOCK, args)); |
| 450 | } | ||
| 451 | |||
| 452 | //! Handler for input port tlmWrite | ||
| 453 | 5 | void FpySequencer::tlmWrite_handler(FwIndexType portNum, //!< The port number | |
| 454 | U32 context //!< The call order | ||
| 455 | ) { | ||
| 456 | // only enqueue if a tlmWriteInternal message is not already on the queue | ||
| 457 | 5 | bool expected = false; | |
| 458 |
2/2✓ Branch 4 taken 3 times.
✓ Branch 5 taken 2 times.
|
5 | if (this->m_tlmWriteQueued.compare_exchange_strong(expected, true)) { |
| 459 |
1/1✓ Branch 5 taken 3 times.
|
3 | this->tlmWriteInternal_internalInterfaceInvoke(); |
| 460 | } | ||
| 461 | 5 | } | |
| 462 | |||
| 463 | //! Overflow hook for tlmWriteInternal | ||
| 464 | ✗ | void FpySequencer::tlmWriteInternal_overflowHook() { | |
| 465 | ✗ | this->m_tlmWriteQueued = false; | |
| 466 | ✗ | } | |
| 467 | |||
| 468 | //! Internal interface handler for tlmWriteInternal | ||
| 469 | 3 | void FpySequencer::tlmWriteInternal_internalInterfaceHandler() { | |
| 470 | 3 | FW_ASSERT(this->m_tlmWriteQueued); | |
| 471 | 3 | this->m_tlmWriteQueued = false; | |
| 472 |
3/3✓ Branch 6 taken 3 times.
✓ Branch 11 taken 3 times.
✓ Branch 18 taken 3 times.
|
3 | this->tlmWrite_State(static_cast<FwEnumStoreType>(this->sequencer_getState())); |
| 473 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->tlmWrite_StatementsDispatched(this->m_statementsDispatched); |
| 474 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->tlmWrite_StatementsFailed(this->m_tlm.statementsFailed); |
| 475 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->tlmWrite_SequencesCancelled(this->m_tlm.sequencesCancelled); |
| 476 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->tlmWrite_SequencesSucceeded(this->m_tlm.sequencesSucceeded); |
| 477 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->tlmWrite_SequencesFailed(this->m_tlm.sequencesFailed); |
| 478 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 12 taken 3 times.
|
3 | this->tlmWrite_LastDirectiveError(this->m_tlm.lastDirectiveError); |
| 479 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->tlmWrite_DirectiveErrorIndex(this->m_tlm.directiveErrorIndex); |
| 480 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 12 taken 3 times.
|
3 | this->tlmWrite_DirectiveErrorId(this->m_tlm.directiveErrorId); |
| 481 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 12 taken 3 times.
|
3 | this->tlmWrite_SeqPath(this->m_sequenceFilePath); |
| 482 | |||
| 483 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->tlmWrite_BreakpointIndex(this->m_breakpoint.breakpointIndex); |
| 484 |
3/4✓ Branch 6 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✓ Branch 14 taken 3 times.
|
3 | this->tlmWrite_BreakOnlyOnceOnBreakpoint(this->m_breakpoint.breakOnlyOnceOnBreakpoint); |
| 485 |
3/4✓ Branch 6 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✓ Branch 14 taken 3 times.
|
3 | this->tlmWrite_BreakBeforeNextLine(this->m_breakpoint.breakBeforeNextLine); |
| 486 |
3/4✓ Branch 6 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✓ Branch 14 taken 3 times.
|
3 | this->tlmWrite_BreakpointInUse(this->m_breakpoint.breakpointInUse); |
| 487 | |||
| 488 | 3 | this->updateDebugTelemetryStruct(); | |
| 489 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->tlmWrite_Debug_NextCmdOpcode(this->m_debug.nextCmdOpcode); |
| 490 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->tlmWrite_Debug_NextStatementOpcode(this->m_debug.nextStatementOpcode); |
| 491 |
3/4✓ Branch 6 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✓ Branch 14 taken 3 times.
|
3 | this->tlmWrite_Debug_NextStatementReadSuccess(this->m_debug.nextStatementReadSuccess); |
| 492 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->tlmWrite_Debug_NextStatementIndex(this->m_debug.nextStatementIndex); |
| 493 |
3/4✓ Branch 6 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✓ Branch 14 taken 3 times.
|
3 | this->tlmWrite_Debug_ReachedEndOfFile(this->m_debug.reachedEndOfFile); |
| 494 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->tlmWrite_Debug_StackSize(this->m_debug.stackSize); |
| 495 | 3 | } | |
| 496 | |||
| 497 | 3 | void FpySequencer::updateDebugTelemetryStruct() { | |
| 498 | // only send debug tlm when we are paused | ||
| 499 |
2/3✓ Branch 3 taken 3 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 3 times.
|
3 | if (this->sequencer_getState() == State::RUNNING_PAUSED) { |
| 500 | ✗ | if (this->m_runtime.nextStatementIndex >= this->m_sequenceObj.get_header().get_statementCount()) { | |
| 501 | // reached end of file, turn on EOF flag and otherwise send some default tlm | ||
| 502 | ✗ | this->m_debug.reachedEndOfFile = true; | |
| 503 | ✗ | this->m_debug.nextStatementReadSuccess = false; | |
| 504 | ✗ | this->m_debug.nextStatementOpcode = 0; | |
| 505 | ✗ | this->m_debug.nextCmdOpcode = 0; | |
| 506 | ✗ | this->m_debug.nextStatementIndex = this->m_runtime.nextStatementIndex; | |
| 507 | ✗ | this->m_debug.stackSize = this->m_runtime.stack.size; | |
| 508 | ✗ | return; | |
| 509 | } | ||
| 510 | |||
| 511 | ✗ | FW_ASSERT(this->m_runtime.nextStatementIndex < Fpy::MAX_SEQUENCE_STATEMENT_COUNT, | |
| 512 | static_cast<FwAssertArgType>(this->m_runtime.nextStatementIndex)); | ||
| 513 | ✗ | const Fpy::Statement& nextStmt = this->m_sequenceObj.get_statements()[this->m_runtime.nextStatementIndex]; | |
| 514 | ✗ | DirectiveUnion directiveUnion; | |
| 515 | ✗ | Fw::Success status = this->deserializeDirective(nextStmt, directiveUnion); | |
| 516 | |||
| 517 | ✗ | if (status != Fw::Success::SUCCESS) { | |
| 518 | ✗ | this->m_debug.reachedEndOfFile = false; | |
| 519 | ✗ | this->m_debug.nextStatementReadSuccess = false; | |
| 520 | ✗ | this->m_debug.nextStatementOpcode = nextStmt.get_opCode(); | |
| 521 | ✗ | this->m_debug.nextCmdOpcode = 0; | |
| 522 | ✗ | this->m_debug.nextStatementIndex = this->m_runtime.nextStatementIndex; | |
| 523 | ✗ | this->m_debug.stackSize = this->m_runtime.stack.size; | |
| 524 | ✗ | return; | |
| 525 | } | ||
| 526 | |||
| 527 | ✗ | if (nextStmt.get_opCode() == Fpy::DirectiveId::CONST_CMD) { | |
| 528 | // send opcode of the cmd to the ground | ||
| 529 | ✗ | this->m_debug.reachedEndOfFile = false; | |
| 530 | ✗ | this->m_debug.nextStatementReadSuccess = true; | |
| 531 | ✗ | this->m_debug.nextStatementOpcode = nextStmt.get_opCode(); | |
| 532 | ✗ | this->m_debug.nextCmdOpcode = directiveUnion.constCmd.get_opCode(); | |
| 533 | ✗ | this->m_debug.nextStatementIndex = this->m_runtime.nextStatementIndex; | |
| 534 | ✗ | this->m_debug.stackSize = this->m_runtime.stack.size; | |
| 535 | ✗ | return; | |
| 536 | } | ||
| 537 | |||
| 538 | ✗ | this->m_debug.reachedEndOfFile = false; | |
| 539 | ✗ | this->m_debug.nextStatementReadSuccess = true; | |
| 540 | ✗ | this->m_debug.nextStatementOpcode = nextStmt.get_opCode(); | |
| 541 | ✗ | this->m_debug.nextCmdOpcode = 0; | |
| 542 | ✗ | this->m_debug.nextStatementIndex = this->m_runtime.nextStatementIndex; | |
| 543 | ✗ | this->m_debug.stackSize = this->m_runtime.stack.size; | |
| 544 | ✗ | return; | |
| 545 | ✗ | } | |
| 546 | // send some default tlm when we aren't in debug break | ||
| 547 | 3 | this->m_debug.reachedEndOfFile = false; | |
| 548 | 3 | this->m_debug.nextStatementReadSuccess = false; | |
| 549 | 3 | this->m_debug.nextStatementOpcode = 0; | |
| 550 | 3 | this->m_debug.nextCmdOpcode = 0; | |
| 551 | 3 | this->m_debug.nextStatementIndex = 0; | |
| 552 | 3 | this->m_debug.stackSize = 0; | |
| 553 | } | ||
| 554 | |||
| 555 | ✗ | void FpySequencer::parametersLoaded() { | |
| 556 | ✗ | parameterUpdated(PARAMID_STATEMENT_TIMEOUT_SECS); | |
| 557 | ✗ | parameterUpdated(PARAMID_SEQ_BASE_DIR); | |
| 558 | ✗ | } | |
| 559 | |||
| 560 | 14 | void FpySequencer::parameterUpdated(FwPrmIdType id) { | |
| 561 |
1/1✓ Branch 2 taken 14 times.
|
14 | Fw::ParamValid valid; |
| 562 |
2/3✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
14 | switch (id) { |
| 563 | 7 | case PARAMID_STATEMENT_TIMEOUT_SECS: { | |
| 564 |
3/3✓ Branch 6 taken 7 times.
✓ Branch 13 taken 7 times.
✓ Branch 16 taken 7 times.
|
7 | this->tlmWrite_PRM_STATEMENT_TIMEOUT_SECS(this->paramGet_STATEMENT_TIMEOUT_SECS(valid)); |
| 565 | 7 | break; | |
| 566 | } | ||
| 567 | 7 | case PARAMID_SEQ_BASE_DIR: { | |
| 568 |
3/3✓ Branch 6 taken 7 times.
✓ Branch 11 taken 7 times.
✓ Branch 15 taken 7 times.
|
7 | this->tlmWrite_PRM_SEQ_BASE_DIR(this->paramGet_SEQ_BASE_DIR(valid)); |
| 569 | 7 | break; | |
| 570 | } | ||
| 571 | ✗ | default: { | |
| 572 | ✗ | FW_ASSERT(false, static_cast<FwAssertArgType>(id)); // coding error, forgot to include in switch statement | |
| 573 | } | ||
| 574 | } | ||
| 575 | |||
| 576 | 14 | FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e)); | |
| 577 | 28 | } | |
| 578 | |||
| 579 | 20 | bool FpySequencer::isRunningState(State state) { | |
| 580 | // TODO ask Rob if there's a better way to check if we're in a superstate. I don't want to have | ||
| 581 | // to update this every time I add a new substate to the RUNNING state. | ||
| 582 | |||
| 583 |
4/4✓ Branch 6 taken 11 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 9 times.
✓ Branch 9 taken 2 times.
|
43 | return state == State::RUNNING_AWAITING_STATEMENT_RESPONSE || state == State::RUNNING_DISPATCH_STATEMENT || |
| 584 |
4/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 6 times.
|
43 | state == State::RUNNING_PAUSED || state == State::RUNNING_SLEEPING; |
| 585 | } | ||
| 586 | |||
| 587 | } // namespace Svc | ||
| 588 |