|
|
@ -146,11 +146,16 @@ private: |
|
|
|
ExtMemSlot *m_slot = nullptr; ///< When using EXTERNAL memory, an ExtMemSlot must be provided.
|
|
|
|
ExtMemSlot *m_slot = nullptr; ///< When using EXTERNAL memory, an ExtMemSlot must be provided.
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**************************************************************************//**
|
|
|
|
|
|
|
|
* Customer RingBuffer with random access |
|
|
|
|
|
|
|
*****************************************************************************/ |
|
|
|
template <class T> |
|
|
|
template <class T> |
|
|
|
class RingBuffer { |
|
|
|
class RingBuffer { |
|
|
|
public: |
|
|
|
public: |
|
|
|
RingBuffer() = delete; |
|
|
|
RingBuffer() = delete; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Construct a RingBuffer of specified max size
|
|
|
|
|
|
|
|
/// @param maxSize number of entries in ring buffer
|
|
|
|
RingBuffer(const size_t maxSize) : m_maxSize(maxSize) { |
|
|
|
RingBuffer(const size_t maxSize) : m_maxSize(maxSize) { |
|
|
|
m_buffer = new T[maxSize]; |
|
|
|
m_buffer = new T[maxSize]; |
|
|
|
} |
|
|
|
} |
|
|
@ -158,9 +163,12 @@ public: |
|
|
|
if (m_buffer) delete [] m_buffer; |
|
|
|
if (m_buffer) delete [] m_buffer; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Add an element to the back of the queue
|
|
|
|
|
|
|
|
/// @param element element to add to queue
|
|
|
|
|
|
|
|
/// returns 0 if success, otherwise error
|
|
|
|
int push_back(T element) { |
|
|
|
int push_back(T element) { |
|
|
|
|
|
|
|
|
|
|
|
Serial.println(String("RingBuffer::push_back...") + m_head + String(":") + m_tail + String(":") + m_size); |
|
|
|
//Serial.println(String("RingBuffer::push_back...") + m_head + String(":") + m_tail + String(":") + m_size);
|
|
|
|
if ( (m_head == m_tail) && (m_size > 0) ) { |
|
|
|
if ( (m_head == m_tail) && (m_size > 0) ) { |
|
|
|
// overflow
|
|
|
|
// overflow
|
|
|
|
Serial.println("RingBuffer::push_back: overflow"); |
|
|
|
Serial.println("RingBuffer::push_back: overflow"); |
|
|
@ -178,6 +186,8 @@ public: |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Remove the element at teh front of the queue
|
|
|
|
|
|
|
|
/// @returns 0 if success, otherwise error
|
|
|
|
int pop_front() { |
|
|
|
int pop_front() { |
|
|
|
|
|
|
|
|
|
|
|
if (m_size == 0) { |
|
|
|
if (m_size == 0) { |
|
|
@ -195,14 +205,21 @@ public: |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Get the element at the front of the queue
|
|
|
|
|
|
|
|
/// @returns element at front of queue
|
|
|
|
T front() const { |
|
|
|
T front() const { |
|
|
|
return m_buffer[m_tail]; |
|
|
|
return m_buffer[m_tail]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// get the element at the back of the queue
|
|
|
|
|
|
|
|
/// @returns element at the back of the queue
|
|
|
|
T back() const { |
|
|
|
T back() const { |
|
|
|
return m_buffer[m_head-1]; |
|
|
|
return m_buffer[m_head-1]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Get a previously pushed elememt
|
|
|
|
|
|
|
|
/// @param offset zero is last pushed, 1 is second last, etc.
|
|
|
|
|
|
|
|
/// @returns the absolute index corresponding to the requested offset.
|
|
|
|
size_t get_index_from_back(size_t offset = 0) const { |
|
|
|
size_t get_index_from_back(size_t offset = 0) const { |
|
|
|
// the target at m_head - 1 - offset or m_maxSize + m_head -1 - offset;
|
|
|
|
// the target at m_head - 1 - offset or m_maxSize + m_head -1 - offset;
|
|
|
|
size_t idx = (m_maxSize + m_head -1 - offset); |
|
|
|
size_t idx = (m_maxSize + m_head -1 - offset); |
|
|
@ -214,33 +231,44 @@ public: |
|
|
|
return idx; |
|
|
|
return idx; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// get the current size of the queue
|
|
|
|
|
|
|
|
/// @returns size of the queue
|
|
|
|
size_t size() const { |
|
|
|
size_t size() const { |
|
|
|
return m_size; |
|
|
|
return m_size; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// get the maximum size the queue can hold
|
|
|
|
|
|
|
|
/// @returns maximum size of the queue
|
|
|
|
size_t max_size() const { |
|
|
|
size_t max_size() const { |
|
|
|
return m_maxSize; |
|
|
|
return m_maxSize; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// get the element at the specified absolute index
|
|
|
|
|
|
|
|
/// @param index element to retrieve from absolute queue position
|
|
|
|
|
|
|
|
/// @returns the request element
|
|
|
|
T& operator[] (size_t index) { |
|
|
|
T& operator[] (size_t index) { |
|
|
|
return m_buffer[index]; |
|
|
|
return m_buffer[index]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// get the element at the specified absolute index
|
|
|
|
|
|
|
|
/// @param index element to retrieve from absolute queue position
|
|
|
|
|
|
|
|
/// @returns the request element
|
|
|
|
T at(size_t index) const { |
|
|
|
T at(size_t index) const { |
|
|
|
return m_buffer[index]; |
|
|
|
return m_buffer[index]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// DEBUG: Prints the status of the Ringbuffer
|
|
|
|
void print() const { |
|
|
|
void print() const { |
|
|
|
for (int idx=0; idx<m_maxSize; idx++) { |
|
|
|
for (int idx=0; idx<m_maxSize; idx++) { |
|
|
|
Serial.println(idx + String(" address: ") + (uint32_t)m_buffer[idx] + String(" data: ") + (uint32_t)m_buffer[idx]->data); |
|
|
|
Serial.println(idx + String(" address: ") + (uint32_t)m_buffer[idx] + String(" data: ") + (uint32_t)m_buffer[idx]->data); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
private: |
|
|
|
private: |
|
|
|
size_t m_head=0; |
|
|
|
size_t m_head=0; ///< back of the queue
|
|
|
|
size_t m_tail=0; |
|
|
|
size_t m_tail=0; ///< front of the queue
|
|
|
|
size_t m_size=0; |
|
|
|
size_t m_size=0; ///< current size of the qeueu
|
|
|
|
T *m_buffer = nullptr; |
|
|
|
T *m_buffer = nullptr; ///< pointer to the allocated buffer array
|
|
|
|
const size_t m_maxSize; |
|
|
|
const size_t m_maxSize; ///< maximum size of the queue
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|