F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
ComQueue.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title ComQueue.cpp
3 // \author vbai
4 // \brief cpp file for ComQueue component implementation class
5 // ======================================================================
6 
7 #include <Fw/Com/ComPacket.hpp>
8 #include <Fw/Types/Assert.hpp>
10 #include <type_traits>
11 #include "Fw/Types/BasicTypes.hpp"
12 
13 namespace Svc {
14 
15 // ----------------------------------------------------------------------
16 // Construction, initialization, and destruction
17 // ----------------------------------------------------------------------
18 
19 using FwUnsignedIndexType = std::make_unsigned<FwIndexType>::type;
20 
21 ComQueue ::QueueConfigurationTable ::QueueConfigurationTable() {
22  static_assert(static_cast<FwUnsignedIndexType>(std::numeric_limits<FwIndexType>::max()) >=
23  FW_NUM_ARRAY_ELEMENTS(this->entries),
24  "Number of entries must fit into FwIndexType");
25  for (FwIndexType i = 0; i < static_cast<FwIndexType>(FW_NUM_ARRAY_ELEMENTS(this->entries)); i++) {
26  this->entries[i].priority = 0;
27  this->entries[i].depth = 0;
28  this->entries[i].mode = Types::QUEUE_FIFO;
29  this->entries[i].overflowMode = Types::QUEUE_DROP_NEWEST;
30  }
31 }
32 
33 ComQueue ::ComQueue(const char* const compName)
34  : ComQueueComponentBase(compName),
35  m_state(WAITING),
36  m_buffer_state(OWNED),
37  m_allocationId(static_cast<FwEnumStoreType>(-1)),
38  m_allocator(nullptr),
39  m_allocation(nullptr) {
40  // Initialize throttles to "off"
41  for (FwIndexType i = 0; i < TOTAL_PORT_COUNT; i++) {
42  this->m_throttle[i] = false;
43  }
44 
45  static_assert(TOTAL_PORT_COUNT >= 1, "ComQueue must have more than one port");
46 }
47 
49 
51  // Deallocate memory ignoring error conditions
52  if ((this->m_allocator != nullptr) && (this->m_allocation != nullptr)) {
53  this->m_allocator->deallocate(this->m_allocationId, this->m_allocation);
54  }
55 }
56 
58  FwEnumStoreType allocationId,
59  Fw::MemAllocator& allocator) {
60  FwIndexType currentPriorityIndex = 0;
61  FwSizeType totalAllocation = 0;
62 
63  // Store/initialize allocator members
64  this->m_allocator = &allocator;
65  this->m_allocationId = allocationId;
66  this->m_allocation = nullptr;
67 
68  // Initializes the sorted queue metadata list in priority (sorted) order. This is accomplished by walking the
69  // priority values in priority order from 0 to TOTAL_PORT_COUNT. At each priory value, the supplied queue
70  // configuration table is walked and any entry matching the current priority values is used to add queue metadata to
71  // the prioritized list. This results in priority-sorted queue metadata objects that index back into the unsorted
72  // queue data structures.
73  //
74  // The total allocation size is tracked for passing to the allocation call and is a summation of
75  // (depth * message size) for each prioritized metadata object of (depth * message size)
76  for (FwIndexType currentPriority = 0; currentPriority < TOTAL_PORT_COUNT; currentPriority++) {
77  // Walk each queue configuration entry and add them into the prioritized metadata list when matching the current
78  // priority value
79  for (FwIndexType entryIndex = 0;
80  entryIndex < static_cast<FwIndexType>(FW_NUM_ARRAY_ELEMENTS(queueConfig.entries)); entryIndex++) {
81  // Check for valid configuration entry
82  FW_ASSERT(queueConfig.entries[entryIndex].priority < TOTAL_PORT_COUNT,
83  static_cast<FwAssertArgType>(queueConfig.entries[entryIndex].priority),
84  static_cast<FwAssertArgType>(TOTAL_PORT_COUNT), static_cast<FwAssertArgType>(entryIndex));
85 
86  if (currentPriority == queueConfig.entries[entryIndex].priority) {
87  // Set up the queue metadata object in order to track priority, depth, index into the queue list of the
88  // backing queue object, and message size. Both index and message size are calculated where priority and
89  // depth are copied from the configuration object.
90  QueueMetadata& entry = this->m_prioritizedList[currentPriorityIndex];
91  entry.priority = queueConfig.entries[entryIndex].priority;
92  entry.depth = queueConfig.entries[entryIndex].depth;
93  entry.mode = queueConfig.entries[entryIndex].mode;
94  entry.overflowMode = queueConfig.entries[entryIndex].overflowMode;
95  entry.index = entryIndex;
96  // Message size is determined by the type of object being stored, which in turn is determined by the
97  // index of the entry. Those lower than COM_PORT_COUNT are Fw::ComBuffers and those larger Fw::Buffer.
98  entry.msgSize = (entryIndex < COM_PORT_COUNT) ? sizeof(Fw::ComBuffer) : sizeof(Fw::Buffer);
99  // Overflow checks
100  FW_ASSERT((std::numeric_limits<FwSizeType>::max() / entry.depth) >= entry.msgSize,
101  static_cast<FwAssertArgType>(entry.depth), static_cast<FwAssertArgType>(entry.msgSize));
102  FW_ASSERT(std::numeric_limits<FwSizeType>::max() - (entry.depth * entry.msgSize) >= totalAllocation);
103  totalAllocation += entry.depth * entry.msgSize;
104  currentPriorityIndex++;
105  }
106  }
107  }
108  // Allocate a single chunk of memory from the memory allocator. Memory recover is neither needed nor used.
109  bool recoverable = false;
110  this->m_allocation = this->m_allocator->allocate(this->m_allocationId, totalAllocation, recoverable);
111 
112  // Each of the backing queue objects must be supplied memory to store the queued messages. These data regions are
113  // sub-portions of the total allocated data. This memory is passed out by looping through each queue in prioritized
114  // order and passing out the memory to each queue's setup method.
115  FwSizeType allocationOffset = 0;
116  for (FwIndexType i = 0; i < TOTAL_PORT_COUNT; i++) {
117  // Get current queue's allocation size and safety check the values
118  FwSizeType allocationSize = this->m_prioritizedList[i].depth * this->m_prioritizedList[i].msgSize;
119  FW_ASSERT(this->m_prioritizedList[i].index < static_cast<FwIndexType>(FW_NUM_ARRAY_ELEMENTS(this->m_queues)),
120  static_cast<FwAssertArgType>(this->m_prioritizedList[i].index));
121  FW_ASSERT((allocationSize + allocationOffset) <= totalAllocation, static_cast<FwAssertArgType>(allocationSize),
122  static_cast<FwAssertArgType>(allocationOffset), static_cast<FwAssertArgType>(totalAllocation));
123 
124  // Setup queue's memory allocation, depth, and message size. Setup is skipped for a depth 0 queue
125  if (allocationSize > 0) {
126  this->m_queues[this->m_prioritizedList[i].index].setup(
127  reinterpret_cast<U8*>(this->m_allocation) + allocationOffset, allocationSize,
128  this->m_prioritizedList[i].depth, this->m_prioritizedList[i].msgSize, this->m_prioritizedList[i].mode,
129  this->m_prioritizedList[i].overflowMode);
130  }
131  allocationOffset += allocationSize;
132  }
133  // Safety check that all memory was used as expected
134  FW_ASSERT(allocationOffset == totalAllocation, static_cast<FwAssertArgType>(allocationOffset),
135  static_cast<FwAssertArgType>(totalAllocation));
136 }
137 
138 // ----------------------------------------------------------------------
139 // Handler implementations for commands
140 // ----------------------------------------------------------------------
141 
142 void ComQueue ::FLUSH_QUEUE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Svc::QueueType queueType, FwIndexType index) {
143  // Acquire the queue that we need to drain
144  FwIndexType queueIndex = this->getQueueNum(queueType, index);
145 
146  // Validate queue index
147  if (queueIndex < 0 || queueIndex >= TOTAL_PORT_COUNT) {
148  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
149  return;
150  }
151 
152  this->drainQueue(queueIndex);
153  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
154 }
155 
156 void ComQueue ::FLUSH_ALL_QUEUES_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
157  for (FwIndexType i = 0; i < TOTAL_PORT_COUNT; i++) {
158  this->drainQueue(i);
159  }
160  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
161 }
162 
163 void ComQueue::SET_QUEUE_PRIORITY_cmdHandler(FwOpcodeType opCode,
164  U32 cmdSeq,
165  Svc::QueueType queueType,
166  FwIndexType index,
167  FwIndexType newPriority) {
168  // Acquire the queue we are to reprioritize
169  FwIndexType queueIndex = this->getQueueNum(queueType, index);
170 
171  // Validate queue index
172  if (queueIndex < 0 || queueIndex >= TOTAL_PORT_COUNT) {
173  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
174  return;
175  }
176 
177  // Validate priority range
178  if (newPriority < 0 || newPriority >= TOTAL_PORT_COUNT) {
179  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
180  return;
181  }
182 
183  // Find our queue in the prioritized list & update the priority
184  for (FwIndexType prioIndex = 0; prioIndex < TOTAL_PORT_COUNT; prioIndex++) {
185  // If the port based index matches, then update
186  if (m_prioritizedList[prioIndex].index == queueIndex) {
187  m_prioritizedList[prioIndex].priority = newPriority;
188  break; // Since we shouldn't find more than one queue at this port index
189  }
190  }
191 
192  // Re-sort the prioritized list to maintain priority ordering
193  // Using simple bubble sort since TOTAL_PORT_COUNT is typically small
194  for (FwIndexType i = 0; i < TOTAL_PORT_COUNT - 1; i++) {
195  for (FwIndexType j = 0; (j < TOTAL_PORT_COUNT - i - 1) && (j < TOTAL_PORT_COUNT - 1); j++) {
196  if (m_prioritizedList[j].priority > m_prioritizedList[j + 1].priority) {
197  // Swap metadata
198  QueueMetadata temp = m_prioritizedList[j];
199  m_prioritizedList[j] = m_prioritizedList[j + 1];
200  m_prioritizedList[j + 1] = temp;
201  }
202  }
203  }
204 
205  // Emit event for successful priority change
206  this->log_ACTIVITY_HI_QueuePriorityChanged(queueType, queueIndex, newPriority);
207 
208  // Send command response
209  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
210 }
211 
212 // ----------------------------------------------------------------------
213 // Handler implementations for user-defined typed input ports
214 // ----------------------------------------------------------------------
215 
216 void ComQueue::comPacketQueueIn_handler(const FwIndexType portNum, Fw::ComBuffer& data, U32 context) {
217  // Ensure that the port number of comPacketQueueIn is consistent with the expectation
218  FW_ASSERT(portNum >= 0 && portNum < COM_PORT_COUNT, static_cast<FwAssertArgType>(portNum));
219  (void)this->enqueue(portNum, QueueType::COM_QUEUE, reinterpret_cast<const U8*>(&data), sizeof(Fw::ComBuffer));
220 }
221 
222 void ComQueue::bufferQueueIn_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) {
223  FW_ASSERT(std::numeric_limits<FwIndexType>::max() - COM_PORT_COUNT > portNum);
224  const FwIndexType queueNum = static_cast<FwIndexType>(portNum + COM_PORT_COUNT);
225  // Ensure that the port number of bufferQueueIn is consistent with the expectation
226  FW_ASSERT(portNum >= 0 && portNum < BUFFER_PORT_COUNT, static_cast<FwAssertArgType>(portNum));
227  FW_ASSERT(queueNum < TOTAL_PORT_COUNT);
228  bool success =
229  this->enqueue(queueNum, QueueType::BUFFER_QUEUE, reinterpret_cast<const U8*>(&fwBuffer), sizeof(Fw::Buffer));
230  if (!success) {
231  this->bufferReturnOut_out(portNum, fwBuffer);
232  }
233 }
234 
235 void ComQueue::comStatusIn_handler(const FwIndexType portNum, Fw::Success& condition) {
236  switch (this->m_state) {
237  // On success, the queue should be processed. On failure, the component should still wait.
238  case WAITING:
239  if (condition.e == Fw::Success::SUCCESS) {
240  this->m_state = READY;
241  this->processQueue();
242  // A message may or may not be sent. Thus, READY or WAITING are acceptable final states.
243  FW_ASSERT((this->m_state == WAITING || this->m_state == READY),
244  static_cast<FwAssertArgType>(this->m_state));
245  } else {
246  this->m_state = WAITING;
247  }
248  break;
249  // Both READY and unknown states should not be possible at this point. To receive a status message we must be
250  // one of the WAITING or RETRY states.
251  default:
252  FW_ASSERT(0, static_cast<FwAssertArgType>(this->m_state));
253  break;
254  }
255 }
256 
257 void ComQueue::run_handler(const FwIndexType portNum, U32 context) {
258  // Downlink the high-water marks for the Fw::ComBuffer array types
259  ComQueueDepth comQueueDepth;
260  for (U32 i = 0; i < comQueueDepth.SIZE; i++) {
261  comQueueDepth[i] = static_cast<U32>(this->m_queues[i].get_high_water_mark());
262  this->m_queues[i].clear_high_water_mark();
263  }
264  this->tlmWrite_comQueueDepth(comQueueDepth);
265 
266  // Downlink the high-water marks for the Fw::Buffer array types
267  BuffQueueDepth buffQueueDepth;
268  for (U32 i = 0; i < buffQueueDepth.SIZE; i++) {
269  buffQueueDepth[i] = static_cast<U32>(this->m_queues[i + COM_PORT_COUNT].get_high_water_mark());
270  this->m_queues[i + COM_PORT_COUNT].clear_high_water_mark();
271  }
272  this->tlmWrite_buffQueueDepth(buffQueueDepth);
273 }
274 
275 void ComQueue ::dataReturnIn_handler(FwIndexType portNum, Fw::Buffer& data, const ComCfg::FrameContext& context) {
276  static_assert(std::numeric_limits<FwIndexType>::is_signed, "FwIndexType must be signed");
277  FW_ASSERT(this->m_buffer_state == UNOWNED);
278  this->m_buffer_state = OWNED;
279  // For the buffer queues, the index of the queue is portNum offset by COM_PORT_COUNT since
280  // the first COM_PORT_COUNT queues are for ComBuffer. So we have for buffer queues:
281  // queueNum = portNum + COM_PORT_COUNT
282  // Since queueNum is used as APID, we can retrieve the original portNum like such:
283  FwIndexType bufferReturnPortNum = static_cast<FwIndexType>(context.get_comQueueIndex() - ComQueue::COM_PORT_COUNT);
284  // Failing this assert means that context.apid was modified since ComQueue set it, which should not happen
285  FW_ASSERT(bufferReturnPortNum < BUFFER_PORT_COUNT, static_cast<FwAssertArgType>(bufferReturnPortNum));
286  if (bufferReturnPortNum >= 0) {
287  // It is a coding error not to connect the associated bufferReturnOut port for each dataReturnIn port
288  FW_ASSERT(this->isConnected_bufferReturnOut_OutputPort(bufferReturnPortNum),
289  static_cast<FwAssertArgType>(bufferReturnPortNum));
290  // If this is a buffer port, return the buffer to the BufferDownlink
291  this->bufferReturnOut_out(bufferReturnPortNum, data);
292  }
293 }
294 
295 // ----------------------------------------------------------------------
296 // Hook implementations for typed async input ports
297 // ----------------------------------------------------------------------
298 
299 void ComQueue::bufferQueueIn_overflowHook(FwIndexType portNum, Fw::Buffer& fwBuffer) {
300  FW_ASSERT(portNum >= 0 && portNum < BUFFER_PORT_COUNT, static_cast<FwAssertArgType>(portNum));
301  this->bufferReturnOut_out(portNum, fwBuffer);
302 }
303 
304 // ----------------------------------------------------------------------
305 // Private helper methods
306 // ----------------------------------------------------------------------
307 
308 bool ComQueue::enqueue(const FwIndexType queueNum, QueueType queueType, const U8* data, const FwSizeType size) {
309  // Enqueue the given message onto the matching queue. When no space is available then emit the queue overflow event,
310  // set the appropriate throttle, and move on. Will assert if passed a message for a depth 0 queue.
311  const FwSizeType expectedSize = (queueType == QueueType::COM_QUEUE) ? sizeof(Fw::ComBuffer) : sizeof(Fw::Buffer);
312  FW_ASSERT((queueType == QueueType::COM_QUEUE) || (queueNum >= COM_PORT_COUNT),
313  static_cast<FwAssertArgType>(queueType), static_cast<FwAssertArgType>(queueNum));
314  const FwIndexType portNum =
315  static_cast<FwIndexType>(queueNum - ((queueType == QueueType::COM_QUEUE) ? 0 : COM_PORT_COUNT));
316  FW_ASSERT(expectedSize == size, static_cast<FwAssertArgType>(size), static_cast<FwAssertArgType>(expectedSize));
317  FW_ASSERT(portNum >= 0, static_cast<FwAssertArgType>(portNum));
318  Fw::SerializeStatus status = this->m_queues[queueNum].enqueue(data, size);
320  if (!this->m_throttle[queueNum]) {
321  this->log_WARNING_HI_QueueOverflow(queueType, portNum);
322  this->m_throttle[queueNum] = true;
323  }
324  }
325 
326  // When the component is already in READY state process the queue to send out the next available message immediately
327  if (this->m_state == READY) {
328  this->processQueue();
329  }
330 
331  // Check if the buffer was accepted or must be returned
332  return status != Fw::FW_SERIALIZE_NO_ROOM_LEFT;
333 }
334 
335 void ComQueue::sendComBuffer(Fw::ComBuffer& comBuffer, FwIndexType queueIndex) {
336  FW_ASSERT(this->m_state == READY);
337  Fw::Buffer outBuffer(comBuffer.getBuffAddr(), static_cast<Fw::Buffer::SizeType>(comBuffer.getSize()));
338 
339  // Context value is used to determine what to do when the buffer returns on the dataReturnIn port
340  ComCfg::FrameContext context;
341  FwPacketDescriptorType descriptor = 0;
342  Fw::SerializeStatus status = comBuffer.deserializeTo(descriptor);
343  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
344  context.set_apid(static_cast<ComCfg::Apid::T>(descriptor));
345  context.set_comQueueIndex(queueIndex);
346  FW_ASSERT(this->m_buffer_state == OWNED);
347  this->m_buffer_state = UNOWNED;
348  this->dataOut_out(0, outBuffer, context);
349  // Set state to WAITING for the status to come back
350  this->m_state = WAITING;
351 }
352 
353 void ComQueue::sendBuffer(Fw::Buffer& buffer, FwIndexType queueIndex) {
354  // Retry buffer expected to be cleared as we are either transferring ownership or have already deallocated it.
355  FW_ASSERT(this->m_state == READY);
356 
357  // Context value is used to determine what to do when the buffer returns on the dataReturnIn port
358  ComCfg::FrameContext context;
359  FwPacketDescriptorType descriptor;
360  Fw::SerializeStatus status = buffer.getDeserializer().deserializeTo(descriptor);
361  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
362  context.set_apid(static_cast<ComCfg::Apid::T>(descriptor));
363  context.set_comQueueIndex(queueIndex);
364  FW_ASSERT(this->m_buffer_state == OWNED);
365  this->m_buffer_state = UNOWNED;
366  this->dataOut_out(0, buffer, context);
367  // Set state to WAITING for the status to come back
368  this->m_state = WAITING;
369 }
370 
371 void ComQueue::drainQueue(FwIndexType index) {
372  FW_ASSERT(index >= 0 && index < TOTAL_PORT_COUNT, static_cast<FwAssertArgType>(index));
373  Types::Queue& queue = this->m_queues[index];
374 
375  // Read all messages from the queue and discard them
377  const FwSizeType available = queue.getQueueSize();
378  for (FwSizeType i = 0; (i < available) && (status == Fw::FW_SERIALIZE_OK); i++) {
379  if (index < COM_PORT_COUNT) {
380  // Dequeueing is reading the whole persisted Fw::ComBuffer object from the queue's storage.
381  // thus it takes an address to the object to fill and the size of the actual object
382  Fw::ComBuffer comBuffer;
383  status = queue.dequeue(reinterpret_cast<U8*>(&comBuffer), sizeof(comBuffer));
384  } else {
385  // For buffer queues, if the buffer requires ownership return, return it via the bufferReturnOut port
386  // Dequeueing is reading the whole persisted Fw::Buffer object from the queue's storage.
387  Fw::Buffer buffer;
388  status = queue.dequeue(reinterpret_cast<U8*>(&buffer), sizeof(buffer));
389  this->bufferReturnOut_out(static_cast<FwIndexType>(index - COM_PORT_COUNT), buffer);
390  }
391  }
392 }
393 
394 void ComQueue::processQueue() {
395  FwIndexType priorityIndex = 0;
396  FwIndexType sendPriority = 0;
397  // Check that we are in the appropriate state
398  FW_ASSERT(this->m_state == READY);
399 
400  // Walk all the queues in priority order. Send the first message that is available in priority order. No balancing
401  // is done within this loop.
402  for (priorityIndex = 0; priorityIndex < TOTAL_PORT_COUNT; priorityIndex++) {
403  QueueMetadata& entry = this->m_prioritizedList[priorityIndex];
404  Types::Queue& queue = this->m_queues[entry.index];
405 
406  // Continue onto next prioritized queue if there is no items in the current queue
407  if (queue.getQueueSize() == 0) {
408  continue;
409  }
410 
411  // Send out the message based on the type
412  if (entry.index < COM_PORT_COUNT) {
413  // Dequeue is reading the whole persisted Fw::ComBuffer object from the queue's storage.
414  // thus it takes an address to the object to fill and the size of the actual object.
415  FW_ASSERT(this->m_buffer_state == OWNED);
416  auto dequeue_status =
417  queue.dequeue(reinterpret_cast<U8*>(&this->m_dequeued_com_buffer), sizeof(this->m_dequeued_com_buffer));
419  static_cast<FwAssertArgType>(dequeue_status));
420  this->sendComBuffer(this->m_dequeued_com_buffer, entry.index);
421  } else {
422  Fw::Buffer buffer;
423  auto dequeue_status = queue.dequeue(reinterpret_cast<U8*>(&buffer), sizeof(buffer));
425  static_cast<FwAssertArgType>(dequeue_status));
426  this->sendBuffer(buffer, entry.index);
427  }
428 
429  // Update the throttle and the index that was just sent
430  this->m_throttle[entry.index] = false;
431 
432  // Priority used in the next loop
433  sendPriority = entry.priority;
434  break;
435  }
436 
437  // Starting on the priority entry after the one dispatched and continuing through the end of the set of entries that
438  // share the same priority, rotate those entries such that the currently dispatched queue is last and the rest are
439  // shifted up by one. This effectively round-robins the queues of the same priority.
440  for (priorityIndex++;
441  priorityIndex < TOTAL_PORT_COUNT && (this->m_prioritizedList[priorityIndex].priority == sendPriority);
442  priorityIndex++) {
443  // Swap the previous entry with this one.
444  QueueMetadata temp = this->m_prioritizedList[priorityIndex];
445  this->m_prioritizedList[priorityIndex] = this->m_prioritizedList[priorityIndex - 1];
446  this->m_prioritizedList[priorityIndex - 1] = temp;
447  }
448 }
449 
450 FwIndexType ComQueue::getQueueNum(Svc::QueueType queueType, FwIndexType portNum) {
451  // Acquire the queue that we need to drain
452  return static_cast<FwIndexType>(portNum + ((queueType == QueueType::COM_QUEUE) ? 0 : COM_PORT_COUNT));
453 }
454 } // end namespace Svc
Serialization/Deserialization operation was successful.
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
U16 FwPacketDescriptorType
The width of packet descriptors when they are serialized by the framework.
virtual void * allocate(const FwEnumStoreType identifier, FwSizeType &size, bool &recoverable, FwSizeType alignment=alignof(std::max_align_t))=0
FwIdType FwOpcodeType
The type of a command opcode.
std::make_unsigned< FwIndexType >::type FwUnsignedIndexType
Definition: ComQueue.cpp:19
Representing success.
PlatformSizeType FwSizeType
void tlmWrite_buffQueueDepth(const Svc::BuffQueueDepth &arg, Fw::Time _tlmTime=Fw::Time()) const
I32 FwEnumStoreType
Serialization succeeded, but deleted old data.
QueueConfigurationEntry entries[TOTAL_PORT_COUNT]
Definition: ComQueue.hpp:75
configuration table for each queue
Definition: ComQueue.hpp:74
static const FwIndexType TOTAL_PORT_COUNT
Total count of input buffer ports and thus total queues.
Definition: ComQueue.hpp:41
ComQueue(const char *const compName)
Definition: ComQueue.cpp:33
Serializable::SizeType getSize() const override
Get current buffer size.
void dataOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context)
Invoke output port dataOut.
void setup(U8 *const storage, const FwSizeType storage_size, const FwSizeType depth, const FwSizeType message_size, const QueueMode mode=QUEUE_FIFO, const QueueOverflowMode overflow_mode=QUEUE_DROP_NEWEST)
setup the queue object to setup storage
Definition: Queue.cpp:17
No room left in the buffer to serialize data.
void set_apid(ComCfg::Apid::T apid)
Set member apid.
void log_ACTIVITY_HI_QueuePriorityChanged(Svc::QueueType queueType, FwIndexType indexType, FwIndexType newPriority) const
void clear_high_water_mark()
Definition: Queue.cpp:98
bool isConnected_bufferReturnOut_OutputPort(FwIndexType portNum)
void cleanup()
Definition: ComQueue.cpp:50
static const FwIndexType BUFFER_PORT_COUNT
Definition: ComQueue.hpp:36
static const FwIndexType COM_PORT_COUNT
< Count of Fw::Com input ports and thus Fw::Com queues
Definition: ComQueue.hpp:33
An enumeration of queue data types.
FwIndexType get_comQueueIndex() const
Get member comQueueIndex.
SerializeStatus
forward declaration for string
void log_WARNING_HI_QueueOverflow(Svc::QueueType queueType, FwIndexType index) const
ExternalSerializeBufferWithMemberCopy getDeserializer()
Definition: Buffer.cpp:105
FwIndexType priority
Priority of the queue [0, TOTAL_PORT_COUNT)
Definition: ComQueue.hpp:60
Fw::SerializeStatus enqueue(const U8 *const message, const FwSizeType size)
pushes a fixed-size message onto the queue
Definition: Queue.cpp:36
FwSizeType depth
Depth of the queue [0, infinity)
Definition: ComQueue.hpp:59
U8 * getBuffAddr()
Get buffer address for data filling (non-const version)
Definition: ComBuffer.cpp:42
Command successfully executed.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:53
Memory Allocation base class.
void set_comQueueIndex(FwIndexType comQueueIndex)
Set member comQueueIndex.
Types::QueueOverflowMode overflowMode
Overflow handling mode (DROP_NEWEST or DROP_OLDEST)
Definition: ComQueue.hpp:62
First-In-First-Out: dequeue from front.
Definition: Queue.hpp:26
enum T e
The raw enum value.
FwSizeType get_high_water_mark() const
Definition: Queue.cpp:93
PlatformIndexType FwIndexType
Drop the newest (incoming) message on overflow.
Definition: Queue.hpp:34
FwSizeType SizeType
The size type for a buffer - for backwards compatibility.
Definition: Buffer.hpp:61
Types::QueueMode mode
Queue mode (FIFO or LIFO)
Definition: ComQueue.hpp:61
C++ header for working with basic fprime types.
#define FW_NUM_ARRAY_ELEMENTS(a)
number of elements in an array
Definition: BasicTypes.h:90
Type used to pass context info between components during framing/deframing.
void tlmWrite_comQueueDepth(const Svc::ComQueueDepth &arg, Fw::Time _tlmTime=Fw::Time()) const
Command failed validation.
RateGroupDivider component implementation.
SerializeStatus deserializeTo(U8 &val, Endianness mode=Endianness::BIG) override
Deserialize an 8-bit unsigned integer value.
virtual void deallocate(const FwEnumStoreType identifier, void *ptr)=0
FwSizeType getQueueSize() const
Definition: Queue.cpp:102
Fw::SerializeStatus dequeue(U8 *const message, const FwSizeType size)
pops a fixed-size message off the queue
Definition: Queue.cpp:64
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Success/Failure.
void configure(QueueConfigurationTable queueConfig, FwEnumStoreType allocationId, Fw::MemAllocator &allocator)
Definition: ComQueue.cpp:57
Auto-generated base for ComQueue component.
void bufferReturnOut_out(FwIndexType portNum, Fw::Buffer &fwBuffer)
Invoke output port bufferReturnOut.