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"
25 #include "config/CommandDispatcherImplCfg.hpp"
29 
30 namespace Svc {
31 
32 U8* WasmSequencer ::globalAllocCallback(void* userdata, size_t size, size_t align) {
33  if (userdata == nullptr) {
34  return nullptr;
35  }
36  return static_cast<WasmSequencer*>(userdata)->globalAlloc(static_cast<U32>(size), static_cast<U32>(align));
37 }
38 
39 void WasmSequencer ::globalDeallocCallback(void* userdata, U8* ptr, size_t size, size_t align) {
40  (void)size;
41  (void)align;
42  if (userdata != nullptr) {
43  static_cast<WasmSequencer*>(userdata)->globalDealloc(ptr);
44  }
45 }
46 
47 // ----------------------------------------------------------------------
48 // Component construction and destruction
49 // ----------------------------------------------------------------------
50 
51 WasmSequencer ::WasmSequencer(const char* const compName)
52  : WasmSequencerComponentBase(compName),
53  m_heapPages(nullptr),
54  m_heapPagesUsed(0),
55  m_heapPoisoned(false),
56  m_guestPool(nullptr),
57  m_guestPoolOffset(0),
58  m_wasm(nullptr),
59  m_hasExecutingContext(false),
60  m_pendingTimer(),
61  m_hasPendingTimer(false),
62  m_hostFunctionStart(),
63  m_hasHostFunctionStart(false),
64  m_dequeueSucceeded(false),
65  m_invokeStatus(SPACEWASM_OK),
66  m_pendingPause(false),
67  m_cancelRequested(false),
68  m_writeTelemetryQueued(false),
69  m_sequencesStarted(0) {}
70 
72  FW_ASSERT(this->m_wasm == nullptr);
73  FW_ASSERT(this->m_allocator == nullptr);
74 
75  getGlobalAllocatorLock()->lock();
76  const auto status = spacewasm_fprime_register_global_allocator(&globalAllocCallback, &globalDeallocCallback, this);
77  getGlobalAllocatorLock()->unlock();
78 
79  FW_ASSERT(status == SPACEWASM_OK, status);
80 
81  this->m_config = cfg;
82 
83  // Allocate the heap memory pool
84  {
85  FW_ASSERT(
86  this->m_config.heapPages > 0 && this->m_config.heapPages <= Svc::WasmSequencerConfig::SPACEWASM_MAX_PAGES,
87  static_cast<FwAssertArgType>(this->m_config.heapPages), Svc::WasmSequencerConfig::SPACEWASM_MAX_PAGES);
88 
89  // Allocate the heap page list
90  {
91  FwSizeType actualSize = sizeof(U8*) * this->m_config.heapPages;
92  auto ptr = mallocator.checkedAllocate(0, actualSize);
93  this->m_heapPages = reinterpret_cast<U8**>(ptr);
94  }
95 
96  // Allocate each heap page
97  for (FwSizeType i = 0; i < this->m_config.heapPages; i++) {
99  auto ptr =
100  mallocator.checkedAllocate(static_cast<FwIndexType>(i) + 1, actualSize, SPACEWASM_MEMORY_ALIGNMENT);
101  this->m_heapPages[i] = reinterpret_cast<U8*>(ptr);
102  }
103  this->m_heapPagesUsed = 0;
104  }
105 
106  // Allocate the guest memory pool
107  {
108  auto actualSize = this->m_config.guestMemorySize;
109  auto ptr = mallocator.checkedAllocate(static_cast<FwIndexType>(this->m_config.heapPages) + 1, actualSize,
111  this->m_guestPoolOffset = 0;
112  this->m_guestPool = reinterpret_cast<U8*>(ptr);
113  }
114 
115  // Allocate the serialOut buffer
116  if (this->m_config.serialOutMax > 0) {
117  auto actualSize = this->m_config.serialOutMax;
118  auto ptr = mallocator.checkedAllocate(static_cast<FwIndexType>(this->m_config.heapPages) + 2, actualSize);
119  this->m_serialOutBuffer.setExtBuffer(reinterpret_cast<U8*>(ptr), actualSize);
120  }
121 
122  // Allocate the serialIn queues
123  {
124  Os::ScopeLock scopeLock(this->m_serialInMutex);
125  for (FwIndexType i = 0; i < NUM_SERIALIN_INPUT_PORTS; i++) {
126  if (this->m_config.serialIn[i].size > 0) {
127  auto actualSize = this->m_config.serialIn[i].size;
128  auto ptr =
129  mallocator.checkedAllocate(static_cast<FwIndexType>(this->m_config.heapPages) + 3 + i, actualSize);
130  this->m_serialInQueue[i].setup(reinterpret_cast<U8*>(ptr), actualSize);
131  }
132  }
133  }
134 
135  // Allocate the initial store
136  this->m_allocator = &mallocator;
137  this->createStore();
138 }
139 
141  if (this->m_wasm != nullptr) {
142  this->destroyStore();
143  }
144 
145  if (this->m_allocator != nullptr) {
146  // Deallocate each heap page
147  for (FwSizeType i = 0; i < this->m_config.heapPages; i++) {
148  this->m_allocator->deallocate(static_cast<FwIndexType>(i) + 1, this->m_heapPages[i]);
149  this->m_heapPages[i] = nullptr;
150  }
151 
152  // Deallocate the heap page pool
153  this->m_allocator->deallocate(0, this->m_heapPages);
154 
155  // Deallocate the guest memory pool
156  if (this->m_guestPool != nullptr) {
157  this->m_allocator->deallocate(static_cast<FwIndexType>(this->m_config.heapPages) + 1, this->m_guestPool);
158  }
159 
160  // Deallocate the serialOut buffer
161  if (this->m_serialOutBuffer.getBuffAddr() != nullptr) {
162  this->m_allocator->deallocate(static_cast<FwIndexType>(this->m_config.heapPages) + 2,
163  this->m_serialOutBuffer.getBuffAddr());
164  }
165 
166  // Deallocate the serialIn queues
167  for (FwIndexType i = 0; i < NUM_SERIALIN_INPUT_PORTS; i++) {
168  if (this->m_serialInQueue[i].get_capacity() > 0) {
169  this->m_allocator->deallocate(static_cast<FwIndexType>(this->m_config.heapPages) + 3 + i,
170  this->m_serialInQueue[i].get_buffer());
171  }
172  }
173  }
174 
175  // Release our slot in the process-wide global-allocator registry so it can
176  // be reused by a later sequencer instance.
177  getGlobalAllocatorLock()->lock();
179  getGlobalAllocatorLock()->unlock();
180 
181  // Clean up dangling pointers
182  this->m_allocator = nullptr;
183  this->m_wasm = nullptr;
184 
186 }
187 
188 // ----------------------------------------------------------------------
189 // Handler implementations for typed input ports
190 // ----------------------------------------------------------------------
191 
192 void WasmSequencer ::checkTimers_handler(FwIndexType portNum, U32 context) {
193  // Drive the sleep-wake / host-function-timeout checks in the state machine.
195 }
196 
197 void WasmSequencer ::cmdResponseIn_handler(FwIndexType portNum,
198  FwOpcodeType opCode,
199  U32 cmdSeq,
200  const Fw::CmdResponse& response) {
201  FW_ASSERT(this->m_wasm != nullptr);
202 
203  // The CmdDisp echoes back the context we sent, not a real cmdSeq. We packed
204  // our cmdUid into that context (see makeCmdUid); rename for clarity.
205  const U32 cmdUid = cmdSeq;
206  const U16 sequenceIndex = static_cast<U16>((cmdUid & 0xFFFF0000) >> 16);
207  const U16 cmdIndex = static_cast<U16>(cmdUid & 0xFFFF);
208  const U16 currentSequenceIndex = static_cast<U16>(this->m_sequencesStarted & 0xFFFF);
209  const U16 currentCmdIndex = static_cast<U16>(this->m_tlm.commandsDispatched & 0xFFFF);
210 
211  // If the response is from a previous execution window, treat it as a nominal
212  // late reply (e.g. a command that returned after a CANCEL) and just report it
213  // without failing the current sequence.
214  if (sequenceIndex != currentSequenceIndex) {
216  sequenceIndex, currentSequenceIndex);
217  return;
218  }
219 
220  // From here on the response claims to be from the current sequence, so any
221  // inconsistency is a genuine error that should fail the sequence.
222  if (this->interpreter_getState() !=
224  this->m_pendingHostFunction.kind != WasmSequencer_HostFunction::COMMAND) {
226  return;
227  }
228 
229  // Awaiting a command response, but was it for this exact dispatch instance, or
230  // an earlier one in this sequence with the same opcode?
231  if (cmdIndex != currentCmdIndex) {
233  currentCmdIndex);
235  return;
236  }
237 
238  this->m_pendingHostFunction.clear();
239 
240  // Track commands that came back with a non-OK response.
241  if (response != Fw::CmdResponse::OK) {
242  this->m_tlm.commandsFailed++;
243  }
244 
245  this->interpreter_sendSignal_hostResumeI32(static_cast<I32>(response.e));
246 }
247 
248 void WasmSequencer ::writeTelemetry_handler(FwIndexType portNum, U32 context) {
249  bool expected = false;
250  if (this->m_writeTelemetryQueued.compare_exchange_strong(expected, true)) {
252  }
253 }
254 
255 void WasmSequencer ::writeTelemetryInternal_overflowHook() {
256  this->m_writeTelemetryQueued = false;
257 }
258 
259 void WasmSequencer ::writeTelemetryInternal_internalInterfaceHandler() {
260  this->m_writeTelemetryQueued = false;
261  FW_ASSERT(this->m_wasm != nullptr);
262 
263  auto now = this->getTime();
264 
265  this->tlmWrite_ControllerState(this->controller_getState(), now);
267  this->tlmWrite_SequencesSucceeded(this->m_tlm.sequencesSucceeded, now);
268  this->tlmWrite_SequencesFailed(this->m_tlm.sequencesFailed, now);
269  this->tlmWrite_SequencesCancelled(this->m_tlm.sequencesCancelled, now);
270  this->tlmWrite_CommandsDispatched(this->m_tlm.commandsDispatched, now);
271  this->tlmWrite_CommandsFailed(this->m_tlm.commandsFailed, now);
272  this->tlmWrite_LastTrapReason(this->m_exit.lastTrapReason, now);
273  this->tlmWrite_SeqName(this->m_tlm.sequenceName, now);
274 }
275 
276 void WasmSequencer ::seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename, const Svc::SeqArgs& args) {
277  FW_ASSERT(this->m_wasm != nullptr);
278 
279  Fw::String runModuleName = "";
280 
282  filename, runModuleName,
285  /* moduleIdx */ 0 // placeholder, gets filled in after load
286  )));
287 }
288 
289 void WasmSequencer ::seqCancelIn_handler(FwIndexType portNum) {
292 }
293 
294 // ----------------------------------------------------------------------
295 // Handler implementations for serial input ports
296 // ----------------------------------------------------------------------
297 
298 void WasmSequencer ::serialIn_handler(FwIndexType portNum, Fw::LinearBufferBase& buffer) {
300  Os::ScopeLock scopeLock(this->m_serialInMutex);
301  auto& queue = this->m_serialInQueue[portNum];
302  auto fullFullBehavior = this->m_config.serialIn[portNum].fullBehavior;
303 
304  // Each message is framed on the queue as [U32 length][payload]
305  const FwSizeType headerSize = sizeof(U32);
306  const FwSizeType payloadSize = buffer.getSize();
307  const FwSizeType capacity = queue.get_capacity();
308 
309  // Make sure the queue is sized to hold this framed message at all. This does
310  // not check free space, only that the queue's capacity is large enough.
311  if (headerSize + payloadSize > capacity) {
312  // The largest payload this queue could ever hold is capacity - headerSize. A queue smaller
313  // than the header (including a port left un-configured with capacity 0) can hold nothing.
314  const FwSizeType maxPayload = (capacity > headerSize) ? (capacity - headerSize) : 0;
315  this->log_WARNING_HI_SerialInFrameTooLarge(static_cast<U32>(portNum), static_cast<U32>(payloadSize),
316  static_cast<U32>(maxPayload));
317  return;
318  }
319 
320  // Total framed size; <= capacity by the assertions above, so it cannot overflow.
321  const FwSizeType frameSize = headerSize + payloadSize;
322 
323  // Check if we _can_ push the data to the queue
324  if (frameSize > queue.get_free_size()) {
325  // The queue is full and cannot push this data
326  switch (fullFullBehavior) {
328  // Drop oldest messages until this one fits.
329  while (frameSize > queue.get_free_size()) {
330  U32 nextMsgSize;
331  auto status = queue.peek(nextMsgSize);
332  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, portNum, status);
333 
334  const FwSizeType allocated = queue.get_allocated_size();
335  FW_ASSERT(allocated >= headerSize, portNum, static_cast<FwAssertArgType>(allocated));
336  FW_ASSERT(static_cast<FwSizeType>(nextMsgSize) <= allocated - headerSize, portNum,
337  static_cast<FwAssertArgType>(nextMsgSize), static_cast<FwAssertArgType>(allocated));
338 
339  status = queue.rotate(headerSize + nextMsgSize);
340 
341  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, portNum, status);
342  }
343 
344  // Now it fits, fall through to push the data to the queue
345  break;
347  // Drop this message
348  return;
349 
351  FW_ASSERT(false, portNum, static_cast<FwAssertArgType>(frameSize),
352  static_cast<FwAssertArgType>(queue.get_free_size()), static_cast<FwAssertArgType>(capacity));
353  break;
354  }
355  }
356 
357  // The message should be able to be put into the queue.
358  // Enqueue it as a raw [U32 size][payload] frame. We use the raw (const U8*, size)
360  auto status = sizeSer.serializeFrom(static_cast<U32>(payloadSize));
361  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
362 
363  status = queue.serialize(sizeSer.getBuffAddr(), headerSize);
364  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
365 
366  status = queue.serialize(buffer.getBuffAddr(), payloadSize);
367  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
368 
369  // Wake up any blocking recv calls
371 }
372 
373 // ----------------------------------------------------------------------
374 // Handler implementations for commands
375 // ----------------------------------------------------------------------
376 
377 void WasmSequencer ::RUN_cmdHandler(FwOpcodeType opCode,
378  U32 cmdSeq,
379  const Fw::CmdStringArg& fileName,
380  const Svc::BlockState& block) {
381  FW_ASSERT(this->m_wasm != nullptr);
382 
383  Fw::String runModuleName = "";
385  fileName, runModuleName,
387  WasmSequencer_CommandRequest(opCode, cmdSeq), block,
388  /* moduleIdx */ 0 // placeholder, gets filled in after load
389  )));
390 }
391 
392 void WasmSequencer ::WAIT_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
393  FW_ASSERT(this->m_wasm != nullptr);
394 
395  switch (this->controller_getState()) {
398  // Nothing is executing, respond immediately
399  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
400  break;
401  default: {
402  const auto status = this->m_waiting.enqueue(WaitingCmd(opCode, cmdSeq));
403  if (status != Fw::Success::SUCCESS) {
405  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
406  }
407  }
408  }
409 }
410 
411 void WasmSequencer ::LOAD_cmdHandler(FwOpcodeType opCode,
412  U32 cmdSeq,
413  const Fw::CmdStringArg& fileName,
414  const Fw::CmdStringArg& name) {
415  FW_ASSERT(this->m_wasm != nullptr);
416 
418  fileName, name,
420  WasmSequencer_CommandRequest(opCode, cmdSeq), Svc::BlockState::BLOCK,
421  /* moduleIdx */ 0 // placeholder, gets filled in after load
422  )));
423 }
424 
425 void WasmSequencer ::INVOKE_cmdHandler(FwOpcodeType opCode,
426  U32 cmdSeq,
427  const Fw::CmdStringArg& module,
428  const Svc::BlockState& block) {
429  FW_ASSERT(this->m_wasm != nullptr);
430 
433  WasmSequencer_CommandRequest(opCode, cmdSeq), block,
434  /* moduleIdx */ 0 // placeholder, gets filled in after invoke
435  )));
436 }
437 
438 void WasmSequencer ::CANCEL_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
440  this->interpreter_sendSignal_cmdCancel(WasmSequencer_CommandRequest(opCode, cmdSeq));
441 }
442 
443 void WasmSequencer ::PAUSE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
446  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
447  return;
448  }
449 
450  this->m_pendingPause = true;
451  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
452 }
453 
454 void WasmSequencer ::CONTINUE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
455  FW_ASSERT(this->m_wasm != nullptr);
456 
457  switch (this->interpreter_getState()) {
461  // Already running
462  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
463  break;
466  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
467  break;
470  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
471  break;
472  default:
473  FW_ASSERT(false, this->interpreter_getState());
474  }
475 }
476 
477 void WasmSequencer ::GLOBAL_SET_I32_cmdHandler(FwOpcodeType opCode,
478  U32 cmdSeq,
479  const Fw::CmdStringArg& moduleName,
480  const Fw::CmdStringArg& name,
481  I32 value) {
482  FW_ASSERT(this->m_wasm != nullptr);
483 
484  spacewasm_value_t s_value;
485  s_value.tag = SPACEWASM_I32;
486  s_value.u.i32_ = value;
487 
488  auto status = this->setGlobal(moduleName, name, s_value);
489  if (status == SPACEWASM_OK) {
490  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
491  } else {
492  this->log_WARNING_LO_GlobalSetFailed(moduleName, name, status);
493  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
494  }
495 }
496 
497 void WasmSequencer ::GLOBAL_SET_I64_cmdHandler(FwOpcodeType opCode,
498  U32 cmdSeq,
499  const Fw::CmdStringArg& moduleName,
500  const Fw::CmdStringArg& name,
501  I64 value) {
502  FW_ASSERT(this->m_wasm != nullptr);
503 
504  spacewasm_value_t s_value;
505  s_value.tag = SPACEWASM_I64;
506  s_value.u.i64_ = value;
507 
508  auto status = this->setGlobal(moduleName, name, s_value);
509  if (status == SPACEWASM_OK) {
510  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
511  } else {
512  this->log_WARNING_LO_GlobalSetFailed(moduleName, name, status);
513  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
514  }
515 }
516 
517 void WasmSequencer ::GLOBAL_SET_F32_cmdHandler(FwOpcodeType opCode,
518  U32 cmdSeq,
519  const Fw::CmdStringArg& moduleName,
520  const Fw::CmdStringArg& name,
521  F32 value) {
522  FW_ASSERT(this->m_wasm != nullptr);
523 
524  spacewasm_value_t s_value;
525  s_value.tag = SPACEWASM_F32;
526  s_value.u.f32_ = value;
527 
528  auto status = this->setGlobal(moduleName, name, s_value);
529  if (status == SPACEWASM_OK) {
530  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
531  } else {
532  this->log_WARNING_LO_GlobalSetFailed(moduleName, name, status);
533  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
534  }
535 }
536 
537 void WasmSequencer ::GLOBAL_SET_F64_cmdHandler(FwOpcodeType opCode,
538  U32 cmdSeq,
539  const Fw::CmdStringArg& moduleName,
540  const Fw::CmdStringArg& name,
541  F64 value) {
542  FW_ASSERT(this->m_wasm != nullptr);
543 
544  spacewasm_value_t g_value;
545  g_value.tag = SPACEWASM_F64;
546  g_value.u.f64_ = value;
547 
548  auto status = this->setGlobal(moduleName, name, g_value);
549  if (status == SPACEWASM_OK) {
550  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
551  } else {
552  this->log_WARNING_LO_GlobalSetFailed(moduleName, name, status);
553  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
554  }
555 }
556 
557 void WasmSequencer ::GLOBAL_GET_cmdHandler(FwOpcodeType opCode,
558  U32 cmdSeq,
559  const Fw::CmdStringArg& moduleName,
560  const Fw::CmdStringArg& name) {
561  FW_ASSERT(this->m_wasm != nullptr);
562 
563  spacewasm_value_t g_value;
564  auto status = this->getGlobal(moduleName, name, g_value);
565  if (status == SPACEWASM_OK) {
566  switch (g_value.tag) {
567  case SPACEWASM_I32:
568  this->log_ACTIVITY_LO_GlobalValueI32(moduleName, name, g_value.u.i32_);
569  break;
570  case SPACEWASM_I64:
571  this->log_ACTIVITY_LO_GlobalValueI64(moduleName, name, g_value.u.i64_);
572  break;
573  case SPACEWASM_F32:
574  this->log_ACTIVITY_LO_GlobalValueF32(moduleName, name, g_value.u.f32_);
575  break;
576  case SPACEWASM_F64:
577  this->log_ACTIVITY_LO_GlobalValueF64(moduleName, name, g_value.u.f64_);
578  break;
579  default:
580  FW_ASSERT(false, g_value.tag);
581  }
582 
583  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
584  } else {
585  this->log_WARNING_LO_GlobalGetFailed(moduleName, name, status);
586  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
587  }
588 }
589 
590 } // 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 writeTelemetryInternal_internalInterfaceInvoke()
Internal interface base-class function for writeTelemetryInternal.
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 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
FwOpcodeType getEventOpcode(const FwOpcodeType opcode)
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.
void lock()
lock the mutex and assert success
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
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
void unlock()
alias for unLock to meet BasicLockable requirements
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 tlmWrite_CommandsDispatched(U64 arg, Fw::Time _tlmTime=Fw::Time())