F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
FpySequencerRunState.cpp
Go to the documentation of this file.
1 #include "Fw/Com/ComPacket.hpp"
2 #include "Fw/Time/Time.hpp"
5 namespace Svc {
6 
7 Signal FpySequencer::dispatchStatement() {
8  if (this->m_runtime.nextStatementIndex == this->m_sequenceObj.getheader().getstatementCount()) {
10  }
11 
12  // check to make sure no array out of bounds
13  FW_ASSERT(this->m_runtime.nextStatementIndex < this->m_sequenceObj.getheader().getstatementCount());
14 
15  const Fpy::Statement& nextStatement = this->m_sequenceObj.getstatements()[this->m_runtime.nextStatementIndex];
16  this->m_runtime.nextStatementIndex++;
17  this->m_runtime.currentStatementOpcode = nextStatement.getopCode();
18  this->m_runtime.currentStatementType = nextStatement.gettype();
19 
20  Fw::Success result;
21 
22  // based on the statement type (directive or cmd)
23  // send it to where it needs to go
24  if (nextStatement.gettype() == Fpy::StatementType::DIRECTIVE) {
25  result = this->dispatchDirective(nextStatement);
26  } else {
27  result = this->dispatchCommand(nextStatement);
28  }
29 
30  this->m_statementsDispatched++;
31 
32  if (result == Fw::Success::SUCCESS) {
34  } else {
36  }
37 }
38 
39 // dispatches a command out via port.
40 // return true if successfully dispatched.
41 Fw::Success FpySequencer::dispatchCommand(const Fpy::Statement& stmt) {
42  Fw::ComBuffer cmdBuf;
45  this->log_WARNING_HI_CommandSerializeError(stmt.getopCode(), cmdBuf.getBuffCapacity(), cmdBuf.getBuffLength(),
46  sizeof(Fw::ComPacket::FW_PACKET_COMMAND), stat, this->m_runtime.nextStatementIndex - 1);
47  return Fw::Success::FAILURE;
48  }
49  stat = cmdBuf.serialize(stmt.getopCode());
51  this->log_WARNING_HI_CommandSerializeError(stmt.getopCode(), cmdBuf.getBuffCapacity(), cmdBuf.getBuffLength(), sizeof(stmt.getopCode()),
52  stat, this->m_runtime.nextStatementIndex - 1);
53  return Fw::Success::FAILURE;
54  }
55  stat = cmdBuf.serialize(stmt.getargBuf().getBuffAddr(), stmt.getargBuf().getBuffLength(), true);
57  this->log_WARNING_HI_CommandSerializeError(stmt.getopCode(), cmdBuf.getBuffCapacity(), cmdBuf.getBuffLength(),
58  stmt.getargBuf().getBuffLength(), stat, this->m_runtime.nextStatementIndex - 1);
59  return Fw::Success::FAILURE;
60  }
61 
62  // calculate the unique command identifier:
63  // cmd UID is formatted like XXYY, where XX are the first two bytes of the m_sequencesStarted counter
64  // and YY are the first two bytes of the m_statementsDispatched counter.
65  // this way, we know when we get a cmd back A) whether or not it's from this sequence (modulo 2^16) and B)
66  // whether or not it's this specific instance of the cmd in the sequence, and not another one with the same opcode
67  // somewhere else in the file.
68  // if we put this uid in the context we send to the cmdDisp, we will get it back when the cmd returns
69  U32 cmdUid = static_cast<U32>(((this->m_sequencesStarted & 0xFFFF) << 16) | (this->m_statementsDispatched & 0xFFFF));
70 
71  // little note--theoretically this could produce a cmdResponse before we send the
72  // dispatchSuccess signal. however b/c of priorities the dispatchSuccess signal will
73  // always get processed first, leaving us in the right state for the cmdresponse
74  this->cmdOut_out(0, cmdBuf, cmdUid);
75 
76  return Fw::Success::SUCCESS;
77 }
78 
79 Fw::Success FpySequencer::dispatchDirective(const Fpy::Statement& stmt) {
80  Fw::SerializeStatus status;
81  // make our own esb so we can deser from stmt without breaking its constness
82  Fw::ExternalSerializeBuffer argBuf(const_cast<U8*>(stmt.getargBuf().getBuffAddr()),
83  stmt.getargBuf().getBuffLength());
84  argBuf.setBuffLen(stmt.getargBuf().getBuffLength());
85 
86  switch (stmt.getopCode()) {
88  FpySequencer_WaitRelDirective directive;
89  status = argBuf.deserialize(directive);
90  if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
91  this->log_WARNING_HI_DirectiveDeserializeError(stmt.getopCode(), this->m_runtime.nextStatementIndex - 1, status, argBuf.getBuffLeft(),
92  argBuf.getBuffLength());
93  return Fw::Success::FAILURE;
94  }
96  break;
97  }
99  FpySequencer_WaitAbsDirective directive;
100  status = argBuf.deserialize(directive);
101  if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
102  this->log_WARNING_HI_DirectiveDeserializeError(stmt.getopCode(), this->m_runtime.nextStatementIndex - 1, status, argBuf.getBuffLeft(),
103  argBuf.getBuffLength());
104  return Fw::Success::FAILURE;
105  }
107  break;
108  }
109  default: {
110  // unsure what this opcode is. check compiler version matches sequencer
111  this->log_WARNING_HI_UnknownSequencerDirective(stmt.getopCode(), this->m_runtime.nextStatementIndex - 1, this->m_sequenceFilePath);
112  return Fw::Success::FAILURE;
113  }
114  }
115  return Fw::Success::SUCCESS;
116 }
117 
118 Signal FpySequencer::checkShouldWake() {
119  Fw::Time currentTime = this->getTime();
120 
121 #ifdef FW_USE_TIME_BASE
122  if (currentTime.getTimeBase() != this->m_runtime.wakeupTime.getTimeBase()) {
123  // cannot compare these times.
124  this->log_WARNING_HI_MismatchedTimeBase(currentTime.getTimeBase(), this->m_runtime.wakeupTime.getTimeBase());
125 
127  }
128 #endif
129 
130 #ifdef FW_USE_TIME_CONTEXT
131  if (currentTime.getContext() != this->m_runtime.wakeupTime.getContext()) {
132  // cannot compare these times.
133  this->log_WARNING_HI_MismatchedTimeContext(currentTime.getContext(), this->m_runtime.wakeupTime.getContext());
134 
136  }
137 #endif
138 
139  if (currentTime < this->m_runtime.wakeupTime) {
140  // not time to wake up!
142  }
143 
144  // say we've finished our sleep
146 }
147 
148 // checks whether the currently executing statement timed out
149 Signal FpySequencer::checkStatementTimeout() {
150  Fw::ParamValid valid;
151  F32 timeout = this->paramGet_STATEMENT_TIMEOUT_SECS(valid);
152  if (timeout <= 0 || timeout > static_cast<F32>(std::numeric_limits<U32>::max())) {
153  // no timeout
155  }
156 
157  Fw::Time currentTime = getTime();
158 
159 #ifdef FW_USE_TIME_BASE
160  if (currentTime.getTimeBase() != this->m_runtime.currentStatementDispatchTime.getTimeBase()) {
161  // can't compare time base. must have changed
163  this->m_runtime.currentStatementDispatchTime.getTimeBase());
165  }
166 #endif
167 #ifdef FW_USE_TIME_CONTEXT
168  if (currentTime.getContext() != this->m_runtime.currentStatementDispatchTime.getContext()) {
169  // can't compare time ctx. must have changed
171  this->m_runtime.currentStatementDispatchTime.getContext());
173  }
174 #endif
175 
176  if (this->m_runtime.currentStatementDispatchTime.getSeconds() > currentTime.getSeconds()) {
177  // somehow we've gone back in time... just ignore it and move on. should get fixed
178  // if we wait I guess
180  }
181 
182  if (this->m_runtime.currentStatementDispatchTime.getSeconds() == currentTime.getSeconds() &&
183  this->m_runtime.currentStatementDispatchTime.getUSeconds() > currentTime.getUSeconds()) {
184  // same as above
186  }
187 
188  U64 currentUSeconds = currentTime.getSeconds() * 1000000 + currentTime.getUSeconds();
189  U64 dispatchUSeconds = this->m_runtime.currentStatementDispatchTime.getSeconds() * 1000000 +
190  this->m_runtime.currentStatementDispatchTime.getUSeconds();
191 
192  U64 timeoutUSeconds = static_cast<U64>(timeout * 1000000.0f);
193 
194  if (currentUSeconds - dispatchUSeconds < timeoutUSeconds) {
195  // not over timeout
197  }
198 
199  this->log_WARNING_HI_StatementTimedOut(this->m_runtime.currentStatementType,
200  this->m_runtime.currentStatementOpcode,
201  this->m_runtime.nextStatementIndex - 1,
202  this->m_sequenceFilePath);
204 }
205 
206 } // namespace Svc
Serialization/Deserialization operation was successful.
called in dispatchStatement method when a statement was unable to be sent out
Definition: Time.hpp:9
FwSizeType getBuffCapacity() const
returns capacity, not current size, of buffer
Definition: ComBuffer.cpp:32
called in dispatchStatement method when there were no more statements in the sequence ...
Representing success.
SerializeStatus serialize(U8 val)
serialize 8-bit unsigned int
TimeBase getTimeBase() const
Definition: Time.cpp:143
SerializeStatus
forward declaration for string
float F32
32-bit floating point
Definition: BasicTypes.h:86
void log_WARNING_HI_StatementTimedOut(Svc::Fpy::StatementType stmtType, U32 stmtOpcode, U32 stmtIdx, const Fw::StringBase &filePath) const
Log event StatementTimedOut.
Serializable::SizeType getBuffLength() const
returns current buffer size
called in dispatchStatement method when a statement was successfully dispatched
F32 paramGet_STATEMENT_TIMEOUT_SECS(Fw::ParamValid &valid)
External serialize buffer with no copy semantics.
U32 getSeconds() const
Definition: Time.cpp:135
void directive_waitAbs_internalInterfaceInvoke(const Svc::FpySequencer_WaitAbsDirective &directive)
Internal interface base-class function for directive_waitAbs.
void log_WARNING_HI_DirectiveDeserializeError(U32 opcode, U32 stmtIdx, I32 errorCode, U64 buffLeft, U64 buffLength) const
Log event DirectiveDeserializeError.
Representing failure.
void log_WARNING_HI_CommandSerializeError(U32 cmdOpcode, U64 bufCapacity, U64 curPos, U64 writeSize, U8 errorCode, U32 stmtIdx) const
Log event CommandSerializeError.
Type_of_statements & getstatements()
Get member statements.
FwTimeContextStoreType getContext() const
Definition: Time.cpp:147
U32 getUSeconds() const
Definition: Time.cpp:139
void log_WARNING_HI_MismatchedTimeContext(I32 internalTimeContext, I32 otherTimeContext) const
Log event MismatchedTimeContext.
void cmdOut_out(FwIndexType portNum, Fw::ComBuffer &data, U32 context)
Invoke output port cmdOut.
RateGroupDivider component implementation.
Enum representing parameter validity.
void log_WARNING_HI_MismatchedTimeBase(I32 internalTimeBase, I32 otherTimeBase) const
Log event MismatchedTimeBase.
void directive_waitRel_internalInterfaceInvoke(const Svc::FpySequencer_WaitRelDirective &directive)
Internal interface base-class function for directive_waitRel.
void log_WARNING_HI_UnknownSequencerDirective(U32 opcode, U32 stmtIdx, const Fw::StringBase &filePath) const
Log event UnknownSequencerDirective.
FpySequencer_SequencerStateMachineStateMachineBase::Signal Signal
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Success/Failure.
SerializeStatus setBuffLen(Serializable::SizeType length)
sets buffer length manually after filling with data
#define U64(C)
Definition: sha.h:180