| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // ====================================================================== | ||
| 2 | // \title FpySequencer.hpp | ||
| 3 | // \author zimri.leisher | ||
| 4 | // \brief hpp file for FpySequencer component implementation class | ||
| 5 | // ====================================================================== | ||
| 6 | |||
| 7 | #ifndef FpySequencer_HPP | ||
| 8 | #define FpySequencer_HPP | ||
| 9 | |||
| 10 | #include <random> | ||
| 11 | #include "Fw/Types/FileNameString.hpp" | ||
| 12 | #include "Fw/Types/MemAllocator.hpp" | ||
| 13 | #include "Fw/Types/StringBase.hpp" | ||
| 14 | #include "Fw/Types/SuccessEnumAc.hpp" | ||
| 15 | #include "Fw/Types/WaitEnumAc.hpp" | ||
| 16 | #include "Os/File.hpp" | ||
| 17 | #include "Svc/FpySequencer/DirectiveIdEnumAc.hpp" | ||
| 18 | #include "Svc/FpySequencer/FooterSerializableAc.hpp" | ||
| 19 | #include "Svc/FpySequencer/FppConstantsAc.hpp" | ||
| 20 | #include "Svc/FpySequencer/FpySequencerComponentAc.hpp" | ||
| 21 | #include "Svc/FpySequencer/FpySequencer_GoalStateEnumAc.hpp" | ||
| 22 | #include "Svc/FpySequencer/HeaderSerializableAc.hpp" | ||
| 23 | #include "Svc/FpySequencer/SequenceSerializableAc.hpp" | ||
| 24 | #include "Svc/FpySequencer/StatementSerializableAc.hpp" | ||
| 25 | #include "Svc/Seq/BlockStateEnumAc.hpp" | ||
| 26 | #include "Utils/Hash/Hash.hpp" | ||
| 27 | #include "config/FppConstantsAc.hpp" | ||
| 28 | |||
| 29 | static_assert(Svc::Fpy::MAX_SEQUENCE_ARG_COUNT <= std::numeric_limits<U8>::max(), | ||
| 30 | "Sequence arg count must be below U8 max"); | ||
| 31 | static_assert(Svc::Fpy::MAX_SEQUENCE_STATEMENT_COUNT <= std::numeric_limits<U16>::max(), | ||
| 32 | "Sequence statement count must be below U16 max"); | ||
| 33 | static_assert(Svc::Fpy::MAX_STACK_SIZE <= std::numeric_limits<Svc::Fpy::StackSizeType>::max(), | ||
| 34 | "Max stack size must be below Svc::Fpy::StackSizeType max"); | ||
| 35 | static_assert(Svc::Fpy::MAX_STACK_SIZE >= static_cast<FwSizeType>(FW_TLM_BUFFER_MAX_SIZE), | ||
| 36 | "Max stack size must be greater than max tlm buffer size"); | ||
| 37 | static_assert(Svc::Fpy::MAX_STACK_SIZE >= static_cast<FwSizeType>(FW_PARAM_BUFFER_MAX_SIZE), | ||
| 38 | "Max stack size must be greater than max prm buffer size"); | ||
| 39 | |||
| 40 | namespace Svc { | ||
| 41 | |||
| 42 | using Signal = FpySequencer_SequencerStateMachineStateMachineBase::Signal; | ||
| 43 | using State = FpySequencer_SequencerStateMachineStateMachineBase::State; | ||
| 44 | using DirectiveError = Fpy::DirectiveErrorCode; | ||
| 45 | |||
| 46 | class FpySequencer : public FpySequencerComponentBase { | ||
| 47 | friend class FpySequencerTester; | ||
| 48 | |||
| 49 | public: | ||
| 50 | union DirectiveUnion { | ||
| 51 | FpySequencer_WaitRelDirective waitRel; | ||
| 52 | FpySequencer_WaitAbsDirective waitAbs; | ||
| 53 | FpySequencer_GotoDirective gotoDirective; | ||
| 54 | FpySequencer_IfDirective ifDirective; | ||
| 55 | FpySequencer_NoOpDirective noOp; | ||
| 56 | FpySequencer_PushTlmValDirective pushTlmVal; | ||
| 57 | FpySequencer_PushTlmValAndTimeDirective pushTlmValAndTime; | ||
| 58 | FpySequencer_PushPrmDirective pushPrm; | ||
| 59 | FpySequencer_ConstCmdDirective constCmd; | ||
| 60 | FpySequencer_StackOpDirective stackOp; | ||
| 61 | FpySequencer_ExitDirective exit; | ||
| 62 | FpySequencer_AllocateDirective allocate; | ||
| 63 | FpySequencer_StoreRelConstOffsetDirective storeRelConstOffset; | ||
| 64 | FpySequencer_LoadRelDirective loadRel; | ||
| 65 | FpySequencer_PushValDirective pushVal; | ||
| 66 | FpySequencer_DiscardDirective discard; | ||
| 67 | FpySequencer_MemCmpDirective memCmp; | ||
| 68 | FpySequencer_StackCmdDirective stackCmd; | ||
| 69 | FpySequencer_PushTimeDirective pushTime; | ||
| 70 | FpySequencer_SetSeedDirective setSeed; | ||
| 71 | FpySequencer_PushRandDirective pushRand; | ||
| 72 | FpySequencer_GetFieldDirective getField; | ||
| 73 | FpySequencer_PeekDirective peek; | ||
| 74 | FpySequencer_StoreRelDirective storeRel; | ||
| 75 | FpySequencer_CallDirective call; | ||
| 76 | FpySequencer_ReturnDirective returnDirective; | ||
| 77 | FpySequencer_LoadAbsDirective loadAbs; | ||
| 78 | FpySequencer_StoreAbsDirective storeAbs; | ||
| 79 | FpySequencer_StoreAbsConstOffsetDirective storeAbsConstOffset; | ||
| 80 | FpySequencer_PopEventDirective popEvent; | ||
| 81 | FpySequencer_PopSerializableDirective popSerializable; | ||
| 82 | |||
| 83 | ✗ | DirectiveUnion() {} | |
| 84 | ✗ | ~DirectiveUnion() {} | |
| 85 | }; | ||
| 86 | |||
| 87 | class Stack { | ||
| 88 | public: | ||
| 89 | // the byte array of the program stack, storing lvars, operands and function calls | ||
| 90 | U8 bytes[Fpy::MAX_STACK_SIZE] = {0}; | ||
| 91 | // how many bytes high the stack is | ||
| 92 | Fpy::StackSizeType size = 0; | ||
| 93 | // the byte offset from the start of the stack where the current function's local variables begin. | ||
| 94 | // analogous to a 'frame pointer'. | ||
| 95 | Fpy::StackSizeType currentFrameStart = 0; | ||
| 96 | |||
| 97 | // pops a value off of the top of the stack | ||
| 98 | // converts it from big endian | ||
| 99 | template <typename T> | ||
| 100 | T pop(); | ||
| 101 | |||
| 102 | // pushes a value onto the top of the stack | ||
| 103 | // converts it to big endian | ||
| 104 | template <typename T> | ||
| 105 | void push(T val); | ||
| 106 | |||
| 107 | // pops a byte array from the top of the stack into the destination array | ||
| 108 | // does not convert endianness | ||
| 109 | void pop(U8* dest, Fpy::StackSizeType size); | ||
| 110 | |||
| 111 | // pushes a byte array to the top of the stack from the source array | ||
| 112 | // leaves the source array unmodified | ||
| 113 | // does not convert endianness | ||
| 114 | void push(const U8* src, Fpy::StackSizeType size); | ||
| 115 | |||
| 116 | // pushes zero bytes to the stack | ||
| 117 | void pushZeroes(Fpy::StackSizeType byteCount); | ||
| 118 | |||
| 119 | // returns a pointer to the next unused byte at the top of the stack | ||
| 120 | U8* top(); | ||
| 121 | |||
| 122 | // Copies data from one region of the stack to another | ||
| 123 | // Asserts that both regions are within bounds and do not overlap | ||
| 124 | // Does not modify stack size | ||
| 125 | void copy(Fpy::StackSizeType destOffset, Fpy::StackSizeType srcOffset, Fpy::StackSizeType copySize); | ||
| 126 | |||
| 127 | // Moves data within the stack (handles overlapping regions) | ||
| 128 | // Asserts that both source and destination are within bounds | ||
| 129 | // Does not modify stack size | ||
| 130 | void move(Fpy::StackSizeType destOffset, Fpy::StackSizeType srcOffset, Fpy::StackSizeType moveSize); | ||
| 131 | }; | ||
| 132 | |||
| 133 | // ---------------------------------------------------------------------- | ||
| 134 | // Construction, initialization, and destruction | ||
| 135 | // ---------------------------------------------------------------------- | ||
| 136 | |||
| 137 | //! Construct object FpySequencer | ||
| 138 | //! | ||
| 139 | FpySequencer(const char* const compName /*!< The component name*/ | ||
| 140 | ); | ||
| 141 | |||
| 142 | //! Destroy object FpySequencer | ||
| 143 | //! | ||
| 144 | ~FpySequencer(); | ||
| 145 | |||
| 146 | private: | ||
| 147 | //! Handler for command RUN | ||
| 148 | //! | ||
| 149 | //! Loads, validates and runs a sequence | ||
| 150 | void RUN_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 151 | U32 cmdSeq, //!< The command sequence number | ||
| 152 | const Fw::CmdStringArg& fileName, //!< The name of the sequence file | ||
| 153 | const Svc::BlockState& block //!< Return command status when complete or not | ||
| 154 | ) override; | ||
| 155 | |||
| 156 | //! Handler implementation for command RUN_ARGS | ||
| 157 | void RUN_ARGS_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 158 | U32 cmdSeq, //!< The command sequence number | ||
| 159 | const Fw::CmdStringArg& fileName, //!< The name of the sequence file | ||
| 160 | const Svc::BlockState& block, //!< Return command status when complete or not | ||
| 161 | const Svc::SeqArgs& args //!< Arguments to pass to the sequencer | ||
| 162 | ) override; | ||
| 163 | |||
| 164 | //! Handler for command VALIDATE | ||
| 165 | //! | ||
| 166 | //! Loads and validates a sequence | ||
| 167 | void VALIDATE_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 168 | U32 cmdSeq, //!< The command sequence number | ||
| 169 | const Fw::CmdStringArg& fileName //!< The name of the sequence file | ||
| 170 | ) override; | ||
| 171 | |||
| 172 | //! Handler implementation for command VALIDATE_ARGS | ||
| 173 | //! | ||
| 174 | //! Loads and validates a sequence with arguments | ||
| 175 | void VALIDATE_ARGS_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 176 | U32 cmdSeq, //!< The command sequence number | ||
| 177 | const Fw::CmdStringArg& fileName, //!< The name of the sequence file | ||
| 178 | const Svc::SeqArgs& buffer //!< Arguments to pass to the sequencer | ||
| 179 | ) override; | ||
| 180 | |||
| 181 | //! Handler implementation for command RUN_VALIDATED | ||
| 182 | //! | ||
| 183 | //! Must be called after VALIDATE. Runs the sequence that was validated. | ||
| 184 | void RUN_VALIDATED_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 185 | U32 cmdSeq, //!< The command sequence number | ||
| 186 | const Svc::BlockState& block //!< Return command status when complete or not | ||
| 187 | ) override; | ||
| 188 | |||
| 189 | //! Handler for command CANCEL | ||
| 190 | //! | ||
| 191 | //! Cancels a running or validated sequence | ||
| 192 | void CANCEL_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 193 | U32 cmdSeq //!< The command sequence number | ||
| 194 | ) override; | ||
| 195 | |||
| 196 | //! Handler for command SET_BREAKPOINT | ||
| 197 | //! | ||
| 198 | //! Sets the breakpoint which will pause the execution of the sequencer when | ||
| 199 | //! reached, until unpaused by the CONTINUE command. Will pause just before | ||
| 200 | //! dispatching the specified statement. This command is valid in all states. Breakpoint | ||
| 201 | //! settings are cleared after a sequence ends execution. | ||
| 202 | void SET_BREAKPOINT_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 203 | U32 cmdSeq, //!< The command sequence number | ||
| 204 | U32 stmtIdx, //!< The statement index to pause execution before. | ||
| 205 | bool breakOnce //!< Whether or not to break only once at this breakpoint | ||
| 206 | ) override; | ||
| 207 | |||
| 208 | //! Handler for command BREAK | ||
| 209 | //! | ||
| 210 | //! Pauses the execution of the sequencer, just before it is about to dispatch the next statement, | ||
| 211 | //! until unpaused by the CONTINUE command, or stepped by the STEP command. This command is only valid in the | ||
| 212 | //! RUNNING state. | ||
| 213 | void BREAK_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 214 | U32 cmdSeq //!< The command sequence number | ||
| 215 | ) override; | ||
| 216 | |||
| 217 | //! Handler for command CONTINUE | ||
| 218 | //! | ||
| 219 | //! Continues the automatic execution of the sequence after it has been paused. If a breakpoint is still | ||
| 220 | //! set, it may pause again on that breakpoint. This command is only valid in the RUNNING.PAUSED state. | ||
| 221 | void CONTINUE_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 222 | U32 cmdSeq //!< The command sequence number | ||
| 223 | ) override; | ||
| 224 | |||
| 225 | //! Handler for command CLEAR_BREAKPOINT | ||
| 226 | //! | ||
| 227 | //! Clears the breakpoint, but does not continue executing the sequence. This command | ||
| 228 | //! is valid in all states. This happens automatically when a sequence ends execution. | ||
| 229 | void CLEAR_BREAKPOINT_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 230 | U32 cmdSeq //!< The command sequence number | ||
| 231 | ) override; | ||
| 232 | |||
| 233 | //! Handler for command STEP | ||
| 234 | //! | ||
| 235 | //! Dispatches and awaits the result of the next directive, or ends the sequence if no more directives remain. | ||
| 236 | //! Returns to the RUNNING.PAUSED state if the directive executes successfully. This command is only valid in the | ||
| 237 | //! RUNNING.PAUSED state. | ||
| 238 | void STEP_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 239 | U32 cmdSeq //!< The command sequence number | ||
| 240 | ) override; | ||
| 241 | |||
| 242 | //! Handler for command DUMP_STACK_TO_FILE | ||
| 243 | //! | ||
| 244 | //! Writes the contents of the stack to a file. This command is only valid in the RUNNING.PAUSED state. | ||
| 245 | void DUMP_STACK_TO_FILE_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 246 | U32 cmdSeq, //!< The command sequence number | ||
| 247 | const Fw::CmdStringArg& fileName //!< The name of the output file | ||
| 248 | ) override; | ||
| 249 | |||
| 250 | // ---------------------------------------------------------------------- | ||
| 251 | // Functions to implement for internal state machine actions | ||
| 252 | // ---------------------------------------------------------------------- | ||
| 253 | |||
| 254 | //! Implementation for action signalEntered of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 255 | //! | ||
| 256 | //! simply raises the "entered" signal | ||
| 257 | void Svc_FpySequencer_SequencerStateMachine_action_signalEntered( | ||
| 258 | SmId smId, //!< The state machine id | ||
| 259 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 260 | ) override; | ||
| 261 | |||
| 262 | //! Implementation for action setSequenceFilePath of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 263 | //! | ||
| 264 | //! sets the current sequence file path member var | ||
| 265 | void Svc_FpySequencer_SequencerStateMachine_action_setSequenceFilePath( | ||
| 266 | SmId smId, //!< The state machine id | ||
| 267 | Svc_FpySequencer_SequencerStateMachine::Signal signal, //!< The signal | ||
| 268 | const Svc::FpySequencer_SequenceExecutionArgs& value //!< The value | ||
| 269 | ) override; | ||
| 270 | |||
| 271 | //! Implementation for action setSequenceBlockState of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 272 | //! | ||
| 273 | //! sets the block state of the sequence to be run | ||
| 274 | void Svc_FpySequencer_SequencerStateMachine_action_setSequenceBlockState( | ||
| 275 | SmId smId, //!< The state machine id | ||
| 276 | Svc_FpySequencer_SequencerStateMachine::Signal signal, //!< The signal | ||
| 277 | const Svc::FpySequencer_SequenceExecutionArgs& value //!< The value | ||
| 278 | ) override; | ||
| 279 | |||
| 280 | //! Implementation for action setSequenceArguments of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 281 | //! | ||
| 282 | //! sets the arguments to pass to the sequence | ||
| 283 | void Svc_FpySequencer_SequencerStateMachine_action_setSequenceArguments( | ||
| 284 | SmId smId, //!< The state machine id | ||
| 285 | Svc_FpySequencer_SequencerStateMachine::Signal signal, //!< The signal | ||
| 286 | const Svc::FpySequencer_SequenceExecutionArgs& value //!< The value | ||
| 287 | ) override; | ||
| 288 | |||
| 289 | //! Implementation for action validate of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 290 | //! | ||
| 291 | //! performs all steps necessary for sequence validation, and raises a signal result_success or result_failure | ||
| 292 | void Svc_FpySequencer_SequencerStateMachine_action_validate( | ||
| 293 | SmId smId, //!< The state machine id | ||
| 294 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 295 | ) override; | ||
| 296 | |||
| 297 | //! Implementation for action report_seqSucceeded of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 298 | //! | ||
| 299 | //! reports that a sequence succeeded | ||
| 300 | void Svc_FpySequencer_SequencerStateMachine_action_report_seqSucceeded( | ||
| 301 | SmId smId, //!< The state machine id | ||
| 302 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 303 | ) override; | ||
| 304 | |||
| 305 | //! Implementation for action report_seqCancelled of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 306 | //! | ||
| 307 | //! reports that a sequence was cancelled | ||
| 308 | void Svc_FpySequencer_SequencerStateMachine_action_report_seqCancelled( | ||
| 309 | SmId smId, //!< The state machine id | ||
| 310 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 311 | ) override; | ||
| 312 | |||
| 313 | //! Implementation for action setGoalState_RUNNING of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 314 | //! | ||
| 315 | //! sets the goal state to RUNNING | ||
| 316 | void Svc_FpySequencer_SequencerStateMachine_action_setGoalState_RUNNING( | ||
| 317 | SmId smId, //!< The state machine id | ||
| 318 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 319 | ) override; | ||
| 320 | |||
| 321 | //! Implementation for action setGoalState_VALID of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 322 | //! | ||
| 323 | //! sets the goal state to VALID | ||
| 324 | void Svc_FpySequencer_SequencerStateMachine_action_setGoalState_VALID( | ||
| 325 | SmId smId, //!< The state machine id | ||
| 326 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 327 | ) override; | ||
| 328 | |||
| 329 | //! Implementation for action setGoalState_IDLE of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 330 | //! | ||
| 331 | //! sets the goal state to IDLE | ||
| 332 | void Svc_FpySequencer_SequencerStateMachine_action_setGoalState_IDLE( | ||
| 333 | SmId smId, //!< The state machine id | ||
| 334 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 335 | ) override; | ||
| 336 | |||
| 337 | //! Implementation for action sendCmdResponse_OK of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 338 | //! | ||
| 339 | //! responds to the calling command with OK | ||
| 340 | void Svc_FpySequencer_SequencerStateMachine_action_sendCmdResponse_OK( | ||
| 341 | SmId smId, //!< The state machine id | ||
| 342 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 343 | ) override; | ||
| 344 | |||
| 345 | //! Implementation for action sendCmdResponse_EXECUTION_ERROR of state machine | ||
| 346 | //! Svc_FpySequencer_SequencerStateMachine | ||
| 347 | //! | ||
| 348 | //! responds to the calling command with EXECUTION_ERROR | ||
| 349 | void Svc_FpySequencer_SequencerStateMachine_action_sendCmdResponse_EXECUTION_ERROR( | ||
| 350 | SmId smId, //!< The state machine id | ||
| 351 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 352 | ) override; | ||
| 353 | |||
| 354 | //! Implementation for action dispatchStatement of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 355 | //! | ||
| 356 | //! iterates to the next statement and dispatches it | ||
| 357 | void Svc_FpySequencer_SequencerStateMachine_action_dispatchStatement( | ||
| 358 | SmId smId, //!< The state machine id | ||
| 359 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 360 | ) override; | ||
| 361 | |||
| 362 | //! Implementation for action clearSequenceFile of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 363 | //! | ||
| 364 | //! clears all variables related to the loading/validating of the sequence file | ||
| 365 | void Svc_FpySequencer_SequencerStateMachine_action_clearSequenceFile( | ||
| 366 | SmId smId, //!< The state machine id | ||
| 367 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 368 | ) override; | ||
| 369 | |||
| 370 | //! Implementation for action clearSequenceArguments of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 371 | //! | ||
| 372 | //! clears arguments | ||
| 373 | void Svc_FpySequencer_SequencerStateMachine_action_clearSequenceArguments( | ||
| 374 | SmId smId, //!< The state machine id | ||
| 375 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 376 | ) override; | ||
| 377 | |||
| 378 | //! Implementation for action checkShouldWake of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 379 | //! | ||
| 380 | //! checks if sequencer should wake from sleep | ||
| 381 | void Svc_FpySequencer_SequencerStateMachine_action_checkShouldWake( | ||
| 382 | SmId smId, //!< The state machine id | ||
| 383 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 384 | ) override; | ||
| 385 | |||
| 386 | //! Implementation for action resetRuntime of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 387 | //! | ||
| 388 | //! resets the sequence runtime | ||
| 389 | void Svc_FpySequencer_SequencerStateMachine_action_resetRuntime( | ||
| 390 | SmId smId, //!< The state machine id | ||
| 391 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 392 | ) override; | ||
| 393 | |||
| 394 | //! Implementation for action checkStatementTimeout of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 395 | //! | ||
| 396 | //! checks if the current statement has timed out | ||
| 397 | void Svc_FpySequencer_SequencerStateMachine_action_checkStatementTimeout( | ||
| 398 | SmId smId, //!< The state machine id | ||
| 399 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 400 | ) override; | ||
| 401 | |||
| 402 | //! Implementation for action incrementSequenceCounter of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 403 | //! | ||
| 404 | //! increments the m_sequencesStarted counter | ||
| 405 | void Svc_FpySequencer_SequencerStateMachine_action_incrementSequenceCounter( | ||
| 406 | SmId smId, //!< The state machine id | ||
| 407 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 408 | ) override; | ||
| 409 | |||
| 410 | //! Implementation for action pushArgsToStack of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 411 | //! | ||
| 412 | //! pushes sequence arguments to the stack | ||
| 413 | void Svc_FpySequencer_SequencerStateMachine_action_pushArgsToStack( | ||
| 414 | SmId smId, //!< The state machine id | ||
| 415 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 416 | ) override; | ||
| 417 | |||
| 418 | //! Implementation for action clearBreakpoint of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 419 | //! | ||
| 420 | //! clears the breakpoint, allowing execution of the sequence to continue | ||
| 421 | void Svc_FpySequencer_SequencerStateMachine_action_clearBreakpoint( | ||
| 422 | SmId smId, //!< The state machine id | ||
| 423 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 424 | ) override; | ||
| 425 | |||
| 426 | //! Implementation for action report_seqBroken of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 427 | //! | ||
| 428 | //! reports that a breakpoint was hit | ||
| 429 | void Svc_FpySequencer_SequencerStateMachine_action_report_seqBroken( | ||
| 430 | SmId smId, //!< The state machine id | ||
| 431 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 432 | ) override; | ||
| 433 | |||
| 434 | //! Implementation for action setBreakpoint of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 435 | //! | ||
| 436 | //! sets the breakpoint to the provided args | ||
| 437 | void Svc_FpySequencer_SequencerStateMachine_action_setBreakpoint( | ||
| 438 | SmId smId, //!< The state machine id | ||
| 439 | Svc_FpySequencer_SequencerStateMachine::Signal signal, //!< The signal | ||
| 440 | const Svc::FpySequencer_BreakpointArgs& value //!< The value | ||
| 441 | ) override; | ||
| 442 | |||
| 443 | //! Implementation for action setBreakBeforeNextLine of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 444 | //! | ||
| 445 | //! sets the "break on next line" flag to true | ||
| 446 | void Svc_FpySequencer_SequencerStateMachine_action_setBreakBeforeNextLine( | ||
| 447 | SmId smId, //!< The state machine id | ||
| 448 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 449 | ) override; | ||
| 450 | |||
| 451 | //! Implementation for action clearBreakBeforeNextLine of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 452 | //! | ||
| 453 | //! sets the "break on next line" flag to false | ||
| 454 | void Svc_FpySequencer_SequencerStateMachine_action_clearBreakBeforeNextLine( | ||
| 455 | SmId smId, //!< The state machine id | ||
| 456 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 457 | ) override; | ||
| 458 | |||
| 459 | //! Implementation for action report_seqFailed of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 460 | //! | ||
| 461 | //! called when a sequence failed to execute successfully | ||
| 462 | void Svc_FpySequencer_SequencerStateMachine_action_report_seqFailed( | ||
| 463 | SmId smId, //!< The state machine id | ||
| 464 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 465 | ) override; | ||
| 466 | |||
| 467 | //! Implementation for action report_seqStarted of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 468 | //! | ||
| 469 | //! reports that a sequence was started | ||
| 470 | void Svc_FpySequencer_SequencerStateMachine_action_report_seqStarted( | ||
| 471 | SmId smId, //!< The state machine id | ||
| 472 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 473 | ) override; | ||
| 474 | |||
| 475 | protected: | ||
| 476 | // ---------------------------------------------------------------------- | ||
| 477 | // Functions to implement for internal state machine guards | ||
| 478 | // ---------------------------------------------------------------------- | ||
| 479 | |||
| 480 | //! Implementation for guard goalStateIs_RUNNING of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 481 | //! | ||
| 482 | //! return true if the goal state is RUNNING | ||
| 483 | bool Svc_FpySequencer_SequencerStateMachine_guard_goalStateIs_RUNNING( | ||
| 484 | SmId smId, //!< The state machine id | ||
| 485 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 486 | ) const override; | ||
| 487 | |||
| 488 | //! Implementation for guard shouldBreak of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 489 | //! | ||
| 490 | //! return true if should break at this point in execution, before dispatching | ||
| 491 | //! next stmt | ||
| 492 | bool Svc_FpySequencer_SequencerStateMachine_guard_shouldBreak( | ||
| 493 | SmId smId, //!< The state machine id | ||
| 494 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 495 | ) const override; | ||
| 496 | |||
| 497 | //! Implementation for guard breakOnce of state machine Svc_FpySequencer_SequencerStateMachine | ||
| 498 | //! | ||
| 499 | //! return true if this breakpoint should only happen once | ||
| 500 | bool Svc_FpySequencer_SequencerStateMachine_guard_breakOnce( | ||
| 501 | SmId smId, //!< The state machine id | ||
| 502 | Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal | ||
| 503 | ) const override; | ||
| 504 | |||
| 505 | // ---------------------------------------------------------------------- | ||
| 506 | // Handlers to implement for typed input ports | ||
| 507 | // ---------------------------------------------------------------------- | ||
| 508 | |||
| 509 | //! Handler for input port checkTimers | ||
| 510 | void checkTimers_handler(FwIndexType portNum, //!< The port number | ||
| 511 | U32 context //!< The call order | ||
| 512 | ) override; | ||
| 513 | |||
| 514 | //! Handler for input port cmdResponseIn | ||
| 515 | void cmdResponseIn_handler(FwIndexType portNum, //!< The port number | ||
| 516 | FwOpcodeType opCode, //!< Command Op Code | ||
| 517 | U32 cmdSeq, //!< Command Sequence | ||
| 518 | const Fw::CmdResponse& response //!< The command response argument | ||
| 519 | ) override; | ||
| 520 | |||
| 521 | //! Handler for input port seqRunIn | ||
| 522 | void seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename, const Svc::SeqArgs& args) override; | ||
| 523 | |||
| 524 | //! Handler implementation for seqCancelIn | ||
| 525 | //! | ||
| 526 | //! port for requesting to cancel the currently running sequence | ||
| 527 | void seqCancelIn_handler(FwIndexType portNum //!< The port number | ||
| 528 | ) override; | ||
| 529 | |||
| 530 | //! Handler for input port pingIn | ||
| 531 | void pingIn_handler(FwIndexType portNum, //!< The port number | ||
| 532 | U32 key //!< Value to return to pinger | ||
| 533 | ) override; | ||
| 534 | |||
| 535 | //! Handler for input port tlmWrite | ||
| 536 | void tlmWrite_handler(FwIndexType portNum, //!< The port number | ||
| 537 | U32 context //!< The call order | ||
| 538 | ) override; | ||
| 539 | |||
| 540 | //! Internal interface handler for directive_waitAbs | ||
| 541 | void directive_waitAbs_internalInterfaceHandler(const FpySequencer_WaitAbsDirective& directive) override; | ||
| 542 | |||
| 543 | //! Internal interface handler for directive_waitRel | ||
| 544 | void directive_waitRel_internalInterfaceHandler(const FpySequencer_WaitRelDirective& directive) override; | ||
| 545 | |||
| 546 | //! Internal interface handler for directive_goto | ||
| 547 | void directive_goto_internalInterfaceHandler(const Svc::FpySequencer_GotoDirective& directive) override; | ||
| 548 | |||
| 549 | //! Internal interface handler for directive_if | ||
| 550 | void directive_if_internalInterfaceHandler(const Svc::FpySequencer_IfDirective& directive) override; | ||
| 551 | |||
| 552 | //! Internal interface handler for directive_noOp | ||
| 553 | void directive_noOp_internalInterfaceHandler(const Svc::FpySequencer_NoOpDirective& directive) override; | ||
| 554 | |||
| 555 | //! Internal interface handler for directive_pushTlmVal | ||
| 556 | void directive_pushTlmVal_internalInterfaceHandler(const Svc::FpySequencer_PushTlmValDirective& directive) override; | ||
| 557 | |||
| 558 | //! Internal interface handler for directive_pushTlmValAndTime | ||
| 559 | void directive_pushTlmValAndTime_internalInterfaceHandler( | ||
| 560 | const Svc::FpySequencer_PushTlmValAndTimeDirective& directive) override; | ||
| 561 | |||
| 562 | //! Internal interface handler for directive_pushPrm | ||
| 563 | void directive_pushPrm_internalInterfaceHandler(const Svc::FpySequencer_PushPrmDirective& directive) override; | ||
| 564 | |||
| 565 | //! Internal interface handler for directive_constCmd | ||
| 566 | void directive_constCmd_internalInterfaceHandler(const Svc::FpySequencer_ConstCmdDirective& directive) override; | ||
| 567 | |||
| 568 | //! Internal interface handler for directive_stackOp | ||
| 569 | void directive_stackOp_internalInterfaceHandler(const Svc::FpySequencer_StackOpDirective& directive) override; | ||
| 570 | |||
| 571 | //! Internal interface handler for directive_exit | ||
| 572 | void directive_exit_internalInterfaceHandler(const Svc::FpySequencer_ExitDirective& directive) override; | ||
| 573 | |||
| 574 | //! Internal interface handler for directive_allocate | ||
| 575 | void directive_allocate_internalInterfaceHandler(const Svc::FpySequencer_AllocateDirective& directive) override; | ||
| 576 | |||
| 577 | //! Internal interface handler for directive_storeRelConstOffset | ||
| 578 | void directive_storeRelConstOffset_internalInterfaceHandler( | ||
| 579 | const Svc::FpySequencer_StoreRelConstOffsetDirective& directive) override; | ||
| 580 | |||
| 581 | //! Internal interface handler for directive_loadRel | ||
| 582 | void directive_loadRel_internalInterfaceHandler(const Svc::FpySequencer_LoadRelDirective& directive) override; | ||
| 583 | |||
| 584 | //! Internal interface handler for directive_pushVal | ||
| 585 | void directive_pushVal_internalInterfaceHandler(const Svc::FpySequencer_PushValDirective& directive) override; | ||
| 586 | |||
| 587 | //! Internal interface handler for directive_discard | ||
| 588 | void directive_discard_internalInterfaceHandler(const Svc::FpySequencer_DiscardDirective& directive) override; | ||
| 589 | |||
| 590 | //! Internal interface handler for directive_memCmp | ||
| 591 | void directive_memCmp_internalInterfaceHandler(const Svc::FpySequencer_MemCmpDirective& directive) override; | ||
| 592 | |||
| 593 | //! Internal interface handler for directive_stackCmd | ||
| 594 | void directive_stackCmd_internalInterfaceHandler(const Svc::FpySequencer_StackCmdDirective& directive) override; | ||
| 595 | |||
| 596 | //! Internal interface handler for directive_pushTime | ||
| 597 | void directive_pushTime_internalInterfaceHandler(const Svc::FpySequencer_PushTimeDirective& directive) override; | ||
| 598 | |||
| 599 | //! Internal interface handler for directive_setSeed | ||
| 600 | void directive_setSeed_internalInterfaceHandler(const Svc::FpySequencer_SetSeedDirective& directive) override; | ||
| 601 | |||
| 602 | //! Internal interface handler for directive_pushRand | ||
| 603 | void directive_pushRand_internalInterfaceHandler(const Svc::FpySequencer_PushRandDirective& directive) override; | ||
| 604 | |||
| 605 | //! Internal interface handler for directive_getField | ||
| 606 | void directive_getField_internalInterfaceHandler(const Svc::FpySequencer_GetFieldDirective& directive) override; | ||
| 607 | |||
| 608 | //! Internal interface handler for directive_peek | ||
| 609 | void directive_peek_internalInterfaceHandler(const Svc::FpySequencer_PeekDirective& directive) override; | ||
| 610 | |||
| 611 | //! Internal interface handler for directive_storeRel | ||
| 612 | void directive_storeRel_internalInterfaceHandler(const Svc::FpySequencer_StoreRelDirective& directive) override; | ||
| 613 | |||
| 614 | //! Internal interface handler for directive_call | ||
| 615 | void directive_call_internalInterfaceHandler(const Svc::FpySequencer_CallDirective& directive) override; | ||
| 616 | |||
| 617 | //! Internal interface handler for directive_return | ||
| 618 | void directive_return_internalInterfaceHandler(const Svc::FpySequencer_ReturnDirective& directive) override; | ||
| 619 | |||
| 620 | //! Internal interface handler for directive_loadAbs | ||
| 621 | void directive_loadAbs_internalInterfaceHandler(const Svc::FpySequencer_LoadAbsDirective& directive) override; | ||
| 622 | |||
| 623 | //! Internal interface handler for directive_storeAbs | ||
| 624 | void directive_storeAbs_internalInterfaceHandler(const Svc::FpySequencer_StoreAbsDirective& directive) override; | ||
| 625 | |||
| 626 | //! Internal interface handler for directive_storeAbsConstOffset | ||
| 627 | void directive_storeAbsConstOffset_internalInterfaceHandler( | ||
| 628 | const Svc::FpySequencer_StoreAbsConstOffsetDirective& directive) override; | ||
| 629 | |||
| 630 | //! Internal interface handler for directive_popEvent | ||
| 631 | void directive_popEvent_internalInterfaceHandler(const Svc::FpySequencer_PopEventDirective& directive) override; | ||
| 632 | |||
| 633 | //! Internal interface handler for directive_popSerializable | ||
| 634 | void directive_popSerializable_internalInterfaceHandler( | ||
| 635 | const Svc::FpySequencer_PopSerializableDirective& directive) override; | ||
| 636 | |||
| 637 | void parametersLoaded() override; | ||
| 638 | void parameterUpdated(FwPrmIdType id) override; | ||
| 639 | |||
| 640 | public: | ||
| 641 | void allocateBuffer(FwEnumStoreType identifier, Fw::MemAllocator& allocator, FwSizeType bytes); | ||
| 642 | |||
| 643 | void deallocateBuffer(Fw::MemAllocator& allocator); | ||
| 644 | |||
| 645 | private: | ||
| 646 | static constexpr U32 CRC_INITIAL_VALUE = 0xFFFFFFFFU; | ||
| 647 | |||
| 648 | // allocated at startup | ||
| 649 | Fw::ExternalSerializeBuffer m_sequenceBuffer; | ||
| 650 | // id of allocator that gave us m_sequenceBuffer | ||
| 651 | FwEnumStoreType m_allocatorId; | ||
| 652 | |||
| 653 | // assigned by the user via cmd | ||
| 654 | // length is FileNameStringSize | ||
| 655 | Fw::FileNameString m_sequenceFilePath; | ||
| 656 | // the sequence, loaded in memory | ||
| 657 | Fpy::Sequence m_sequenceObj; | ||
| 658 | // live running computation of CRC (updated as we read) | ||
| 659 | Utils::Hash m_computedCRC; | ||
| 660 | |||
| 661 | // Size of arguments read in current sequence. Used for validation between | ||
| 662 | // User provided arguments and what is requested of the sequence. | ||
| 663 | Fpy::StackSizeType m_totalExpectedArgSize; | ||
| 664 | |||
| 665 | // whether or not the sequence we're about to run should return immediately or | ||
| 666 | // block on completion | ||
| 667 | Svc::BlockState m_sequenceBlockState; | ||
| 668 | // if we are to block on completion, save the opCode and cmdSeq we should | ||
| 669 | // return | ||
| 670 | FwOpcodeType m_savedOpCode; | ||
| 671 | U32 m_savedCmdSeq; | ||
| 672 | |||
| 673 | // sequence arguments to push to stack when entering RUNNING state | ||
| 674 | Svc::SeqArgs m_sequenceArgs{}; | ||
| 675 | |||
| 676 | // the goal state is the state that we're trying to reach in the sequencer | ||
| 677 | // if it's RUNNING, then we should promptly go to RUNNING once we validate the | ||
| 678 | // sequence. if it's VALID, we should wait after VALIDATING | ||
| 679 | FpySequencer_GoalState m_goalState; | ||
| 680 | |||
| 681 | // the total number of sequences this sequencer has started since construction | ||
| 682 | U64 m_sequencesStarted; | ||
| 683 | // the total number of statements this sequencer has dispatched, successfully or | ||
| 684 | // otherwise, since construction | ||
| 685 | U64 m_statementsDispatched; | ||
| 686 | |||
| 687 | const Fw::String NO_SEQ{"<no seq>"}; | ||
| 688 | |||
| 689 | // the runtime state of the sequence. encapsulates all state | ||
| 690 | // needed to run the sequence. | ||
| 691 | // this is distinct from the state of the sequencer. the | ||
| 692 | // sequencer and all its state is really just a shell to load | ||
| 693 | // and execute this runtime. | ||
| 694 | struct Runtime { | ||
| 695 | // the index of the next statement to be executed | ||
| 696 | U32 nextStatementIndex = 0; | ||
| 697 | |||
| 698 | // the opcode of the statement that is currently executing | ||
| 699 | U8 currentStatementOpcode = Fpy::DirectiveId::INVALID; | ||
| 700 | // the opcode of the command that we are currently awaiting, or 0 if we are executing a directive | ||
| 701 | FwOpcodeType currentCmdOpcode = 0; | ||
| 702 | // the time we dispatched the statement that is currently executing | ||
| 703 | Fw::Time currentStatementDispatchTime = Fw::Time(); | ||
| 704 | |||
| 705 | // the absolute time we should wait for until returning | ||
| 706 | // a statement response | ||
| 707 | Fw::Time wakeupTime = Fw::Time(); | ||
| 708 | |||
| 709 | // RNG state used by PUSH_RAND and SET_SEED directives during this run | ||
| 710 | std::mt19937 rng; | ||
| 711 | bool rngSeeded = false; | ||
| 712 | |||
| 713 | Stack stack = Stack(); | ||
| 714 | } m_runtime; | ||
| 715 | |||
| 716 | // the state of the debugger. debugger is separate from runtime | ||
| 717 | // because it can be set up before running the sequence. | ||
| 718 | struct BreakpointInfo { | ||
| 719 | // whether or not to break at the debug breakpoint index | ||
| 720 | bool breakpointInUse = false; | ||
| 721 | // whether or not to remove the breakpoint after breaking on it | ||
| 722 | bool breakOnlyOnceOnBreakpoint = false; | ||
| 723 | // the statement index at which to break, before dispatching | ||
| 724 | U32 breakpointIndex = 0; | ||
| 725 | // whether or not to break before dispatching the next line, | ||
| 726 | // independent of what line it is. | ||
| 727 | // can be used in combination with breakpointIndex | ||
| 728 | bool breakBeforeNextLine = false; | ||
| 729 | } m_breakpoint; | ||
| 730 | |||
| 731 | // debug information about the sequence. only valid in the PAUSED state | ||
| 732 | // which you can access via BREAK or SET_BREAKPOINT cmds | ||
| 733 | struct DebugInfo { | ||
| 734 | // true if there are no statements remaining in the sequence file | ||
| 735 | bool reachedEndOfFile = false; | ||
| 736 | // true if we were able to deserialize the next statement successfully | ||
| 737 | bool nextStatementReadSuccess = false; | ||
| 738 | // the opcode of the next statement to dispatch. | ||
| 739 | U8 nextStatementOpcode = 0; | ||
| 740 | // if the next statement is a cmd directive, the opcode of that cmd | ||
| 741 | FwOpcodeType nextCmdOpcode = 0; | ||
| 742 | // the index of the next statement we're going to execute | ||
| 743 | U32 nextStatementIndex = 0; | ||
| 744 | // the size of the stack. store this separately from the real stack size | ||
| 745 | // so we can avoid changing this during runtime, only modify it during | ||
| 746 | // debug | ||
| 747 | Fpy::StackSizeType stackSize = 0; | ||
| 748 | } m_debug; | ||
| 749 | |||
| 750 | struct Telemetry { | ||
| 751 | // the number of statements that failed to execute | ||
| 752 | U64 statementsFailed = 0; | ||
| 753 | // the number of sequences successfully completed | ||
| 754 | U64 sequencesSucceeded = 0; | ||
| 755 | // the number of sequences that failed to validate or execute | ||
| 756 | U64 sequencesFailed = 0; | ||
| 757 | // the number of sequences that have been cancelled | ||
| 758 | U64 sequencesCancelled = 0; | ||
| 759 | |||
| 760 | // the error code of the last directive that ran | ||
| 761 | DirectiveError lastDirectiveError = DirectiveError::NO_ERROR; | ||
| 762 | // the index of the last directive that errored | ||
| 763 | U64 directiveErrorIndex = 0; | ||
| 764 | // the opcode of the last directive that errored | ||
| 765 | Fpy::DirectiveId directiveErrorId = Fpy::DirectiveId::INVALID; | ||
| 766 | } m_tlm; | ||
| 767 | |||
| 768 | // ---------------------------------------------------------------------- | ||
| 769 | // Validation state | ||
| 770 | // ---------------------------------------------------------------------- | ||
| 771 | |||
| 772 | // loads the sequence in memory, and does header/crc/integrity checks. | ||
| 773 | // return SUCCESS if sequence is valid, FAILURE otherwise | ||
| 774 | Fw::Success validate(); | ||
| 775 | // reads and validates the header from the m_sequenceBuffer | ||
| 776 | // return SUCCESS if sequence is valid, FAILURE otherwise | ||
| 777 | Fw::Success readHeader(); | ||
| 778 | // reads and validates the body from the m_sequenceBuffer | ||
| 779 | // return SUCCESS if sequence is valid, FAILURE otherwise | ||
| 780 | Fw::Success readBody(); | ||
| 781 | // reads and validates the footer from the m_sequenceBuffer | ||
| 782 | // return SUCCESS if sequence is valid, FAILURE otherwise | ||
| 783 | Fw::Success readFooter(); | ||
| 784 | |||
| 785 | // reads some bytes from the open file into the m_sequenceBuffer. | ||
| 786 | // updates the CRC by default, but can be turned off if the contents | ||
| 787 | // aren't included in CRC. | ||
| 788 | // return success if successful | ||
| 789 | Fw::Success readBytes(Os::File& file, | ||
| 790 | FwSizeType readLen, | ||
| 791 | const FpySequencer_FileReadStage& readStage, | ||
| 792 | bool updateCrc = true); | ||
| 793 | |||
| 794 | // ---------------------------------------------------------------------- | ||
| 795 | // Run state | ||
| 796 | // ---------------------------------------------------------------------- | ||
| 797 | |||
| 798 | // utility method for updating telemetry based on a directive error code | ||
| 799 | void handleDirectiveErrorCode(Fpy::DirectiveId id, DirectiveError err); | ||
| 800 | |||
| 801 | // dispatches the next statement | ||
| 802 | Signal dispatchStatement(); | ||
| 803 | |||
| 804 | // deserializes a directive from bytes into the Fpy type | ||
| 805 | // returns success if able to deserialize, and returns the Fpy type object | ||
| 806 | // as a reference, in a union of all the possible directive type objects | ||
| 807 | Fw::Success deserializeDirective(const Fpy::Statement& stmt, DirectiveUnion& deserializedDirective); | ||
| 808 | |||
| 809 | // dispatches a deserialized sequencer directive to the right handler. | ||
| 810 | void dispatchDirective(const DirectiveUnion& directive, const Fpy::DirectiveId& id); | ||
| 811 | |||
| 812 | // checks whether the currently executing statement timed out | ||
| 813 | Signal checkStatementTimeout(); | ||
| 814 | |||
| 815 | // checks whether the sequencer should wake from sleeping | ||
| 816 | Signal checkShouldWake(); | ||
| 817 | |||
| 818 | // return true if state is a substate of RUNNING | ||
| 819 | bool isRunningState(State state); | ||
| 820 | |||
| 821 | // update a struct containing debug telemetry, or defaults if not in debug break | ||
| 822 | void updateDebugTelemetryStruct(); | ||
| 823 | |||
| 824 | // ---------------------------------------------------------------------- | ||
| 825 | // Directives | ||
| 826 | // ---------------------------------------------------------------------- | ||
| 827 | |||
| 828 | // sends a signal based on a signal id | ||
| 829 | void sendSignal(Signal signal); | ||
| 830 | |||
| 831 | // dispatches a command, returns whether successful or not | ||
| 832 | Fw::Success sendCmd(FwOpcodeType opcode, const U8* argBuf, FwSizeType argBufSize); | ||
| 833 | |||
| 834 | // returns the index of the current statement | ||
| 835 | U32 currentStatementIdx(); | ||
| 836 | |||
| 837 | // we split these functions up into the internalInterfaceInvoke and these custom member funcs | ||
| 838 | // so that we can unit test them easier | ||
| 839 | Signal waitRel_directiveHandler(const FpySequencer_WaitRelDirective& directive, DirectiveError& error); | ||
| 840 | Signal waitAbs_directiveHandler(const FpySequencer_WaitAbsDirective& directive, DirectiveError& error); | ||
| 841 | Signal goto_directiveHandler(const FpySequencer_GotoDirective& directive, DirectiveError& error); | ||
| 842 | Signal if_directiveHandler(const FpySequencer_IfDirective& directive, DirectiveError& error); | ||
| 843 | Signal noOp_directiveHandler(const FpySequencer_NoOpDirective& directive, DirectiveError& error); | ||
| 844 | Signal pushTlmVal_directiveHandler(const FpySequencer_PushTlmValDirective& directive, DirectiveError& error); | ||
| 845 | Signal pushTlmValAndTime_directiveHandler(const FpySequencer_PushTlmValAndTimeDirective& directive, | ||
| 846 | DirectiveError& error); | ||
| 847 | Signal pushPrm_directiveHandler(const FpySequencer_PushPrmDirective& directive, DirectiveError& error); | ||
| 848 | Signal constCmd_directiveHandler(const FpySequencer_ConstCmdDirective& directive, DirectiveError& error); | ||
| 849 | Signal stackOp_directiveHandler(const FpySequencer_StackOpDirective& directive, DirectiveError& error); | ||
| 850 | |||
| 851 | DirectiveError op_or(); | ||
| 852 | DirectiveError op_and(); | ||
| 853 | DirectiveError op_ieq(); | ||
| 854 | DirectiveError op_ine(); | ||
| 855 | DirectiveError op_ult(); | ||
| 856 | DirectiveError op_ule(); | ||
| 857 | DirectiveError op_ugt(); | ||
| 858 | DirectiveError op_uge(); | ||
| 859 | DirectiveError op_slt(); | ||
| 860 | DirectiveError op_sle(); | ||
| 861 | DirectiveError op_sgt(); | ||
| 862 | DirectiveError op_sge(); | ||
| 863 | DirectiveError op_feq(); | ||
| 864 | DirectiveError op_fne(); | ||
| 865 | DirectiveError op_flt(); | ||
| 866 | DirectiveError op_fle(); | ||
| 867 | DirectiveError op_fgt(); | ||
| 868 | DirectiveError op_fge(); | ||
| 869 | DirectiveError op_not(); | ||
| 870 | DirectiveError op_fpext(); | ||
| 871 | DirectiveError op_fptrunc(); | ||
| 872 | DirectiveError op_fptoui(); | ||
| 873 | DirectiveError op_fptosi(); | ||
| 874 | DirectiveError op_sitofp(); | ||
| 875 | DirectiveError op_uitofp(); | ||
| 876 | DirectiveError op_add(); | ||
| 877 | DirectiveError op_sub(); | ||
| 878 | DirectiveError op_mul(); | ||
| 879 | DirectiveError op_udiv(); | ||
| 880 | DirectiveError op_sdiv(); | ||
| 881 | DirectiveError op_umod(); | ||
| 882 | DirectiveError op_smod(); | ||
| 883 | DirectiveError op_fadd(); | ||
| 884 | DirectiveError op_fsub(); | ||
| 885 | DirectiveError op_fmul(); | ||
| 886 | DirectiveError op_fdiv(); | ||
| 887 | DirectiveError op_fpow(); | ||
| 888 | DirectiveError op_flog(); | ||
| 889 | DirectiveError op_fmod(); | ||
| 890 | DirectiveError op_siext_8_64(); | ||
| 891 | DirectiveError op_siext_16_64(); | ||
| 892 | DirectiveError op_siext_32_64(); | ||
| 893 | DirectiveError op_ziext_8_64(); | ||
| 894 | DirectiveError op_ziext_16_64(); | ||
| 895 | DirectiveError op_ziext_32_64(); | ||
| 896 | DirectiveError op_itrunc_64_8(); | ||
| 897 | DirectiveError op_itrunc_64_16(); | ||
| 898 | DirectiveError op_itrunc_64_32(); | ||
| 899 | DirectiveError op_ffloor(); | ||
| 900 | DirectiveError op_iabs(); | ||
| 901 | DirectiveError op_fabs(); | ||
| 902 | |||
| 903 | Signal exit_directiveHandler(const FpySequencer_ExitDirective& directive, DirectiveError& error); | ||
| 904 | Signal allocate_directiveHandler(const FpySequencer_AllocateDirective& directive, DirectiveError& error); | ||
| 905 | //! Helper to pop value from stack top and store at destOffset | ||
| 906 | Signal storeHelper(Fpy::StackSizeType destOffset, Fpy::StackSizeType size, DirectiveError& error); | ||
| 907 | //! Helper to load value from srcOffset and push to stack top | ||
| 908 | Signal loadHelper(Fpy::StackSizeType srcOffset, Fpy::StackSizeType size, DirectiveError& error); | ||
| 909 | Signal storeRelConstOffset_directiveHandler(const FpySequencer_StoreRelConstOffsetDirective& directive, | ||
| 910 | DirectiveError& error); | ||
| 911 | Signal loadRel_directiveHandler(const FpySequencer_LoadRelDirective& directive, DirectiveError& error); | ||
| 912 | Signal pushVal_directiveHandler(const FpySequencer_PushValDirective& directive, DirectiveError& error); | ||
| 913 | Signal discard_directiveHandler(const FpySequencer_DiscardDirective& directive, DirectiveError& error); | ||
| 914 | Signal memCmp_directiveHandler(const FpySequencer_MemCmpDirective& directive, DirectiveError& error); | ||
| 915 | Signal stackCmd_directiveHandler(const FpySequencer_StackCmdDirective& directive, DirectiveError& error); | ||
| 916 | Signal pushTime_directiveHandler(const FpySequencer_PushTimeDirective& directive, DirectiveError& error); | ||
| 917 | Signal setSeed_directiveHandler(const FpySequencer_SetSeedDirective& directive, DirectiveError& error); | ||
| 918 | Signal pushRand_directiveHandler(const FpySequencer_PushRandDirective& directive, DirectiveError& error); | ||
| 919 | Signal getField_directiveHandler(const FpySequencer_GetFieldDirective& directive, DirectiveError& error); | ||
| 920 | Signal peek_directiveHandler(const FpySequencer_PeekDirective& directive, DirectiveError& error); | ||
| 921 | Signal storeRel_directiveHandler(const FpySequencer_StoreRelDirective& directive, DirectiveError& error); | ||
| 922 | Signal call_directiveHandler(const FpySequencer_CallDirective& directive, DirectiveError& error); | ||
| 923 | Signal return_directiveHandler(const FpySequencer_ReturnDirective& directive, DirectiveError& error); | ||
| 924 | Signal loadAbs_directiveHandler(const FpySequencer_LoadAbsDirective& directive, DirectiveError& error); | ||
| 925 | Signal storeAbs_directiveHandler(const FpySequencer_StoreAbsDirective& directive, DirectiveError& error); | ||
| 926 | Signal storeAbsConstOffset_directiveHandler(const FpySequencer_StoreAbsConstOffsetDirective& directive, | ||
| 927 | DirectiveError& error); | ||
| 928 | Signal popEvent_directiveHandler(const FpySequencer_PopEventDirective& directive, DirectiveError& error); | ||
| 929 | Signal popSerializable_directiveHandler(const FpySequencer_PopSerializableDirective& directive, | ||
| 930 | DirectiveError& error); | ||
| 931 | }; | ||
| 932 | |||
| 933 | } // namespace Svc | ||
| 934 | |||
| 935 | #endif | ||
| 936 |