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 <type_traits>
3 #include "Fw/Com/ComPacket.hpp"
5 
6 namespace Svc {
7 
8 void FpySequencer::sendSignal(Signal signal) {
9  switch (signal) {
12  break;
13  }
16  break;
17  }
20  break;
21  }
24  break;
25  }
26  default: {
27  FW_ASSERT(0, static_cast<FwAssertArgType>(signal));
28  }
29  }
30 }
31 
32 // utility method for updating telemetry based on a directive error code
33 void FpySequencer::handleDirectiveErrorCode(Fpy::DirectiveId id, DirectiveError err) {
34  this->m_tlm.lastDirectiveError = err;
35  if (err != DirectiveError::NO_ERROR) {
36  this->m_tlm.directiveErrorIndex = this->currentStatementIdx();
37  this->m_tlm.directiveErrorId = id;
38  }
39 }
40 
41 Fw::Success FpySequencer::sendCmd(FwOpcodeType opcode, const U8* argBuf, FwSizeType argBufSize) {
42  Fw::ComBuffer cmdBuf;
43  Fw::SerializeStatus stat =
44  cmdBuf.serializeFrom(static_cast<FwPacketDescriptorType>(Fw::ComPacketType::FW_PACKET_COMMAND));
45  // TODO should I assert here? this really shouldn't fail, I should just add a static assert
46  // on com buf size and then assert here
48  return Fw::Success::FAILURE;
49  }
50  stat = cmdBuf.serializeFrom(opcode);
52  return Fw::Success::FAILURE;
53  }
54  stat = cmdBuf.serializeFrom(argBuf, argBufSize, Fw::Serialization::OMIT_LENGTH);
56  return Fw::Success::FAILURE;
57  }
58 
59  // calculate the unique command identifier:
60  // cmd UID is formatted like XXYY, where XX are the first two bytes of the m_sequencesStarted counter
61  // and YY are the first two bytes of the m_statementsDispatched counter.
62  // this way, we know when we get a cmd back A) whether or not it's from this sequence (modulo 2^16) and B)
63  // whether or not it's this specific instance of the cmd in the sequence, and not another one with the same opcode
64  // somewhere else in the file.
65  // if we put this uid in the context we send to the cmdDisp, we will get it back when the cmd returns
66  U32 cmdUid =
67  static_cast<U32>(((this->m_sequencesStarted & 0xFFFF) << 16) | (this->m_statementsDispatched & 0xFFFF));
68 
69  this->cmdOut_out(0, cmdBuf, cmdUid);
70 
71  return Fw::Success::SUCCESS;
72 }
73 
77  this->sendSignal(this->waitRel_directiveHandler(directive, error));
78  handleDirectiveErrorCode(Fpy::DirectiveId::WAIT_REL, error);
79 }
80 
84  this->sendSignal(this->waitAbs_directiveHandler(directive, error));
85  handleDirectiveErrorCode(Fpy::DirectiveId::WAIT_ABS, error);
86 }
87 
91  this->sendSignal(this->goto_directiveHandler(directive, error));
92  handleDirectiveErrorCode(Fpy::DirectiveId::GOTO, error);
93 }
94 
98  this->sendSignal(this->if_directiveHandler(directive, error));
99  handleDirectiveErrorCode(Fpy::DirectiveId::IF, error);
100 }
101 
105  this->sendSignal(this->noOp_directiveHandler(directive, error));
106  handleDirectiveErrorCode(Fpy::DirectiveId::NO_OP, error);
107 }
108 
111  const Svc::FpySequencer_PushTlmValDirective& directive) {
113  this->sendSignal(this->pushTlmVal_directiveHandler(directive, error));
114  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_TLM_VAL, error);
115 }
116 
121  this->sendSignal(this->pushTlmValAndTime_directiveHandler(directive, error));
122  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_TLM_VAL_AND_TIME, error);
123 }
124 
128  this->sendSignal(this->pushPrm_directiveHandler(directive, error));
129  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_PRM, error);
130 }
131 
135  this->sendSignal(this->constCmd_directiveHandler(directive, error));
136  handleDirectiveErrorCode(Fpy::DirectiveId::CONST_CMD, error);
137 }
138 
142  this->sendSignal(this->stackOp_directiveHandler(directive, error));
143  handleDirectiveErrorCode(directive.get__op(), error);
144 }
145 
149  this->sendSignal(this->exit_directiveHandler(directive, error));
150  handleDirectiveErrorCode(Fpy::DirectiveId::EXIT, error);
151 }
152 
156  this->sendSignal(this->allocate_directiveHandler(directive, error));
157  handleDirectiveErrorCode(Fpy::DirectiveId::ALLOCATE, error);
158 }
159 
164  this->sendSignal(this->storeConstOffset_directiveHandler(directive, error));
165  handleDirectiveErrorCode(Fpy::DirectiveId::STORE_CONST_OFFSET, error);
166 }
167 
171  this->sendSignal(this->pushVal_directiveHandler(directive, error));
172  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_VAL, error);
173 }
174 
178  this->sendSignal(this->load_directiveHandler(directive, error));
179  handleDirectiveErrorCode(Fpy::DirectiveId::LOAD, error);
180 }
181 
185  this->sendSignal(this->discard_directiveHandler(directive, error));
186  handleDirectiveErrorCode(Fpy::DirectiveId::DISCARD, error);
187 }
188 
192  this->sendSignal(this->memCmp_directiveHandler(directive, error));
193  handleDirectiveErrorCode(Fpy::DirectiveId::MEMCMP, error);
194 }
195 
199  this->sendSignal(this->stackCmd_directiveHandler(directive, error));
200  handleDirectiveErrorCode(Fpy::DirectiveId::STACK_CMD, error);
201 }
202 
206  this->sendSignal(this->pushTime_directiveHandler(directive, error));
207  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_TIME, error);
208 }
209 
213  this->sendSignal(this->setFlag_directiveHandler(directive, error));
214  handleDirectiveErrorCode(Fpy::DirectiveId::SET_FLAG, error);
215 }
216 
220  this->sendSignal(this->getFlag_directiveHandler(directive, error));
221  handleDirectiveErrorCode(Fpy::DirectiveId::GET_FLAG, error);
222 }
223 
227  this->sendSignal(this->getField_directiveHandler(directive, error));
228  handleDirectiveErrorCode(Fpy::DirectiveId::GET_FIELD, error);
229 }
230 
234  this->sendSignal(this->peek_directiveHandler(directive, error));
235  handleDirectiveErrorCode(Fpy::DirectiveId::PEEK, error);
236 }
237 
241  this->sendSignal(this->store_directiveHandler(directive, error));
242  handleDirectiveErrorCode(Fpy::DirectiveId::STORE, error);
243 }
244 
246 Signal FpySequencer::waitRel_directiveHandler(const FpySequencer_WaitRelDirective& directive, DirectiveError& error) {
247  if (this->m_runtime.stack.size < 8) {
250  }
251 
252  Fw::Time wakeupTime = this->getTime();
253 
254  U32 uSeconds = this->m_runtime.stack.pop<U32>();
255  U32 seconds = this->m_runtime.stack.pop<U32>();
256 
257  wakeupTime.add(seconds, uSeconds);
258  this->m_runtime.wakeupTime = wakeupTime;
260 }
261 
263 Signal FpySequencer::waitAbs_directiveHandler(const FpySequencer_WaitAbsDirective& directive, DirectiveError& error) {
264  if (this->m_runtime.stack.size < 10 + sizeof(FwTimeContextStoreType)) {
267  }
268 
269  U32 uSeconds = this->m_runtime.stack.pop<U32>();
270  U32 seconds = this->m_runtime.stack.pop<U32>();
271  FwTimeContextStoreType ctx = this->m_runtime.stack.pop<FwTimeContextStoreType>();
272  U16 base = this->m_runtime.stack.pop<U16>();
273 
274  this->m_runtime.wakeupTime = Fw::Time(static_cast<TimeBase::T>(base), ctx, seconds, uSeconds);
276 }
277 
279 Signal FpySequencer::goto_directiveHandler(const FpySequencer_GotoDirective& directive, DirectiveError& error) {
280  // check within sequence bounds, or at EOF (we allow == case cuz this just ends the sequence)
281  if (directive.get_statementIndex() > m_sequenceObj.get_header().get_statementCount()) {
284  }
285  m_runtime.nextStatementIndex = directive.get_statementIndex();
287 }
288 
290 Signal FpySequencer::if_directiveHandler(const FpySequencer_IfDirective& directive, DirectiveError& error) {
291  if (this->m_runtime.stack.size < 1) {
294  }
295  // check within sequence bounds, or at EOF (we allow == case cuz this just ends the sequence)
296  if (directive.get_falseGotoStmtIndex() > m_sequenceObj.get_header().get_statementCount()) {
299  }
300 
301  if (this->m_runtime.stack.pop<U8>() != 0) {
302  // proceed to next instruction
304  }
305 
306  // conditional false case
307  this->m_runtime.nextStatementIndex = directive.get_falseGotoStmtIndex();
309 }
310 
311 Signal FpySequencer::noOp_directiveHandler(const FpySequencer_NoOpDirective& directive, DirectiveError& error) {
313 }
314 
315 Signal FpySequencer::pushTlmVal_directiveHandler(const FpySequencer_PushTlmValDirective& directive,
316  DirectiveError& error) {
317  if (!this->isConnected_getTlmChan_OutputPort(0)) {
320  }
321  Fw::Time tlmTime;
322  Fw::TlmBuffer tlmValue;
323  Fw::TlmValid valid = this->getTlmChan_out(0, directive.get_chanId(), tlmTime, tlmValue);
324 
325  if (valid != Fw::TlmValid::VALID) {
326  // could not find this tlm chan
329  }
330 
331  if (Fpy::MAX_STACK_SIZE - tlmValue.getSize() < this->m_runtime.stack.size) {
334  }
335  this->m_runtime.stack.push(tlmValue.getBuffAddr(), static_cast<Fpy::StackSizeType>(tlmValue.getSize()));
337 }
338 
339 Signal FpySequencer::pushTlmValAndTime_directiveHandler(const FpySequencer_PushTlmValAndTimeDirective& directive,
340  DirectiveError& error) {
341  if (!this->isConnected_getTlmChan_OutputPort(0)) {
344  }
345 
346  Fw::Time tlmTime;
347  Fw::TlmBuffer tlmValue;
348  Fw::TlmValid valid = this->getTlmChan_out(0, directive.get_chanId(), tlmTime, tlmValue);
349 
350  if (valid != Fw::TlmValid::VALID) {
351  // could not find this tlm chan
354  }
355 
356  U8 tlmTimeBuf[Fw::Time::SERIALIZED_SIZE] = {};
358  Fw::SerializeStatus stat = timeEsb.serializeFrom(tlmTime);
359 
360  // coding error if this failed, we should have enough space
361  FW_ASSERT(stat == Fw::SerializeStatus::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(stat));
362 
363  // check that our stack won't overflow if we put both val and time on it
364  if (Fpy::MAX_STACK_SIZE - tlmValue.getSize() - timeEsb.getSize() < this->m_runtime.stack.size) {
367  }
368 
369  // push tlm to end of stack
370  this->m_runtime.stack.push(tlmValue.getBuffAddr(), static_cast<Fpy::StackSizeType>(tlmValue.getSize()));
371  // now push time to end of stack
372  this->m_runtime.stack.push(timeEsb.getBuffAddr(), static_cast<Fpy::StackSizeType>(timeEsb.getSize()));
374 }
375 
376 Signal FpySequencer::pushPrm_directiveHandler(const FpySequencer_PushPrmDirective& directive, DirectiveError& error) {
377  if (!this->isConnected_prmGet_OutputPort(0)) {
380  }
381 
382  Fw::ParamBuffer prmValue;
383  Fw::ParamValid valid = this->getParam_out(0, directive.get_prmId(), prmValue);
384 
385  if (valid != Fw::ParamValid::VALID) {
386  // could not find this prm in the DB
389  }
390 
391  if (Fpy::MAX_STACK_SIZE - prmValue.getSize() < this->m_runtime.stack.size) {
394  }
395 
396  this->m_runtime.stack.push(prmValue.getBuffAddr(), static_cast<Fpy::StackSizeType>(prmValue.getSize()));
398 }
399 
400 Signal FpySequencer::constCmd_directiveHandler(const FpySequencer_ConstCmdDirective& directive, DirectiveError& error) {
401  if (this->sendCmd(directive.get_opCode(), directive.get_argBuf(), directive.get__argBufSize()) ==
404  } else {
405  // now tell the SM to wait some more until we get the cmd response back
406  // if we've already got the response back this should be harmless
408  }
409 }
410 
411 DirectiveError FpySequencer::op_or() {
412  if (this->m_runtime.stack.size < sizeof(U8) * 2) {
414  }
415  this->m_runtime.stack.push(static_cast<U8>(this->m_runtime.stack.pop<U8>() | this->m_runtime.stack.pop<U8>()));
417 }
418 DirectiveError FpySequencer::op_and() {
419  if (this->m_runtime.stack.size < sizeof(U8) * 2) {
421  }
422  this->m_runtime.stack.push(static_cast<U8>(this->m_runtime.stack.pop<U8>() & this->m_runtime.stack.pop<U8>()));
424 }
425 DirectiveError FpySequencer::op_ieq() {
426  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
428  }
429  this->m_runtime.stack.push(static_cast<U8>(this->m_runtime.stack.pop<I64>() == this->m_runtime.stack.pop<I64>()));
431 }
432 DirectiveError FpySequencer::op_ine() {
433  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
435  }
436  this->m_runtime.stack.push(static_cast<U8>(this->m_runtime.stack.pop<I64>() != this->m_runtime.stack.pop<I64>()));
438 }
439 DirectiveError FpySequencer::op_ult() {
440  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
442  }
443  U64 rhs = this->m_runtime.stack.pop<U64>();
444  U64 lhs = this->m_runtime.stack.pop<U64>();
445  this->m_runtime.stack.push(static_cast<U8>(lhs < rhs));
447 }
448 DirectiveError FpySequencer::op_ule() {
449  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
451  }
452  U64 rhs = this->m_runtime.stack.pop<U64>();
453  U64 lhs = this->m_runtime.stack.pop<U64>();
454  this->m_runtime.stack.push(static_cast<U8>(lhs <= rhs));
456 }
457 DirectiveError FpySequencer::op_ugt() {
458  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
460  }
461  U64 rhs = this->m_runtime.stack.pop<U64>();
462  U64 lhs = this->m_runtime.stack.pop<U64>();
463  this->m_runtime.stack.push(static_cast<U8>(lhs > rhs));
465 }
466 DirectiveError FpySequencer::op_uge() {
467  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
469  }
470  U64 rhs = this->m_runtime.stack.pop<U64>();
471  U64 lhs = this->m_runtime.stack.pop<U64>();
472  this->m_runtime.stack.push(static_cast<U8>(lhs >= rhs));
474 }
475 DirectiveError FpySequencer::op_slt() {
476  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
478  }
479  I64 rhs = this->m_runtime.stack.pop<I64>();
480  I64 lhs = this->m_runtime.stack.pop<I64>();
481  this->m_runtime.stack.push(static_cast<U8>(lhs < rhs));
483 }
484 DirectiveError FpySequencer::op_sle() {
485  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
487  }
488  I64 rhs = this->m_runtime.stack.pop<I64>();
489  I64 lhs = this->m_runtime.stack.pop<I64>();
490  this->m_runtime.stack.push(static_cast<U8>(lhs <= rhs));
492 }
493 DirectiveError FpySequencer::op_sgt() {
494  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
496  }
497  I64 rhs = this->m_runtime.stack.pop<I64>();
498  I64 lhs = this->m_runtime.stack.pop<I64>();
499  this->m_runtime.stack.push(static_cast<U8>(lhs > rhs));
501 }
502 DirectiveError FpySequencer::op_sge() {
503  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
505  }
506  I64 rhs = this->m_runtime.stack.pop<I64>();
507  I64 lhs = this->m_runtime.stack.pop<I64>();
508  this->m_runtime.stack.push(static_cast<U8>(lhs >= rhs));
510 }
511 DirectiveError FpySequencer::op_feq() {
512  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
514  }
515  F64 rhs = this->m_runtime.stack.pop<F64>();
516  F64 lhs = this->m_runtime.stack.pop<F64>();
517  // eq is true if they are equal and neither is nan
518  this->m_runtime.stack.push(static_cast<U8>((lhs == rhs) ? 1 : 0));
520 }
521 DirectiveError FpySequencer::op_fne() {
522  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
524  }
525  F64 rhs = this->m_runtime.stack.pop<F64>();
526  F64 lhs = this->m_runtime.stack.pop<F64>();
527  // ne is true if they are not equal or either is nan
528  this->m_runtime.stack.push(static_cast<U8>((lhs != rhs) ? 1 : 0));
530 }
531 DirectiveError FpySequencer::op_flt() {
532  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
534  }
535  F64 rhs = this->m_runtime.stack.pop<F64>();
536  F64 lhs = this->m_runtime.stack.pop<F64>();
537  this->m_runtime.stack.push(static_cast<U8>(std::isless(lhs, rhs)));
539 }
540 DirectiveError FpySequencer::op_fle() {
541  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
543  }
544  F64 rhs = this->m_runtime.stack.pop<F64>();
545  F64 lhs = this->m_runtime.stack.pop<F64>();
546  this->m_runtime.stack.push(static_cast<U8>(std::islessequal(lhs, rhs)));
548 }
549 DirectiveError FpySequencer::op_fgt() {
550  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
552  }
553  F64 rhs = this->m_runtime.stack.pop<F64>();
554  F64 lhs = this->m_runtime.stack.pop<F64>();
555  this->m_runtime.stack.push(static_cast<U8>(std::isgreater(lhs, rhs)));
557 }
558 DirectiveError FpySequencer::op_fge() {
559  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
561  }
562  F64 rhs = this->m_runtime.stack.pop<F64>();
563  F64 lhs = this->m_runtime.stack.pop<F64>();
564  this->m_runtime.stack.push(static_cast<U8>(std::isgreaterequal(lhs, rhs)));
566 }
567 DirectiveError FpySequencer::op_not() {
568  if (this->m_runtime.stack.size < sizeof(U8)) {
570  }
571  this->m_runtime.stack.push(static_cast<U8>(this->m_runtime.stack.pop<U8>() == 0));
573 }
574 DirectiveError FpySequencer::op_fpext() {
575  // convert F32 to F64
576  if (this->m_runtime.stack.size < sizeof(F32)) {
578  }
579  this->m_runtime.stack.push(static_cast<F64>(this->m_runtime.stack.pop<F32>()));
581 }
582 DirectiveError FpySequencer::op_fptrunc() {
583  // convert F64 to F32
584  if (this->m_runtime.stack.size < sizeof(F64)) {
586  }
587  this->m_runtime.stack.push(static_cast<F32>(this->m_runtime.stack.pop<F64>()));
589 }
590 DirectiveError FpySequencer::op_fptosi() {
591  if (this->m_runtime.stack.size < sizeof(F64)) {
593  }
594  this->m_runtime.stack.push(static_cast<I64>(this->m_runtime.stack.pop<F64>()));
596 }
597 DirectiveError FpySequencer::op_sitofp() {
598  if (this->m_runtime.stack.size < sizeof(I64)) {
600  }
601  this->m_runtime.stack.push(static_cast<F64>(this->m_runtime.stack.pop<I64>()));
603 }
604 DirectiveError FpySequencer::op_fptoui() {
605  if (this->m_runtime.stack.size < sizeof(F64)) {
607  }
608  this->m_runtime.stack.push(static_cast<U64>(this->m_runtime.stack.pop<F64>()));
610 }
611 DirectiveError FpySequencer::op_uitofp() {
612  if (this->m_runtime.stack.size < sizeof(U64)) {
614  }
615  this->m_runtime.stack.push(static_cast<F64>(this->m_runtime.stack.pop<U64>()));
617 }
618 DirectiveError FpySequencer::op_add() {
619  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
621  }
622  I64 rhs = this->m_runtime.stack.pop<I64>();
623  I64 lhs = this->m_runtime.stack.pop<I64>();
624  // Check for overflow and underflow and return the appropriate error code
625  // Overflow can only occur with both operands positive and occurs when one operand is greater than the maximum value
626  // less the other operand. If either operand is negative or zero, overflow cannot occur.
627  if ((rhs > 0) && (lhs > 0) && ((std::numeric_limits<I64>::max() - rhs) < lhs)) {
629  }
630  // Underflow can only occur with both operands negative and occurs when one operand is less than the minimum value
631  // minus the other operand. If either operand is positive or zero, underflow cannot occur.
632  else if ((rhs < 0) && (lhs < 0) && ((std::numeric_limits<I64>::min() - rhs) > lhs)) {
634  }
635  this->m_runtime.stack.push(static_cast<I64>(lhs + rhs));
637 }
638 DirectiveError FpySequencer::op_sub() {
639  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
641  }
642  I64 rhs = this->m_runtime.stack.pop<I64>();
643  I64 lhs = this->m_runtime.stack.pop<I64>();
644  // Check for overflow and underflow and return the appropriate error code
645  // Overflow can only occur when the left operand is positive and the right operand is negative. It occurs when the
646  // left (positive) operand is greater than the maximum value plus the other (negative) operand. If the right
647  // operand is positive or zero, overflow cannot occur.
648  if ((rhs < 0) && (lhs > 0) && ((std::numeric_limits<I64>::max() + rhs) < lhs)) {
650  }
651  // Underflow can only occur when the left operand is negative and the right operand is positive. It occurs when the
652  // left (negative) operand is less than the minimum value plus the other (positive) operand. If the right operand
653  // is negative or zero, underflow cannot occur.
654  else if ((rhs > 0) && (lhs < 0) && ((std::numeric_limits<I64>::min() + rhs) > lhs)) {
656  }
657  this->m_runtime.stack.push(static_cast<I64>(lhs - rhs));
659 }
660 DirectiveError FpySequencer::op_mul() {
661  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
663  }
664  I64 rhs = this->m_runtime.stack.pop<I64>();
665  I64 lhs = this->m_runtime.stack.pop<I64>();
666  // Check for overflow and underflow and return the appropriate error code
667  // Overflow can only occur with operands of matching signs and occurs when one operand is greater (or less) than the
668  // maximum value divided by the other operand. Either operand being zero precludes overflow.
669  // Check the both positive case.
670  if ((rhs > 0) && (lhs > 0) && ((std::numeric_limits<I64>::max() / rhs) < lhs)) {
672  }
673  // Check the both negative case
674  else if ((rhs < 0) && (lhs < 0) && ((std::numeric_limits<I64>::max() / (-1 * rhs)) < (-1 * lhs))) {
676  }
677  // Underflow can occur with operands of differing signs and occurs when one operand is less than the minimum value
678  // divided by the other operand. Either operand being zero precludes underflow.
679  // Check the case where lhs is positive.
680  else if ((rhs < 0) && (lhs > 0) && ((std::numeric_limits<I64>::min() / lhs) > rhs)) {
682  }
683  // Check the case where rhs is positive.
684  else if ((rhs > 0) && (lhs < 0) && ((std::numeric_limits<I64>::min() / rhs) > lhs)) {
686  }
687  this->m_runtime.stack.push(static_cast<I64>(lhs * rhs));
689 }
690 DirectiveError FpySequencer::op_udiv() {
691  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
693  }
694  U64 rhs = this->m_runtime.stack.pop<U64>();
695  U64 lhs = this->m_runtime.stack.pop<U64>();
696  // Prevent division by zero
697  if (rhs == 0) {
699  }
700  this->m_runtime.stack.push(static_cast<U64>(lhs / rhs));
702 }
703 DirectiveError FpySequencer::op_sdiv() {
704  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
706  }
707 
708  I64 rhs = this->m_runtime.stack.pop<I64>();
709  I64 lhs = this->m_runtime.stack.pop<I64>();
710  // Prevent division by zero
711  if (rhs == 0) {
713  }
714  this->m_runtime.stack.push(static_cast<I64>(lhs / rhs));
716 }
717 DirectiveError FpySequencer::op_umod() {
718  if (this->m_runtime.stack.size < sizeof(U64) * 2) {
720  }
721  U64 rhs = this->m_runtime.stack.pop<U64>();
722  if (rhs == 0) {
724  }
725  U64 lhs = this->m_runtime.stack.pop<U64>();
726  this->m_runtime.stack.push(static_cast<U64>(lhs % rhs));
728 }
729 DirectiveError FpySequencer::op_smod() {
730  if (this->m_runtime.stack.size < sizeof(I64) * 2) {
732  }
733  I64 rhs = this->m_runtime.stack.pop<I64>();
734  if (rhs == 0) {
736  }
737  I64 lhs = this->m_runtime.stack.pop<I64>();
738  I64 res = static_cast<I64>(lhs % rhs);
739  // in order to match Python's behavior,
740  // if the signs of the remainder and divisor differ, adjust the result.
741  // this happens when the result should be positive but is negative, or vice-versa.
742  // credit Gemini 2.5 pro
743  if ((res > 0 && rhs < 0) || (res < 0 && rhs > 0)) {
744  res += rhs;
745  }
746  this->m_runtime.stack.push(res);
748 }
749 DirectiveError FpySequencer::op_fadd() {
750  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
752  }
753  F64 rhs = this->m_runtime.stack.pop<F64>();
754  F64 lhs = this->m_runtime.stack.pop<F64>();
755  this->m_runtime.stack.push(static_cast<F64>(lhs + rhs));
757 }
758 DirectiveError FpySequencer::op_fsub() {
759  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
761  }
762  F64 rhs = this->m_runtime.stack.pop<F64>();
763  F64 lhs = this->m_runtime.stack.pop<F64>();
764  this->m_runtime.stack.push(static_cast<F64>(lhs - rhs));
766 }
767 DirectiveError FpySequencer::op_fmul() {
768  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
770  }
771  F64 rhs = this->m_runtime.stack.pop<F64>();
772  F64 lhs = this->m_runtime.stack.pop<F64>();
773  this->m_runtime.stack.push(static_cast<F64>(lhs * rhs));
775 }
776 DirectiveError FpySequencer::op_fdiv() {
777  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
779  }
780  F64 rhs = this->m_runtime.stack.pop<F64>();
781  F64 lhs = this->m_runtime.stack.pop<F64>();
782  this->m_runtime.stack.push(static_cast<F64>(lhs / rhs));
784 }
785 DirectiveError FpySequencer::op_fpow() {
786  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
788  }
789  F64 rhs = this->m_runtime.stack.pop<F64>();
790  F64 lhs = this->m_runtime.stack.pop<F64>();
791  this->m_runtime.stack.push(static_cast<F64>(pow(lhs, rhs)));
793 }
794 DirectiveError FpySequencer::op_flog() {
795  if (this->m_runtime.stack.size < sizeof(F64)) {
797  }
798  F64 val = this->m_runtime.stack.pop<F64>();
799  if (val <= 0.0) {
801  }
802  this->m_runtime.stack.push(static_cast<F64>(log(val)));
804 }
805 DirectiveError FpySequencer::op_fmod() {
806  if (this->m_runtime.stack.size < sizeof(F64) * 2) {
808  }
809  F64 rhs = this->m_runtime.stack.pop<F64>();
810  if (rhs == 0.0) {
812  }
813  F64 lhs = this->m_runtime.stack.pop<F64>();
814  this->m_runtime.stack.push(static_cast<F64>(lhs - rhs * std::floor(lhs / rhs)));
816 }
817 DirectiveError FpySequencer::op_siext_8_64() {
818  if (this->m_runtime.stack.size < sizeof(I8)) {
820  }
821  I8 src = this->m_runtime.stack.pop<I8>();
822  this->m_runtime.stack.push(static_cast<I64>(src));
824 }
825 DirectiveError FpySequencer::op_siext_16_64() {
826  if (this->m_runtime.stack.size < sizeof(I16)) {
828  }
829  I16 src = this->m_runtime.stack.pop<I16>();
830  this->m_runtime.stack.push(static_cast<I64>(src));
832 }
833 DirectiveError FpySequencer::op_siext_32_64() {
834  if (this->m_runtime.stack.size < sizeof(I32)) {
836  }
837  I32 src = this->m_runtime.stack.pop<I32>();
838  this->m_runtime.stack.push(static_cast<I64>(src));
840 }
841 DirectiveError FpySequencer::op_ziext_8_64() {
842  if (this->m_runtime.stack.size < sizeof(U8)) {
844  }
845  U8 src = this->m_runtime.stack.pop<U8>();
846  this->m_runtime.stack.push(static_cast<U64>(src));
848 }
849 DirectiveError FpySequencer::op_ziext_16_64() {
850  if (this->m_runtime.stack.size < sizeof(U16)) {
852  }
853  U16 src = this->m_runtime.stack.pop<U16>();
854  this->m_runtime.stack.push(static_cast<U64>(src));
856 }
857 DirectiveError FpySequencer::op_ziext_32_64() {
858  if (this->m_runtime.stack.size < sizeof(U32)) {
860  }
861  U32 src = this->m_runtime.stack.pop<U32>();
862  this->m_runtime.stack.push(static_cast<U64>(src));
864 }
865 DirectiveError FpySequencer::op_itrunc_64_8() {
866  if (this->m_runtime.stack.size < sizeof(U64)) {
868  }
869  U64 src = this->m_runtime.stack.pop<U64>();
870  this->m_runtime.stack.push(static_cast<U8>(src));
872 }
873 DirectiveError FpySequencer::op_itrunc_64_16() {
874  if (this->m_runtime.stack.size < sizeof(U64)) {
876  }
877  U64 src = this->m_runtime.stack.pop<U64>();
878  this->m_runtime.stack.push(static_cast<U16>(src));
880 }
881 DirectiveError FpySequencer::op_itrunc_64_32() {
882  if (this->m_runtime.stack.size < sizeof(U64)) {
884  }
885  U64 src = this->m_runtime.stack.pop<U64>();
886  this->m_runtime.stack.push(static_cast<U32>(src));
888 }
889 Signal FpySequencer::stackOp_directiveHandler(const FpySequencer_StackOpDirective& directive, DirectiveError& error) {
890  // coding error, should not have gotten to this stack op handler
891  FW_ASSERT(directive.get__op() >= Fpy::DirectiveId::OR && directive.get__op() <= Fpy::DirectiveId::ITRUNC_64_32,
892  static_cast<FwAssertArgType>(directive.get__op()));
893 
894  switch (directive.get__op()) {
896  error = this->op_or();
897  break;
899  error = this->op_and();
900  break;
902  error = this->op_ieq();
903  break;
905  error = this->op_ine();
906  break;
908  error = this->op_ult();
909  break;
911  error = this->op_ule();
912  break;
914  error = this->op_ugt();
915  break;
917  error = this->op_uge();
918  break;
920  error = this->op_slt();
921  break;
923  error = this->op_sle();
924  break;
926  error = this->op_sgt();
927  break;
929  error = this->op_sge();
930  break;
932  error = this->op_feq();
933  break;
935  error = this->op_fne();
936  break;
938  error = this->op_flt();
939  break;
941  error = this->op_fle();
942  break;
944  error = this->op_fgt();
945  break;
947  error = this->op_fge();
948  break;
950  error = this->op_not();
951  break;
953  error = this->op_fpext();
954  break;
956  error = this->op_fptrunc();
957  break;
959  error = this->op_fptosi();
960  break;
962  error = this->op_fptoui();
963  break;
965  error = this->op_sitofp();
966  break;
968  error = this->op_uitofp();
969  break;
971  error = this->op_add();
972  break;
974  error = this->op_sub();
975  break;
977  error = this->op_mul();
978  break;
980  error = this->op_udiv();
981  break;
983  error = this->op_sdiv();
984  break;
986  error = this->op_umod();
987  break;
989  error = this->op_smod();
990  break;
992  error = this->op_fadd();
993  break;
995  error = this->op_fsub();
996  break;
998  error = this->op_fmul();
999  break;
1001  error = this->op_fdiv();
1002  break;
1004  error = this->op_fpow();
1005  break;
1007  error = this->op_flog();
1008  break;
1010  error = this->op_fmod();
1011  break;
1013  error = this->op_siext_8_64();
1014  break;
1016  error = this->op_siext_16_64();
1017  break;
1019  error = this->op_siext_32_64();
1020  break;
1022  error = this->op_ziext_8_64();
1023  break;
1025  error = this->op_ziext_16_64();
1026  break;
1028  error = this->op_ziext_32_64();
1029  break;
1031  error = this->op_itrunc_64_8();
1032  break;
1034  error = this->op_itrunc_64_16();
1035  break;
1037  error = this->op_itrunc_64_32();
1038  break;
1039  default:
1040  FW_ASSERT(0, directive.get__op());
1041  break;
1042  }
1043  if (error != DirectiveError::NO_ERROR) {
1045  }
1047 }
1048 
1049 Signal FpySequencer::exit_directiveHandler(const FpySequencer_ExitDirective& directive, DirectiveError& error) {
1050  if (this->m_runtime.stack.size < 1) {
1053  }
1054  U8 errorCode = this->m_runtime.stack.pop<U8>();
1055  // exit(0), no error
1056  if (errorCode == 0) {
1057  // just goto the end of the sequence
1058  this->m_runtime.nextStatementIndex = this->m_sequenceObj.get_header().get_statementCount();
1060  }
1061  // otherwise, kill the sequence here
1062  // raise the user defined error code as an event
1063  this->log_WARNING_HI_SequenceExitedWithError(this->m_sequenceFilePath, errorCode);
1066 }
1067 
1068 Signal FpySequencer::allocate_directiveHandler(const FpySequencer_AllocateDirective& directive, DirectiveError& error) {
1069  if (this->m_runtime.stack.size + directive.get_size() > Fpy::MAX_STACK_SIZE) {
1072  }
1073  this->m_runtime.stack.pushZeroes(directive.get_size());
1075 }
1076 
1077 Signal FpySequencer::storeConstOffset_directiveHandler(const FpySequencer_StoreConstOffsetDirective& directive,
1078  DirectiveError& error) {
1079  if (this->m_runtime.stack.size < directive.get_size()) {
1080  // not enough bytes to pop
1083  }
1084  Fpy::StackSizeType stackOffset = this->m_runtime.stack.lvarOffset() + directive.get_lvarOffset();
1085  // if we popped these bytes off, and put them in lvar array, would we go out of bounds
1086  if (stackOffset + directive.get_size() > this->m_runtime.stack.size - directive.get_size()) {
1087  // write into lvar array would go out of bounds
1090  }
1091  // i believe we can be sure the regions are not overlapping, due to the above check
1092  memcpy(this->m_runtime.stack.bytes + stackOffset, this->m_runtime.stack.top() - directive.get_size(),
1093  directive.get_size());
1094  this->m_runtime.stack.size -= directive.get_size();
1096 }
1097 
1098 Signal FpySequencer::load_directiveHandler(const FpySequencer_LoadDirective& directive, DirectiveError& error) {
1099  if (this->m_runtime.stack.size + directive.get_size() > Fpy::MAX_STACK_SIZE) {
1102  }
1103  // calculate the offset in the lvar array we're going to pull from
1104  Fpy::StackSizeType stackOffset = this->m_runtime.stack.lvarOffset() + directive.get_lvarOffset();
1105  // if we accessed these bytes, would we go out of bounds
1106  if (stackOffset + directive.get_size() > this->m_runtime.stack.size) {
1109  }
1110  // copy from lvar array to top of stack, add to stack size.
1111  memcpy(this->m_runtime.stack.top(), this->m_runtime.stack.bytes + stackOffset, directive.get_size());
1112  this->m_runtime.stack.size += directive.get_size();
1114 }
1115 
1116 Signal FpySequencer::pushVal_directiveHandler(const FpySequencer_PushValDirective& directive, DirectiveError& error) {
1117  if (this->m_runtime.stack.size + directive.get__valSize() > Fpy::MAX_STACK_SIZE) {
1120  }
1121  // copy from the bytearray in the directive to the stack, add to stack size.
1122  memcpy(this->m_runtime.stack.top(), directive.get_val(), directive.get__valSize());
1123  this->m_runtime.stack.size += static_cast<Fpy::StackSizeType>(directive.get__valSize());
1125 }
1126 
1127 Signal FpySequencer::discard_directiveHandler(const FpySequencer_DiscardDirective& directive, DirectiveError& error) {
1128  if (this->m_runtime.stack.size < directive.get_size()) {
1131  }
1132  // drop the specified amount of bytes off the stack. simple as.
1133  this->m_runtime.stack.size -= directive.get_size();
1135 }
1136 
1137 Signal FpySequencer::memCmp_directiveHandler(const FpySequencer_MemCmpDirective& directive, DirectiveError& error) {
1138  // we are going to pop 2x the size off the stack. check that we can
1139  if (this->m_runtime.stack.size < directive.get_size() * 2) {
1142  }
1143 
1144  // find the starting offsets of the two byte arrays
1145  U64 lhsOffset = this->m_runtime.stack.size - directive.get_size() * 2;
1146  U64 rhsOffset = this->m_runtime.stack.size - directive.get_size();
1147 
1148  // "officially" remove them from the stack
1149  // you have to do this before pushing to the stack, otherwise the result would get placed
1150  // after the byte arrays
1151  this->m_runtime.stack.size -= directive.get_size() * 2;
1152 
1153  // memcmp the two byte arrays, push 1 if they were equal, 0 otherwise
1154  if (memcmp(this->m_runtime.stack.bytes + lhsOffset, this->m_runtime.stack.bytes + rhsOffset,
1155  directive.get_size()) == 0) {
1156  this->m_runtime.stack.push<U8>(1);
1157  } else {
1158  this->m_runtime.stack.push<U8>(0);
1159  }
1161 }
1162 
1163 Signal FpySequencer::stackCmd_directiveHandler(const FpySequencer_StackCmdDirective& directive, DirectiveError& error) {
1164  if (this->m_runtime.stack.size < static_cast<U64>(directive.get_argsSize() + sizeof(FwOpcodeType))) {
1167  }
1168 
1169  // pop the opcode of the cmd off the stack
1170  // note this means that, unlike the actual byte array that the dispatcher gets,
1171  // these cmds have opcode after the argument buffer
1172  FwOpcodeType opcode = this->m_runtime.stack.pop<FwOpcodeType>();
1173  U64 argBufOffset = this->m_runtime.stack.size - directive.get_argsSize();
1174 
1175  // update the opcode of the cmd we will await
1176  this->m_runtime.currentCmdOpcode = opcode;
1177 
1178  // also pop the args off the stack
1179  this->m_runtime.stack.size -= directive.get_argsSize();
1180 
1181  if (this->sendCmd(opcode, this->m_runtime.stack.bytes + argBufOffset, directive.get_argsSize()) ==
1184  } else {
1185  // now tell the SM to wait some more until we get the cmd response back
1186  // if we've already got the response back this should be harmless
1188  }
1189 
1191 }
1192 
1193 Signal FpySequencer::pushTime_directiveHandler(const FpySequencer_PushTimeDirective& directive, DirectiveError& error) {
1194  if (Fpy::MAX_STACK_SIZE - Fw::Time::SERIALIZED_SIZE < this->m_runtime.stack.size) {
1197  }
1198 
1199  Fw::Time currentTime = this->getTime();
1200 
1201  U8 currentTimeBuf[Fw::Time::SERIALIZED_SIZE] = {};
1202  Fw::ExternalSerializeBuffer timeEsb(currentTimeBuf, Fw::Time::SERIALIZED_SIZE);
1203  Fw::SerializeStatus stat = timeEsb.serializeFrom(currentTime);
1204 
1205  // coding error if this failed, we should have enough space
1206  FW_ASSERT(stat == Fw::SerializeStatus::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(stat));
1207 
1208  // push time to end of stack
1209  memcpy(this->m_runtime.stack.bytes + this->m_runtime.stack.size, timeEsb.getBuffAddr(), timeEsb.getSize());
1210  this->m_runtime.stack.size += static_cast<Fpy::StackSizeType>(timeEsb.getSize());
1212 }
1213 
1214 Signal FpySequencer::setFlag_directiveHandler(const FpySequencer_SetFlagDirective& directive, DirectiveError& error) {
1215  if (this->m_runtime.stack.size < 1) {
1218  }
1219  if (directive.get_flagIdx() >= Fpy::FLAG_COUNT) {
1222  }
1223 
1224  // 1 if the stack bool is nonzero, 0 otherwise
1225  U8 flagVal = this->m_runtime.stack.pop<U8>() != 0;
1226 
1227  this->m_runtime.flags[directive.get_flagIdx()] = flagVal == 1;
1229 }
1230 
1231 Signal FpySequencer::getFlag_directiveHandler(const FpySequencer_GetFlagDirective& directive, DirectiveError& error) {
1232  if (Fpy::MAX_STACK_SIZE - this->m_runtime.stack.size < 1) {
1235  }
1236  if (directive.get_flagIdx() >= Fpy::FLAG_COUNT) {
1239  }
1240 
1241  bool flagVal = this->m_runtime.flags[directive.get_flagIdx()];
1242  this->m_runtime.stack.push<U8>(flagVal);
1244 }
1245 
1246 Signal FpySequencer::getField_directiveHandler(const FpySequencer_GetFieldDirective& directive, DirectiveError& error) {
1247  if (this->m_runtime.stack.size < sizeof(Fpy::StackSizeType) ||
1248  this->m_runtime.stack.size < directive.get_parentSize()) {
1251  }
1252 
1253  Fpy::StackSizeType offset = this->m_runtime.stack.pop<Fpy::StackSizeType>();
1254 
1255  if (offset + directive.get_memberSize() > directive.get_parentSize()) {
1256  // i think it's somewhat ambiguous whether this is a stack access out of bounds
1257  // but there isn't really an error code that better reflects this, and i guess
1258  // it's technically true
1261  }
1262 
1263  // the resulting bytes should move to the start of the parent array
1264 
1265  // get pointer to the start of the parent
1266  U8* parentStartPtr = this->m_runtime.stack.top() - directive.get_parentSize();
1267  // move the field bytes to the start of the parent
1268  memmove(parentStartPtr, parentStartPtr + offset, directive.get_memberSize());
1269  // adjust stack size by the diff between the member and the parent
1270  this->m_runtime.stack.size -= (directive.get_parentSize() - directive.get_memberSize());
1272 }
1273 
1274 Signal FpySequencer::peek_directiveHandler(const FpySequencer_PeekDirective& directive, DirectiveError& error) {
1275  // must have at least two StackSizeType on stack
1276  if (this->m_runtime.stack.size < sizeof(Fpy::StackSizeType) * 2) {
1279  }
1280 
1281  Fpy::StackSizeType offset = this->m_runtime.stack.pop<Fpy::StackSizeType>();
1282  if (offset > this->m_runtime.stack.size) {
1283  // would access past the bottom of the stack
1284  // note we allow the equals case because the byteCount might be 0
1287  }
1288  Fpy::StackSizeType byteCount = this->m_runtime.stack.pop<Fpy::StackSizeType>();
1289  if (Fpy::MAX_STACK_SIZE - this->m_runtime.stack.size < byteCount) {
1290  // we would overflow the stack if we pushed this many bytes to it
1293  }
1294  if (this->m_runtime.stack.size < byteCount + offset) {
1295  // would access past the bottom of the stack
1298  }
1299  // start copying from the lowest byte of the src array
1300  U8* src = this->m_runtime.stack.top() - offset - byteCount;
1301  this->m_runtime.stack.push(src, byteCount);
1303 }
1304 
1305 Signal FpySequencer::store_directiveHandler(const FpySequencer_StoreDirective& directive, DirectiveError& error) {
1306  if (this->m_runtime.stack.size < directive.get_size() + sizeof(Fpy::StackSizeType)) {
1307  // not enough bytes to pop the value and the stack offset
1310  }
1311  Fpy::StackSizeType stackOffset =
1312  this->m_runtime.stack.lvarOffset() + this->m_runtime.stack.pop<Fpy::StackSizeType>();
1313  // if we popped these bytes off, and put them in lvar array, would we go out of bounds
1314  if (stackOffset + directive.get_size() > this->m_runtime.stack.size - directive.get_size()) {
1315  // write into lvar array would go out of bounds
1318  }
1319  // i believe we can be sure the regions are not overlapping, due to the above check
1320  memcpy(this->m_runtime.stack.bytes + stackOffset, this->m_runtime.stack.top() - directive.get_size(),
1321  directive.get_size());
1322  this->m_runtime.stack.size -= directive.get_size();
1324 }
1325 
1326 } // 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