27 CmdSequencerComponentBase(name),
28 m_FPrimeSequence(*this),
29 m_sequence(&this->m_FPrimeSequence),
36 m_totalExecutedCount(0),
37 m_sequencesCompletedCount(0),
39 m_blockState(
Svc::CmdSequencer_BlockState::NO_BLOCK),
49 CmdSequencerComponentBase::init(queueDepth, instance);
53 this->m_timeout = timeout;
56 void CmdSequencerComponentImpl ::
57 setSequenceFormat(
Sequence& sequence)
59 this->m_sequence = &sequence;
62 void CmdSequencerComponentImpl ::
72 void CmdSequencerComponentImpl ::
75 FW_ASSERT(this->m_runMode == STOPPED, this->m_runMode);
76 if (not this->loadFile(fileName)) {
77 this->m_sequence->clear();
81 void CmdSequencerComponentImpl ::
84 this->m_sequence->deallocateBuffer(allocator);
95 void CmdSequencerComponentImpl::CS_RUN_cmdHandler(
99 Svc::CmdSequencer_BlockState block) {
101 if (not this->requireRunMode(STOPPED)) {
102 if (m_join_waiting) {
104 this->log_WARNING_HI_CS_JoinWaitingNotComplete();
106 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
110 this->m_blockState = block.e;
111 this->m_cmdSeq = cmdSeq;
112 this->m_opCode = opCode;
115 if (not this->loadFile(fileName)) {
116 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
120 this->m_executedCount = 0;
123 if (AUTO == this->m_stepMode) {
124 this->m_runMode = RUNNING;
125 this->performCmd_Step();
128 if (Svc::CmdSequencer_BlockState::NO_BLOCK == this->m_blockState) {
129 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
133 void CmdSequencerComponentImpl::CS_VALIDATE_cmdHandler(
139 if (!this->requireRunMode(STOPPED)) {
140 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
145 if (not this->loadFile(fileName)) {
146 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
151 this->m_sequence->
clear();
153 this->log_ACTIVITY_HI_CS_SequenceValid(this->m_sequence->
getLogFileName());
155 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
160 void CmdSequencerComponentImpl::seqRunIn_handler(
165 if (!this->requireRunMode(STOPPED)) {
166 this->seqDone_out(0,0,0,Fw::CmdResponse::EXECUTION_ERROR);
172 if (filename !=
"") {
174 const bool status = this->loadFile(cmdStr);
176 this->seqDone_out(0,0,0,Fw::CmdResponse::EXECUTION_ERROR);
182 this->log_WARNING_LO_CS_NoSequenceActive();
184 this->seqDone_out(0,0,0,Fw::CmdResponse::EXECUTION_ERROR);
188 this->m_executedCount = 0;
191 if (AUTO == this->m_stepMode) {
192 this->m_runMode = RUNNING;
193 this->performCmd_Step();
196 this->log_ACTIVITY_HI_CS_PortSequenceStarted(this->m_sequence->
getLogFileName());
199 void CmdSequencerComponentImpl ::
203 if (RUNNING == this->m_runMode) {
204 this->performCmd_Cancel();
205 this->log_ACTIVITY_HI_CS_SequenceCanceled(this->m_sequence->getLogFileName());
206 ++this->m_cancelCmdCount;
207 this->tlmWrite_CS_CancelCommands(this->m_cancelCmdCount);
209 this->log_WARNING_LO_CS_NoSequenceActive();
213 void CmdSequencerComponentImpl::CS_CANCEL_cmdHandler(
215 if (RUNNING == this->m_runMode) {
216 this->performCmd_Cancel();
217 this->log_ACTIVITY_HI_CS_SequenceCanceled(this->m_sequence->
getLogFileName());
218 ++this->m_cancelCmdCount;
219 this->tlmWrite_CS_CancelCommands(this->m_cancelCmdCount);
221 this->log_WARNING_LO_CS_NoSequenceActive();
223 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
226 void CmdSequencerComponentImpl::CS_JOIN_WAIT_cmdHandler(
230 if (m_runMode != RUNNING) {
231 this->log_WARNING_LO_CS_NoSequenceActive();
232 this->cmdResponse_out(opCode,cmdSeq,Fw::CmdResponse::OK);
235 m_join_waiting =
true;
237 this->log_ACTIVITY_HI_CS_JoinWaiting(logFileName, m_cmdSeq, m_opCode);
247 bool CmdSequencerComponentImpl ::
250 const bool status = this->m_sequence->loadFile(fileName);
253 this->log_ACTIVITY_LO_CS_SequenceLoaded(logFileName);
254 ++this->m_loadCmdCount;
255 this->tlmWrite_CS_LoadCommands(this->m_loadCmdCount);
260 void CmdSequencerComponentImpl::error() {
261 ++this->m_errorCount;
262 this->tlmWrite_CS_Errors(m_errorCount);
265 void CmdSequencerComponentImpl::performCmd_Cancel() {
266 this->m_sequence->
reset();
267 this->m_runMode = STOPPED;
268 this->m_cmdTimer.clear();
269 this->m_cmdTimeoutTimer.clear();
270 this->m_executedCount = 0;
272 if (this->isConnected_seqDone_OutputPort(0)) {
273 this->seqDone_out(0,0,0,Fw::CmdResponse::EXECUTION_ERROR);
276 if (Svc::CmdSequencer_BlockState::BLOCK == this->m_blockState || m_join_waiting) {
278 this->m_join_waiting =
false;
279 this->cmdResponse_out(this->m_opCode, this->m_cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
282 this->m_blockState = Svc::CmdSequencer_BlockState::NO_BLOCK;
285 void CmdSequencerComponentImpl ::
286 cmdResponseIn_handler(
290 const Fw::CmdResponse& response
293 if (this->m_runMode == STOPPED) {
295 this->log_WARNING_HI_CS_UnexpectedCompletion(opcode);
298 this->m_cmdTimeoutTimer.clear();
299 if (response != Fw::CmdResponse::OK) {
300 this->commandError(this->m_executedCount, opcode, response.e);
301 this->performCmd_Cancel();
302 }
else if (this->m_runMode == RUNNING && this->m_stepMode == AUTO) {
304 this->commandComplete(opcode);
305 if (not this->m_sequence->hasMoreRecords()) {
307 this->m_runMode = STOPPED;
308 this->sequenceComplete();
310 this->performCmd_Step();
314 this->commandComplete(opcode);
315 if (not this->m_sequence->hasMoreRecords()) {
316 this->m_runMode = STOPPED;
317 this->sequenceComplete();
323 void CmdSequencerComponentImpl ::
327 Fw::Time currTime = this->getTime();
329 if (this->m_cmdTimer.isExpiredAt(currTime)) {
330 this->comCmdOut_out(0, m_record.m_command, 0);
331 this->m_cmdTimer.clear();
333 this->setCmdTimeout(currTime);
334 }
else if (this->m_cmdTimeoutTimer.isExpiredAt(this->getTime())) {
335 this->log_WARNING_HI_CS_SequenceTimeout(
336 m_sequence->getLogFileName(),
337 this->m_executedCount
340 this->performCmd_Cancel();
344 void CmdSequencerComponentImpl ::
347 if (not this->m_sequence->hasMoreRecords()) {
349 this->log_WARNING_LO_CS_NoSequenceActive();
350 this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
353 if (!this->requireRunMode(STOPPED)) {
354 this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
358 this->m_blockState = Svc::CmdSequencer_BlockState::NO_BLOCK;
359 this->m_runMode = RUNNING;
360 this->performCmd_Step();
361 this->log_ACTIVITY_HI_CS_CmdStarted(this->m_sequence->getLogFileName());
362 this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::OK);
365 void CmdSequencerComponentImpl ::
368 if (this->requireRunMode(RUNNING)) {
369 this->performCmd_Step();
371 if (this->m_runMode != STOPPED) {
372 this->log_ACTIVITY_HI_CS_CmdStepped(
373 this->m_sequence->getLogFileName(),
374 this->m_executedCount
377 this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::OK);
379 this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
383 void CmdSequencerComponentImpl ::
386 if (this->requireRunMode(STOPPED)) {
387 this->m_stepMode = AUTO;
388 this->log_ACTIVITY_HI_CS_ModeSwitched(CmdSequencer_SeqMode::AUTO);
389 this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::OK);
391 this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
395 void CmdSequencerComponentImpl ::
398 if (this->requireRunMode(STOPPED)) {
399 this->m_stepMode = MANUAL;
400 this->log_ACTIVITY_HI_CS_ModeSwitched(CmdSequencer_SeqMode::STEP);
401 this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::OK);
403 this->cmdResponse_out(opcode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
411 bool CmdSequencerComponentImpl::requireRunMode(RunMode mode) {
412 if (this->m_runMode == mode) {
415 this->log_WARNING_HI_CS_InvalidMode();
420 void CmdSequencerComponentImpl ::
427 this->log_WARNING_HI_CS_CommandError(
428 this->m_sequence->getLogFileName(),
436 void CmdSequencerComponentImpl::performCmd_Step() {
440 const Sequence::Header& header = this->m_sequence->
getHeader();
444 Fw::Time currentTime = this->getTime();
447 this->m_runMode = STOPPED;
448 this->sequenceComplete();
451 this->performCmd_Step_RELATIVE(currentTime);
454 this->performCmd_Step_ABSOLUTE(currentTime);
461 void CmdSequencerComponentImpl::sequenceComplete() {
462 ++this->m_sequencesCompletedCount;
464 this->m_sequence->
clear();
465 this->log_ACTIVITY_HI_CS_SequenceComplete(this->m_sequence->
getLogFileName());
466 this->tlmWrite_CS_SequencesCompleted(this->m_sequencesCompletedCount);
467 this->m_executedCount = 0;
469 if (this->isConnected_seqDone_OutputPort(0)) {
470 this->seqDone_out(0,0,0,Fw::CmdResponse::OK);
473 if (Svc::CmdSequencer_BlockState::BLOCK == this->m_blockState || m_join_waiting) {
474 this->cmdResponse_out(this->m_opCode, this->m_cmdSeq, Fw::CmdResponse::OK);
477 m_join_waiting =
false;
478 this->m_blockState = Svc::CmdSequencer_BlockState::NO_BLOCK;
482 void CmdSequencerComponentImpl::commandComplete(
const U32 opcode) {
483 this->log_ACTIVITY_LO_CS_CommandComplete(
485 this->m_executedCount,
488 ++this->m_executedCount;
489 ++this->m_totalExecutedCount;
490 this->tlmWrite_CS_CommandsExecuted(this->m_totalExecutedCount);
493 void CmdSequencerComponentImpl ::
494 performCmd_Step_RELATIVE(
Fw::Time& currentTime)
497 this->performCmd_Step_ABSOLUTE(currentTime);
500 void CmdSequencerComponentImpl ::
501 performCmd_Step_ABSOLUTE(
Fw::Time& currentTime)
503 if (currentTime >= this->m_record.m_timeTag) {
504 this->comCmdOut_out(0, m_record.m_command, 0);
505 this->setCmdTimeout(currentTime);
507 this->m_cmdTimer.set(this->m_record.m_timeTag);
511 void CmdSequencerComponentImpl ::
518 this->pingOut_out(0,key);
521 void CmdSequencerComponentImpl ::
522 setCmdTimeout(
const Fw::Time ¤tTime)
525 if ((this->m_timeout > 0) and (AUTO == this->m_stepMode)) {
527 expTime.
add(this->m_timeout,0);
528 this->m_cmdTimeoutTimer.
set(expTime);
PlatformIntType NATIVE_INT_TYPE
PlatformUIntType NATIVE_UINT_TYPE
static Time add(const Time &a, const Time &b)
void set(U32 seconds, U32 useconds)
void setTimeContext(FwTimeContextStoreType context)
void setTimeBase(TimeBase timeBase)
@ END_OF_SEQUENCE
end of sequence
Descriptor m_descriptor
The descriptor.
Fw::Time m_timeTag
The time tag. NOTE: timeBase and context not filled in.
A sequence with unspecified binary format.
void allocateBuffer(NATIVE_INT_TYPE identifier, Fw::MemAllocator &allocator, NATIVE_UINT_TYPE bytes)
Give the sequence representation a memory buffer.
virtual void nextRecord(Record &record)=0
virtual bool hasMoreRecords() const =0
const Header & getHeader() const
Get the sequence header.
Fw::LogStringArg & getLogFileName()
~CmdSequencerComponentImpl()
Destroy a CmdDispatcherComponentBase.
void init(const NATIVE_INT_TYPE queueDepth, const NATIVE_INT_TYPE instance)
Initialize a CmdSequencer.
CmdSequencerComponentImpl(const char *compName)
Construct a CmdSequencer.
void setTimeout(const NATIVE_UINT_TYPE seconds)