F´ Flight Software - C/C++ Documentation  NASA-v1.5.0
A framework for building embedded system applications to NASA flight quality standards.
Queue.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title Queue.cpp
3 // \author mstarch, borrowed from @dinkel
4 // \brief Queue implementation for Baremetal devices. No IPC nor thread
5 // safety is implemented as this intended for baremetal devices.
6 // Based on Os/Pthreads/Queue.cpp from @dinkel
7 // ======================================================================
10 #include <Fw/Types/Assert.hpp>
11 #include <Os/Queue.hpp>
12 
13 #include <stdio.h>
14 
15 namespace Os {
21  public:
22  BareQueueHandle() : m_init(false) {}
27  bool create(NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize) {
28  bool ret = m_queue.create(depth, msgSize);
29  m_init = ret;
30  return ret;
31  }
32  bool m_init;
35 };
40  m_handle(static_cast<POINTER_CAST>(NULL))
41 { }
42 
52  BareQueueHandle* handle = reinterpret_cast<BareQueueHandle*>(this->m_handle);
53  // Queue has already been created... remove it and try again:
54  if (NULL != handle) {
55  delete handle;
56  handle = NULL;
57  }
58  //New queue handle, check for success or return error
59  handle = new BareQueueHandle;
60  if (NULL == handle || !handle->create(depth, msgSize)) {
61  return QUEUE_UNINITIALIZED;
62  }
63  //Set handle member variable
64  this->m_handle = reinterpret_cast<POINTER_CAST>(handle);
65  //Register the queue
66  #if FW_QUEUE_REGISTRATION
67  if (this->s_queueRegistry) {
68  this->s_queueRegistry->regQueue(this);
69  }
70  #endif
71  return QUEUE_OK;
72 }
77  // Clean up the queue handle:
78  BareQueueHandle* handle = reinterpret_cast<BareQueueHandle*>(this->m_handle);
79  if (NULL != handle) {
80  delete handle;
81  }
82  this->m_handle = static_cast<POINTER_CAST>(NULL);
83 }
88  FW_ASSERT(handle.m_init);
89  BufferQueue& queue = handle.m_queue;
91  // Push item onto queue:
92  bool success = queue.push(buffer, size, priority);
93  if(!success) {
94  status = Queue::QUEUE_FULL;
95  }
96  return status;
97 }
103  FW_ASSERT(handle.m_init);
104  BufferQueue& queue = handle.m_queue;
105  // If the queue is full, wait until a message is taken off the queue.
106  while(queue.isFull()) {
107  //Forced to assert, as blocking would destroy timely-ness
108  FW_ASSERT(false);
109  }
110  // Push item onto queue:
111  bool success = queue.push(buffer, size, priority);
112  // The only reason push would not succeed is if the queue
113  // was full. Since we waited for the queue to NOT be full
114  // before sending on the queue, the push must have succeeded
115  // unless there was a programming error or a bit flip.
116  FW_ASSERT(success, success);
117  return Queue::QUEUE_OK;
118 }
119 
121  //Check if the handle is null or check the underlying queue is null
122  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
123  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
124  return QUEUE_UNINITIALIZED;
125  }
126  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
127  BufferQueue& queue = handle.m_queue;
128  //Check that the buffer is non-null
129  if (NULL == buffer) {
130  return QUEUE_EMPTY_BUFFER;
131  }
132  //Fail if there is a size miss-match
133  if (size < 0 || (NATIVE_UINT_TYPE) size > queue.getMsgSize()) {
134  return QUEUE_SIZE_MISMATCH;
135  }
136  //Send to the queue
137  if( QUEUE_NONBLOCKING == block ) {
138  return bareSendNonBlock(handle, buffer, size, priority);
139  }
140 
141  return bareSendBlock(handle, buffer, size, priority);
142 }
143 
145  FW_ASSERT(handle.m_init);
146  BufferQueue& queue = handle.m_queue;
147  NATIVE_UINT_TYPE size = capacity;
148  NATIVE_INT_TYPE pri = 0;
150  // Get an item off of the queue:
151  bool success = queue.pop(buffer, size, pri);
152  if(success) {
153  // Pop worked - set the return size and priority:
154  actualSize = (NATIVE_INT_TYPE) size;
155  priority = pri;
156  }
157  else {
158  actualSize = 0;
159  if( size > (NATIVE_UINT_TYPE) capacity ) {
160  // The buffer capacity was too small!
162  }
163  else if( size == 0 ) {
164  // The queue is empty:
165  status = Queue::QUEUE_NO_MORE_MSGS;
166  }
167  else {
168  // If this happens, a programming error or bit flip occured:
169  FW_ASSERT(0);
170  }
171  }
172  return status;
173 }
174 
176  FW_ASSERT(handle.m_init);
177  BufferQueue& queue = handle.m_queue;
178  NATIVE_UINT_TYPE size = capacity;
179  NATIVE_INT_TYPE pri = 0;
181  // If the queue is full, wait until a message is taken off the queue.
182  while(queue.isEmpty()) {
183  //Forced to assert, as blocking would destroy timely-ness
184  FW_ASSERT(false);
185  }
186  // Get an item off of the queue:
187  bool success = queue.pop(buffer, size, pri);
188  if(success) {
189  // Pop worked - set the return size and priority:
190  actualSize = (NATIVE_INT_TYPE) size;
191  priority = pri;
192  }
193  else {
194  actualSize = 0;
195  if( size > (NATIVE_UINT_TYPE) capacity ) {
196  // The buffer capacity was too small!
198  }
199  else {
200  // If this happens, a programming error or bit flip occurred:
201  // The only reason a pop should fail is if the user's buffer
202  // was too small.
203  FW_ASSERT(0);
204  }
205  }
206  return status;
207 }
208 
210  //Check if the handle is null or check the underlying queue is null
211  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
212  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
213  return QUEUE_UNINITIALIZED;
214  }
215  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
216  //Check the buffer can hold the out-going message
217  if (capacity < this->getMsgSize()) {
218  return QUEUE_SIZE_MISMATCH;
219  }
220  //Receive either non-blocking or blocking
221  if(QUEUE_NONBLOCKING == block) {
222  return bareReceiveNonBlock(handle, buffer, capacity, actualSize, priority);
223  }
224  return bareReceiveBlock(handle, buffer, capacity, actualSize, priority);
225 }
226 
228  //Check if the handle is null or check the underlying queue is null
229  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
230  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
231  return 0;
232  }
233  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
234  BufferQueue& queue = handle.m_queue;
235  return queue.getCount();
236 }
237 
239  //Check if the handle is null or check the underlying queue is null
240  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
241  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
242  return 0;
243  }
244  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
245  BufferQueue& queue = handle.m_queue;
246  return queue.getMaxCount();
247 }
248 
250  //Check if the handle is null or check the underlying queue is null
251  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
252  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
253  return 0;
254  }
255  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
256  BufferQueue& queue = handle.m_queue;
257  return queue.getDepth();
258  }
259 
261  //Check if the handle is null or check the underlying queue is null
262  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
263  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
264  return 0;
265  }
266  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
267  BufferQueue& queue = handle.m_queue;
268  return queue.getMsgSize();
269 }
270 }//Namespace Os
Os
Definition: File.cpp:7
Os::BufferQueue::getDepth
NATIVE_UINT_TYPE getDepth()
Get the queue depths.
Definition: BufferQueueCommon.cpp:112
Os::Queue::QUEUE_FULL
@ QUEUE_FULL
queue was full when attempting to send a message
Definition: Queue.hpp:36
Fw::StringBase
Definition: StringType.hpp:23
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
Os::BufferQueue::getCount
NATIVE_UINT_TYPE getCount()
Get the current number of items on the queue.
Definition: BufferQueueCommon.cpp:99
Os::Queue::QueueStatus
QueueStatus
Definition: Queue.hpp:27
Os::Queue::getQueueSize
NATIVE_INT_TYPE getQueueSize(void) const
get the queue depth (maximum number of messages queue can hold)
Definition: Queue.cpp:249
Os::Queue::m_handle
POINTER_CAST m_handle
handle for implementation specific queue
Definition: Queue.hpp:69
Os::BufferQueue::push
bool push(const U8 *buffer, NATIVE_UINT_TYPE size, NATIVE_INT_TYPE priority)
push an item onto the queue
Definition: BufferQueueCommon.cpp:51
Os::BufferQueue
A generic buffer queue data structure.
Definition: BufferQueue.hpp:26
Os::Queue::QUEUE_EMPTY_BUFFER
@ QUEUE_EMPTY_BUFFER
supplied buffer is empty
Definition: Queue.hpp:35
Assert.hpp
Os::BareQueueHandle::m_init
bool m_init
Actual queue used to store.
Definition: Queue.cpp:32
Os::BareQueueHandle::m_queue
BufferQueue m_queue
Definition: Queue.cpp:34
Os::Queue::send
QueueStatus send(const Fw::SerializeBufferBase &buffer, NATIVE_INT_TYPE priority, QueueBlocking block)
send a message
Definition: QueueCommon.cpp:13
Os::Queue::Queue
Queue()
Definition: Queue.cpp:39
Os::Queue::QUEUE_SIZE_MISMATCH
@ QUEUE_SIZE_MISMATCH
attempted to send or receive with buffer too large, too small
Definition: Queue.hpp:31
Os::bareReceiveNonBlock
Queue::QueueStatus bareReceiveNonBlock(BareQueueHandle &handle, U8 *buffer, NATIVE_INT_TYPE capacity, NATIVE_INT_TYPE &actualSize, NATIVE_INT_TYPE &priority)
Definition: Queue.cpp:144
Os::Queue::QueueBlocking
QueueBlocking
Definition: Queue.hpp:40
Os::BufferQueue::getMaxCount
NATIVE_UINT_TYPE getMaxCount()
Get the maximum number of items seen on the queue.
Definition: BufferQueueCommon.cpp:103
Os::Queue::receive
QueueStatus receive(Fw::SerializeBufferBase &buffer, NATIVE_INT_TYPE &priority, QueueBlocking block)
receive a message
Definition: QueueCommon.cpp:22
Os::Queue::QUEUE_UNINITIALIZED
@ QUEUE_UNINITIALIZED
Queue wasn't initialized successfully.
Definition: Queue.hpp:30
BufferQueue.hpp
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:30
Os::bareReceiveBlock
Queue::QueueStatus bareReceiveBlock(BareQueueHandle &handle, U8 *buffer, NATIVE_INT_TYPE capacity, NATIVE_INT_TYPE &actualSize, NATIVE_INT_TYPE &priority)
Definition: Queue.cpp:175
Os::BareQueueHandle::create
bool create(NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize)
Definition: Queue.cpp:27
Os::BufferQueue::isEmpty
bool isEmpty()
check if the queue is empty
Definition: BufferQueueCommon.cpp:95
Os::Queue::QUEUE_NO_MORE_MSGS
@ QUEUE_NO_MORE_MSGS
If non-blocking, all the messages have been drained.
Definition: Queue.hpp:29
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Os::BufferQueue::isFull
bool isFull()
check if the queue is full
Definition: BufferQueueCommon.cpp:91
Os::Queue::getMsgSize
NATIVE_INT_TYPE getMsgSize(void) const
get the message size (maximum message size queue can hold)
Definition: Queue.cpp:260
Os::Queue::getNumMsgs
NATIVE_INT_TYPE getNumMsgs(void) const
get the number of messages in the queue
Definition: Queue.cpp:227
Os::Queue::QUEUE_OK
@ QUEUE_OK
message sent/received okay
Definition: Queue.hpp:28
Os::BareQueueHandle
Definition: Queue.cpp:20
Os::BufferQueue::getMsgSize
NATIVE_UINT_TYPE getMsgSize()
Get the maximum message size.
Definition: BufferQueueCommon.cpp:108
Os::BufferQueue::create
bool create(NATIVE_UINT_TYPE depth, NATIVE_UINT_TYPE msgSize)
BufferQueue creation.
Definition: BufferQueueCommon.cpp:38
Os::bareSendBlock
Queue::QueueStatus bareSendBlock(BareQueueHandle &handle, const U8 *buffer, NATIVE_INT_TYPE size, NATIVE_INT_TYPE priority)
Definition: Queue.cpp:102
Os::Queue::QUEUE_NONBLOCKING
@ QUEUE_NONBLOCKING
Queue receive always returns even if there is no message.
Definition: Queue.hpp:42
Os::bareSendNonBlock
Queue::QueueStatus bareSendNonBlock(BareQueueHandle &handle, const U8 *buffer, NATIVE_INT_TYPE size, NATIVE_INT_TYPE priority)
Definition: Queue.cpp:87
Os::BufferQueue::pop
bool pop(U8 *buffer, NATIVE_UINT_TYPE &size, NATIVE_INT_TYPE &priority)
pop an item off the queue
Definition: BufferQueueCommon.cpp:72
Os::Queue::getMaxMsgs
NATIVE_INT_TYPE getMaxMsgs(void) const
get the maximum number of messages (high watermark)
Definition: Queue.cpp:238
Os::Queue::createInternal
QueueStatus createInternal(const Fw::StringBase &name, NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize)
create a message queue
Definition: Queue.cpp:51
BasicTypes.hpp
Declares ISF basic types.
Os::Queue::~Queue
virtual ~Queue()
Definition: Queue.cpp:76
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
NULL
#define NULL
NULL.
Definition: BasicTypes.hpp:100
Queue.hpp
Os::BareQueueHandle::BareQueueHandle
BareQueueHandle()
Definition: Queue.cpp:22