F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
FpySequencerStateMachine.cpp
Go to the documentation of this file.
1 #include <new>
3 namespace Svc {
4 
5 // ----------------------------------------------------------------------
6 // Functions to implement for internal state machine actions
7 // ----------------------------------------------------------------------
8 
12 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_signalEntered(
13  SmId smId,
15 ) {
17 }
18 
25 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_setSequenceFilePath(
26  SmId smId,
29 ) {
30  Fw::ParamValid valid;
31  Fw::ParamString baseDir = this->paramGet_SEQ_BASE_DIR(valid);
32  if (baseDir.length() == 0) {
33  // the assignment here ensures the string is null terminated
34  // because it uses the string_copy method
35  // also, the filePath string in SequenceExecutionArgs is guaranteed
36  // to be truncated to FileNameStringSize chars, so it will not
37  // be truncated by this assignment
38  this->m_sequenceFilePath = value.get_filePath();
39  return;
40  }
41 
42  Fw::FormatStatus status;
43  // the result will get truncated to FileNameStringSize
44  status = this->m_sequenceFilePath.format("%s/%s", baseDir.toChar(), value.get_filePath().toChar());
45  if (status == Fw::FormatStatus::SUCCESS) {
46  return;
47  }
48 
49  // the only runtime-reachable non-success status is OVERFLOWED, which means the
50  // base dir and file name together are longer than the sequence file path buffer.
51  // the other statuses can only result from a bad format string literal, which is a
52  // coding error. let the user know the path was truncated; validate() will then fail
53  // to open the (truncated) path and report a FileOpenError.
54  FW_ASSERT(status == Fw::FormatStatus::OVERFLOWED, static_cast<I32>(status));
56 }
57 
62 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_setSequenceBlockState(
63  SmId smId,
66 ) {
67  this->m_sequenceBlockState = value.get_block();
68 }
69 
74 void FpySequencer ::Svc_FpySequencer_SequencerStateMachine_action_setSequenceArguments(
75  SmId smId,
78  this->m_sequenceArgs = value.get_buffer();
79 }
80 
85 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_report_seqSucceeded(
86  SmId smId,
88 ) {
89  this->m_tlm.sequencesSucceeded++;
90  this->log_ACTIVITY_HI_SequenceDone(this->m_sequenceFilePath);
91  this->m_sequenceFilePath = NO_SEQ;
92  if (this->isConnected_seqDoneOut_OutputPort(0)) {
93  // report that the sequence succeeded to internal callers
94  this->seqDoneOut_out(0, 0, 0, Fw::CmdResponse::OK);
95  }
96 }
97 
102 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_report_seqCancelled(
103  SmId smId,
105 ) {
106  this->m_tlm.sequencesCancelled++;
107  this->log_ACTIVITY_HI_SequenceCancelled(this->m_sequenceFilePath);
108  if (this->isConnected_seqDoneOut_OutputPort(0)) {
109  // report that the sequence failed to internal callers
111  }
112 }
113 
118 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_dispatchStatement(
119  SmId smId,
121 ) {
122  Signal result = this->dispatchStatement();
123  switch (result) {
126  break;
127  }
130  break;
131  }
134  break;
135  }
136  default: {
137  FW_ASSERT(false, static_cast<FwAssertArgType>(result));
138  }
139  }
140 }
141 
146 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_setGoalState_RUNNING(
147  SmId smId,
149 ) {
150  this->m_goalState = FpySequencer_GoalState::RUNNING;
151 }
152 
157 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_setGoalState_VALID(
158  SmId smId,
160 ) {
161  this->m_goalState = FpySequencer_GoalState::VALID;
162 }
163 
168 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_setGoalState_IDLE(
169  SmId smId,
171 ) {
172  this->m_goalState = FpySequencer_GoalState::IDLE;
173 }
174 
179 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_sendCmdResponse_OK(
180  SmId smId,
182 ) {
183  if (this->m_sequenceBlockState == BlockState::BLOCK) {
184  // respond if we were waiting on a response
185  this->cmdResponse_out(this->m_savedOpCode, this->m_savedCmdSeq, Fw::CmdResponse::OK);
186  }
187 }
188 
193 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_sendCmdResponse_EXECUTION_ERROR(
194  SmId smId,
196 ) {
197  if (this->m_sequenceBlockState == BlockState::BLOCK) {
198  // respond if we were waiting on a response
199  this->cmdResponse_out(this->m_savedOpCode, this->m_savedCmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
200  }
201 }
202 
207 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_resetRuntime(
208  SmId smId,
210 ) {
211  // explicitly call dtor
212  this->m_runtime.~Runtime();
213  new (&this->m_runtime) Runtime();
214 }
215 
221 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_validate(
222  SmId smId,
224 ) {
225  Fw::Success result = this->validate();
226  FW_ASSERT(result == Fw::Success::SUCCESS || result == Fw::Success::FAILURE, static_cast<FwAssertArgType>(result));
227  if (result == Fw::Success::FAILURE) {
229  return;
230  }
232 }
233 
237 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_checkShouldWake(
238  SmId smId,
240 ) {
241  Signal result = this->checkShouldWake();
242  switch (result) {
245  break;
246  }
249  break;
250  }
253  break;
254  }
255  default: {
256  FW_ASSERT(false, static_cast<FwAssertArgType>(result));
257  }
258  }
259 }
260 
264 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_checkStatementTimeout(
265  SmId smId,
267 ) {
268  Signal result = this->checkStatementTimeout();
269  switch (result) {
272  break;
273  }
276  break;
277  }
280  break;
281  }
282  default: {
283  FW_ASSERT(false, static_cast<FwAssertArgType>(result));
284  }
285  }
286 }
287 
291 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_incrementSequenceCounter(
292  SmId smId,
294 ) {
295  this->m_sequencesStarted++;
296 }
297 
301 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_pushArgsToStack(
302  SmId smId,
304 ) {
305  const Svc::SeqArgs& args = this->m_sequenceArgs;
306 
307  // Early return if no arguments provided
308  if (args.get_size() == 0) {
309  return;
310  }
311 
312  // Push args buffer to stack. Args are already serialized in big-endian format
313  // by F' serialization system, so no endianness conversion is needed.
314  this->m_runtime.stack.push(args.get_buffer(), static_cast<Fpy::StackSizeType>(args.get_size()));
315 }
316 
320 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_clearSequenceFile(
321  SmId smId,
323 ) {
324  this->m_sequenceFilePath = "";
325 }
326 
330 void FpySequencer ::Svc_FpySequencer_SequencerStateMachine_action_clearSequenceArguments(
331  SmId smId,
333  this->m_sequenceArgs = {0, 0};
334 }
335 
339 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_clearBreakpoint(
340  SmId smId,
342 ) {
343  this->m_breakpoint.breakpointInUse = false;
344  this->m_breakpoint.breakpointIndex = 0;
345  this->m_breakpoint.breakOnlyOnceOnBreakpoint = false;
346  this->m_breakpoint.breakBeforeNextLine = false;
347 }
348 
352 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_report_seqBroken(
353  SmId smId,
355 ) {
356  this->log_ACTIVITY_HI_SequencePaused(this->m_runtime.nextStatementIndex);
357 }
358 
362 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_setBreakpoint(
363  SmId smId,
366 ) {
367  this->m_breakpoint.breakpointInUse = value.get_breakOnBreakpoint();
368  this->m_breakpoint.breakOnlyOnceOnBreakpoint = value.get_breakOnlyOnceOnBreakpoint();
369  this->m_breakpoint.breakpointIndex = value.get_breakpointIndex();
371 }
372 
376 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_setBreakBeforeNextLine(
377  SmId smId,
379 ) {
380  this->m_breakpoint.breakBeforeNextLine = true;
381 }
382 
386 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_clearBreakBeforeNextLine(
387  SmId smId,
389 ) {
390  this->m_breakpoint.breakBeforeNextLine = false;
391 }
392 
396 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_report_seqFailed(
397  SmId smId,
399 ) {
400  if (this->isConnected_seqDoneOut_OutputPort(0)) {
401  // report that the sequence failed to internal callers
403  }
404 }
405 
409 void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_report_seqStarted(
410  SmId smId,
412 ) {
413  if (this->isConnected_seqStartOut_OutputPort(0)) {
414  // report that the sequence started to internal callers
415  // NOTE: Sequence Arguments would be cleared if a VALIDATION command is sent, not a full RUN command.
416  this->seqStartOut_out(0, this->m_sequenceFilePath, this->m_sequenceArgs);
417  }
418 }
419 // ----------------------------------------------------------------------
420 // Functions to implement for internal state machine guards
421 // ----------------------------------------------------------------------
422 
428  SmId smId,
430 ) const {
431  return this->m_goalState == FpySequencer_GoalState::RUNNING;
432 }
433 
439  SmId smId,
441 ) const {
442  // there are really two mechanisms for pausing the execution of the seq
443  // one is the "break on next line flag", and the other is the breakpoint
444  return this->m_breakpoint.breakBeforeNextLine ||
445  (this->m_breakpoint.breakpointInUse &&
446  this->m_breakpoint.breakpointIndex == this->m_runtime.nextStatementIndex);
447 }
448 
453  SmId smId,
455 ) const {
456  return this->m_breakpoint.breakOnlyOnceOnBreakpoint;
457 }
458 } // namespace Svc
void sequencer_sendSignal_result_dispatchStatement_noMoreStatements()
Send signal result_dispatchStatement_noMoreStatements to state machine sequencer. ...
void sequencer_sendSignal_result_checkShouldWake_keepSleeping()
Send signal result_checkShouldWake_keepSleeping to state machine sequencer.
called in dispatchStatement method when a statement was unable to be sent out
void log_ACTIVITY_HI_SequencePaused(U32 stmtIdx) const
Log event SequencePaused.
called in dispatchStatement method when there were no more statements in the sequence ...
U32 get_breakpointIndex() const
Get member breakpointIndex.
Representing success.
void sequencer_sendSignal_result_dispatchStatement_success()
Send signal result_dispatchStatement_success to state machine sequencer.
bool Svc_FpySequencer_SequencerStateMachine_guard_goalStateIs_RUNNING(SmId smId, Svc_FpySequencer_SequencerStateMachine::Signal signal) const override
void sequencer_sendSignal_result_checkShouldWake_wakeup()
Send signal result_checkShouldWake_wakeup to state machine sequencer.
void log_WARNING_HI_SequenceFilePathTooLong(const Fw::StringBase &baseDir, const Fw::StringBase &fileName) const
Log event SequenceFilePathTooLong.
Format overflowed.
void sequencer_sendSignal_result_success()
Send signal result_success to state machine sequencer.
void sequencer_sendSignal_result_dispatchStatement_failure()
Send signal result_dispatchStatement_failure to state machine sequencer.
called in dispatchStatement method when a statement was successfully dispatched
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
Type_of_buffer & get_buffer()
Get member buffer.
const char * toChar() const
bool Svc_FpySequencer_SequencerStateMachine_guard_shouldBreak(SmId smId, Svc_FpySequencer_SequencerStateMachine::Signal signal) const override
const char * toChar() const
Convert to a C-style char*.
void sequencer_sendSignal_result_checkStatementTimeout_noTimeout()
Send signal result_checkStatementTimeout_noTimeout to state machine sequencer.
FwSizeType get_size() const
Get member size.
Representing failure.
FormatStatus format(const CHAR *formatString,...)
write formatted string to buffer
Definition: StringBase.cpp:58
Command successfully executed.
void seqDoneOut_out(FwIndexType portNum, FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdResponse &response) const
Invoke output port seqDoneOut.
void log_ACTIVITY_HI_BreakpointSet(U32 breakpointIdx, bool breakOnce) const
Log event BreakpointSet.
void sequencer_sendSignal_result_timeOpFailed()
Send signal result_timeOpFailed to state machine sequencer.
Command had execution error.
void sequencer_sendSignal_result_checkStatementTimeout_statementTimeout()
Send signal result_checkStatementTimeout_statementTimeout to state machine sequencer.
void log_ACTIVITY_HI_SequenceCancelled(const Fw::StringBase &filePath) const
Log event SequenceCancelled.
Fw::ParamString paramGet_SEQ_BASE_DIR(Fw::ParamValid &valid)
bool Svc_FpySequencer_SequencerStateMachine_guard_breakOnce(SmId smId, Svc_FpySequencer_SequencerStateMachine::Signal signal) const override
RateGroupDivider component implementation.
virtual SizeType length() const
Get the length of the string.
Enum representing parameter validity.
void sequencer_sendSignal_result_failure()
Send signal result_failure to state machine sequencer.
bool isConnected_seqStartOut_OutputPort(FwIndexType portNum) const
void seqStartOut_out(FwIndexType portNum, const Fw::StringBase &filename, const Svc::SeqArgs &args) const
Invoke output port seqStartOut.
void sequencer_sendSignal_entered()
Send signal entered to state machine sequencer.
bool get_breakOnlyOnceOnBreakpoint() const
Get member breakOnlyOnceOnBreakpoint.
void log_ACTIVITY_HI_SequenceDone(const Fw::StringBase &filePath) const
Log event SequenceDone.
bool get_breakOnBreakpoint() const
Get member breakOnBreakpoint.
FpySequencer_SequencerStateMachineStateMachineBase::Signal Signal
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Success/Failure.
bool isConnected_seqDoneOut_OutputPort(FwIndexType portNum) const
U32 StackSizeType
the type which everything referencing a size or offset on the stack is represented in ...
FormatStatus
status of string format calls
Definition: format.hpp:18