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 
74 template <typename T>
75 T FpySequencer::pop() {
76  static_assert(sizeof(T) == 8 || sizeof(T) == 4 || sizeof(T) == 2 || sizeof(T) == 1, "size must be 1, 2, 4, 8");
77  FW_ASSERT(this->m_runtime.stackSize >= sizeof(T), static_cast<FwAssertArgType>(this->m_runtime.stackSize),
78  static_cast<FwAssertArgType>(sizeof(T)));
79  // first make a byte array which can definitely store our val
80  U8 valBytes[8] = {0};
81  // now move top of stack into byte array and shrink stack
82  memcpy(valBytes, this->top() - sizeof(T), sizeof(T));
83  this->m_runtime.stackSize -= static_cast<Fpy::StackSizeType>(sizeof(T));
84 
85  // now do appropriate byteswap on byte array
86  if (sizeof(T) == 8) {
87  return static_cast<T>((static_cast<T>(valBytes[7]) << 0) | (static_cast<T>(valBytes[6]) << 8) |
88  (static_cast<T>(valBytes[5]) << 16) | (static_cast<T>(valBytes[4]) << 24) |
89  (static_cast<T>(valBytes[3]) << 32) | (static_cast<T>(valBytes[2]) << 40) |
90  (static_cast<T>(valBytes[1]) << 48) | (static_cast<T>(valBytes[0]) << 56));
91  } else if (sizeof(T) == 4) {
92  return static_cast<T>((static_cast<T>(valBytes[3]) << 0) | (static_cast<T>(valBytes[2]) << 8) |
93  (static_cast<T>(valBytes[1]) << 16) | (static_cast<T>(valBytes[0]) << 24));
94  } else if (sizeof(T) == 2) {
95  return static_cast<T>((static_cast<T>(valBytes[1]) << 0) | (static_cast<T>(valBytes[0]) << 8));
96  } else {
97  return static_cast<T>(valBytes[0]);
98  }
99 }
100 
101 template U8 FpySequencer::pop();
102 template U16 FpySequencer::pop();
103 template U32 FpySequencer::pop();
104 template U64 FpySequencer::pop();
105 template I8 FpySequencer::pop();
106 template I16 FpySequencer::pop();
107 template I32 FpySequencer::pop();
108 template I64 FpySequencer::pop();
109 
110 template <>
111 F32 FpySequencer::pop<F32>() {
112  U32 endianness = this->pop<U32>();
113  F32 val;
114  memcpy(&val, &endianness, sizeof(val));
115  return val;
116 }
117 
118 template <>
119 F64 FpySequencer::pop<F64>() {
120  U64 endianness = this->pop<U64>();
121  F64 val;
122  memcpy(&val, &endianness, sizeof(val));
123  return val;
124 }
125 
126 template <typename T>
127 void FpySequencer::push(T val) {
128  static_assert(sizeof(T) == 8 || sizeof(T) == 4 || sizeof(T) == 2 || sizeof(T) == 1, "size must be 1, 2, 4, 8");
129  FW_ASSERT(this->m_runtime.stackSize + sizeof(val) < Fpy::MAX_STACK_SIZE,
130  static_cast<FwAssertArgType>(this->m_runtime.stackSize), static_cast<FwAssertArgType>(sizeof(T)));
131  // first make a byte array which can definitely store our val
132  U8 valBytes[8] = {0};
133  // convert val to unsigned to avoid undefined behavior for bitshifts of signed types
134  using UnsignedT = typename std::make_unsigned<T>::type;
135  UnsignedT valUnsigned = static_cast<UnsignedT>(val);
136  if (sizeof(T) == 8) {
137  valBytes[0] = static_cast<U8>(valUnsigned >> 56);
138  valBytes[1] = static_cast<U8>(valUnsigned >> 48);
139  valBytes[2] = static_cast<U8>(valUnsigned >> 40);
140  valBytes[3] = static_cast<U8>(valUnsigned >> 32);
141  valBytes[4] = static_cast<U8>(valUnsigned >> 24);
142  valBytes[5] = static_cast<U8>(valUnsigned >> 16);
143  valBytes[6] = static_cast<U8>(valUnsigned >> 8);
144  valBytes[7] = static_cast<U8>(valUnsigned >> 0);
145  } else if (sizeof(T) == 4) {
146  valBytes[0] = static_cast<U8>(valUnsigned >> 24);
147  valBytes[1] = static_cast<U8>(valUnsigned >> 16);
148  valBytes[2] = static_cast<U8>(valUnsigned >> 8);
149  valBytes[3] = static_cast<U8>(valUnsigned >> 0);
150  } else if (sizeof(T) == 2) {
151  valBytes[0] = static_cast<U8>(valUnsigned >> 8);
152  valBytes[1] = static_cast<U8>(valUnsigned >> 0);
153  } else {
154  valBytes[0] = static_cast<U8>(valUnsigned);
155  }
156  memcpy(this->top(), valBytes, sizeof(T));
157  this->m_runtime.stackSize += static_cast<Fpy::StackSizeType>(sizeof(T));
158 }
159 
160 template void FpySequencer::push(U8);
161 template void FpySequencer::push(U16);
162 template void FpySequencer::push(U32);
163 template void FpySequencer::push(U64);
164 template void FpySequencer::push(I8);
165 template void FpySequencer::push(I16);
166 template void FpySequencer::push(I32);
167 template void FpySequencer::push(I64);
168 
169 template <>
170 void FpySequencer::push<F32>(F32 val) {
171  U32 endianness;
172  memcpy(&endianness, &val, sizeof(val));
173  this->push(endianness);
174 }
175 
176 template <>
177 void FpySequencer::push<F64>(F64 val) {
178  U64 endianness;
179  memcpy(&endianness, &val, sizeof(val));
180  this->push(endianness);
181 }
182 
183 U8* FpySequencer::top() {
184  return &this->m_runtime.stack[this->m_runtime.stackSize];
185 }
186 
187 U8* FpySequencer::lvars() {
188  return this->m_runtime.stack + this->lvarOffset();
189 }
190 
191 Fpy::StackSizeType FpySequencer::lvarOffset() {
192  // at the moment, because we only have one stack frame,
193  // lvars always start at 0
194  return 0;
195 }
196 
200  this->sendSignal(this->waitRel_directiveHandler(directive, error));
201  handleDirectiveErrorCode(Fpy::DirectiveId::WAIT_REL, error);
202 }
203 
207  this->sendSignal(this->waitAbs_directiveHandler(directive, error));
208  handleDirectiveErrorCode(Fpy::DirectiveId::WAIT_ABS, error);
209 }
210 
214  this->sendSignal(this->goto_directiveHandler(directive, error));
215  handleDirectiveErrorCode(Fpy::DirectiveId::GOTO, error);
216 }
217 
221  this->sendSignal(this->if_directiveHandler(directive, error));
222  handleDirectiveErrorCode(Fpy::DirectiveId::IF, error);
223 }
224 
228  this->sendSignal(this->noOp_directiveHandler(directive, error));
229  handleDirectiveErrorCode(Fpy::DirectiveId::NO_OP, error);
230 }
231 
234  const Svc::FpySequencer_StoreTlmValDirective& directive) {
236  this->sendSignal(this->storeTlmVal_directiveHandler(directive, error));
237  handleDirectiveErrorCode(Fpy::DirectiveId::STORE_TLM_VAL, error);
238 }
239 
244  this->sendSignal(this->pushTlmValAndTime_directiveHandler(directive, error));
245  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_TLM_VAL_AND_TIME, error);
246 }
247 
251  this->sendSignal(this->storePrm_directiveHandler(directive, error));
252  handleDirectiveErrorCode(Fpy::DirectiveId::STORE_PRM, error);
253 }
254 
258  this->sendSignal(this->constCmd_directiveHandler(directive, error));
259  handleDirectiveErrorCode(Fpy::DirectiveId::CONST_CMD, error);
260 }
261 
265  this->sendSignal(this->stackOp_directiveHandler(directive, error));
266  handleDirectiveErrorCode(directive.get__op(), error);
267 }
268 
272  this->sendSignal(this->exit_directiveHandler(directive, error));
273  handleDirectiveErrorCode(Fpy::DirectiveId::EXIT, error);
274 }
275 
279  this->sendSignal(this->allocate_directiveHandler(directive, error));
280  handleDirectiveErrorCode(Fpy::DirectiveId::ALLOCATE, error);
281 }
282 
286  this->sendSignal(this->store_directiveHandler(directive, error));
287  handleDirectiveErrorCode(Fpy::DirectiveId::STORE, error);
288 }
289 
293  this->sendSignal(this->pushVal_directiveHandler(directive, error));
294  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_VAL, error);
295 }
296 
300  this->sendSignal(this->load_directiveHandler(directive, error));
301  handleDirectiveErrorCode(Fpy::DirectiveId::LOAD, error);
302 }
303 
307  this->sendSignal(this->discard_directiveHandler(directive, error));
308  handleDirectiveErrorCode(Fpy::DirectiveId::DISCARD, error);
309 }
310 
314  this->sendSignal(this->memCmp_directiveHandler(directive, error));
315  handleDirectiveErrorCode(Fpy::DirectiveId::MEMCMP, error);
316 }
317 
321  this->sendSignal(this->stackCmd_directiveHandler(directive, error));
322  handleDirectiveErrorCode(Fpy::DirectiveId::STACK_CMD, error);
323 }
324 
328  this->sendSignal(this->pushTime_directiveHandler(directive, error));
329  handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_TIME, error);
330 }
331 
335  this->sendSignal(this->setFlag_directiveHandler(directive, error));
336  handleDirectiveErrorCode(Fpy::DirectiveId::SET_FLAG, error);
337 }
338 
342  this->sendSignal(this->getFlag_directiveHandler(directive, error));
343  handleDirectiveErrorCode(Fpy::DirectiveId::GET_FLAG, error);
344 }
345 
347 Signal FpySequencer::waitRel_directiveHandler(const FpySequencer_WaitRelDirective& directive, DirectiveError& error) {
348  if (this->m_runtime.stackSize < 8) {
351  }
352 
353  Fw::Time wakeupTime = this->getTime();
354 
355  U32 uSeconds = this->pop<U32>();
356  U32 seconds = this->pop<U32>();
357 
358  wakeupTime.add(seconds, uSeconds);
359  this->m_runtime.wakeupTime = wakeupTime;
361 }
362 
364 Signal FpySequencer::waitAbs_directiveHandler(const FpySequencer_WaitAbsDirective& directive, DirectiveError& error) {
365  if (this->m_runtime.stackSize < 10 + sizeof(FwTimeContextStoreType)) {
368  }
369 
370  U32 uSeconds = this->pop<U32>();
371  U32 seconds = this->pop<U32>();
372  FwTimeContextStoreType ctx = this->pop<FwTimeContextStoreType>();
373  U16 base = this->pop<U16>();
374 
375  this->m_runtime.wakeupTime = Fw::Time(static_cast<TimeBase::T>(base), ctx, seconds, uSeconds);
377 }
378 
380 Signal FpySequencer::goto_directiveHandler(const FpySequencer_GotoDirective& directive, DirectiveError& error) {
381  // check within sequence bounds, or at EOF (we allow == case cuz this just ends the sequence)
382  if (directive.get_statementIndex() > m_sequenceObj.get_header().get_statementCount()) {
385  }
386  m_runtime.nextStatementIndex = directive.get_statementIndex();
388 }
389 
391 Signal FpySequencer::if_directiveHandler(const FpySequencer_IfDirective& directive, DirectiveError& error) {
392  if (this->m_runtime.stackSize < 1) {
395  }
396  // check within sequence bounds, or at EOF (we allow == case cuz this just ends the sequence)
397  if (directive.get_falseGotoStmtIndex() > m_sequenceObj.get_header().get_statementCount()) {
400  }
401 
402  if (this->pop<U8>() != 0) {
403  // proceed to next instruction
405  }
406 
407  // conditional false case
408  this->m_runtime.nextStatementIndex = directive.get_falseGotoStmtIndex();
410 }
411 
412 Signal FpySequencer::noOp_directiveHandler(const FpySequencer_NoOpDirective& directive, DirectiveError& error) {
414 }
415 
416 Signal FpySequencer::storeTlmVal_directiveHandler(const FpySequencer_StoreTlmValDirective& directive,
417  DirectiveError& error) {
418  if (!this->isConnected_getTlmChan_OutputPort(0)) {
421  }
422  Fpy::StackSizeType stackOffset = this->lvarOffset() + directive.get_lvarOffset();
423  if (stackOffset >= this->m_runtime.stackSize) {
426  }
427  Fw::Time tlmTime;
428  Fw::TlmBuffer tlmValue;
429  Fw::TlmValid valid = this->getTlmChan_out(0, directive.get_chanId(), tlmTime, tlmValue);
430 
431  if (valid != Fw::TlmValid::VALID) {
432  // could not find this tlm chan
435  }
436 
437  // if we were to write this buf at this offset
438  // would it go over the current size of the stack (NOT the max size b/c
439  // we aren't supposed to add anything to the stack when we store)
440 
441  if (stackOffset + tlmValue.getBuffLength() > this->m_runtime.stackSize) {
444  }
445 
446  memcpy(this->m_runtime.stack + stackOffset, tlmValue.getBuffAddr(), tlmValue.getBuffLength());
448 }
449 
450 Signal FpySequencer::pushTlmValAndTime_directiveHandler(const FpySequencer_PushTlmValAndTimeDirective& directive,
451  DirectiveError& error) {
452  if (!this->isConnected_getTlmChan_OutputPort(0)) {
455  }
456 
457  Fw::Time tlmTime;
458  Fw::TlmBuffer tlmValue;
459  Fw::TlmValid valid = this->getTlmChan_out(0, directive.get_chanId(), tlmTime, tlmValue);
460 
461  if (valid != Fw::TlmValid::VALID) {
462  // could not find this tlm chan
465  }
466 
467  U8 tlmTimeBuf[Fw::Time::SERIALIZED_SIZE] = {};
469  Fw::SerializeStatus stat = timeEsb.serializeFrom(tlmTime);
470 
471  // coding error if this failed, we should have enough space
472  FW_ASSERT(stat == Fw::SerializeStatus::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(stat));
473 
474  // check that our stack won't overflow if we put both val and time on it
475  if (Fpy::MAX_STACK_SIZE - tlmValue.getBuffLength() - timeEsb.getBuffLength() < this->m_runtime.stackSize) {
478  }
479 
480  // push tlm to end of stack
481  memcpy(this->m_runtime.stack + this->m_runtime.stackSize, tlmValue.getBuffAddr(), tlmValue.getBuffLength());
482  this->m_runtime.stackSize += static_cast<Fpy::StackSizeType>(tlmValue.getBuffLength());
483  // now push time to end of stack
484  memcpy(this->m_runtime.stack + this->m_runtime.stackSize, timeEsb.getBuffAddr(), timeEsb.getBuffLength());
485  this->m_runtime.stackSize += static_cast<Fpy::StackSizeType>(timeEsb.getBuffLength());
487 }
488 
489 Signal FpySequencer::storePrm_directiveHandler(const FpySequencer_StorePrmDirective& directive, DirectiveError& error) {
490  if (!this->isConnected_prmGet_OutputPort(0)) {
493  }
494  Fpy::StackSizeType stackOffset = this->lvarOffset() + directive.get_lvarOffset();
495  if (stackOffset >= this->m_runtime.stackSize) {
498  }
499  Fw::ParamBuffer prmValue;
500  Fw::ParamValid valid = this->getParam_out(0, directive.get_prmId(), prmValue);
501 
502  if (valid != Fw::ParamValid::VALID) {
503  // could not find this prm in the DB
506  }
507 
508  // if we were to write this buf at this offset
509  // would it overflow the current size of the stack (NOT the max size b/c
510  // we aren't supposed to add anything to the stack when we store)
511 
512  if (stackOffset + prmValue.getBuffLength() > this->m_runtime.stackSize) {
515  }
516 
517  memcpy(this->m_runtime.stack + stackOffset, prmValue.getBuffAddr(), prmValue.getBuffLength());
519 }
520 
521 Signal FpySequencer::constCmd_directiveHandler(const FpySequencer_ConstCmdDirective& directive, DirectiveError& error) {
522  if (this->sendCmd(directive.get_opCode(), directive.get_argBuf(), directive.get__argBufSize()) ==
525  } else {
526  // now tell the SM to wait some more until we get the cmd response back
527  // if we've already got the response back this should be harmless
529  }
530 }
531 
532 I8 floatCmp(F64 lhs, F64 rhs) {
533  if (std::isunordered(lhs, rhs)) {
534  // nan is one of the args
535  // always fail a comparison if nan
536  return -2;
537  } else if (std::isgreater(lhs, rhs)) {
538  return 1;
539  } else if (std::isless(lhs, rhs)) {
540  return -1;
541  }
542  return 0;
543 }
544 
545 DirectiveError FpySequencer::op_or() {
546  if (this->m_runtime.stackSize < sizeof(U8) * 2) {
548  }
549  this->push(static_cast<U8>(this->pop<U8>() | this->pop<U8>()));
551 }
552 DirectiveError FpySequencer::op_and() {
553  if (this->m_runtime.stackSize < sizeof(U8) * 2) {
555  }
556  this->push(static_cast<U8>(this->pop<U8>() & this->pop<U8>()));
558 }
559 DirectiveError FpySequencer::op_ieq() {
560  if (this->m_runtime.stackSize < sizeof(I64) * 2) {
562  }
563  this->push(static_cast<U8>(this->pop<I64>() == this->pop<I64>()));
565 }
566 DirectiveError FpySequencer::op_ine() {
567  if (this->m_runtime.stackSize < sizeof(I64) * 2) {
569  }
570  this->push(static_cast<U8>(this->pop<I64>() != this->pop<I64>()));
572 }
573 DirectiveError FpySequencer::op_ult() {
574  if (this->m_runtime.stackSize < sizeof(U64) * 2) {
576  }
577  U64 rhs = this->pop<U64>();
578  U64 lhs = this->pop<U64>();
579  this->push(static_cast<U8>(lhs < rhs));
581 }
582 DirectiveError FpySequencer::op_ule() {
583  if (this->m_runtime.stackSize < sizeof(U64) * 2) {
585  }
586  U64 rhs = this->pop<U64>();
587  U64 lhs = this->pop<U64>();
588  this->push(static_cast<U8>(lhs <= rhs));
590 }
591 DirectiveError FpySequencer::op_ugt() {
592  if (this->m_runtime.stackSize < sizeof(U64) * 2) {
594  }
595  U64 rhs = this->pop<U64>();
596  U64 lhs = this->pop<U64>();
597  this->push(static_cast<U8>(lhs > rhs));
599 }
600 DirectiveError FpySequencer::op_uge() {
601  if (this->m_runtime.stackSize < sizeof(U64) * 2) {
603  }
604  U64 rhs = this->pop<U64>();
605  U64 lhs = this->pop<U64>();
606  this->push(static_cast<U8>(lhs >= rhs));
608 }
609 DirectiveError FpySequencer::op_slt() {
610  if (this->m_runtime.stackSize < sizeof(I64) * 2) {
612  }
613  I64 rhs = this->pop<I64>();
614  I64 lhs = this->pop<I64>();
615  this->push(static_cast<U8>(lhs < rhs));
617 }
618 DirectiveError FpySequencer::op_sle() {
619  if (this->m_runtime.stackSize < sizeof(I64) * 2) {
621  }
622  I64 rhs = this->pop<I64>();
623  I64 lhs = this->pop<I64>();
624  this->push(static_cast<U8>(lhs <= rhs));
626 }
627 DirectiveError FpySequencer::op_sgt() {
628  if (this->m_runtime.stackSize < sizeof(I64) * 2) {
630  }
631  I64 rhs = this->pop<I64>();
632  I64 lhs = this->pop<I64>();
633  this->push(static_cast<U8>(lhs > rhs));
635 }
636 DirectiveError FpySequencer::op_sge() {
637  if (this->m_runtime.stackSize < sizeof(I64) * 2) {
639  }
640  I64 rhs = this->pop<I64>();
641  I64 lhs = this->pop<I64>();
642  this->push(static_cast<U8>(lhs >= rhs));
644 }
645 DirectiveError FpySequencer::op_feq() {
646  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
648  }
649  F64 rhs = this->pop<F64>();
650  F64 lhs = this->pop<F64>();
651  // eq is true if they are equal and neither is nan
652  this->push(static_cast<U8>(floatCmp(lhs, rhs) == 0));
654 }
655 DirectiveError FpySequencer::op_fne() {
656  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
658  }
659  F64 rhs = this->pop<F64>();
660  F64 lhs = this->pop<F64>();
661  I8 cmp = floatCmp(lhs, rhs);
662  // ne is true if they are not equal and neither is nan
663  this->push(static_cast<U8>(cmp != 0 && cmp != -2));
665 }
666 DirectiveError FpySequencer::op_flt() {
667  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
669  }
670  F64 rhs = this->pop<F64>();
671  F64 lhs = this->pop<F64>();
672  this->push(static_cast<U8>(floatCmp(lhs, rhs) == -1));
674 }
675 DirectiveError FpySequencer::op_fle() {
676  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
678  }
679  F64 rhs = this->pop<F64>();
680  F64 lhs = this->pop<F64>();
681  I8 cmp = floatCmp(lhs, rhs);
682  this->push(static_cast<U8>(cmp == 0 || cmp == -1));
684 }
685 DirectiveError FpySequencer::op_fgt() {
686  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
688  }
689  F64 rhs = this->pop<F64>();
690  F64 lhs = this->pop<F64>();
691  this->push(static_cast<U8>(floatCmp(lhs, rhs) == 1));
693 }
694 DirectiveError FpySequencer::op_fge() {
695  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
697  }
698  F64 rhs = this->pop<F64>();
699  F64 lhs = this->pop<F64>();
700  I8 cmp = floatCmp(lhs, rhs);
701  this->push(static_cast<U8>(cmp == 0 || cmp == 1));
703 }
704 DirectiveError FpySequencer::op_not() {
705  if (this->m_runtime.stackSize < sizeof(U8)) {
707  }
708  this->push(static_cast<U8>(this->pop<U8>() == 0));
710 }
711 DirectiveError FpySequencer::op_fpext() {
712  // convert F32 to F64
713  if (this->m_runtime.stackSize < sizeof(F32)) {
715  }
716  this->push(static_cast<F64>(this->pop<F32>()));
718 }
719 DirectiveError FpySequencer::op_fptrunc() {
720  // convert F64 to F32
721  if (this->m_runtime.stackSize < sizeof(F64)) {
723  }
724  this->push(static_cast<F32>(this->pop<F64>()));
726 }
727 DirectiveError FpySequencer::op_fptosi() {
728  if (this->m_runtime.stackSize < sizeof(F64)) {
730  }
731  this->push(static_cast<I64>(this->pop<F64>()));
733 }
734 DirectiveError FpySequencer::op_sitofp() {
735  if (this->m_runtime.stackSize < sizeof(I64)) {
737  }
738  this->push(static_cast<F64>(this->pop<I64>()));
740 }
741 DirectiveError FpySequencer::op_fptoui() {
742  if (this->m_runtime.stackSize < sizeof(F64)) {
744  }
745  this->push(static_cast<U64>(this->pop<F64>()));
747 }
748 DirectiveError FpySequencer::op_uitofp() {
749  if (this->m_runtime.stackSize < sizeof(U64)) {
751  }
752  this->push(static_cast<F64>(this->pop<U64>()));
754 }
755 DirectiveError FpySequencer::op_iadd() {
756  if (this->m_runtime.stackSize < sizeof(I64) * 2) {
758  }
759  I64 rhs = this->pop<I64>();
760  I64 lhs = this->pop<I64>();
761  this->push(static_cast<I64>(lhs + rhs));
763 }
764 DirectiveError FpySequencer::op_isub() {
765  if (this->m_runtime.stackSize < sizeof(I64) * 2) {
767  }
768  I64 rhs = this->pop<I64>();
769  I64 lhs = this->pop<I64>();
770  this->push(static_cast<I64>(lhs - rhs));
772 }
773 DirectiveError FpySequencer::op_imul() {
774  if (this->m_runtime.stackSize < sizeof(I64) * 2) {
776  }
777  I64 rhs = this->pop<I64>();
778  I64 lhs = this->pop<I64>();
779  this->push(static_cast<I64>(lhs * rhs));
781 }
782 DirectiveError FpySequencer::op_udiv() {
783  if (this->m_runtime.stackSize < sizeof(U64) * 2) {
785  }
786  U64 rhs = this->pop<U64>();
787  U64 lhs = this->pop<U64>();
788  this->push(static_cast<U64>(lhs / rhs));
790 }
791 DirectiveError FpySequencer::op_sdiv() {
792  if (this->m_runtime.stackSize < sizeof(I64) * 2) {
794  }
795  I64 rhs = this->pop<I64>();
796  I64 lhs = this->pop<I64>();
797  this->push(static_cast<I64>(lhs / rhs));
799 }
800 DirectiveError FpySequencer::op_umod() {
801  if (this->m_runtime.stackSize < sizeof(U64) * 2) {
803  }
804  U64 rhs = this->pop<U64>();
805  if (rhs == 0) {
807  }
808  U64 lhs = this->pop<U64>();
809  this->push(static_cast<U64>(lhs % rhs));
811 }
812 DirectiveError FpySequencer::op_smod() {
813  if (this->m_runtime.stackSize < sizeof(I64) * 2) {
815  }
816  I64 rhs = this->pop<I64>();
817  if (rhs == 0) {
819  }
820  I64 lhs = this->pop<I64>();
821  I64 res = static_cast<I64>(lhs % rhs);
822  // in order to match Python's behavior,
823  // if the signs of the remainder and divisor differ, adjust the result.
824  // this happens when the result should be positive but is negative, or vice-versa.
825  // credit Gemini 2.5 pro
826  if ((res > 0 && rhs < 0) || (res < 0 && rhs > 0)) {
827  res += rhs;
828  }
829  this->push(res);
831 }
832 DirectiveError FpySequencer::op_fadd() {
833  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
835  }
836  F64 rhs = this->pop<F64>();
837  F64 lhs = this->pop<F64>();
838  this->push(static_cast<F64>(lhs + rhs));
840 }
841 DirectiveError FpySequencer::op_fsub() {
842  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
844  }
845  F64 rhs = this->pop<F64>();
846  F64 lhs = this->pop<F64>();
847  this->push(static_cast<F64>(lhs - rhs));
849 }
850 DirectiveError FpySequencer::op_fmul() {
851  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
853  }
854  F64 rhs = this->pop<F64>();
855  F64 lhs = this->pop<F64>();
856  this->push(static_cast<F64>(lhs * rhs));
858 }
859 DirectiveError FpySequencer::op_fdiv() {
860  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
862  }
863  F64 rhs = this->pop<F64>();
864  F64 lhs = this->pop<F64>();
865  this->push(static_cast<F64>(lhs / rhs));
867 }
868 DirectiveError FpySequencer::op_float_floor_div() {
869  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
871  }
872  F64 rhs = this->pop<F64>();
873  F64 lhs = this->pop<F64>();
874  this->push(static_cast<F64>(floor(lhs / rhs)));
876 }
877 DirectiveError FpySequencer::op_fpow() {
878  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
880  }
881  F64 rhs = this->pop<F64>();
882  F64 lhs = this->pop<F64>();
883  this->push(static_cast<F64>(pow(lhs, rhs)));
885 }
886 DirectiveError FpySequencer::op_flog() {
887  if (this->m_runtime.stackSize < sizeof(F64)) {
889  }
890  F64 val = this->pop<F64>();
891  this->push(static_cast<F64>(log(val)));
893 }
894 DirectiveError FpySequencer::op_fmod() {
895  if (this->m_runtime.stackSize < sizeof(F64) * 2) {
897  }
898  F64 rhs = this->pop<F64>();
899  if (rhs == 0.0) {
901  }
902  F64 lhs = this->pop<F64>();
903  this->push(static_cast<F64>(lhs - rhs * std::floor(lhs / rhs)));
905 }
906 DirectiveError FpySequencer::op_siext_8_64() {
907  if (this->m_runtime.stackSize < sizeof(I8)) {
909  }
910  I8 src = this->pop<I8>();
911  this->push(static_cast<I64>(src));
913 }
914 DirectiveError FpySequencer::op_siext_16_64() {
915  if (this->m_runtime.stackSize < sizeof(I16)) {
917  }
918  I16 src = this->pop<I16>();
919  this->push(static_cast<I64>(src));
921 }
922 DirectiveError FpySequencer::op_siext_32_64() {
923  if (this->m_runtime.stackSize < sizeof(I32)) {
925  }
926  I32 src = this->pop<I32>();
927  this->push(static_cast<I64>(src));
929 }
930 DirectiveError FpySequencer::op_ziext_8_64() {
931  if (this->m_runtime.stackSize < sizeof(U8)) {
933  }
934  U8 src = this->pop<U8>();
935  this->push(static_cast<U64>(src));
937 }
938 DirectiveError FpySequencer::op_ziext_16_64() {
939  if (this->m_runtime.stackSize < sizeof(U16)) {
941  }
942  U16 src = this->pop<U16>();
943  this->push(static_cast<U64>(src));
945 }
946 DirectiveError FpySequencer::op_ziext_32_64() {
947  if (this->m_runtime.stackSize < sizeof(U32)) {
949  }
950  U32 src = this->pop<U32>();
951  this->push(static_cast<U64>(src));
953 }
954 DirectiveError FpySequencer::op_itrunc_64_8() {
955  if (this->m_runtime.stackSize < sizeof(U64)) {
957  }
958  U64 src = this->pop<U64>();
959  this->push(static_cast<U8>(src));
961 }
962 DirectiveError FpySequencer::op_itrunc_64_16() {
963  if (this->m_runtime.stackSize < sizeof(U64)) {
965  }
966  U64 src = this->pop<U64>();
967  this->push(static_cast<U16>(src));
969 }
970 DirectiveError FpySequencer::op_itrunc_64_32() {
971  if (this->m_runtime.stackSize < sizeof(U64)) {
973  }
974  U64 src = this->pop<U64>();
975  this->push(static_cast<U32>(src));
977 }
978 Signal FpySequencer::stackOp_directiveHandler(const FpySequencer_StackOpDirective& directive, DirectiveError& error) {
979  // coding error, should not have gotten to this stack op handler
980  FW_ASSERT(directive.get__op() >= Fpy::DirectiveId::OR && directive.get__op() <= Fpy::DirectiveId::ITRUNC_64_32,
981  static_cast<FwAssertArgType>(directive.get__op()));
982 
983  switch (directive.get__op()) {
985  error = this->op_or();
986  break;
988  error = this->op_and();
989  break;
991  error = this->op_ieq();
992  break;
994  error = this->op_ine();
995  break;
997  error = this->op_ult();
998  break;
1000  error = this->op_ule();
1001  break;
1002  case Fpy::DirectiveId::UGT:
1003  error = this->op_ugt();
1004  break;
1005  case Fpy::DirectiveId::UGE:
1006  error = this->op_uge();
1007  break;
1008  case Fpy::DirectiveId::SLT:
1009  error = this->op_slt();
1010  break;
1011  case Fpy::DirectiveId::SLE:
1012  error = this->op_sle();
1013  break;
1014  case Fpy::DirectiveId::SGT:
1015  error = this->op_sgt();
1016  break;
1017  case Fpy::DirectiveId::SGE:
1018  error = this->op_sge();
1019  break;
1020  case Fpy::DirectiveId::FEQ:
1021  error = this->op_feq();
1022  break;
1023  case Fpy::DirectiveId::FNE:
1024  error = this->op_fne();
1025  break;
1026  case Fpy::DirectiveId::FLT:
1027  error = this->op_flt();
1028  break;
1029  case Fpy::DirectiveId::FLE:
1030  error = this->op_fle();
1031  break;
1032  case Fpy::DirectiveId::FGT:
1033  error = this->op_fgt();
1034  break;
1035  case Fpy::DirectiveId::FGE:
1036  error = this->op_fge();
1037  break;
1038  case Fpy::DirectiveId::NOT:
1039  error = this->op_not();
1040  break;
1042  error = this->op_fpext();
1043  break;
1045  error = this->op_fptrunc();
1046  break;
1048  error = this->op_fptosi();
1049  break;
1051  error = this->op_fptoui();
1052  break;
1054  error = this->op_sitofp();
1055  break;
1057  error = this->op_uitofp();
1058  break;
1060  error = this->op_iadd();
1061  break;
1063  error = this->op_isub();
1064  break;
1066  error = this->op_imul();
1067  break;
1069  error = this->op_udiv();
1070  break;
1072  error = this->op_sdiv();
1073  break;
1075  error = this->op_umod();
1076  break;
1078  error = this->op_smod();
1079  break;
1081  error = this->op_fadd();
1082  break;
1084  error = this->op_fsub();
1085  break;
1087  error = this->op_fmul();
1088  break;
1090  error = this->op_fdiv();
1091  break;
1093  error = this->op_float_floor_div();
1094  break;
1096  error = this->op_fpow();
1097  break;
1099  error = this->op_flog();
1100  break;
1102  error = this->op_fmod();
1103  break;
1105  error = this->op_siext_8_64();
1106  break;
1108  error = this->op_siext_16_64();
1109  break;
1111  error = this->op_siext_32_64();
1112  break;
1114  error = this->op_ziext_8_64();
1115  break;
1117  error = this->op_ziext_16_64();
1118  break;
1120  error = this->op_ziext_32_64();
1121  break;
1123  error = this->op_itrunc_64_8();
1124  break;
1126  error = this->op_itrunc_64_16();
1127  break;
1129  error = this->op_itrunc_64_32();
1130  break;
1131  default:
1132  FW_ASSERT(0, directive.get__op());
1133  break;
1134  }
1135  if (error != DirectiveError::NO_ERROR) {
1137  }
1139 }
1140 
1141 Signal FpySequencer::exit_directiveHandler(const FpySequencer_ExitDirective& directive, DirectiveError& error) {
1142  if (this->m_runtime.stackSize < 1) {
1145  }
1146  if (this->pop<U8>() != 0) {
1147  // just goto the end of the sequence
1148  this->m_runtime.nextStatementIndex = this->m_sequenceObj.get_header().get_statementCount();
1150  }
1151  // otherwise, kill the sequence here
1154 }
1155 
1156 Signal FpySequencer::allocate_directiveHandler(const FpySequencer_AllocateDirective& directive, DirectiveError& error) {
1157  if (this->m_runtime.stackSize + directive.get_size() > Fpy::MAX_STACK_SIZE) {
1160  }
1161  // starting from the top, set n bytes to 0
1162  memset(this->top(), 0, directive.get_size());
1163  this->m_runtime.stackSize += directive.get_size();
1165 }
1166 
1167 Signal FpySequencer::store_directiveHandler(const FpySequencer_StoreDirective& directive, DirectiveError& error) {
1168  if (this->m_runtime.stackSize < directive.get_size()) {
1169  // not enough bytes to pop
1172  }
1173  Fpy::StackSizeType stackOffset = this->lvarOffset() + directive.get_lvarOffset();
1174  // if we popped these bytes off, and put them in lvar array, would we go out of bounds
1175  if (stackOffset + directive.get_size() > this->m_runtime.stackSize - directive.get_size()) {
1176  // write into lvar array would go out of bounds
1179  }
1180  // i believe we can be sure the regions are not overlapping, due to the above check
1181  memcpy(this->m_runtime.stack + stackOffset, this->top() - directive.get_size(), directive.get_size());
1182  this->m_runtime.stackSize -= directive.get_size();
1184 }
1185 
1186 Signal FpySequencer::load_directiveHandler(const FpySequencer_LoadDirective& directive, DirectiveError& error) {
1187  if (this->m_runtime.stackSize + directive.get_size() > Fpy::MAX_STACK_SIZE) {
1190  }
1191  // calculate the offset in the lvar array we're going to pull from
1192  Fpy::StackSizeType stackOffset = this->lvarOffset() + directive.get_lvarOffset();
1193  // if we accessed these bytes, would we go out of bounds
1194  if (stackOffset + directive.get_size() > this->m_runtime.stackSize) {
1197  }
1198  // copy from lvar array to top of stack, add to stack size.
1199  memcpy(this->top(), this->m_runtime.stack + stackOffset, directive.get_size());
1200  this->m_runtime.stackSize += directive.get_size();
1202 }
1203 
1204 Signal FpySequencer::pushVal_directiveHandler(const FpySequencer_PushValDirective& directive, DirectiveError& error) {
1205  if (this->m_runtime.stackSize + directive.get__valSize() > Fpy::MAX_STACK_SIZE) {
1208  }
1209  // copy from the bytearray in the directive to the stack, add to stack size.
1210  memcpy(this->top(), directive.get_val(), directive.get__valSize());
1211  this->m_runtime.stackSize += static_cast<Fpy::StackSizeType>(directive.get__valSize());
1213 }
1214 
1215 Signal FpySequencer::discard_directiveHandler(const FpySequencer_DiscardDirective& directive, DirectiveError& error) {
1216  if (this->m_runtime.stackSize < directive.get_size()) {
1219  }
1220  // drop the specified amount of bytes off the stack. simple as.
1221  this->m_runtime.stackSize -= directive.get_size();
1223 }
1224 
1225 Signal FpySequencer::memCmp_directiveHandler(const FpySequencer_MemCmpDirective& directive, DirectiveError& error) {
1226  // we are going to pop 2x the size off the stack. check that we can
1227  if (this->m_runtime.stackSize < directive.get_size() * 2) {
1230  }
1231 
1232  // find the starting offsets of the two byte arrays
1233  U64 lhsOffset = this->m_runtime.stackSize - directive.get_size() * 2;
1234  U64 rhsOffset = this->m_runtime.stackSize - directive.get_size();
1235 
1236  // "officially" remove them from the stack
1237  // you have to do this before pushing to the stack, otherwise the result would get placed
1238  // after the byte arrays
1239  this->m_runtime.stackSize -= directive.get_size() * 2;
1240 
1241  // memcmp the two byte arrays, push 1 if they were equal, 0 otherwise
1242  if (memcmp(this->m_runtime.stack + lhsOffset, this->m_runtime.stack + rhsOffset, directive.get_size()) == 0) {
1243  this->push<U8>(1);
1244  } else {
1245  this->push<U8>(0);
1246  }
1248 }
1249 
1250 Signal FpySequencer::stackCmd_directiveHandler(const FpySequencer_StackCmdDirective& directive, DirectiveError& error) {
1251  if (this->m_runtime.stackSize < static_cast<U64>(directive.get_argsSize() + sizeof(FwOpcodeType))) {
1254  }
1255 
1256  // pop the opcode of the cmd off the stack
1257  // note this means that, unlike the actual byte array that the dispatcher gets,
1258  // these cmds have opcode after the argument buffer
1259  FwOpcodeType opcode = this->pop<FwOpcodeType>();
1260  U64 argBufOffset = this->m_runtime.stackSize - directive.get_argsSize();
1261 
1262  // update the opcode of the cmd we will await
1263  this->m_runtime.currentCmdOpcode = opcode;
1264 
1265  // also pop the args off the stack
1266  this->m_runtime.stackSize -= directive.get_argsSize();
1267 
1268  if (this->sendCmd(opcode, this->m_runtime.stack + argBufOffset, directive.get_argsSize()) == Fw::Success::FAILURE) {
1270  } else {
1271  // now tell the SM to wait some more until we get the cmd response back
1272  // if we've already got the response back this should be harmless
1274  }
1275 
1277 }
1278 
1279 Signal FpySequencer::pushTime_directiveHandler(const FpySequencer_PushTimeDirective& directive, DirectiveError& error) {
1280  if (Fpy::MAX_STACK_SIZE - Fw::Time::SERIALIZED_SIZE < this->m_runtime.stackSize) {
1283  }
1284 
1285  Fw::Time currentTime = this->getTime();
1286 
1287  U8 currentTimeBuf[Fw::Time::SERIALIZED_SIZE] = {};
1288  Fw::ExternalSerializeBuffer timeEsb(currentTimeBuf, Fw::Time::SERIALIZED_SIZE);
1289  Fw::SerializeStatus stat = timeEsb.serializeFrom(currentTime);
1290 
1291  // coding error if this failed, we should have enough space
1292  FW_ASSERT(stat == Fw::SerializeStatus::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(stat));
1293 
1294  // push time to end of stack
1295  memcpy(this->m_runtime.stack + this->m_runtime.stackSize, timeEsb.getBuffAddr(), timeEsb.getBuffLength());
1296  this->m_runtime.stackSize += static_cast<Fpy::StackSizeType>(timeEsb.getBuffLength());
1298 }
1299 
1300 Signal FpySequencer::setFlag_directiveHandler(const FpySequencer_SetFlagDirective& directive, DirectiveError& error) {
1301  if (this->m_runtime.stackSize < 1) {
1304  }
1305  if (directive.get_flagIdx() >= Fpy::FLAG_COUNT) {
1308  }
1309 
1310  // 1 if the stack bool is nonzero, 0 otherwise
1311  U8 flagVal = this->pop<U8>() != 0;
1312 
1313  this->m_runtime.flags[directive.get_flagIdx()] = flagVal == 1;
1315 }
1316 
1317 Signal FpySequencer::getFlag_directiveHandler(const FpySequencer_GetFlagDirective& directive, DirectiveError& error) {
1318  if (Fpy::MAX_STACK_SIZE - this->m_runtime.stackSize < 1) {
1321  }
1322  if (directive.get_flagIdx() >= Fpy::FLAG_COUNT) {
1325  }
1326 
1327  bool flagVal = this->m_runtime.flags[directive.get_flagIdx()];
1328  this->push<U8>(flagVal);
1330 }
1331 
1332 } // namespace Svc
Serialization/Deserialization operation was successful.
sets the index of the next directive to execute
U8 * getBuffAddr()
gets buffer address for data filling
Definition: PrmBuffer.cpp:38
FwIdType FwOpcodeType
The type of a command opcode.
void directive_load_internalInterfaceHandler(const Svc::FpySequencer_LoadDirective &directive) override
Internal interface handler for directive_load.
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
I8 floatCmp(F64 lhs, F64 rhs)
void directive_stackOp_internalInterfaceHandler(const Svc::FpySequencer_StackOpDirective &directive) override
Internal interface handler for directive_stackOp.
void directive_storePrm_internalInterfaceHandler(const Svc::FpySequencer_StorePrmDirective &directive) override
Internal interface handler for directive_storePrm.
called when statement successfully executed. only raised in the RUNNING.AWAITING_CMD_RESPONSE state ...
Fw::TlmValid getTlmChan_out(FwIndexType portNum, FwChanIdType id, Fw::Time &timeTag, Fw::TlmBuffer &val)
Invoke output port getTlmChan.
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 sequencer_sendSignal_stmtResponse_success()
Send signal stmtResponse_success to state machine sequencer.
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.
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.
SerializeStatus
forward declaration for string
float F32
32-bit floating point
Definition: BasicTypes.h:83
void directive_allocate_internalInterfaceHandler(const Svc::FpySequencer_AllocateDirective &directive) override
Internal interface handler for directive_allocate.
void directive_storeTlmVal_internalInterfaceHandler(const Svc::FpySequencer_StoreTlmValDirective &directive) override
Internal interface handler for directive_storeTlmVal.
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.
Serializable::SizeType getBuffLength() const
returns current buffer size
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.
FpySequencer_DirectiveErrorCode DirectiveError
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()
gets buffer address for data filling
Definition: TlmBuffer.cpp:38
void directive_goto_internalInterfaceHandler(const Svc::FpySequencer_GotoDirective &directive) override
Internal interface handler for directive_goto.
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.
SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG)
serialize 8-bit unsigned int
Representing failure.
void directive_getFlag_internalInterfaceHandler(const Svc::FpySequencer_GetFlagDirective &directive) override
Internal interface handler for directive_getFlag.
pops some bytes off the stack and puts them in lvar array
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 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 ...
#define U64(C)
Definition: sha.h:181