F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
CmdSequencerImpl.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title CmdSequencerImpl.cpp
3 // \author Bocchino/Canham
4 // \brief cpp file for CmdDispatcherComponentBase component implementation class
5 //
6 // Copyright (C) 2009-2018 California Institute of Technology.
7 // ALL RIGHTS RESERVED. United States Government Sponsorship
8 // acknowledged.
9 
10 #include <Fw/Com/ComPacket.hpp>
11 #include <Fw/Types/Assert.hpp>
15 #include <Utils/Hash/Hash.hpp>
16 #include <config/CommandDispatcherImplCfg.hpp>
17 
18 namespace Svc {
19 
20 // ----------------------------------------------------------------------
21 // Construction, initialization, and destruction
22 // ----------------------------------------------------------------------
23 
26  m_FPrimeSequence(*this),
27  m_sequence(&this->m_FPrimeSequence),
28  m_loadCmdCount(0),
29  m_cancelCmdCount(0),
30  m_errorCount(0),
31  m_runMode(STOPPED),
32  m_stepMode(AUTO),
33  m_executedCount(0),
34  m_totalExecutedCount(0),
35  m_sequencesCompletedCount(0),
36  m_timeout(0),
37  m_blockState(Svc::BlockState::NO_BLOCK),
38  m_opCode(0),
39  m_cmdSeq(0),
40  m_join_waiting(false) {}
41 
42 void CmdSequencerComponentImpl::setTimeout(const U32 timeout) {
43  this->m_timeout = timeout;
44 }
45 
47  this->m_sequence = &sequence;
48 }
49 
51  Fw::MemAllocator& allocator,
52  const FwSizeType bytes) {
53  this->m_sequence->allocateBuffer(identifier, allocator, bytes);
54 }
55 
57  FW_ASSERT(this->m_runMode == STOPPED, this->m_runMode);
58  if (not this->loadFile(fileName)) {
59  this->m_sequence->clear();
60  }
61 }
62 
64  this->m_sequence->deallocateBuffer(allocator);
65 }
66 
68 
69 // ----------------------------------------------------------------------
70 // Handler implementations
71 // ----------------------------------------------------------------------
72 
73 void CmdSequencerComponentImpl::CS_RUN_cmdHandler(FwOpcodeType opCode,
74  U32 cmdSeq,
75  const Fw::CmdStringArg& fileName,
76  const Svc::BlockState& block) {
77  if (not this->requireRunMode(STOPPED)) {
78  if (m_join_waiting) {
79  // Inform user previous seq file is not complete
81  }
83  return;
84  }
85 
86  if ((Svc::BlockState::BLOCK == block.e) && (MANUAL == this->m_stepMode)) {
87  // In MANUAL mode nothing executes until CS_STEP, so a BLOCK response could never be sent
90  return;
91  }
92 
93  this->m_blockState = block.e;
94  this->m_cmdSeq = cmdSeq;
95  this->m_opCode = opCode;
96 
97  // load commands
98  if (not this->loadFile(fileName)) {
99  // Clear the recorded command state so a later port-driven run cannot
100  // emit a duplicate response for this already-answered command
101  this->m_blockState = Svc::BlockState::NO_BLOCK;
102  this->m_opCode = 0;
103  this->m_cmdSeq = 0;
104  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
105  return;
106  }
107 
108  this->m_executedCount = 0;
109 
110  // Check the step mode. If it is auto, start the sequence
111  if (AUTO == this->m_stepMode) {
112  this->m_runMode = RUNNING;
113  this->tlmWrite_CS_CurrentSequence(this->m_sequence->getStringFileName());
114  if (this->isConnected_seqStartOut_OutputPort(0)) {
115  // Create empty SeqArgs as placeholder
116  // Use parameterized constructor to ensure m_size is initialized to 0
117  Svc::SeqArgs emptyArgs{0, 0};
118  this->seqStartOut_out(0, this->m_sequence->getStringFileName(), emptyArgs);
119  }
120  this->performCmd_Step();
121  }
122 
123  if (Svc::BlockState::NO_BLOCK == this->m_blockState) {
124  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
125  }
126 }
127 
128 void CmdSequencerComponentImpl::CS_VALIDATE_cmdHandler(FwOpcodeType opCode,
129  U32 cmdSeq,
130  const Fw::CmdStringArg& fileName) {
131  FW_ASSERT(this->m_sequence != nullptr);
132  if (!this->requireRunMode(STOPPED)) {
133  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
134  return;
135  }
136 
137  // load commands
138  if (not this->loadFile(fileName)) {
139  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
140  return;
141  }
142 
143  // clear the buffer
144  this->m_sequence->clear();
145 
146  this->log_ACTIVITY_HI_CS_SequenceValid(this->m_sequence->getLogFileName());
147 
148  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
149 }
150 
152 void CmdSequencerComponentImpl::doSequenceRun(const Fw::StringBase& filename) {
153  if (MANUAL == this->m_stepMode) {
154  // In MANUAL mode nothing executes until CS_STEP, so a port-driven run would wedge
157  return;
158  }
159  if (!this->requireRunMode(STOPPED)) {
161  return;
162  }
163 
164  // If file name is non-empty, load a file.
165  // Empty file name means don't load.
166  if (filename != "") {
167  Fw::CmdStringArg cmdStr(filename);
168  const bool status = this->loadFile(cmdStr);
169  if (!status) {
171  return;
172  }
173  } else if (not this->m_sequence->hasMoreRecords()) {
174  // No sequence loaded
176  this->error();
178  return;
179  }
180 
181  this->m_executedCount = 0;
182 
183  // Check the step mode. If it is auto, start the sequence
184  if (AUTO == this->m_stepMode) {
185  this->m_runMode = RUNNING;
186  this->tlmWrite_CS_CurrentSequence(this->m_sequence->getStringFileName());
187  if (this->isConnected_seqStartOut_OutputPort(0)) {
188  // Create empty SeqArgs as placeholder
189  // Use parameterized constructor to ensure m_size is initialized to 0
190  Svc::SeqArgs emptyArgs{0, 0};
191  this->seqStartOut_out(0, this->m_sequence->getStringFileName(), emptyArgs);
192  }
193  this->performCmd_Step();
194  }
195 
196  this->log_ACTIVITY_HI_CS_PortSequenceStarted(this->m_sequence->getLogFileName());
197 }
198 
199 void CmdSequencerComponentImpl::seqRunIn_handler(FwIndexType portNum,
200  const Fw::StringBase& filename,
201  const Svc::SeqArgs& args) {
202  (void)args; // Suppress unused parameter warning
203  this->doSequenceRun(filename);
204 }
205 
206 void CmdSequencerComponentImpl::seqDispatchIn_handler(FwIndexType portNum, Fw::StringBase& file_name) {
207  this->doSequenceRun(file_name);
208 }
209 
210 void CmdSequencerComponentImpl ::seqCancelIn_handler(const FwIndexType portNum) {
211  if (RUNNING == this->m_runMode) {
212  this->performCmd_Cancel();
213  this->log_ACTIVITY_HI_CS_SequenceCanceled(this->m_sequence->getLogFileName());
214  ++this->m_cancelCmdCount;
215  this->tlmWrite_CS_CancelCommands(this->m_cancelCmdCount);
216  } else {
218  }
219 }
220 
221 void CmdSequencerComponentImpl::CS_CANCEL_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
222  if (RUNNING == this->m_runMode) {
223  this->performCmd_Cancel();
224  this->log_ACTIVITY_HI_CS_SequenceCanceled(this->m_sequence->getLogFileName());
225  ++this->m_cancelCmdCount;
226  this->tlmWrite_CS_CancelCommands(this->m_cancelCmdCount);
227  } else {
229  }
230  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
231 }
232 
233 void CmdSequencerComponentImpl::CS_JOIN_WAIT_cmdHandler(const FwOpcodeType opCode, const U32 cmdSeq) {
234  // If there is no running sequence do not wait
235  if (m_runMode != RUNNING) {
237  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
238  return;
239  } else if ((Svc::BlockState::BLOCK == this->m_blockState) || this->m_join_waiting) {
240  // A command response is already owed to a BLOCK-mode CS_RUN caller or a
241  // previous CS_JOIN_WAIT caller. Reject rather than overwrite that state,
242  // which would leave the original caller without a completion response.
244  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
245  } else {
246  m_join_waiting = true;
247  Fw::LogStringArg& logFileName = this->m_sequence->getLogFileName();
248  this->log_ACTIVITY_HI_CS_JoinWaiting(logFileName, m_cmdSeq, CmdDispatcherCfg::getEventOpcode(m_opCode));
249  m_cmdSeq = cmdSeq;
250  m_opCode = opCode;
251  }
252 }
253 
254 // ----------------------------------------------------------------------
255 // Private helper methods
256 // ----------------------------------------------------------------------
257 
258 bool CmdSequencerComponentImpl ::loadFile(const Fw::ConstStringBase& fileName) {
259  const bool status = this->m_sequence->loadFile(fileName);
260  if (status) {
261  Fw::LogStringArg& logFileName = this->m_sequence->getLogFileName();
262  this->log_ACTIVITY_LO_CS_SequenceLoaded(logFileName);
263  ++this->m_loadCmdCount;
264  this->tlmWrite_CS_LoadCommands(this->m_loadCmdCount);
265  } else {
266  // A partial load may have populated m_buffer before an intermediate
267  // validation step (e.g. CRC, time, record structure) failed. Without
268  // an explicit reset, FPrimeSequence::hasMoreRecords() still returns
269  // true because getDeserializeSizeLeft() > 0, so a subsequent CS_START
270  // bypasses the "no sequence active" guard and reaches
271  // FPrimeSequence::nextRecord, which asserts on the failed deserialize
272  // and aborts the FSW. Clearing the sequence on every load failure
273  // closes that window.
274  this->m_sequence->clear();
275  }
276  return status;
277 }
278 
279 void CmdSequencerComponentImpl::error() {
280  ++this->m_errorCount;
281  this->tlmWrite_CS_Errors(m_errorCount);
282 }
283 
284 void CmdSequencerComponentImpl::performCmd_Cancel() {
285  FW_ASSERT(this->m_sequence != nullptr);
286  this->m_sequence->reset();
287  this->m_runMode = STOPPED;
288  this->m_cmdTimer.clear();
289  this->m_cmdTimeoutTimer.clear();
290  this->m_executedCount = 0;
291  // write sequence done port with error, if connected
292  if (this->isConnected_seqDone_OutputPort(0)) {
294  }
295 
296  if (Svc::BlockState::BLOCK == this->m_blockState || m_join_waiting) {
297  // Do not wait if sequence was canceled or a cmd failed
298  this->m_join_waiting = false;
299  this->cmdResponse_out(this->m_opCode, this->m_cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
300  }
301 
302  this->m_blockState = Svc::BlockState::NO_BLOCK;
303 }
304 
305 void CmdSequencerComponentImpl ::cmdResponseIn_handler(FwIndexType portNum,
306  FwOpcodeType opcode,
307  U32 cmdSeq,
308  const Fw::CmdResponse& response) {
309  if (this->m_runMode == STOPPED) {
310  // Sequencer is not running
312  } else {
313  // clear command timeout
314  this->m_cmdTimeoutTimer.clear();
315  if (response != Fw::CmdResponse::OK) {
316  this->commandError(this->m_executedCount, opcode, response.e);
317  this->performCmd_Cancel();
318  } else if (this->m_runMode == RUNNING && this->m_stepMode == AUTO) {
319  // Auto mode
320  this->commandComplete(opcode);
321  if (not this->m_sequence->hasMoreRecords()) {
322  // No data left
323  this->m_runMode = STOPPED;
324  this->sequenceComplete();
325  } else {
326  this->performCmd_Step();
327  }
328  } else {
329  // Manual step mode
330  this->commandComplete(opcode);
331  if (not this->m_sequence->hasMoreRecords()) {
332  this->m_runMode = STOPPED;
333  this->sequenceComplete();
334  }
335  }
336  }
337 }
338 
339 void CmdSequencerComponentImpl ::schedIn_handler(FwIndexType portNum, U32 order) {
340  Fw::Time currTime = this->getTime();
341  // check to see if a command time is pending
342  if (this->m_cmdTimer.isExpiredAt(currTime)) {
343  this->comCmdOut_out(0, m_record.m_command, 0);
344  this->m_cmdTimer.clear();
345  // start command timeout timer
346  this->setCmdTimeout(currTime);
347  } else if (this->m_cmdTimeoutTimer.isExpiredAt(this->getTime())) { // check for command timeout
348  this->log_WARNING_HI_CS_SequenceTimeout(m_sequence->getLogFileName(), this->m_executedCount);
349  // If there is a command timeout, cancel the sequence
350  this->performCmd_Cancel();
351  }
352 }
353 
354 void CmdSequencerComponentImpl ::CS_START_cmdHandler(FwOpcodeType opcode, U32 cmdSeq) {
355  if (not this->m_sequence->hasMoreRecords()) {
356  // No sequence loaded
358  this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
359  return;
360  }
361  if (!this->requireRunMode(STOPPED)) {
362  this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
363  return;
364  }
365 
366  this->m_blockState = Svc::BlockState::NO_BLOCK;
367  this->m_runMode = RUNNING;
368  this->tlmWrite_CS_CurrentSequence(this->m_sequence->getStringFileName());
369  this->log_ACTIVITY_HI_CS_CmdStarted(this->m_sequence->getLogFileName());
370  this->performCmd_Step();
371  if (this->isConnected_seqStartOut_OutputPort(0)) {
372  // Create empty SeqArgs as placeholder
373  Svc::SeqArgs emptyArgs{0, 0};
374  this->seqStartOut_out(0, this->m_sequence->getStringFileName(), emptyArgs);
375  }
376  this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::OK);
377 }
378 
379 void CmdSequencerComponentImpl ::CS_STEP_cmdHandler(FwOpcodeType opcode, U32 cmdSeq) {
380  FW_ASSERT(this->m_sequence != nullptr);
381  if (this->requireRunMode(RUNNING)) {
382  if (MANUAL != this->m_stepMode) {
383  // CS_STEP is valid only in MANUAL step mode
385  this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
386  return;
387  }
388  if (not this->m_sequence->hasMoreRecords()) {
389  // A sequence with no end-of-sequence record leaves nothing to step; stepping anyway
390  // asserts in the sequence reader
392  this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
393  return;
394  }
395  this->performCmd_Step();
396  // check for special case where end of sequence entry was encountered
397  if (this->m_runMode != STOPPED) {
398  this->log_ACTIVITY_HI_CS_CmdStepped(this->m_sequence->getLogFileName(), this->m_executedCount);
399  }
400  this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::OK);
401  } else {
402  this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
403  }
404 }
405 
406 void CmdSequencerComponentImpl ::CS_AUTO_cmdHandler(FwOpcodeType opcode, U32 cmdSeq) {
407  if (this->requireRunMode(STOPPED)) {
408  this->m_stepMode = AUTO;
410  this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::OK);
411  } else {
412  this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
413  }
414 }
415 
416 void CmdSequencerComponentImpl ::CS_MANUAL_cmdHandler(FwOpcodeType opcode, U32 cmdSeq) {
417  if (this->requireRunMode(STOPPED)) {
418  this->m_stepMode = MANUAL;
420  this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::OK);
421  } else {
422  this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
423  }
424 }
425 
426 // ----------------------------------------------------------------------
427 // Helper methods
428 // ----------------------------------------------------------------------
429 
430 bool CmdSequencerComponentImpl::requireRunMode(RunMode mode) {
431  if (this->m_runMode == mode) {
432  return true;
433  } else {
435  return false;
436  }
437 }
438 
439 void CmdSequencerComponentImpl ::commandError(const U32 number, const FwOpcodeType opCode, const U32 error) {
440  this->log_WARNING_HI_CS_CommandError(this->m_sequence->getLogFileName(), number,
441  CmdDispatcherCfg::getEventOpcode(opCode), error);
442  this->error();
443 }
444 
445 void CmdSequencerComponentImpl::performCmd_Step() {
446  this->m_sequence->nextRecord(m_record);
447  // set clock time base and context from value set when sequence was loaded
448  const Sequence::Header& header = this->m_sequence->getHeader();
449  this->m_record.m_timeTag.setTimeBase(header.m_timeBase);
450  this->m_record.m_timeTag.setTimeContext(header.m_timeContext);
451 
452  Fw::Time currentTime = this->getTime();
453  switch (this->m_record.m_descriptor) {
455  this->m_runMode = STOPPED;
456  this->sequenceComplete();
457  break;
459  this->performCmd_Step_RELATIVE(currentTime);
460  break;
462  this->performCmd_Step_ABSOLUTE(currentTime);
463  break;
464  default:
465  FW_ASSERT(false, m_record.m_descriptor);
466  }
467 }
468 
469 void CmdSequencerComponentImpl::sequenceComplete() {
470  FW_ASSERT(this->m_sequence != nullptr);
471  ++this->m_sequencesCompletedCount;
472  // reset buffer
473  this->m_sequence->clear();
474  this->log_ACTIVITY_HI_CS_SequenceComplete(this->m_sequence->getLogFileName());
475  this->tlmWrite_CS_SequencesCompleted(this->m_sequencesCompletedCount);
476  this->m_executedCount = 0;
477  // write sequence done port, if connected
478  if (this->isConnected_seqDone_OutputPort(0)) {
479  this->seqDone_out(0, 0, 0, Fw::CmdResponse::OK);
480  }
481 
482  if (Svc::BlockState::BLOCK == this->m_blockState || m_join_waiting) {
483  this->cmdResponse_out(this->m_opCode, this->m_cmdSeq, Fw::CmdResponse::OK);
484  }
485 
486  m_join_waiting = false;
487  this->m_blockState = Svc::BlockState::NO_BLOCK;
488  this->tlmWrite_CS_CurrentSequence(NO_SEQ);
489 }
490 
491 void CmdSequencerComponentImpl::commandComplete(const FwOpcodeType opcode) {
492  this->log_ACTIVITY_LO_CS_CommandComplete(this->m_sequence->getLogFileName(), this->m_executedCount,
494  ++this->m_executedCount;
495  ++this->m_totalExecutedCount;
496  this->tlmWrite_CS_CommandsExecuted(this->m_totalExecutedCount);
497 }
498 
499 void CmdSequencerComponentImpl ::performCmd_Step_RELATIVE(Fw::Time& currentTime) {
500  this->m_record.m_timeTag.add(currentTime.getSeconds(), currentTime.getUSeconds());
501  this->performCmd_Step_ABSOLUTE(currentTime);
502 }
503 
504 void CmdSequencerComponentImpl ::performCmd_Step_ABSOLUTE(Fw::Time& currentTime) {
505  if (currentTime >= this->m_record.m_timeTag) {
506  this->comCmdOut_out(0, m_record.m_command, 0);
507  this->setCmdTimeout(currentTime);
508  } else {
509  this->m_cmdTimer.set(this->m_record.m_timeTag);
510  }
511 }
512 
513 void CmdSequencerComponentImpl ::pingIn_handler(FwIndexType portNum,
514  U32 key
515 ) {
516  // send ping response
517  this->pingOut_out(0, key);
518 }
519 
520 void CmdSequencerComponentImpl ::setCmdTimeout(const Fw::Time& currentTime) {
521  // start timeout timer if enabled and not in step mode
522  if ((this->m_timeout > 0) and (AUTO == this->m_stepMode)) {
523  Fw::Time expTime = currentTime;
524  expTime.add(this->m_timeout, 0);
525  this->m_cmdTimeoutTimer.set(expTime);
526  }
527 }
528 
529 } // namespace Svc
constexpr FwOpcodeType getEventOpcode(const FwOpcodeType opcode)
void loadSequence(const Fw::ConstStringBase &fileName)
void tlmWrite_CS_LoadCommands(U32 arg, Fw::Time _tlmTime=Fw::Time()) const
void setSequenceFormat(Sequence &sequence)
FwIdType FwOpcodeType
The type of a command opcode.
PlatformSizeType FwSizeType
I32 FwEnumStoreType
CmdSequencerComponentImpl(const char *compName)
Construct a CmdSequencer.
void tlmWrite_CS_Errors(U32 arg, Fw::Time _tlmTime=Fw::Time()) const
void log_ACTIVITY_HI_CS_JoinWaiting(const Fw::StringBase &filename, U32 recordNumber, FwOpcodeType opCode) const
void log_WARNING_HI_CS_UnexpectedCompletion(FwOpcodeType opcode) const
void log_ACTIVITY_LO_CS_SequenceLoaded(const Fw::StringBase &fileName) const
enum T e
The raw enum value.
Fw::Time m_timeTag
The time tag. NOTE: timeBase and context not filled in.
void tlmWrite_CS_CurrentSequence(const Fw::StringBase &arg, Fw::Time _tlmTime=Fw::Time())
void log_ACTIVITY_HI_CS_CmdStarted(const Fw::StringBase &filename) const
Enum representing a command response.
bool isConnected_seqDone_OutputPort(FwIndexType portNum) const
void log_WARNING_HI_CS_SequenceTimeout(const Fw::StringBase &filename, U32 command) const
bool isConnected_seqStartOut_OutputPort(FwIndexType portNum) const
void allocateBuffer(FwEnumStoreType identifier, Fw::MemAllocator &allocator, FwSizeType bytes)
Give the sequence representation a memory buffer.
Definition: Sequence.cpp:45
virtual bool hasMoreRecords() const =0
void tlmWrite_CS_CancelCommands(U32 arg, Fw::Time _tlmTime=Fw::Time()) const
void tlmWrite_CS_CommandsExecuted(U32 arg, Fw::Time _tlmTime=Fw::Time()) const
~CmdSequencerComponentImpl()
Destroy a CmdDispatcherComponentBase.
void log_ACTIVITY_HI_CS_PortSequenceStarted(const Fw::StringBase &filename) const
void seqStartOut_out(FwIndexType portNum, const Fw::StringBase &filename, const Svc::SeqArgs &args) const
Invoke output port seqStartOut.
void log_ACTIVITY_HI_CS_SequenceCanceled(const Fw::StringBase &fileName) const
void setTimeContext(FwTimeContextStoreType context)
Definition: Time.cpp:262
void allocateBuffer(const FwEnumStoreType identifier, Fw::MemAllocator &allocator, const FwSizeType bytes)
A sequence with unspecified binary format.
void deallocateBuffer(Fw::MemAllocator &allocator)
Deallocate the buffer.
Definition: Sequence.cpp:55
U32 getSeconds() const
Definition: Time.cpp:128
Sequencer blocking state.
void setTimeBase(TimeBase timeBase)
Definition: Time.cpp:258
void log_ACTIVITY_HI_CS_ModeSwitched(const Svc::CmdSequencer_SeqMode &mode) const
void setTimeout(const U32 seconds)
Command successfully executed.
virtual bool loadFile(const Fw::ConstStringBase &fileName)=0
Command had execution error.
static Time add(const Time &a, const Time &b)
Definition: Time.cpp:174
void deallocateBuffer(Fw::MemAllocator &allocator)
Return allocated buffer. Call during shutdown.
Memory Allocation base class.
U32 getUSeconds() const
Definition: Time.cpp:132
A read-only abstract superclass for StringBase.
PlatformIndexType FwIndexType
Auto-generated base for CmdSequencer component.
void comCmdOut_out(FwIndexType portNum, Fw::ComBuffer &data, U32 context) const
Invoke output port comCmdOut.
RateGroupDivider component implementation.
virtual void nextRecord(Record &record)=0
void log_ACTIVITY_HI_CS_SequenceComplete(const Fw::StringBase &fileName) const
void seqDone_out(FwIndexType portNum, FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdResponse &response) const
Invoke output port seqDone.
void log_ACTIVITY_LO_CS_CommandComplete(const Fw::StringBase &fileName, U32 recordNumber, FwOpcodeType opCode) const
void log_WARNING_HI_CS_CommandError(const Fw::StringBase &fileName, U32 recordNumber, FwOpcodeType opCode, U32 errorStatus) const
#define FW_ASSERT(...)
Definition: Assert.hpp:14
void pingOut_out(FwIndexType portNum, U32 key) const
Invoke output port pingOut.
const Header & getHeader() const
Get the sequence header.
Definition: Sequence.cpp:60
void log_ACTIVITY_HI_CS_SequenceValid(const Fw::StringBase &filename) const
enum T e
The raw enum value.
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
void tlmWrite_CS_SequencesCompleted(U32 arg, Fw::Time _tlmTime=Fw::Time()) const
void log_ACTIVITY_HI_CS_CmdStepped(const Fw::StringBase &filename, U32 command) const