F´ Flight Software - C/C++ Documentation  NASA-v2.1.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 };
36 
38  m_handle(static_cast<POINTER_CAST>(NULL))
39 { }
40 
42  BareQueueHandle* handle = reinterpret_cast<BareQueueHandle*>(this->m_handle);
43  // Queue has already been created... remove it and try again:
44  if (NULL != handle) {
45  delete handle;
46  handle = NULL;
47  }
48  //New queue handle, check for success or return error
49  handle = new BareQueueHandle;
50  if (NULL == handle || !handle->create(depth, msgSize)) {
51  return QUEUE_UNINITIALIZED;
52  }
53  //Set handle member variable
54  this->m_handle = reinterpret_cast<POINTER_CAST>(handle);
55  //Register the queue
56  #if FW_QUEUE_REGISTRATION
57  if (this->s_queueRegistry) {
58  this->s_queueRegistry->regQueue(this);
59  }
60  #endif
61  return QUEUE_OK;
62 }
63 
65  // Clean up the queue handle:
66  BareQueueHandle* handle = reinterpret_cast<BareQueueHandle*>(this->m_handle);
67  if (NULL != handle) {
68  delete handle;
69  }
70  this->m_handle = static_cast<POINTER_CAST>(NULL);
71 }
72 
74  FW_ASSERT(handle.m_init);
75  BufferQueue& queue = handle.m_queue;
77  // Push item onto queue:
78  bool success = queue.push(buffer, size, priority);
79  if(!success) {
80  status = Queue::QUEUE_FULL;
81  }
82  return status;
83 }
84 
86  FW_ASSERT(handle.m_init);
87  BufferQueue& queue = handle.m_queue;
88  // If the queue is full, wait until a message is taken off the queue.
89  while(queue.isFull()) {
90  //Forced to assert, as blocking would destroy timely-ness
91  FW_ASSERT(false);
92  }
93  // Push item onto queue:
94  bool success = queue.push(buffer, size, priority);
95  // The only reason push would not succeed is if the queue
96  // was full. Since we waited for the queue to NOT be full
97  // before sending on the queue, the push must have succeeded
98  // unless there was a programming error or a bit flip.
99  FW_ASSERT(success, success);
100  return Queue::QUEUE_OK;
101 }
102 
104  //Check if the handle is null or check the underlying queue is null
105  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
106  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
107  return QUEUE_UNINITIALIZED;
108  }
109  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
110  BufferQueue& queue = handle.m_queue;
111  //Check that the buffer is non-null
112  if (NULL == buffer) {
113  return QUEUE_EMPTY_BUFFER;
114  }
115  //Fail if there is a size miss-match
116  if (size < 0 || (NATIVE_UINT_TYPE) size > queue.getMsgSize()) {
117  return QUEUE_SIZE_MISMATCH;
118  }
119  //Send to the queue
120  if( QUEUE_NONBLOCKING == block ) {
121  return bareSendNonBlock(handle, buffer, size, priority);
122  }
123 
124  return bareSendBlock(handle, buffer, size, priority);
125 }
126 
128  FW_ASSERT(handle.m_init);
129  BufferQueue& queue = handle.m_queue;
130  NATIVE_UINT_TYPE size = capacity;
131  NATIVE_INT_TYPE pri = 0;
133  // Get an item off of the queue:
134  bool success = queue.pop(buffer, size, pri);
135  if(success) {
136  // Pop worked - set the return size and priority:
137  actualSize = (NATIVE_INT_TYPE) size;
138  priority = pri;
139  }
140  else {
141  actualSize = 0;
142  if( size > (NATIVE_UINT_TYPE) capacity ) {
143  // The buffer capacity was too small!
145  }
146  else if( size == 0 ) {
147  // The queue is empty:
148  status = Queue::QUEUE_NO_MORE_MSGS;
149  }
150  else {
151  // If this happens, a programming error or bit flip occurred:
152  FW_ASSERT(0);
153  }
154  }
155  return status;
156 }
157 
159  FW_ASSERT(handle.m_init);
160  BufferQueue& queue = handle.m_queue;
161  NATIVE_UINT_TYPE size = capacity;
162  NATIVE_INT_TYPE pri = 0;
164  // If the queue is full, wait until a message is taken off the queue.
165  while(queue.isEmpty()) {
166  //Forced to assert, as blocking would destroy timely-ness
167  FW_ASSERT(false);
168  }
169  // Get an item off of the queue:
170  bool success = queue.pop(buffer, size, pri);
171  if(success) {
172  // Pop worked - set the return size and priority:
173  actualSize = (NATIVE_INT_TYPE) size;
174  priority = pri;
175  }
176  else {
177  actualSize = 0;
178  if( size > (NATIVE_UINT_TYPE) capacity ) {
179  // The buffer capacity was too small!
181  }
182  else {
183  // If this happens, a programming error or bit flip occurred:
184  // The only reason a pop should fail is if the user's buffer
185  // was too small.
186  FW_ASSERT(0);
187  }
188  }
189  return status;
190 }
191 
193  //Check if the handle is null or check the underlying queue is null
194  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
195  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
196  return QUEUE_UNINITIALIZED;
197  }
198  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
199  //Check the buffer can hold the out-going message
200  if (capacity < this->getMsgSize()) {
201  return QUEUE_SIZE_MISMATCH;
202  }
203  //Receive either non-blocking or blocking
204  if(QUEUE_NONBLOCKING == block) {
205  return bareReceiveNonBlock(handle, buffer, capacity, actualSize, priority);
206  }
207  return bareReceiveBlock(handle, buffer, capacity, actualSize, priority);
208 }
209 
211  //Check if the handle is null or check the underlying queue is null
212  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
213  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
214  return 0;
215  }
216  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
217  BufferQueue& queue = handle.m_queue;
218  return queue.getCount();
219 }
220 
222  //Check if the handle is null or check the underlying queue is null
223  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
224  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
225  return 0;
226  }
227  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
228  BufferQueue& queue = handle.m_queue;
229  return queue.getMaxCount();
230 }
231 
233  //Check if the handle is null or check the underlying queue is null
234  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
235  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
236  return 0;
237  }
238  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
239  BufferQueue& queue = handle.m_queue;
240  return queue.getDepth();
241  }
242 
244  //Check if the handle is null or check the underlying queue is null
245  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
246  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
247  return 0;
248  }
249  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
250  BufferQueue& queue = handle.m_queue;
251  return queue.getMsgSize();
252 }
253 }//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:232
Os::Queue::m_handle
POINTER_CAST m_handle
handle for implementation specific queue
Definition: Queue.hpp:75
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:37
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:127
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:158
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:243
Os::Queue::getNumMsgs
NATIVE_INT_TYPE getNumMsgs(void) const
get the number of messages in the queue
Definition: Queue.cpp:210
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:85
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:73
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:221
Os::Queue::createInternal
QueueStatus createInternal(const Fw::StringBase &name, NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize)
create a message queue
Definition: Queue.cpp:41
BasicTypes.hpp
Declares ISF basic types.
Os::Queue::~Queue
virtual ~Queue()
Definition: Queue.cpp:64
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