F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
FpySequencerDirectives.cpp
Go to the documentation of this file.
1 #include <cmath>
2 #include <cstring>
3 #include <type_traits>
4 #include "Fw/Com/ComPacket.hpp"
6 
7 namespace Svc {
8 
9 void FpySequencer::sendSignal(Signal signal) {
10  switch (signal) {
13  break;
14  }
17  break;
18  }
21  break;
22  }
25  break;
26  }
27  default: {
28  FW_ASSERT(0, static_cast<FwAssertArgType>(signal));
29  }
30  }
31 }
32 
33 // utility method for updating telemetry based on a directive error code
34 void FpySequencer::handleDirectiveErrorCode(Fpy::DirectiveId id, DirectiveError err) {
35  this->m_tlm.lastDirectiveError = err;
36  if (err != DirectiveError::NO_ERROR) {
37  this->m_tlm.directiveErrorIndex = this->currentStatementIdx();
38  this->m_tlm.directiveErrorId = id;
39  }
40 }
41 
42 Fw::Success FpySequencer::sendCmd(FwOpcodeType opcode, const U8* argBuf, FwSizeType argBufSize) {
43  Fw::ComBuffer cmdBuf;
44  Fw::SerializeStatus stat =
45  cmdBuf.serializeFrom(static_cast<FwPacketDescriptorType>(Fw::ComPacketType::FW_PACKET_COMMAND));
46  // TODO should I assert here? this really shouldn't fail, I should just add a static assert
47  // on com buf size and then assert here
49  return Fw::Success::FAILURE;
50  }
51  stat = cmdBuf.serializeFrom(opcode);
53  return Fw::Success::FAILURE;
54  }
55  stat = cmdBuf.serializeFrom(argBuf, argBufSize, Fw::Serialization::OMIT_LENGTH);
57  return Fw::Success::FAILURE;
58  }
59 
60  // calculate the unique command identifier:
61  // cmd UID is formatted like XXYY, where XX are the first two bytes of the m_sequencesStarted counter
62  // and YY are the first two bytes of the m_statementsDispatched counter.
63  // this way, we know when we get a cmd back A) whether or not it's from this sequence (modulo 2^16) and B)
64  // whether or not it's this specific instance of the cmd in the sequence, and not another one with the same opcode
65  // somewhere else in the file.
66  // if we put this uid in the context we send to the cmdDisp, we will get it back when the cmd returns
67  U32 cmdUid =
68  static_cast<U32>(((this->m_sequencesStarted & 0xFFFF) << 16) | (this->m_statementsDispatched & 0xFFFF));
69 
70  this->cmdOut_out(0, cmdBuf, cmdUid);
71 
72  return Fw::Success::SUCCESS;
73 }
74 
78  this->sendSignal(this->waitRel_directiveHandler(directive, error));
79  handleDirectiveErrorCode(Fpy::DirectiveId::WAIT_REL, error);
80 }
81 
85  this->sendSignal(this->waitAbs_directiveHandler(directive, error));
86  handleDirectiveErrorCode(Fpy::DirectiveId::WAIT_ABS, error);
87 }
88 
92  this->sendSignal(this->goto_directiveHandler(directive, error));
93  handleDirectiveErrorCode(Fpy::DirectiveId::GOTO, error);
94 }
95 
99  this->sendSignal(this->if_directiveHandler(directive, error));
100  handleDirectiveErrorCode(Fpy::DirectiveId::IF, error);
101 }
102 
106  this->sendSignal(this->noOp_directiveHandler(directive, error));
107  handleDirectiveErrorCode(Fpy::DirectiveId::NO_OP, error);
108 }
109 
112  const Svc::FpySequencer_PushTlmValDirective& directive) {
114  this->sendSignal(this->pushTlmVal_directiveHandler(directive, error));
115  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_TLM_VAL, error);
116 }
117 
122  this->sendSignal(this->pushTlmValAndTime_directiveHandler(directive, error));
123  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_TLM_VAL_AND_TIME, error);
124 }
125 
129  this->sendSignal(this->pushPrm_directiveHandler(directive, error));
130  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_PRM, error);
131 }
132 
136  this->sendSignal(this->constCmd_directiveHandler(directive, error));
137  handleDirectiveErrorCode(Fpy::DirectiveId::CONST_CMD, error);
138 }
139 
143  this->sendSignal(this->stackOp_directiveHandler(directive, error));
144  handleDirectiveErrorCode(directive.get__op(), error);
145 }
146 
150  this->sendSignal(this->exit_directiveHandler(directive, error));
151  handleDirectiveErrorCode(Fpy::DirectiveId::EXIT, error);
152 }
153 
157  this->sendSignal(this->allocate_directiveHandler(directive, error));
158  handleDirectiveErrorCode(Fpy::DirectiveId::ALLOCATE, error);
159 }
160 
165  this->sendSignal(this->storeConstOffset_directiveHandler(directive, error));
166  handleDirectiveErrorCode(Fpy::DirectiveId::STORE_CONST_OFFSET, error);
167 }
168 
172  this->sendSignal(this->pushVal_directiveHandler(directive, error));
173  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_VAL, error);
174 }
175 
179  this->sendSignal(this->load_directiveHandler(directive, error));
180  handleDirectiveErrorCode(Fpy::DirectiveId::LOAD, error);
181 }
182 
186  this->sendSignal(this->discard_directiveHandler(directive, error));
187  handleDirectiveErrorCode(Fpy::DirectiveId::DISCARD, error);
188 }
189 
193  this->sendSignal(this->memCmp_directiveHandler(directive, error));
194  handleDirectiveErrorCode(Fpy::DirectiveId::MEMCMP, error);
195 }
196 
200  this->sendSignal(this->stackCmd_directiveHandler(directive, error));
201  handleDirectiveErrorCode(Fpy::DirectiveId::STACK_CMD, error);
202 }
203 
207  this->sendSignal(this->pushTime_directiveHandler(directive, error));
208  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_TIME, error);
209 }
210 
214  this->sendSignal(this->setFlag_directiveHandler(directive, error));
215  handleDirectiveErrorCode(Fpy::DirectiveId::SET_FLAG, error);
216 }
217 
221  this->sendSignal(this->getFlag_directiveHandler(directive, error));
222  handleDirectiveErrorCode(Fpy::DirectiveId::GET_FLAG, error);
223 }
224 
228  this->sendSignal(this->getField_directiveHandler(directive, error));
229  handleDirectiveErrorCode(Fpy::DirectiveId::GET_FIELD, error);
230 }
231 
235  this->sendSignal(this->peek_directiveHandler(directive, error));
236  handleDirectiveErrorCode(Fpy::DirectiveId::PEEK, error);
237 }
238 
242  this->sendSignal(this->store_directiveHandler(directive, error));
243  handleDirectiveErrorCode(Fpy::DirectiveId::STORE, error);
244 }
245 
247 Signal FpySequencer::waitRel_directiveHandler(const FpySequencer_WaitRelDirective& directive, DirectiveError& error) {
248  if (this->m_runtime.stack.size < 8) {
251  }
252 
253  Fw::Time wakeupTime = this->getTime();
254 
255  U32 uSeconds = this->m_runtime.stack.pop<U32>();
256  U32 seconds = this->m_runtime.stack.pop<U32>();
257 
258  wakeupTime.add(seconds, uSeconds);
259  this->m_runtime.wakeupTime = wakeupTime;
261 }
262 
264 Signal FpySequencer::waitAbs_directiveHandler(const FpySequencer_WaitAbsDirective& directive, DirectiveError& error) {
265  if (this->m_runtime.stack.size < 10 + sizeof(FwTimeContextStoreType)) {
268  }
269 
270  U32 uSeconds = this->m_runtime.stack.pop<U32>();
271  U32 seconds = this->m_runtime.stack.pop<U32>();
272  FwTimeContextStoreType ctx = this->m_runtime.stack.pop<FwTimeContextStoreType>();
273  U16 base = this->m_runtime.stack.pop<U16>();
274 
275  this->m_runtime.wakeupTime = Fw::Time(static_cast<TimeBase::T>(base), ctx, seconds, uSeconds);
277 }
278 
280 Signal FpySequencer::goto_directiveHandler(const FpySequencer_GotoDirective& directive, DirectiveError& error) {
281  // check within sequence bounds, or at EOF (we allow == case cuz this just ends the sequence)
282  if (directive.get_statementIndex() > m_sequenceObj.get_header().get_statementCount()) {
285  }
286  m_runtime.nextStatementIndex = directive.get_statementIndex();
288 }
289 
291 Signal FpySequencer::if_directiveHandler(const FpySequencer_IfDirective& directive, DirectiveError& error) {
292  if (this->m_runtime.stack.size < 1) {
295  }
296  // check within sequence bounds, or at EOF (we allow == case cuz this just ends the sequence)
297  if (directive.get_falseGotoStmtIndex() > m_sequenceObj.get_header().get_statementCount()) {
300  }
301 
302  if (this->m_runtime.stack.pop<U8>() != 0) {
303  // proceed to next instruction
305  }
306 
307  // conditional false case
308  this->m_runtime.nextStatementIndex = directive.get_falseGotoStmtIndex();
310 }
311 
312 Signal FpySequencer::noOp_directiveHandler(const FpySequencer_NoOpDirective& directive, DirectiveError& error) {
314 }
315 
316 Signal FpySequencer::pushTlmVal_directiveHandler(const FpySequencer_PushTlmValDirective& directive,
317  DirectiveError& error) {
318  if (!this->isConnected_getTlmChan_OutputPort(0)) {
321  }
322  Fw::Time tlmTime;
323  Fw::TlmBuffer tlmValue;
324  Fw::TlmValid valid = this->getTlmChan_out(0, directive.get_chanId(), tlmTime, tlmValue);
325 
326  if (valid != Fw::TlmValid::VALID) {
327  // could not find this tlm chan
330  }
331 
332  if (Fpy::MAX_STACK_SIZE - tlmValue.getSize() < this->m_runtime.stack.size) {
335  }
336  this->m_runtime.stack.push(tlmValue.getBuffAddr(), static_cast<Fpy::StackSizeType>(tlmValue.getSize()));
338 }
339 
340 Signal FpySequencer::pushTlmValAndTime_directiveHandler(const FpySequencer_PushTlmValAndTimeDirective& directive,
341  DirectiveError& error) {
342  if (!this->isConnected_getTlmChan_OutputPort(0)) {
345  }
346 
347  Fw::Time tlmTime;
348  Fw::TlmBuffer tlmValue;
349  Fw::TlmValid valid = this->getTlmChan_out(0, directive.get_chanId(), tlmTime, tlmValue);
350 
351  if (valid != Fw::TlmValid::VALID) {
352  // could not find this tlm chan
355  }
356 
357  U8 tlmTimeBuf[Fw::Time::SERIALIZED_SIZE] = {};
359  Fw::SerializeStatus stat = timeEsb.serializeFrom(tlmTime);
360 
361  // coding error if this failed, we should have enough space
362  FW_ASSERT(stat == Fw::SerializeStatus::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(stat));
363 
364  // check that our stack won't overflow if we put both val and time on it
365  if (Fpy::MAX_STACK_SIZE - tlmValue.getSize() - timeEsb.getSize() < this->m_runtime.stack.size) {
368  }
369 
370  // push tlm to end of stack
371  this->m_runtime.stack.push(tlmValue.getBuffAddr(), static_cast<Fpy::StackSizeType>(tlmValue.getSize()));
372  // now push time to end of stack
373  this->m_runtime.stack.push(timeEsb.getBuffAddr(), static_cast<Fpy::StackSizeType>(timeEsb.getSize()));
375 }
376 
377 Signal FpySequencer::pushPrm_directiveHandler(const FpySequencer_PushPrmDirective& directive, DirectiveError& error) {
378  if (!this->isConnected_prmGet_OutputPort(0)) {
381  }
382 
383  Fw::ParamBuffer prmValue;
384  Fw::ParamValid valid = this->getParam_out(0, directive.get_prmId(), prmValue);
385 
386  if (valid != Fw::ParamValid::VALID) {
387  // could not find this prm in the DB
390  }
391 
392  if (Fpy::MAX_STACK_SIZE - prmValue.getSize() < this->m_runtime.stack.size) {
395  }
396 
397  this->m_runtime.stack.push(prmValue.getBuffAddr(), static_cast<Fpy::StackSizeType>(prmValue.getSize()));
399 }
400 
401 Signal FpySequencer::constCmd_directiveHandler(const FpySequencer_ConstCmdDirective& directive, DirectiveError& error) {
402  if (this->sendCmd(directive.get_opCode(), directive.get_argBuf(), directive.get__argBufSize()) ==
405  } else {
406  // now tell the SM to wait some more until we get the cmd response back
407  // if we've already got the response back this should be harmless
409  }
410 }
411 
412 DirectiveError FpySequencer::op_or() {
413  if (this->m_runtime.stack.size < sizeof(U8) * 2) {
415  }
416  this->m_runtime.stack.push(static_cast<U8>(this->m_runtime.stack.pop<U8>() | this->m_runtime.stack.pop<U8>()));
418 }
419 DirectiveError FpySequencer::op_and() {
420  if (this->m_runtime.stack.size < sizeof(U8) * 2) {
422  }
423  this->m_runtime.stack.push(static_cast<U8>(this->m_runtime.stack.pop<U8>() & this->m_runtime.stack.pop<U8>()));
425 }
426 DirectiveError FpySequencer::op_ieq() {
427  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
429  }
430  this->m_runtime.stack.push(static_cast<U8>(this->m_runtime.stack.pop<I64>() == this->m_runtime.stack.pop<I64>()));
432 }
433 DirectiveError FpySequencer::op_ine() {
434  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
436  }
437  this->m_runtime.stack.push(static_cast<U8>(this->m_runtime.stack.pop<I64>() != this->m_runtime.stack.pop<I64>()));
439 }
440 DirectiveError FpySequencer::op_ult() {
441  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
443  }
444  U64 rhs = this->m_runtime.stack.pop<U64>();
445  U64 lhs = this->m_runtime.stack.pop<U64>();
446  this->m_runtime.stack.push(static_cast<U8>(lhs < rhs));
448 }
449 DirectiveError FpySequencer::op_ule() {
450  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
452  }
453  U64 rhs = this->m_runtime.stack.pop<U64>();
454  U64 lhs = this->m_runtime.stack.pop<U64>();
455  this->m_runtime.stack.push(static_cast<U8>(lhs <= rhs));
457 }
458 DirectiveError FpySequencer::op_ugt() {
459  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
461  }
462  U64 rhs = this->m_runtime.stack.pop<U64>();
463  U64 lhs = this->m_runtime.stack.pop<U64>();
464  this->m_runtime.stack.push(static_cast<U8>(lhs > rhs));
466 }
467 DirectiveError FpySequencer::op_uge() {
468  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
470  }
471  U64 rhs = this->m_runtime.stack.pop<U64>();
472  U64 lhs = this->m_runtime.stack.pop<U64>();
473  this->m_runtime.stack.push(static_cast<U8>(lhs >= rhs));
475 }
476 DirectiveError FpySequencer::op_slt() {
477  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
479  }
480  I64 rhs = this->m_runtime.stack.pop<I64>();
481  I64 lhs = this->m_runtime.stack.pop<I64>();
482  this->m_runtime.stack.push(static_cast<U8>(lhs < rhs));
484 }
485 DirectiveError FpySequencer::op_sle() {
486  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
488  }
489  I64 rhs = this->m_runtime.stack.pop<I64>();
490  I64 lhs = this->m_runtime.stack.pop<I64>();
491  this->m_runtime.stack.push(static_cast<U8>(lhs <= rhs));
493 }
494 DirectiveError FpySequencer::op_sgt() {
495  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
497  }
498  I64 rhs = this->m_runtime.stack.pop<I64>();
499  I64 lhs = this->m_runtime.stack.pop<I64>();
500  this->m_runtime.stack.push(static_cast<U8>(lhs > rhs));
502 }
503 DirectiveError FpySequencer::op_sge() {
504  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
506  }
507  I64 rhs = this->m_runtime.stack.pop<I64>();
508  I64 lhs = this->m_runtime.stack.pop<I64>();
509  this->m_runtime.stack.push(static_cast<U8>(lhs >= rhs));
511 }
512 DirectiveError FpySequencer::op_feq() {
513  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
515  }
516  F64 rhs = this->m_runtime.stack.pop<F64>();
517  F64 lhs = this->m_runtime.stack.pop<F64>();
518  // eq is true if they are equal and neither is nan
519  this->m_runtime.stack.push(static_cast<U8>((lhs == rhs) ? 1 : 0));
521 }
522 DirectiveError FpySequencer::op_fne() {
523  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
525  }
526  F64 rhs = this->m_runtime.stack.pop<F64>();
527  F64 lhs = this->m_runtime.stack.pop<F64>();
528  // ne is true if they are not equal or either is nan
529  this->m_runtime.stack.push(static_cast<U8>((lhs != rhs) ? 1 : 0));
531 }
532 DirectiveError FpySequencer::op_flt() {
533  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
535  }
536  F64 rhs = this->m_runtime.stack.pop<F64>();
537  F64 lhs = this->m_runtime.stack.pop<F64>();
538  this->m_runtime.stack.push(static_cast<U8>(std::isless(lhs, rhs)));
540 }
541 DirectiveError FpySequencer::op_fle() {
542  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
544  }
545  F64 rhs = this->m_runtime.stack.pop<F64>();
546  F64 lhs = this->m_runtime.stack.pop<F64>();
547  this->m_runtime.stack.push(static_cast<U8>(std::islessequal(lhs, rhs)));
549 }
550 DirectiveError FpySequencer::op_fgt() {
551  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
553  }
554  F64 rhs = this->m_runtime.stack.pop<F64>();
555  F64 lhs = this->m_runtime.stack.pop<F64>();
556  this->m_runtime.stack.push(static_cast<U8>(std::isgreater(lhs, rhs)));
558 }
559 DirectiveError FpySequencer::op_fge() {
560  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
562  }
563  F64 rhs = this->m_runtime.stack.pop<F64>();
564  F64 lhs = this->m_runtime.stack.pop<F64>();
565  this->m_runtime.stack.push(static_cast<U8>(std::isgreaterequal(lhs, rhs)));
567 }
568 DirectiveError FpySequencer::op_not() {
569  if (this->m_runtime.stack.size < sizeof(U8)) {
571  }
572  this->m_runtime.stack.push(static_cast<U8>(this->m_runtime.stack.pop<U8>() == 0));
574 }
575 DirectiveError FpySequencer::op_fpext() {
576  // convert F32 to F64
577  if (this->m_runtime.stack.size < sizeof(F32)) {
579  }
580  this->m_runtime.stack.push(static_cast<F64>(this->m_runtime.stack.pop<F32>()));
582 }
583 DirectiveError FpySequencer::op_fptrunc() {
584  // convert F64 to F32
585  if (this->m_runtime.stack.size < sizeof(F64)) {
587  }
588  this->m_runtime.stack.push(static_cast<F32>(this->m_runtime.stack.pop<F64>()));
590 }
591 DirectiveError FpySequencer::op_fptosi() {
592  if (this->m_runtime.stack.size < sizeof(F64)) {
594  }
595  this->m_runtime.stack.push(static_cast<I64>(this->m_runtime.stack.pop<F64>()));
597 }
598 DirectiveError FpySequencer::op_sitofp() {
599  if (this->m_runtime.stack.size < sizeof(I64)) {
601  }
602  this->m_runtime.stack.push(static_cast<F64>(this->m_runtime.stack.pop<I64>()));
604 }
605 DirectiveError FpySequencer::op_fptoui() {
606  if (this->m_runtime.stack.size < sizeof(F64)) {
608  }
609  this->m_runtime.stack.push(static_cast<U64>(this->m_runtime.stack.pop<F64>()));
611 }
612 DirectiveError FpySequencer::op_uitofp() {
613  if (this->m_runtime.stack.size < sizeof(U64)) {
615  }
616  this->m_runtime.stack.push(static_cast<F64>(this->m_runtime.stack.pop<U64>()));
618 }
619 DirectiveError FpySequencer::op_add() {
620  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
622  }
623  I64 rhs = this->m_runtime.stack.pop<I64>();
624  I64 lhs = this->m_runtime.stack.pop<I64>();
625  // Check for overflow and underflow and return the appropriate error code
626  // Overflow can only occur with both operands positive and occurs when one operand is greater than the maximum value
627  // less the other operand. If either operand is negative or zero, overflow cannot occur.
628  if ((rhs > 0) && (lhs > 0) && ((std::numeric_limits<I64>::max() - rhs) < lhs)) {
630  }
631  // Underflow can only occur with both operands negative and occurs when one operand is less than the minimum value
632  // minus the other operand. If either operand is positive or zero, underflow cannot occur.
633  else if ((rhs < 0) && (lhs < 0) && ((std::numeric_limits<I64>::min() - rhs) > lhs)) {
635  }
636  this->m_runtime.stack.push(static_cast<I64>(lhs + rhs));
638 }
639 DirectiveError FpySequencer::op_sub() {
640  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
642  }
643  I64 rhs = this->m_runtime.stack.pop<I64>();
644  I64 lhs = this->m_runtime.stack.pop<I64>();
645  // Check for overflow and underflow and return the appropriate error code
646  // Overflow can only occur when the left operand is positive and the right operand is negative. It occurs when the
647  // left (positive) operand is greater than the maximum value plus the other (negative) operand. If the right
648  // operand is positive or zero, overflow cannot occur.
649  if ((rhs < 0) && (lhs > 0) && ((std::numeric_limits<I64>::max() + rhs) < lhs)) {
651  }
652  // Underflow can only occur when the left operand is negative and the right operand is positive. It occurs when the
653  // left (negative) operand is less than the minimum value plus the other (positive) operand. If the right operand
654  // is negative or zero, underflow cannot occur.
655  else if ((rhs > 0) && (lhs < 0) && ((std::numeric_limits<I64>::min() + rhs) > lhs)) {
657  }
658  this->m_runtime.stack.push(static_cast<I64>(lhs - rhs));
660 }
661 DirectiveError FpySequencer::op_mul() {
662  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
664  }
665  I64 rhs = this->m_runtime.stack.pop<I64>();
666  I64 lhs = this->m_runtime.stack.pop<I64>();
667  // Check for overflow and underflow and return the appropriate error code
668  // Overflow can only occur with operands of matching signs and occurs when one operand is greater (or less) than the
669  // maximum value divided by the other operand. Either operand being zero precludes overflow.
670  // Check the both positive case.
671  if ((rhs > 0) && (lhs > 0) && ((std::numeric_limits<I64>::max() / rhs) < lhs)) {
673  }
674  // Check the both negative case
675  else if ((rhs < 0) && (lhs < 0) && ((std::numeric_limits<I64>::max() / (-1 * rhs)) < (-1 * lhs))) {
677  }
678  // Underflow can occur with operands of differing signs and occurs when one operand is less than the minimum value
679  // divided by the other operand. Either operand being zero precludes underflow.
680  // Check the case where lhs is positive.
681  else if ((rhs < 0) && (lhs > 0) && ((std::numeric_limits<I64>::min() / lhs) > rhs)) {
683  }
684  // Check the case where rhs is positive.
685  else if ((rhs > 0) && (lhs < 0) && ((std::numeric_limits<I64>::min() / rhs) > lhs)) {
687  }
688  this->m_runtime.stack.push(static_cast<I64>(lhs * rhs));
690 }
691 DirectiveError FpySequencer::op_udiv() {
692  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
694  }
695  U64 rhs = this->m_runtime.stack.pop<U64>();
696  U64 lhs = this->m_runtime.stack.pop<U64>();
697  // Prevent division by zero
698  if (rhs == 0) {
700  }
701  this->m_runtime.stack.push(static_cast<U64>(lhs / rhs));
703 }
704 DirectiveError FpySequencer::op_sdiv() {
705  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
707  }
708 
709  I64 rhs = this->m_runtime.stack.pop<I64>();
710  I64 lhs = this->m_runtime.stack.pop<I64>();
711  // Prevent division by zero
712  if (rhs == 0) {
714  }
715  this->m_runtime.stack.push(static_cast<I64>(lhs / rhs));
717 }
718 DirectiveError FpySequencer::op_umod() {
719  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
721  }
722  U64 rhs = this->m_runtime.stack.pop<U64>();
723  if (rhs == 0) {
725  }
726  U64 lhs = this->m_runtime.stack.pop<U64>();
727  this->m_runtime.stack.push(static_cast<U64>(lhs % rhs));
729 }
730 DirectiveError FpySequencer::op_smod() {
731  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
733  }
734  I64 rhs = this->m_runtime.stack.pop<I64>();
735  if (rhs == 0) {
737  }
738  I64 lhs = this->m_runtime.stack.pop<I64>();
739  I64 res = static_cast<I64>(lhs % rhs);
740  // in order to match Python's behavior,
741  // if the signs of the remainder and divisor differ, adjust the result.
742  // this happens when the result should be positive but is negative, or vice-versa.
743  // credit Gemini 2.5 pro
744  if ((res > 0 && rhs < 0) || (res < 0 && rhs > 0)) {
745  res += rhs;
746  }
747  this->m_runtime.stack.push(res);
749 }
750 DirectiveError FpySequencer::op_fadd() {
751  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
753  }
754  F64 rhs = this->m_runtime.stack.pop<F64>();
755  F64 lhs = this->m_runtime.stack.pop<F64>();
756  this->m_runtime.stack.push(static_cast<F64>(lhs + rhs));
758 }
759 DirectiveError FpySequencer::op_fsub() {
760  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
762  }
763  F64 rhs = this->m_runtime.stack.pop<F64>();
764  F64 lhs = this->m_runtime.stack.pop<F64>();
765  this->m_runtime.stack.push(static_cast<F64>(lhs - rhs));
767 }
768 DirectiveError FpySequencer::op_fmul() {
769  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
771  }
772  F64 rhs = this->m_runtime.stack.pop<F64>();
773  F64 lhs = this->m_runtime.stack.pop<F64>();
774  this->m_runtime.stack.push(static_cast<F64>(lhs * rhs));
776 }
777 DirectiveError FpySequencer::op_fdiv() {
778  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
780  }
781  F64 rhs = this->m_runtime.stack.pop<F64>();
782  F64 lhs = this->m_runtime.stack.pop<F64>();
783  this->m_runtime.stack.push(static_cast<F64>(lhs / rhs));
785 }
786 DirectiveError FpySequencer::op_fpow() {
787  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
789  }
790  F64 rhs = this->m_runtime.stack.pop<F64>();
791  F64 lhs = this->m_runtime.stack.pop<F64>();
792  this->m_runtime.stack.push(static_cast<F64>(pow(lhs, rhs)));
794 }
795 DirectiveError FpySequencer::op_flog() {
796  if (this->m_runtime.stack.size < sizeof(F64)) {
798  }
799  F64 val = this->m_runtime.stack.pop<F64>();
800  if (val <= 0.0) {
802  }
803  this->m_runtime.stack.push(static_cast<F64>(log(val)));
805 }
806 DirectiveError FpySequencer::op_fmod() {
807  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
809  }
810  F64 rhs = this->m_runtime.stack.pop<F64>();
811  if (rhs == 0.0) {
813  }
814  F64 lhs = this->m_runtime.stack.pop<F64>();
815  this->m_runtime.stack.push(static_cast<F64>(lhs - rhs * std::floor(lhs / rhs)));
817 }
818 DirectiveError FpySequencer::op_siext_8_64() {
819  if (this->m_runtime.stack.size < sizeof(I8)) {
821  }
822  I8 src = this->m_runtime.stack.pop<I8>();
823  this->m_runtime.stack.push(static_cast<I64>(src));
825 }
826 DirectiveError FpySequencer::op_siext_16_64() {
827  if (this->m_runtime.stack.size < sizeof(I16)) {
829  }
830  I16 src = this->m_runtime.stack.pop<I16>();
831  this->m_runtime.stack.push(static_cast<I64>(src));
833 }
834 DirectiveError FpySequencer::op_siext_32_64() {
835  if (this->m_runtime.stack.size < sizeof(I32)) {
837  }
838  I32 src = this->m_runtime.stack.pop<I32>();
839  this->m_runtime.stack.push(static_cast<I64>(src));
841 }
842 DirectiveError FpySequencer::op_ziext_8_64() {
843  if (this->m_runtime.stack.size < sizeof(U8)) {
845  }
846  U8 src = this->m_runtime.stack.pop<U8>();
847  this->m_runtime.stack.push(static_cast<U64>(src));
849 }
850 DirectiveError FpySequencer::op_ziext_16_64() {
851  if (this->m_runtime.stack.size < sizeof(U16)) {
853  }
854  U16 src = this->m_runtime.stack.pop<U16>();
855  this->m_runtime.stack.push(static_cast<U64>(src));
857 }
858 DirectiveError FpySequencer::op_ziext_32_64() {
859  if (this->m_runtime.stack.size < sizeof(U32)) {
861  }
862  U32 src = this->m_runtime.stack.pop<U32>();
863  this->m_runtime.stack.push(static_cast<U64>(src));
865 }
866 DirectiveError FpySequencer::op_itrunc_64_8() {
867  if (this->m_runtime.stack.size < sizeof(U64)) {
869  }
870  U64 src = this->m_runtime.stack.pop<U64>();
871  this->m_runtime.stack.push(static_cast<U8>(src));
873 }
874 DirectiveError FpySequencer::op_itrunc_64_16() {
875  if (this->m_runtime.stack.size < sizeof(U64)) {
877  }
878  U64 src = this->m_runtime.stack.pop<U64>();
879  this->m_runtime.stack.push(static_cast<U16>(src));
881 }
882 DirectiveError FpySequencer::op_itrunc_64_32() {
883  if (this->m_runtime.stack.size < sizeof(U64)) {
885  }
886  U64 src = this->m_runtime.stack.pop<U64>();
887  this->m_runtime.stack.push(static_cast<U32>(src));
889 }
890 Signal FpySequencer::stackOp_directiveHandler(const FpySequencer_StackOpDirective& directive, DirectiveError& error) {
891  // coding error, should not have gotten to this stack op handler
892  FW_ASSERT(directive.get__op() >= Fpy::DirectiveId::OR && directive.get__op() <= Fpy::DirectiveId::ITRUNC_64_32,
893  static_cast<FwAssertArgType>(directive.get__op()));
894 
895  switch (directive.get__op()) {
897  error = this->op_or();
898  break;
900  error = this->op_and();
901  break;
903  error = this->op_ieq();
904  break;
906  error = this->op_ine();
907  break;
909  error = this->op_ult();
910  break;
912  error = this->op_ule();
913  break;
915  error = this->op_ugt();
916  break;
918  error = this->op_uge();
919  break;
921  error = this->op_slt();
922  break;
924  error = this->op_sle();
925  break;
927  error = this->op_sgt();
928  break;
930  error = this->op_sge();
931  break;
933  error = this->op_feq();
934  break;
936  error = this->op_fne();
937  break;
939  error = this->op_flt();
940  break;
942  error = this->op_fle();
943  break;
945  error = this->op_fgt();
946  break;
948  error = this->op_fge();
949  break;
951  error = this->op_not();
952  break;
954  error = this->op_fpext();
955  break;
957  error = this->op_fptrunc();
958  break;
960  error = this->op_fptosi();
961  break;
963  error = this->op_fptoui();
964  break;
966  error = this->op_sitofp();
967  break;
969  error = this->op_uitofp();
970  break;
972  error = this->op_add();
973  break;
975  error = this->op_sub();
976  break;
978  error = this->op_mul();
979  break;
981  error = this->op_udiv();
982  break;
984  error = this->op_sdiv();
985  break;
987  error = this->op_umod();
988  break;
990  error = this->op_smod();
991  break;
993  error = this->op_fadd();
994  break;
996  error = this->op_fsub();
997  break;
999  error = this->op_fmul();
1000  break;
1002  error = this->op_fdiv();
1003  break;
1005  error = this->op_fpow();
1006  break;
1008  error = this->op_flog();
1009  break;
1011  error = this->op_fmod();
1012  break;
1014  error = this->op_siext_8_64();
1015  break;
1017  error = this->op_siext_16_64();
1018  break;
1020  error = this->op_siext_32_64();
1021  break;
1023  error = this->op_ziext_8_64();
1024  break;
1026  error = this->op_ziext_16_64();
1027  break;
1029  error = this->op_ziext_32_64();
1030  break;
1032  error = this->op_itrunc_64_8();
1033  break;
1035  error = this->op_itrunc_64_16();
1036  break;
1038  error = this->op_itrunc_64_32();
1039  break;
1040  default:
1041  FW_ASSERT(0, directive.get__op());
1042  break;
1043  }
1044  if (error != DirectiveError::NO_ERROR) {
1046  }
1048 }
1049 
1050 Signal FpySequencer::exit_directiveHandler(const FpySequencer_ExitDirective& directive, DirectiveError& error) {
1051  if (this->m_runtime.stack.size < 1) {
1054  }
1055  U8 errorCode = this->m_runtime.stack.pop<U8>();
1056  // exit(0), no error
1057  if (errorCode == 0) {
1058  // just goto the end of the sequence
1059  this->m_runtime.nextStatementIndex = this->m_sequenceObj.get_header().get_statementCount();
1061  }
1062  // otherwise, kill the sequence here
1063  // raise the user defined error code as an event
1064  this->log_WARNING_HI_SequenceExitedWithError(this->m_sequenceFilePath, errorCode);
1067 }
1068 
1069 Signal FpySequencer::allocate_directiveHandler(const FpySequencer_AllocateDirective& directive, DirectiveError& error) {
1070  if (this->m_runtime.stack.size + directive.get_size() > Fpy::MAX_STACK_SIZE) {
1073  }
1074  this->m_runtime.stack.pushZeroes(directive.get_size());
1076 }
1077 
1078 Signal FpySequencer::storeConstOffset_directiveHandler(const FpySequencer_StoreConstOffsetDirective& directive,
1079  DirectiveError& error) {
1080  if (this->m_runtime.stack.size < directive.get_size()) {
1081  // not enough bytes to pop
1084  }
1085  Fpy::StackSizeType stackOffset = this->m_runtime.stack.lvarOffset() + directive.get_lvarOffset();
1086  // if we popped these bytes off, and put them in lvar array, would we go out of bounds
1087  if (stackOffset + directive.get_size() > this->m_runtime.stack.size - directive.get_size()) {
1088  // write into lvar array would go out of bounds
1091  }
1092  // i believe we can be sure the regions are not overlapping, due to the above check
1093  memcpy(this->m_runtime.stack.bytes + stackOffset, this->m_runtime.stack.top() - directive.get_size(),
1094  directive.get_size());
1095  this->m_runtime.stack.size -= directive.get_size();
1097 }
1098 
1099 Signal FpySequencer::load_directiveHandler(const FpySequencer_LoadDirective& directive, DirectiveError& error) {
1100  if (this->m_runtime.stack.size + directive.get_size() > Fpy::MAX_STACK_SIZE) {
1103  }
1104  // calculate the offset in the lvar array we're going to pull from
1105  Fpy::StackSizeType stackOffset = this->m_runtime.stack.lvarOffset() + directive.get_lvarOffset();
1106  // if we accessed these bytes, would we go out of bounds
1107  if (stackOffset + directive.get_size() > this->m_runtime.stack.size) {
1110  }
1111  // copy from lvar array to top of stack, add to stack size.
1112  memcpy(this->m_runtime.stack.top(), this->m_runtime.stack.bytes + stackOffset, directive.get_size());
1113  this->m_runtime.stack.size += directive.get_size();
1115 }
1116 
1117 Signal FpySequencer::pushVal_directiveHandler(const FpySequencer_PushValDirective& directive, DirectiveError& error) {
1118  if (this->m_runtime.stack.size + directive.get__valSize() > Fpy::MAX_STACK_SIZE) {
1121  }
1122  // copy from the bytearray in the directive to the stack, add to stack size.
1123  memcpy(this->m_runtime.stack.top(), directive.get_val(), directive.get__valSize());
1124  this->m_runtime.stack.size += static_cast<Fpy::StackSizeType>(directive.get__valSize());
1126 }
1127 
1128 Signal FpySequencer::discard_directiveHandler(const FpySequencer_DiscardDirective& directive, DirectiveError& error) {
1129  if (this->m_runtime.stack.size < directive.get_size()) {
1132  }
1133  // drop the specified amount of bytes off the stack. simple as.
1134  this->m_runtime.stack.size -= directive.get_size();
1136 }
1137 
1138 Signal FpySequencer::memCmp_directiveHandler(const FpySequencer_MemCmpDirective& directive, DirectiveError& error) {
1139  // we are going to pop 2x the size off the stack. check that we can
1140  if (this->m_runtime.stack.size < directive.get_size() * 2) {
1143  }
1144 
1145  // find the starting offsets of the two byte arrays
1146  U64 lhsOffset = this->m_runtime.stack.size - directive.get_size() * 2;
1147  U64 rhsOffset = this->m_runtime.stack.size - directive.get_size();
1148 
1149  // "officially" remove them from the stack
1150  // you have to do this before pushing to the stack, otherwise the result would get placed
1151  // after the byte arrays
1152  this->m_runtime.stack.size -= directive.get_size() * 2;
1153 
1154  // memcmp the two byte arrays, push 1 if they were equal, 0 otherwise
1155  if (memcmp(this->m_runtime.stack.bytes + lhsOffset, this->m_runtime.stack.bytes + rhsOffset,
1156  directive.get_size()) == 0) {
1157  this->m_runtime.stack.push<U8>(1);
1158  } else {
1159  this->m_runtime.stack.push<U8>(0);
1160  }
1162 }
1163 
1164 Signal FpySequencer::stackCmd_directiveHandler(const FpySequencer_StackCmdDirective& directive, DirectiveError& error) {
1165  if (this->m_runtime.stack.size < static_cast<U64>(directive.get_argsSize() + sizeof(FwOpcodeType))) {
1168  }
1169 
1170  // pop the opcode of the cmd off the stack
1171  // note this means that, unlike the actual byte array that the dispatcher gets,
1172  // these cmds have opcode after the argument buffer
1173  FwOpcodeType opcode = this->m_runtime.stack.pop<FwOpcodeType>();
1174  U64 argBufOffset = this->m_runtime.stack.size - directive.get_argsSize();
1175 
1176  // update the opcode of the cmd we will await
1177  this->m_runtime.currentCmdOpcode = opcode;
1178 
1179  // also pop the args off the stack
1180  this->m_runtime.stack.size -= directive.get_argsSize();
1181 
1182  if (this->sendCmd(opcode, this->m_runtime.stack.bytes + argBufOffset, directive.get_argsSize()) ==
1185  } else {
1186  // now tell the SM to wait some more until we get the cmd response back
1187  // if we've already got the response back this should be harmless
1189  }
1190 
1192 }
1193 
1194 Signal FpySequencer::pushTime_directiveHandler(const FpySequencer_PushTimeDirective& directive, DirectiveError& error) {
1195  if (Fpy::MAX_STACK_SIZE - Fw::Time::SERIALIZED_SIZE < this->m_runtime.stack.size) {
1198  }
1199 
1200  Fw::Time currentTime = this->getTime();
1201 
1202  U8 currentTimeBuf[Fw::Time::SERIALIZED_SIZE] = {};
1203  Fw::ExternalSerializeBuffer timeEsb(currentTimeBuf, Fw::Time::SERIALIZED_SIZE);
1204  Fw::SerializeStatus stat = timeEsb.serializeFrom(currentTime);
1205 
1206  // coding error if this failed, we should have enough space
1207  FW_ASSERT(stat == Fw::SerializeStatus::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(stat));
1208 
1209  // push time to end of stack
1210  memcpy(this->m_runtime.stack.bytes + this->m_runtime.stack.size, timeEsb.getBuffAddr(), timeEsb.getSize());
1211  this->m_runtime.stack.size += static_cast<Fpy::StackSizeType>(timeEsb.getSize());
1213 }
1214 
1215 Signal FpySequencer::setFlag_directiveHandler(const FpySequencer_SetFlagDirective& directive, DirectiveError& error) {
1216  if (this->m_runtime.stack.size < 1) {
1219  }
1220  if (directive.get_flagIdx() >= Fpy::FLAG_COUNT) {
1223  }
1224 
1225  // 1 if the stack bool is nonzero, 0 otherwise
1226  U8 flagVal = this->m_runtime.stack.pop<U8>() != 0;
1227 
1228  this->m_runtime.flags[directive.get_flagIdx()] = flagVal == 1;
1230 }
1231 
1232 Signal FpySequencer::getFlag_directiveHandler(const FpySequencer_GetFlagDirective& directive, DirectiveError& error) {
1233  if (Fpy::MAX_STACK_SIZE - this->m_runtime.stack.size < 1) {
1236  }
1237  if (directive.get_flagIdx() >= Fpy::FLAG_COUNT) {
1240  }
1241 
1242  bool flagVal = this->m_runtime.flags[directive.get_flagIdx()];
1243  this->m_runtime.stack.push<U8>(flagVal);
1245 }
1246 
1247 Signal FpySequencer::getField_directiveHandler(const FpySequencer_GetFieldDirective& directive, DirectiveError& error) {
1248  if (this->m_runtime.stack.size < sizeof(Fpy::StackSizeType) ||
1249  this->m_runtime.stack.size < directive.get_parentSize()) {
1252  }
1253 
1254  Fpy::StackSizeType offset = this->m_runtime.stack.pop<Fpy::StackSizeType>();
1255 
1256  if (offset + directive.get_memberSize() > directive.get_parentSize()) {
1257  // i think it's somewhat ambiguous whether this is a stack access out of bounds
1258  // but there isn't really an error code that better reflects this, and i guess
1259  // it's technically true
1262  }
1263 
1264  // the resulting bytes should move to the start of the parent array
1265 
1266  // get pointer to the start of the parent
1267  U8* parentStartPtr = this->m_runtime.stack.top() - directive.get_parentSize();
1268  // move the field bytes to the start of the parent
1269  memmove(parentStartPtr, parentStartPtr + offset, directive.get_memberSize());
1270  // adjust stack size by the diff between the member and the parent
1271  this->m_runtime.stack.size -= (directive.get_parentSize() - directive.get_memberSize());
1273 }
1274 
1275 Signal FpySequencer::peek_directiveHandler(const FpySequencer_PeekDirective& directive, DirectiveError& error) {
1276  // must have at least two StackSizeType on stack
1277  if (this->m_runtime.stack.size < sizeof(Fpy::StackSizeType) * 2) {
1280  }
1281 
1282  Fpy::StackSizeType offset = this->m_runtime.stack.pop<Fpy::StackSizeType>();
1283  if (offset > this->m_runtime.stack.size) {
1284  // would access past the bottom of the stack
1285  // note we allow the equals case because the byteCount might be 0
1288  }
1289  Fpy::StackSizeType byteCount = this->m_runtime.stack.pop<Fpy::StackSizeType>();
1290  if (Fpy::MAX_STACK_SIZE - this->m_runtime.stack.size < byteCount) {
1291  // we would overflow the stack if we pushed this many bytes to it
1294  }
1295  if (this->m_runtime.stack.size < byteCount + offset) {
1296  // would access past the bottom of the stack
1299  }
1300  // start copying from the lowest byte of the src array
1301  U8* src = this->m_runtime.stack.top() - offset - byteCount;
1302  this->m_runtime.stack.push(src, byteCount);
1304 }
1305 
1306 Signal FpySequencer::store_directiveHandler(const FpySequencer_StoreDirective& directive, DirectiveError& error) {
1307  if (this->m_runtime.stack.size < directive.get_size() + sizeof(Fpy::StackSizeType)) {
1308  // not enough bytes to pop the value and the stack offset
1311  }
1312  Fpy::StackSizeType stackOffset =
1313  this->m_runtime.stack.lvarOffset() + this->m_runtime.stack.pop<Fpy::StackSizeType>();
1314  // if we popped these bytes off, and put them in lvar array, would we go out of bounds
1315  if (stackOffset + directive.get_size() > this->m_runtime.stack.size - directive.get_size()) {
1316  // write into lvar array would go out of bounds
1319  }
1320  // i believe we can be sure the regions are not overlapping, due to the above check
1321  memcpy(this->m_runtime.stack.bytes + stackOffset, this->m_runtime.stack.top() - directive.get_size(),
1322  directive.get_size());
1323  this->m_runtime.stack.size -= directive.get_size();
1325 }
1326 
1327 } // namespace Svc
Serialization/Deserialization operation was successful.
sets the index of the next directive to execute
U8 * getBuffAddr()
Get buffer address for data filling (non-const version)
Definition: PrmBuffer.cpp:42
FwIdType FwOpcodeType
The type of a command opcode.
void directive_load_internalInterfaceHandler(const Svc::FpySequencer_LoadDirective &directive) override
Internal interface handler for directive_load.
SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG) override
Serialize an 8-bit unsigned integer value.
U16 get_statementCount() const
Get member statementCount.
branches based off of the top byte of the stack
void directive_if_internalInterfaceHandler(const Svc::FpySequencer_IfDirective &directive) override
Internal interface handler for directive_if.
Representing success.
PlatformSizeType FwSizeType
void directive_stackOp_internalInterfaceHandler(const Svc::FpySequencer_StackOpDirective &directive) override
Internal interface handler for directive_stackOp.
called when statement successfully executed. only raised in the RUNNING.AWAITING_CMD_RESPONSE state ...
void directive_getField_internalInterfaceHandler(const Svc::FpySequencer_GetFieldDirective &directive) override
Internal interface handler for directive_getField.
Fw::TlmValid getTlmChan_out(FwIndexType portNum, FwChanIdType id, Fw::Time &timeTag, Fw::TlmBuffer &val)
Invoke output port getTlmChan.
Serializable::SizeType getSize() const override
Get current buffer size.
void log_WARNING_HI_SequenceExitedWithError(const Fw::StringBase &filePath, U8 errorCode) const
Log event SequenceExitedWithError.
void directive_pushTlmValAndTime_internalInterfaceHandler(const Svc::FpySequencer_PushTlmValAndTimeDirective &directive) override
Internal interface handler for directive_pushTlmValAndTime.
int8_t I8
8-bit signed integer
Definition: BasicTypes.h:50
void directive_constCmd_internalInterfaceHandler(const Svc::FpySequencer_ConstCmdDirective &directive) override
Internal interface handler for directive_constCmd.
pop an opcode and arg buf off the stack, send to cmd dispatcher and await response ...
void directive_peek_internalInterfaceHandler(const Svc::FpySequencer_PeekDirective &directive) override
Internal interface handler for directive_peek.
void sequencer_sendSignal_stmtResponse_success()
Send signal stmtResponse_success to state machine sequencer.
void directive_storeConstOffset_internalInterfaceHandler(const Svc::FpySequencer_StoreConstOffsetDirective &directive) override
Internal interface handler for directive_storeConstOffset.
void directive_memCmp_internalInterfaceHandler(const Svc::FpySequencer_MemCmpDirective &directive) override
Internal interface handler for directive_memCmp.
void directive_pushVal_internalInterfaceHandler(const Svc::FpySequencer_PushValDirective &directive) override
Internal interface handler for directive_pushVal.
void directive_pushPrm_internalInterfaceHandler(const Svc::FpySequencer_PushPrmDirective &directive) override
Internal interface handler for directive_pushPrm.
pops bytes off the top of the stack and does nothing with them
void directive_pushTime_internalInterfaceHandler(const Svc::FpySequencer_PushTimeDirective &directive) override
Internal interface handler for directive_pushTime.
U8 FwTimeContextStoreType
The type used to serialize a time context value.
pops some bytes off the stack and puts them in lvar array
SerializeStatus
forward declaration for string
float F32
32-bit floating point
Definition: BasicTypes.h:83
Fpy::DirectiveErrorCode DirectiveError
void directive_allocate_internalInterfaceHandler(const Svc::FpySequencer_AllocateDirective &directive) override
Internal interface handler for directive_allocate.
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 directive_stackCmd_internalInterfaceHandler(const Svc::FpySequencer_StackCmdDirective &directive) override
Internal interface handler for directive_stackCmd.
void directive_discard_internalInterfaceHandler(const Svc::FpySequencer_DiscardDirective &directive) override
Internal interface handler for directive_discard.
pop two byte arrays off the top of the stack, call memcmp, push 1 if they were equal, 0 otherwise
Svc::Fpy::Header & get_header()
Get member header.
Omit length from serialization.
void directive_store_internalInterfaceHandler(const Svc::FpySequencer_StoreDirective &directive) override
Internal interface handler for directive_store.
void directive_exit_internalInterfaceHandler(const Svc::FpySequencer_ExitDirective &directive) override
Internal interface handler for directive_exit.
External serialize buffer with no copy semantics.
Svc::Fpy::DirectiveId::T get__op() const
Get member _op.
void directive_waitAbs_internalInterfaceHandler(const FpySequencer_WaitAbsDirective &directive) override
Internal interface handler for directive_waitAbs.
U8 * getBuffAddr()
Get buffer address for data filling (non-const version)
Definition: TlmBuffer.cpp:42
void directive_goto_internalInterfaceHandler(const Svc::FpySequencer_GotoDirective &directive) override
Internal interface handler for directive_goto.
peeks at N bytes from the stack, starting from an offset relative to the top of the stack ...
void sequencer_sendSignal_stmtResponse_failure()
Send signal stmtResponse_failure to state machine sequencer.
void sequencer_sendSignal_stmtResponse_beginSleep()
Send signal stmtResponse_beginSleep to state machine sequencer.
Representing failure.
stores bytes from the top of the stack into a memory location, determined by the stack ...
void directive_getFlag_internalInterfaceHandler(const Svc::FpySequencer_GetFlagDirective &directive) override
Internal interface handler for directive_getFlag.
sleeps for a relative duration from the current time
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:53
gets bytes from lvar array and pushes them to stack
static U32 min(const U32 a, const U32 b)
Definition: Checksum.cpp:16
static Time add(const Time &a, const Time &b)
Definition: Time.cpp:134
void sequencer_sendSignal_stmtResponse_keepWaiting()
Send signal stmtResponse_keepWaiting to state machine sequencer.
called when the statement unsuccessfully executed. only raised in the RUNNING.AWAITING_CMD_RESPONSE s...
double F64
64-bit floating point (double). Required for compiler-supplied double promotion.
Definition: BasicTypes.h:85
bool isConnected_prmGet_OutputPort(FwIndexType portNum)
void cmdOut_out(FwIndexType portNum, Fw::ComBuffer &data, U32 context)
Invoke output port cmdOut.
RateGroupDivider component implementation.
Enum representing parameter validity.
void directive_setFlag_internalInterfaceHandler(const Svc::FpySequencer_SetFlagDirective &directive) override
Internal interface handler for directive_setFlag.
Fw::ParamValid getParam_out(FwIndexType portNum, FwPrmIdType id, Fw::ParamBuffer &val)
Invoke output port getParam.
pushes the current Fw.Time struct to the stack
pops a bool off the stack, sets a flag with a specific index to that bool
bool isConnected_getTlmChan_OutputPort(FwIndexType portNum)
called when the statement is telling the sequencer to await a later stmt response ...
gets a flag and pushes its value as a U8 to the stack
FpySequencer_SequencerStateMachineStateMachineBase::Signal Signal
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Success/Failure.
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.
U32 StackSizeType
the type which everything referencing a size or offset on the stack is represented in ...
void directive_pushTlmVal_internalInterfaceHandler(const Svc::FpySequencer_PushTlmValDirective &directive) override
Internal interface handler for directive_pushTlmVal.
#define U64(C)
Definition: sha.h:181