F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
WasmSequencer.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title WasmSequencer.cpp
3 // \author tumbar
4 // \brief cpp file for WasmSequencer component implementation class
5 // ======================================================================
6 
8 
10 #include "Fw/Types/Assert.hpp"
14 #include "Os/Mutex.hpp"
28 
29 namespace Svc {
30 
31 U8* WasmSequencer ::globalAllocCallback(void* userdata, size_t size, size_t align) {
32  if (userdata == nullptr) {
33  return nullptr;
34  }
35  return static_cast<WasmSequencer*>(userdata)->globalAlloc(static_cast<U32>(size), static_cast<U32>(align));
36 }
37 
38 void WasmSequencer ::globalDeallocCallback(void* userdata, U8* ptr, size_t size, size_t align) {
39  (void)size;
40  (void)align;
41  if (userdata != nullptr) {
42  static_cast<WasmSequencer*>(userdata)->globalDealloc(ptr);
43  }
44 }
45 
46 // ----------------------------------------------------------------------
47 // Component construction and destruction
48 // ----------------------------------------------------------------------
49 
50 WasmSequencer ::WasmSequencer(const char* const compName)
51  : WasmSequencerComponentBase(compName),
52  m_heapPages(nullptr),
53  m_heapPagesUsed(0),
54  m_heapPoisoned(false),
55  m_guestPool(nullptr),
56  m_guestPoolOffset(0),
57  m_wasm(nullptr),
58  m_hasExecutingContext(false),
59  m_pendingTimer(),
60  m_hasPendingTimer(false),
61  m_hostFunctionStart(),
62  m_hasHostFunctionStart(false),
63  m_dequeueSucceeded(false),
64  m_invokeStatus(SPACEWASM_OK),
65  m_pendingPause(false),
66  m_cancelRequested(false),
67  m_sequencesStarted(0) {}
68 
70  FW_ASSERT(this->m_wasm == nullptr);
71  FW_ASSERT(this->m_allocator == nullptr);
72 
73  getGlobalAllocatorLock()->lock();
74  const auto status = spacewasm_fprime_register_global_allocator(&globalAllocCallback, &globalDeallocCallback, this);
75  getGlobalAllocatorLock()->unlock();
76 
77  FW_ASSERT(status == SPACEWASM_OK, status);
78 
79  this->m_config = cfg;
80 
81  // Allocate the heap memory pool
82  {
83  FW_ASSERT(
84  this->m_config.heapPages > 0 && this->m_config.heapPages <= Svc::WasmSequencerConfig::SPACEWASM_MAX_PAGES,
85  static_cast<FwAssertArgType>(this->m_config.heapPages), Svc::WasmSequencerConfig::SPACEWASM_MAX_PAGES);
86 
87  // Allocate the heap page list
88  {
89  FwSizeType actualSize = sizeof(U8*) * this->m_config.heapPages;
90  auto ptr = mallocator.checkedAllocate(0, actualSize);
91  this->m_heapPages = reinterpret_cast<U8**>(ptr);
92  }
93 
94  // Allocate each heap page
95  for (FwSizeType i = 0; i < this->m_config.heapPages; i++) {
97  auto ptr =
98  mallocator.checkedAllocate(static_cast<FwIndexType>(i) + 1, actualSize, SPACEWASM_MEMORY_ALIGNMENT);
99  this->m_heapPages[i] = reinterpret_cast<U8*>(ptr);
100  }
101  this->m_heapPagesUsed = 0;
102  }
103 
104  // Allocate the guest memory pool
105  {
106  auto actualSize = this->m_config.guestMemorySize;
107  auto ptr = mallocator.checkedAllocate(static_cast<FwIndexType>(this->m_config.heapPages) + 1, actualSize,
109  this->m_guestPoolOffset = 0;
110  this->m_guestPool = reinterpret_cast<U8*>(ptr);
111  }
112 
113  // Allocate the serialOut buffer
114  if (this->m_config.serialOutMax > 0) {
115  auto actualSize = this->m_config.serialOutMax;
116  auto ptr = mallocator.checkedAllocate(static_cast<FwIndexType>(this->m_config.heapPages) + 2, actualSize);
117  this->m_serialOutBuffer.setExtBuffer(reinterpret_cast<U8*>(ptr), actualSize);
118  }
119 
120  // Allocate the serialIn queues
121  {
122  Os::ScopeLock scopeLock(this->m_serialInMutex);
123  for (FwIndexType i = 0; i < NUM_SERIALIN_INPUT_PORTS; i++) {
124  if (this->m_config.serialIn[i].size > 0) {
125  auto actualSize = this->m_config.serialIn[i].size;
126  auto ptr =
127  mallocator.checkedAllocate(static_cast<FwIndexType>(this->m_config.heapPages) + 3 + i, actualSize);
128  this->m_serialInQueue[i].setup(reinterpret_cast<U8*>(ptr), actualSize);
129  }
130  }
131  }
132 
133  // Allocate the initial store
134  this->m_allocator = &mallocator;
135  this->createStore();
136 }
137 
139  if (this->m_wasm != nullptr) {
140  this->destroyStore();
141  }
142 
143  if (this->m_allocator != nullptr) {
144  // Deallocate each heap page
145  for (FwSizeType i = 0; i < this->m_config.heapPages; i++) {
146  this->m_allocator->deallocate(static_cast<FwIndexType>(i) + 1, this->m_heapPages[i]);
147  this->m_heapPages[i] = nullptr;
148  }
149 
150  // Deallocate the heap page pool
151  this->m_allocator->deallocate(0, this->m_heapPages);
152 
153  // Deallocate the guest memory pool
154  if (this->m_guestPool != nullptr) {
155  this->m_allocator->deallocate(static_cast<FwIndexType>(this->m_config.heapPages) + 1, this->m_guestPool);
156  }
157 
158  // Deallocate the serialOut buffer
159  if (this->m_serialOutBuffer.getBuffAddr() != nullptr) {
160  this->m_allocator->deallocate(static_cast<FwIndexType>(this->m_config.heapPages) + 2,
161  this->m_serialOutBuffer.getBuffAddr());
162  }
163 
164  // Deallocate the serialIn queues
165  for (FwIndexType i = 0; i < NUM_SERIALIN_INPUT_PORTS; i++) {
166  if (this->m_serialInQueue[i].get_capacity() > 0) {
167  this->m_allocator->deallocate(static_cast<FwIndexType>(this->m_config.heapPages) + 3 + i,
168  this->m_serialInQueue[i].get_buffer());
169  }
170  }
171  }
172 
173  // Release our slot in the process-wide global-allocator registry so it can
174  // be reused by a later sequencer instance.
175  getGlobalAllocatorLock()->lock();
177  getGlobalAllocatorLock()->unlock();
178 
179  // Clean up dangling pointers
180  this->m_allocator = nullptr;
181  this->m_wasm = nullptr;
182 
184 }
185 
186 // ----------------------------------------------------------------------
187 // Handler implementations for typed input ports
188 // ----------------------------------------------------------------------
189 
190 void WasmSequencer ::checkTimers_handler(FwIndexType portNum, U32 context) {
191  // Drive the sleep-wake / host-function-timeout checks in the state machine.
193 }
194 
195 void WasmSequencer ::cmdResponseIn_handler(FwIndexType portNum,
196  FwOpcodeType opCode,
197  U32 cmdSeq,
198  const Fw::CmdResponse& response) {
199  FW_ASSERT(this->m_wasm != nullptr);
200 
201  // The CmdDisp echoes back the context we sent, not a real cmdSeq. We packed
202  // our cmdUid into that context (see makeCmdUid); rename for clarity.
203  const U32 cmdUid = cmdSeq;
204  const U16 sequenceIndex = static_cast<U16>((cmdUid & 0xFFFF0000) >> 16);
205  const U16 cmdIndex = static_cast<U16>(cmdUid & 0xFFFF);
206  const U16 currentSequenceIndex = static_cast<U16>(this->m_sequencesStarted & 0xFFFF);
207  const U16 currentCmdIndex = static_cast<U16>(this->m_tlm.commandsDispatched & 0xFFFF);
208 
209  // If the response is from a previous execution window, treat it as a nominal
210  // late reply (e.g. a command that returned after a CANCEL) and just report it
211  // without failing the current sequence.
212  if (sequenceIndex != currentSequenceIndex) {
213  this->log_WARNING_LO_CmdResponseFromOldSequence(opCode, response, sequenceIndex, currentSequenceIndex);
214  return;
215  }
216 
217  // From here on the response claims to be from the current sequence, so any
218  // inconsistency is a genuine error that should fail the sequence.
219  if (this->interpreter_getState() !=
221  this->m_pendingHostFunction.kind != WasmSequencer_HostFunction::COMMAND) {
223  return;
224  }
225 
226  // Awaiting a command response, but was it for this exact dispatch instance, or
227  // an earlier one in this sequence with the same opcode?
228  if (cmdIndex != currentCmdIndex) {
229  this->log_WARNING_HI_WrongCmdResponseIndex(opCode, response, cmdIndex, currentCmdIndex);
231  return;
232  }
233 
234  this->m_pendingHostFunction.clear();
235 
236  // Track commands that came back with a non-OK response.
237  if (response != Fw::CmdResponse::OK) {
238  this->m_tlm.commandsFailed++;
239  }
240 
241  this->interpreter_sendSignal_hostResumeI32(static_cast<I32>(response.e));
242 }
243 
244 void WasmSequencer ::writeTelemetry_handler(FwIndexType portNum, U32 context) {
245  FW_ASSERT(this->m_wasm != nullptr);
246 
247  auto now = this->getTime();
248 
249  this->tlmWrite_ControllerState(this->controller_getState(), now);
251  this->tlmWrite_SequencesSucceeded(this->m_tlm.sequencesSucceeded, now);
252  this->tlmWrite_SequencesFailed(this->m_tlm.sequencesFailed, now);
253  this->tlmWrite_SequencesCancelled(this->m_tlm.sequencesCancelled, now);
254  this->tlmWrite_CommandsDispatched(this->m_tlm.commandsDispatched, now);
255  this->tlmWrite_CommandsFailed(this->m_tlm.commandsFailed, now);
256  this->tlmWrite_LastTrapReason(this->m_exit.lastTrapReason, now);
257  this->tlmWrite_SeqName(this->m_tlm.sequenceName, now);
258 }
259 
260 void WasmSequencer ::seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename, const Svc::SeqArgs& args) {
261  FW_ASSERT(this->m_wasm != nullptr);
262 
263  Fw::String runModuleName = "";
264 
266  filename, runModuleName, args,
269  /* moduleIdx */ 0 // placeholder, gets filled in after load
270  )));
271 }
272 
273 void WasmSequencer ::seqCancelIn_handler(FwIndexType portNum) {
276 }
277 
278 // ----------------------------------------------------------------------
279 // Handler implementations for serial input ports
280 // ----------------------------------------------------------------------
281 
282 void WasmSequencer ::serialIn_handler(FwIndexType portNum, Fw::LinearBufferBase& buffer) {
284  Os::ScopeLock scopeLock(this->m_serialInMutex);
285  auto& queue = this->m_serialInQueue[portNum];
286  auto fullFullBehavior = this->m_config.serialIn[portNum].fullBehavior;
287 
288  // Each message is framed on the queue as [U32 length][payload]
289  const FwSizeType headerSize = sizeof(U32);
290  const FwSizeType payloadSize = buffer.getSize();
291  const FwSizeType capacity = queue.get_capacity();
292 
293  // Make sure the queue is sized to hold this framed message at all. This does
294  // not check free space, only that the queue's capacity is large enough.
295  if (headerSize + payloadSize > capacity) {
296  // The largest payload this queue could ever hold is capacity - headerSize. A queue smaller
297  // than the header (including a port left un-configured with capacity 0) can hold nothing.
298  const FwSizeType maxPayload = (capacity > headerSize) ? (capacity - headerSize) : 0;
299  this->log_WARNING_HI_SerialInFrameTooLarge(static_cast<U32>(portNum), static_cast<U32>(payloadSize),
300  static_cast<U32>(maxPayload));
301  return;
302  }
303 
304  // Total framed size; <= capacity by the assertions above, so it cannot overflow.
305  const FwSizeType frameSize = headerSize + payloadSize;
306 
307  // Check if we _can_ push the data to the queue
308  if (frameSize > queue.get_free_size()) {
309  // The queue is full and cannot push this data
310  switch (fullFullBehavior) {
312  // Drop oldest messages until this one fits.
313  while (frameSize > queue.get_free_size()) {
314  U32 nextMsgSize;
315  auto status = queue.peek(nextMsgSize);
316  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, portNum, status);
317 
318  const FwSizeType allocated = queue.get_allocated_size();
319  FW_ASSERT(allocated >= headerSize, portNum, static_cast<FwAssertArgType>(allocated));
320  FW_ASSERT(static_cast<FwSizeType>(nextMsgSize) <= allocated - headerSize, portNum,
321  static_cast<FwAssertArgType>(nextMsgSize), static_cast<FwAssertArgType>(allocated));
322 
323  status = queue.rotate(headerSize + nextMsgSize);
324 
325  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, portNum, status);
326  }
327 
328  // Now it fits, fall through to push the data to the queue
329  break;
331  // Drop this message
332  return;
333 
335  FW_ASSERT(false, portNum, static_cast<FwAssertArgType>(frameSize),
336  static_cast<FwAssertArgType>(queue.get_free_size()), static_cast<FwAssertArgType>(capacity));
337  break;
338  }
339  }
340 
341  // The message should be able to be put into the queue.
342  // Enqueue it as a raw [U32 size][payload] frame. We use the raw (const U8*, size)
344  auto status = sizeSer.serializeFrom(static_cast<U32>(payloadSize));
345  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
346 
347  status = queue.serialize(sizeSer.getBuffAddr(), headerSize);
348  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
349 
350  status = queue.serialize(buffer.getBuffAddr(), payloadSize);
351  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
352 
353  // Wake up any blocking recv calls
355 }
356 
357 // ----------------------------------------------------------------------
358 // Handler implementations for commands
359 // ----------------------------------------------------------------------
360 
361 void WasmSequencer ::RUN_cmdHandler(FwOpcodeType opCode,
362  U32 cmdSeq,
363  const Fw::CmdStringArg& fileName,
364  const Svc::BlockState& block,
365  const SeqArgs& seqArgs) {
366  FW_ASSERT(this->m_wasm != nullptr);
367 
368  Fw::String runModuleName = "";
370  fileName, runModuleName, seqArgs,
372  WasmSequencer_CommandRequest(opCode, cmdSeq), block,
373  /* moduleIdx */ 0 // placeholder, gets filled in after load
374  )));
375 }
376 
377 void WasmSequencer ::WAIT_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
378  FW_ASSERT(this->m_wasm != nullptr);
379 
380  switch (this->controller_getState()) {
383  // Nothing is executing, respond immediately
384  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
385  break;
386  default: {
387  const auto status = this->m_waiting.enqueue(WaitingCmd(opCode, cmdSeq));
388  if (status != Fw::Success::SUCCESS) {
390  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
391  }
392  }
393  }
394 }
395 
396 void WasmSequencer ::LOAD_cmdHandler(FwOpcodeType opCode,
397  U32 cmdSeq,
398  const Fw::CmdStringArg& fileName,
399  const Fw::CmdStringArg& name) {
400  FW_ASSERT(this->m_wasm != nullptr);
401 
403  fileName, name, Svc::SeqArgs(),
405  WasmSequencer_CommandRequest(opCode, cmdSeq), Svc::BlockState::BLOCK,
406  /* moduleIdx */ 0 // placeholder, gets filled in after load
407  )));
408 }
409 
410 void WasmSequencer ::INVOKE_cmdHandler(FwOpcodeType opCode,
411  U32 cmdSeq,
412  const Fw::CmdStringArg& module,
413  const Svc::BlockState& block,
414  const Svc::SeqArgs& seqArgs) {
415  FW_ASSERT(this->m_wasm != nullptr);
416 
418  module, seqArgs,
420  WasmSequencer_CommandRequest(opCode, cmdSeq), block,
421  /* moduleIdx */ 0 // placeholder, gets filled in after invoke
422  )));
423 }
424 
425 void WasmSequencer ::CANCEL_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
427  this->interpreter_sendSignal_cmdCancel(WasmSequencer_CommandRequest(opCode, cmdSeq));
428 }
429 
430 void WasmSequencer ::PAUSE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
433  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
434  return;
435  }
436 
437  this->m_pendingPause = true;
438  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
439 }
440 
441 void WasmSequencer ::CONTINUE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
442  FW_ASSERT(this->m_wasm != nullptr);
443 
444  switch (this->interpreter_getState()) {
448  // Already running
449  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
450  break;
453  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
454  break;
457  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
458  break;
459  default:
460  FW_ASSERT(false, this->interpreter_getState());
461  }
462 }
463 
464 void WasmSequencer ::GLOBAL_SET_I32_cmdHandler(FwOpcodeType opCode,
465  U32 cmdSeq,
466  const Fw::CmdStringArg& moduleName,
467  const Fw::CmdStringArg& name,
468  I32 value) {
469  FW_ASSERT(this->m_wasm != nullptr);
470 
471  spacewasm_value_t s_value;
472  s_value.tag = SPACEWASM_I32;
473  s_value.u.i32_ = value;
474 
475  auto status = this->setGlobal(moduleName, name, s_value);
476  if (status == SPACEWASM_OK) {
477  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
478  } else {
479  this->log_WARNING_LO_GlobalSetFailed(moduleName, name, status);
480  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
481  }
482 }
483 
484 void WasmSequencer ::GLOBAL_SET_I64_cmdHandler(FwOpcodeType opCode,
485  U32 cmdSeq,
486  const Fw::CmdStringArg& moduleName,
487  const Fw::CmdStringArg& name,
488  I64 value) {
489  FW_ASSERT(this->m_wasm != nullptr);
490 
491  spacewasm_value_t s_value;
492  s_value.tag = SPACEWASM_I64;
493  s_value.u.i64_ = value;
494 
495  auto status = this->setGlobal(moduleName, name, s_value);
496  if (status == SPACEWASM_OK) {
497  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
498  } else {
499  this->log_WARNING_LO_GlobalSetFailed(moduleName, name, status);
500  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
501  }
502 }
503 
504 void WasmSequencer ::GLOBAL_SET_F32_cmdHandler(FwOpcodeType opCode,
505  U32 cmdSeq,
506  const Fw::CmdStringArg& moduleName,
507  const Fw::CmdStringArg& name,
508  F32 value) {
509  FW_ASSERT(this->m_wasm != nullptr);
510 
511  spacewasm_value_t s_value;
512  s_value.tag = SPACEWASM_F32;
513  s_value.u.f32_ = value;
514 
515  auto status = this->setGlobal(moduleName, name, s_value);
516  if (status == SPACEWASM_OK) {
517  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
518  } else {
519  this->log_WARNING_LO_GlobalSetFailed(moduleName, name, status);
520  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
521  }
522 }
523 
524 void WasmSequencer ::GLOBAL_SET_F64_cmdHandler(FwOpcodeType opCode,
525  U32 cmdSeq,
526  const Fw::CmdStringArg& moduleName,
527  const Fw::CmdStringArg& name,
528  F64 value) {
529  FW_ASSERT(this->m_wasm != nullptr);
530 
531  spacewasm_value_t g_value;
532  g_value.tag = SPACEWASM_F64;
533  g_value.u.f64_ = value;
534 
535  auto status = this->setGlobal(moduleName, name, g_value);
536  if (status == SPACEWASM_OK) {
537  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
538  } else {
539  this->log_WARNING_LO_GlobalSetFailed(moduleName, name, status);
540  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
541  }
542 }
543 
544 void WasmSequencer ::GLOBAL_GET_cmdHandler(FwOpcodeType opCode,
545  U32 cmdSeq,
546  const Fw::CmdStringArg& moduleName,
547  const Fw::CmdStringArg& name) {
548  FW_ASSERT(this->m_wasm != nullptr);
549 
550  spacewasm_value_t g_value;
551  auto status = this->getGlobal(moduleName, name, g_value);
552  if (status == SPACEWASM_OK) {
553  switch (g_value.tag) {
554  case SPACEWASM_I32:
555  this->log_ACTIVITY_LO_GlobalValueI32(moduleName, name, g_value.u.i32_);
556  break;
557  case SPACEWASM_I64:
558  this->log_ACTIVITY_LO_GlobalValueI64(moduleName, name, g_value.u.i64_);
559  break;
560  case SPACEWASM_F32:
561  this->log_ACTIVITY_LO_GlobalValueF32(moduleName, name, g_value.u.f32_);
562  break;
563  case SPACEWASM_F64:
564  this->log_ACTIVITY_LO_GlobalValueF64(moduleName, name, g_value.u.f64_);
565  break;
566  default:
567  FW_ASSERT(false, g_value.tag);
568  }
569 
570  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
571  } else {
572  this->log_WARNING_LO_GlobalGetFailed(moduleName, name, status);
573  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
574  }
575 }
576 
577 } // namespace Svc
union spacewasm_value_payload_t u
Definition: spacewasm.h:412
Serialization/Deserialization operation was successful.
void interpreter_sendSignal_hostResumeI32(I32 value)
Send signal hostResumeI32 to state machine interpreter.
void tlmWrite_SequencesSucceeded(U64 arg, Fw::Time _tlmTime=Fw::Time())
FwIdType FwOpcodeType
The type of a command opcode.
void log_WARNING_LO_CmdResponseFromOldSequence(FwOpcodeType opcode, const Fw::CmdResponse &response, U16 oldSequenceIdx, U16 currentSequenceIdx) const
Representing success.
PlatformSizeType FwSizeType
Auto-generated base for WasmSequencer component.
void log_ACTIVITY_LO_GlobalValueF32(const Fw::StringBase &module_name, const Fw::StringBase &globalName, F32 value) const
Log event GlobalValueF32.
constexpr FwSizeType SPACEWASM_PAGE_SIZE
void tlmWrite_InterpreterState(const Svc::WasmSequencer_InterpreterStateMachine_State &arg, Fw::Time _tlmTime=Fw::Time())
Serializable::SizeType getSize() const override
Get current buffer size.
Interpreter has modules loaded into the store and is ready to execute.
WasmSequencer(const char *const compName)
Construct WasmSequencer object.
enum T e
The raw enum value.
void interpreter_sendSignal_serialInMessage(const FwIndexType &value)
Send signal serialInMessage to state machine interpreter.
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
Enum representing a command response.
void deinit() override
Tear down the allocations made by configure()
SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG) override
Serialize an 8-bit unsigned integer value.
static constexpr FwSizeType SPACEWASM_MEMORY_ALIGNMENT
SpaceWasm has a hard-coded memory alignment requirement.
void controller_sendSignal_cancel()
Send signal cancel to state machine controller.
float F32
32-bit floating point
Definition: BasicTypes.h:84
void unlock()
alias for unLock to meet BasicLockable requirements
Definition: Mutex.hpp:64
void log_ACTIVITY_LO_GlobalValueI32(const Fw::StringBase &module_name, const Fw::StringBase &globalName, I32 value) const
Log event GlobalValueI32.
void interpreter_sendSignal_cmd_CONTINUE()
Send signal cmd_CONTINUE to state machine interpreter.
Svc_WasmSequencer_ControllerStateMachine::State controller_getState() const
Get the state of state machine instance controller.
void controller_sendSignal_load(const Svc::WasmSequencer_LoadRequest &value)
Send signal load to state machine controller.
SerialInQueueFullBehavior fullBehavior
Overflow policy applied when a new frame does not fit.
U8 * getBuffAddr()
Get buffer address for data filling (non-const version)
SerialInQueueConfig serialIn[NUM_SERIALIN_INPUT_PORTS]
void interpreter_sendSignal_hostResponseUnexpected(const Svc::WasmSequencer_HostFunction &value)
Send signal hostResponseUnexpected to state machine interpreter.
void tlmWrite_LastTrapReason(const Svc::WasmSequencer_TrapReason &arg, Fw::Time _tlmTime=Fw::Time())
void configure(const Config &cfg, Fw::MemAllocator &mallocator)
void * checkedAllocate(const FwEnumStoreType identifier, FwSizeType &size, bool &recoverable, FwSizeType alignment=alignof(std::max_align_t))
void deinit() override
Allows de-initialization on teardown.
Sequencer blocking state.
void log_ACTIVITY_LO_GlobalValueF64(const Fw::StringBase &module_name, const Fw::StringBase &globalName, F64 value) const
Log event GlobalValueF64.
spacewasm_valtype_t tag
Definition: spacewasm.h:411
void log_WARNING_LO_GlobalSetFailed(const Fw::StringBase &module_name, const Fw::StringBase &globalName, const Svc::WasmSequencer_Status &reason) const
Log event GlobalSetFailed.
void log_WARNING_HI_SerialInFrameTooLarge(U32 portIndex, U32 size, U32 maxSize) const
void tlmWrite_SequencesFailed(U64 arg, Fw::Time _tlmTime=Fw::Time())
Command successfully executed.
void tlmWrite_ControllerState(const Svc::WasmSequencer_ControllerStateMachine_State &arg, Fw::Time _tlmTime=Fw::Time())
void log_ACTIVITY_LO_GlobalValueI64(const Fw::StringBase &module_name, const Fw::StringBase &globalName, I64 value) const
Log event GlobalValueI64.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:54
Svc_WasmSequencer_InterpreterStateMachine::State interpreter_getState() const
Get the state of state machine instance interpreter.
Trigger an assertion if the queue fills and cannot process another message.
Drop the latest message if it cannot fit in the remaining queue space.
void interpreter_sendSignal_checkTimers()
Send signal checkTimers to state machine interpreter.
Command had execution error.
void controller_sendSignal_run(const Svc::WasmSequencer_LoadRequest &value)
Send signal run to state machine controller.
void tlmWrite_SeqName(const Fw::StringBase &arg, Fw::Time _tlmTime=Fw::Time())
void setExtBuffer(U8 *buffPtr, Serializable::SizeType size)
Set the external buffer.
Memory Allocation base class.
void tlmWrite_CommandsFailed(U64 arg, Fw::Time _tlmTime=Fw::Time())
Interpreter does not have any modules loaded or a store initialized.
spacewasm_status_t spacewasm_fprime_deregister_global_allocator(void *userdata)
void log_WARNING_HI_WrongCmdResponseIndex(FwOpcodeType opcode, const Fw::CmdResponse &response, U16 actualCmdIdx, U16 expectedCmdIdx) const
PlatformIndexType FwIndexType
locks a mutex within the current scope
Definition: Mutex.hpp:80
void log_WARNING_LO_GlobalGetFailed(const Fw::StringBase &module_name, const Fw::StringBase &globalName, const Svc::WasmSequencer_Status &reason) const
Log event GlobalGetFailed.
void tlmWrite_SequencesCancelled(U64 arg, Fw::Time _tlmTime=Fw::Time())
spacewasm_status_t spacewasm_fprime_register_global_allocator(spacewasm_global_alloc_fn_t alloc, spacewasm_global_dealloc_fn_t dealloc, void *userdata)
void setup(U8 *const buffer, const FwSizeType size)
double F64
64-bit floating point (double). Required for compiler-supplied double promotion.
Definition: BasicTypes.h:86
Fw::MallocAllocator mallocator
Definition: RefTopology.cpp:23
RateGroupDivider component implementation.
virtual void deallocate(const FwEnumStoreType identifier, void *ptr)=0
Success enqueue(const T &e) override
Definition: FifoQueue.hpp:61
void interpreter_sendSignal_cancel()
Send signal cancel to state machine interpreter.
void interpreter_sendSignal_cmdCancel(const Svc::WasmSequencer_CommandRequest &value)
Send signal cmdCancel to state machine interpreter.
constexpr FwSizeType SPACEWASM_MAX_PAGES
#define FW_ASSERT(...)
Definition: Assert.hpp:14
FwSizeType size
Queue size in bytes. A port left at size 0 gets no queue (all inbound frames on that index are droppe...
void controller_sendSignal_invoke(const Svc::WasmSequencer_InvokeRequest &value)
Send signal invoke to state machine controller.
The idle state means there is no function running in the engine.
void lock()
lock the mutex and assert success
Definition: Mutex.cpp:34
void tlmWrite_CommandsDispatched(U64 arg, Fw::Time _tlmTime=Fw::Time())