F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
FpySequencer.hpp
Go to the documentation of this file.
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 
11 #include "Fw/Types/StringBase.hpp"
13 #include "Fw/Types/WaitEnumAc.hpp"
14 #include "Os/File.hpp"
23 
24 static_assert(Svc::Fpy::MAX_SEQUENCE_ARG_COUNT <= std::numeric_limits<U8>::max(),
25  "Sequence arg count must be below U8 max");
26 static_assert(Svc::Fpy::MAX_SEQUENCE_STATEMENT_COUNT <= std::numeric_limits<U16>::max(),
27  "Sequence statement count must be below U16 max");
28 static_assert(Svc::Fpy::MAX_LOCAL_VARIABLE_BUFFER_SIZE <= std::numeric_limits<FwSizeType>::max(),
29  "Local variable buffer size must be below FwSizeType max");
31  "Local variable buffer size must be greater than FW_TLM_BUFFER_MAX_SIZE");
33  "Local variable buffer size must be greater than FW_PARAM_BUFFER_MAX_SIZE");
34 
35 namespace Svc {
36 
39 
41  public:
51 
54  };
55 
56  // ----------------------------------------------------------------------
57  // Construction, initialization, and destruction
58  // ----------------------------------------------------------------------
59 
62  FpySequencer(const char* const compName
63  );
64 
67  ~FpySequencer();
68 
69  PRIVATE :
70 
74  void
75  RUN_cmdHandler(FwOpcodeType opCode,
76  U32 cmdSeq,
77  const Fw::CmdStringArg& fileName,
79  ) override;
80 
84  void VALIDATE_cmdHandler(FwOpcodeType opCode,
85  U32 cmdSeq,
86  const Fw::CmdStringArg& fileName
87  ) override;
88 
92  void RUN_VALIDATED_cmdHandler(FwOpcodeType opCode,
93  U32 cmdSeq,
95  ) override;
96 
100  void CANCEL_cmdHandler(FwOpcodeType opCode,
101  U32 cmdSeq
102  ) override;
103 
110  void DEBUG_SET_BREAKPOINT_cmdHandler(FwOpcodeType opCode,
111  U32 cmdSeq,
112  U32 stmtIdx,
113  bool breakOnce
114  ) override;
115 
121  void DEBUG_BREAK_cmdHandler(FwOpcodeType opCode,
122  U32 cmdSeq,
123  bool breakOnce
124  ) override;
125 
130  void DEBUG_CONTINUE_cmdHandler(FwOpcodeType opCode,
131  U32 cmdSeq
132  ) override;
133 
138  void DEBUG_CLEAR_BREAKPOINT_cmdHandler(FwOpcodeType opCode,
139  U32 cmdSeq
140  ) override;
141 
142  // ----------------------------------------------------------------------
143  // Functions to implement for internal state machine actions
144  // ----------------------------------------------------------------------
145 
149  void Svc_FpySequencer_SequencerStateMachine_action_signalEntered(
150  SmId smId,
152  ) override;
153 
157  void Svc_FpySequencer_SequencerStateMachine_action_setSequenceFilePath(
158  SmId smId,
161  ) override;
162 
166  void Svc_FpySequencer_SequencerStateMachine_action_setSequenceBlockState(
167  SmId smId,
170  ) override;
171 
175  void Svc_FpySequencer_SequencerStateMachine_action_validate(
176  SmId smId,
178  ) override;
179 
183  void Svc_FpySequencer_SequencerStateMachine_action_report_seqSucceeded(
184  SmId smId,
186  ) override;
187 
191  void Svc_FpySequencer_SequencerStateMachine_action_report_seqCancelled(
192  SmId smId,
194  ) override;
195 
199  void Svc_FpySequencer_SequencerStateMachine_action_setGoalState_RUNNING(
200  SmId smId,
202  ) override;
203 
207  void Svc_FpySequencer_SequencerStateMachine_action_setGoalState_VALID(
208  SmId smId,
210  ) override;
211 
215  void Svc_FpySequencer_SequencerStateMachine_action_setGoalState_IDLE(
216  SmId smId,
218  ) override;
219 
223  void Svc_FpySequencer_SequencerStateMachine_action_sendCmdResponse_OK(
224  SmId smId,
226  ) override;
227 
232  void Svc_FpySequencer_SequencerStateMachine_action_sendCmdResponse_EXECUTION_ERROR(
233  SmId smId,
235  ) override;
236 
240  void Svc_FpySequencer_SequencerStateMachine_action_dispatchStatement(
241  SmId smId,
243  ) override;
244 
248  void Svc_FpySequencer_SequencerStateMachine_action_clearSequenceFile(
249  SmId smId,
251  ) override;
252 
256  void Svc_FpySequencer_SequencerStateMachine_action_checkShouldWake(
257  SmId smId,
259  ) override;
260 
264  void Svc_FpySequencer_SequencerStateMachine_action_resetRuntime(
265  SmId smId,
267  ) override;
268 
272  void Svc_FpySequencer_SequencerStateMachine_action_checkStatementTimeout(
273  SmId smId,
275  ) override;
276 
280  void Svc_FpySequencer_SequencerStateMachine_action_incrementSequenceCounter(
281  SmId smId,
283  ) override;
284 
288  void Svc_FpySequencer_SequencerStateMachine_action_clearDebugBreakpoint(
289  SmId smId,
291  ) override;
292 
296  void Svc_FpySequencer_SequencerStateMachine_action_report_debugBroken(
297  SmId smId,
299  ) override;
300 
304  void Svc_FpySequencer_SequencerStateMachine_action_setDebugBreakpoint(
305  SmId smId,
308  ) override;
309 
310  PROTECTED :
311 
312  // ----------------------------------------------------------------------
313  // Functions to implement for internal state machine guards
314  // ----------------------------------------------------------------------
315 
319  bool
321  SmId smId,
323  ) const override;
324 
330  SmId smId,
332  ) const override;
333 
338  SmId smId,
340  ) const override;
341 
342  // ----------------------------------------------------------------------
343  // Handlers to implement for typed input ports
344  // ----------------------------------------------------------------------
345 
347  void checkTimers_handler(FwIndexType portNum,
348  U32 context
349  ) override;
350 
352  void cmdResponseIn_handler(FwIndexType portNum,
353  FwOpcodeType opCode,
354  U32 cmdSeq,
355  const Fw::CmdResponse& response
356  ) override;
357 
359  void seqRunIn_handler(FwIndexType portNum,
360  const Fw::StringBase& filename
361  ) override;
362 
364  void pingIn_handler(FwIndexType portNum,
365  U32 key
366  ) override;
367 
369  void tlmWrite_handler(FwIndexType portNum,
370  U32 context
371  ) override;
372 
375 
378 
381 
384 
387 
390 
393 
396 
397  void parametersLoaded() override;
398  void parameterUpdated(FwPrmIdType id) override;
399 
400  public:
401  void allocateBuffer(FwEnumStoreType identifier, Fw::MemAllocator& allocator, FwSizeType bytes);
402 
403  void deallocateBuffer(Fw::MemAllocator& allocator);
404  PRIVATE :
405 
406  static constexpr U32 CRC_INITIAL_VALUE = 0xFFFFFFFFU;
407 
408  // allocated at startup
409  Fw::ExternalSerializeBuffer m_sequenceBuffer;
410  // id of allocator that gave us m_sequenceBuffer
411  FwEnumStoreType m_allocatorId;
412 
413  // assigned by the user via cmd
414  Fw::String m_sequenceFilePath;
415  // the sequence, loaded in memory
416  Fpy::Sequence m_sequenceObj;
417  // live running computation of CRC (updated as we read)
418  U32 m_computedCRC;
419 
420  // whether or not the sequence we're about to run should return immediately or
421  // block on completion
422  FpySequencer_BlockState m_sequenceBlockState;
423  // if we are to block on completion, save the opCode and cmdSeq we should
424  // return
425  FwOpcodeType m_savedOpCode;
426  U32 m_savedCmdSeq;
427 
428  // the goal state is the state that we're trying to reach in the sequencer
429  // if it's RUNNING, then we should promptly go to RUNNING once we validate the
430  // sequence. if it's VALID, we should wait after VALIDATING
431  FpySequencer_GoalState m_goalState;
432 
433  // the total number of sequences this sequencer has started since construction
434  U64 m_sequencesStarted;
435  // the total number of statements this sequencer has dispatched, successfully or
436  // otherwise, since construction
437  U64 m_statementsDispatched;
438 
439  // the runtime state of the sequence. encapsulates all state
440  // needed to run the sequence.
441  // this is distinct from the state of the sequencer. the
442  // sequencer and all its state is really just a shell to load
443  // and execute this runtime.
444  struct Runtime {
445  // the index of the next statement to be executed
446  U32 nextStatementIndex = 0;
447 
448  // the opcode of the statement that is currently executing
449  FwOpcodeType currentStatementOpcode = Fpy::DirectiveId::INVALID;
450  // the stmt type of the stmt currently executing (cmd or directive)
451  Fpy::StatementType currentStatementType = Fpy::StatementType::DIRECTIVE;
452  // the time we dispatched the statement that is currently executing
453  Fw::Time currentStatementDispatchTime = Fw::Time();
454 
455  // the absolute time we should wait for until returning
456  // a statement response
457  Fw::Time wakeupTime = Fw::Time();
458 
459  // all the local variables in the sequence
460  struct LocalVariable {
461  // the value buffer of the lvar
463  // the size of the data in the lvar buf
465  } localVariables[Fpy::MAX_SEQUENCE_LOCAL_VARIABLES] = {};
466  } m_runtime;
467 
468  // the state of the debugger. debugger is separate from runtime
469  // because it can be set up before running the sequence.
470  struct Debug {
471  // whether or not to break at the debug breakpoint index
472  bool breakOnBreakpoint = false;
473  // whether or not to remove the breakpoint after breaking on it
474  bool breakOnlyOnceOnBreakpoint = false;
475  // the statement index at which to break, before dispatching
476  U32 breakpointIndex = 0;
477  } m_debug;
478 
479  struct Telemetry {
480  // the number of statements that failed to execute
481  U64 statementsFailed = 0;
482 
483  // the number of sequences successfully completed
484  U64 sequencesSucceeded = 0;
485 
486  // the number of sequences that failed to validate or execute
487  U64 sequencesFailed = 0;
488 
489  // the number of sequences that have been cancelled
490  U64 sequencesCancelled = 0;
491  } m_tlm;
492 
493  // ----------------------------------------------------------------------
494  // Validation state
495  // ----------------------------------------------------------------------
496 
497  static void updateCrc(U32& crc,
498  const U8* buffer,
499  FwSizeType bufferSize
500  );
501 
502  // loads the sequence in memory, and does header/crc/integrity checks.
503  // return success if sequence is valid
504  Fw::Success validate();
505  // reads and validates the header from the m_sequenceBuffer
506  // return success if header is valid
507  Fw::Success readHeader();
508  // reads and validates the body from the m_sequenceBuffer
509  // return success if body is valid
510  Fw::Success readBody();
511  // reads and validates the footer from the m_sequenceBuffer
512  // return success if footer is valid
513  Fw::Success readFooter();
514 
515  // reads some bytes from the open file into the m_sequenceBuffer.
516  // updates the CRC by default, but can be turned off if the contents
517  // aren't included in CRC.
518  // return success if successful
519  Fw::Success readBytes(Os::File& file, FwSizeType readLen, bool updateCrc = true);
520 
521  // ----------------------------------------------------------------------
522  // Run state
523  // ----------------------------------------------------------------------
524 
525  // dispatches the next statement
526  Signal dispatchStatement();
527 
528  // dispatches a command out via port.
529  // return success if successfully dispatched.
530  Fw::Success dispatchCommand(const Fpy::Statement& stmt);
531 
532  // deserializes a directive from bytes into the Fpy type
533  // returns success if able to deserialize, and returns the Fpy type object
534  // as a reference, in a union of all the possible directive type objects
535  Fw::Success deserializeDirective(const Fpy::Statement& stmt, DirectiveUnion& deserializedDirective);
536 
537  // dispatches a deserialized sequencer directive to the right handler.
538  // return success if successfully handled.
539  void dispatchDirective(const DirectiveUnion& directive, const Fpy::DirectiveId& id);
540 
541  // checks whether the currently executing statement timed out
542  Signal checkStatementTimeout();
543 
544  // checks whether the sequencer should wake from sleeping
545  Signal checkShouldWake();
546 
547  // return true if state is a substate of RUNNING
548  bool isRunningState(State state);
549 
550  // return a struct containing debug telemetry, or defaults if not in debug break
551  FpySequencer_DebugTelemetry getDebugTelemetry();
552 
553  // ----------------------------------------------------------------------
554  // Directives
555  // ----------------------------------------------------------------------
556 
557  // sends a signal based on a signal id
558  void sendSignal(Signal signal);
559 
560  // we split these functions up into the internalInterfaceInvoke and these custom member funcs
561  // so that we can unit test them easier
562  Signal waitRel_directiveHandler(const FpySequencer_WaitRelDirective& directive);
563  Signal waitAbs_directiveHandler(const FpySequencer_WaitAbsDirective& directive);
564  Signal setLocalVar_directiveHandler(const FpySequencer_SetLocalVarDirective& directive);
565  Signal goto_directiveHandler(const FpySequencer_GotoDirective& directive);
566  Signal if_directiveHandler(const FpySequencer_IfDirective& directive);
567  Signal noOp_directiveHandler(const FpySequencer_NoOpDirective& directive);
568  Signal getTlm_directiveHandler(const FpySequencer_GetTlmDirective& directive);
569  Signal getPrm_directiveHandler(const FpySequencer_GetPrmDirective& directive);
570 };
571 
572 } // namespace Svc
573 
574 #endif
Definition: Time.hpp:9
void directive_if_internalInterfaceHandler(const Svc::FpySequencer_IfDirective &directive) override
Internal interface handler for directive_if.
PlatformSizeType FwSizeType
FpySequencer_GotoDirective gotoDirective
I32 FwEnumStoreType
bool Svc_FpySequencer_SequencerStateMachine_guard_goalStateIs_RUNNING(SmId smId, Svc_FpySequencer_SequencerStateMachine::Signal signal) const override
void pingIn_handler(FwIndexType portNum, U32 key) override
Handler for input port pingIn.
void directive_getPrm_internalInterfaceHandler(const Svc::FpySequencer_GetPrmDirective &directive) override
Internal interface handler for directive_getPrm.
FpySequencer_WaitRelDirective waitRel
FpySequencer_WaitAbsDirective waitAbs
Enum representing a command response.
void directive_getTlm_internalInterfaceHandler(const Svc::FpySequencer_GetTlmDirective &directive) override
Internal interface handler for directive_getTlm.
FpySequencer_IfDirective ifDirective
FpySequencer_NoOpDirective noOp
void seqRunIn_handler(FwIndexType portNum, const Fw::StringBase &filename) override
Handler for input port seqRunIn.
void directive_waitRel_internalInterfaceHandler(const FpySequencer_WaitRelDirective &directive) override
Internal interface handler for directive_waitRel.
void directive_noOp_internalInterfaceHandler(const Svc::FpySequencer_NoOpDirective &directive) override
Internal interface handler for directive_noOp.
void parametersLoaded() override
Called whenever parameters are loaded.
U32 FwOpcodeType
The type of a command opcode.
void tlmWrite_handler(FwIndexType portNum, U32 context) override
Handler for input port tlmWrite.
FpySequencer_SetLocalVarDirective setLVar
U8 value[Fpy::MAX_LOCAL_VARIABLE_BUFFER_SIZE]
External serialize buffer with no copy semantics.
#define FW_TLM_BUFFER_MAX_SIZE
Definition: FpConfig.h:224
FpySequencer_SequencerStateMachineStateMachineBase::State State
void directive_waitAbs_internalInterfaceHandler(const FpySequencer_WaitAbsDirective &directive) override
Internal interface handler for directive_waitAbs.
void parameterUpdated(FwPrmIdType id) override
Called whenever a parameter is updated.
void directive_goto_internalInterfaceHandler(const Svc::FpySequencer_GotoDirective &directive) override
Internal interface handler for directive_goto.
#define FW_PARAM_BUFFER_MAX_SIZE
Definition: FpConfig.h:239
void allocateBuffer(FwEnumStoreType identifier, Fw::MemAllocator &allocator, FwSizeType bytes)
U32 FwPrmIdType
The type of a parameter identifier.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:56
FpySequencer_GetPrmDirective getPrm
void cmdResponseIn_handler(FwIndexType portNum, FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdResponse &response) override
Handler for input port cmdResponseIn.
void checkTimers_handler(FwIndexType portNum, U32 context) override
Handler for input port checkTimers.
PlatformIndexType FwIndexType
FpySequencer_GetTlmDirective getTlm
RateGroupDivider component implementation.
Defines a base class for a memory allocator for classes.
void directive_setLocalVar_internalInterfaceHandler(const FpySequencer_SetLocalVarDirective &directive) override
Internal interface handler for directive_setLocalVar.
Declares F Prime string base class.
void deallocateBuffer(Fw::MemAllocator &allocator)
Auto-generated base for FpySequencer component.
FpySequencer_SequencerStateMachineStateMachineBase::Signal Signal
Success/Failure.
bool Svc_FpySequencer_SequencerStateMachine_guard_shouldDebugBreak(SmId smId, Svc_FpySequencer_SequencerStateMachine::Signal signal) const override
bool Svc_FpySequencer_SequencerStateMachine_guard_debugBreakOnce(SmId smId, Svc_FpySequencer_SequencerStateMachine::Signal signal) const override
FpySequencer(const char *const compName)
#define U64(C)
Definition: sha.h:180