F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
CircularBuffer.cpp
Go to the documentation of this file.
1 /*
2  * CircularBuffer.cpp:
3  *
4  * Buffer used to efficiently store data in ring data structure. Uses an externally supplied
5  * data store as the backing for this buffer. Thus it is dependent on receiving sole ownership
6  * of the supplied buffer.
7  *
8  * This implementation file contains the function definitions.
9  *
10  * Created on: Apr 4, 2019
11  * Author: lestarch
12  * Revised March 2022
13  * Author: bocchino
14  */
15 #include <FpConfig.hpp>
16 #include <Fw/Types/Assert.hpp>
18 
19 #ifdef CIRCULAR_DEBUG
20  #include <Os/Log.hpp>
21 #endif
22 
23 namespace Types {
24 
26  m_store(nullptr),
27  m_store_size(0),
28  m_head_idx(0),
29  m_allocated_size(0),
30  m_high_water_mark(0)
31 {
32 
33 }
34 
36  m_store(nullptr),
37  m_store_size(0),
38  m_head_idx(0),
39  m_allocated_size(0),
40  m_high_water_mark(0)
41 {
42  setup(buffer, size);
43 }
44 
45 void CircularBuffer :: setup(U8* const buffer, const NATIVE_UINT_TYPE size) {
46  FW_ASSERT(size > 0);
47  FW_ASSERT(buffer != nullptr);
48  FW_ASSERT(m_store == nullptr && m_store_size == 0); // Not already setup
49 
50  // Initialize buffer data
51  m_store = buffer;
52  m_store_size = size;
53  m_head_idx = 0;
54  m_allocated_size = 0;
55  m_high_water_mark = 0;
56 }
57 
59  return m_allocated_size;
60 }
61 
63  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
64  FW_ASSERT(m_allocated_size <= m_store_size, static_cast<FwAssertArgType>(m_allocated_size));
65  return m_store_size - m_allocated_size;
66 }
67 
68 NATIVE_UINT_TYPE CircularBuffer :: advance_idx(NATIVE_UINT_TYPE idx, NATIVE_UINT_TYPE amount) const {
69  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
70  return (idx + amount) % m_store_size;
71 }
72 
74  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
75  FW_ASSERT(buffer != nullptr);
76  // Check there is sufficient space
77  if (size > get_free_size()) {
79  }
80  // Copy in all the supplied data
81  NATIVE_UINT_TYPE idx = advance_idx(m_head_idx, m_allocated_size);
82  for (U32 i = 0; i < size; i++) {
83  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
84  m_store[idx] = buffer[i];
85  idx = advance_idx(idx);
86  }
87  m_allocated_size += size;
88  FW_ASSERT(m_allocated_size <= this->get_capacity(), static_cast<FwAssertArgType>(m_allocated_size));
89  m_high_water_mark = (m_high_water_mark > m_allocated_size) ? m_high_water_mark : m_allocated_size;
90  return Fw::FW_SERIALIZE_OK;
91 }
92 
94  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
95  return peek(reinterpret_cast<U8&>(value), offset);
96 }
97 
99  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
100  // Check there is sufficient data
101  if ((sizeof(U8) + offset) > m_allocated_size) {
103  }
104  const NATIVE_UINT_TYPE idx = advance_idx(m_head_idx, offset);
105  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
106  value = m_store[idx];
107  return Fw::FW_SERIALIZE_OK;
108 }
109 
111  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
112  // Check there is sufficient data
113  if ((sizeof(U32) + offset) > m_allocated_size) {
115  }
116  value = 0;
117  NATIVE_UINT_TYPE idx = advance_idx(m_head_idx, offset);
118 
119  // Deserialize all the bytes from network format
120  for (NATIVE_UINT_TYPE i = 0; i < sizeof(U32); i++) {
121  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
122  value = (value << 8) | static_cast<U32>(m_store[idx]);
123  idx = advance_idx(idx);
124  }
125  return Fw::FW_SERIALIZE_OK;
126 }
127 
129  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
130  FW_ASSERT(buffer != nullptr);
131  // Check there is sufficient data
132  if ((size + offset) > m_allocated_size) {
134  }
135  NATIVE_UINT_TYPE idx = advance_idx(m_head_idx, offset);
136  // Deserialize all the bytes from network format
137  for (NATIVE_UINT_TYPE i = 0; i < size; i++) {
138  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
139  buffer[i] = m_store[idx];
140  idx = advance_idx(idx);
141  }
142  return Fw::FW_SERIALIZE_OK;
143 }
144 
146  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
147  // Check there is sufficient data
148  if (amount > m_allocated_size) {
150  }
151  m_head_idx = advance_idx(m_head_idx, amount);
152  m_allocated_size -= amount;
153  return Fw::FW_SERIALIZE_OK;
154 }
155 
157  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
158  return m_store_size;
159 }
160 
162  return m_high_water_mark;
163 }
164 
166  m_high_water_mark = 0;
167 }
168 
169 #ifdef CIRCULAR_DEBUG
170 void CircularBuffer :: print() {
171  NATIVE_UINT_TYPE idx = m_head_idx;
172  Os::Log::logMsg("Ring: ", 0, 0, 0, 0, 0, 0);
173  for (NATIVE_UINT_TYPE i = 0; i < m_allocated_size; ++i) {
174  Os::Log::logMsg("%c", m_store[idx], 0, 0, 0, 0, 0);
175  idx = advance_idx(idx);
176  }
177  Os::Log::logMsg("\n", 0, 0, 0, 0, 0, 0);
178 }
179 #endif
180 } //End Namespace Types
#define FW_ASSERT(...)
Definition: Assert.hpp:14
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:26
PlatformUIntType NATIVE_UINT_TYPE
Definition: BasicTypes.h:52
PlatformAssertArgType FwAssertArgType
Definition: FpConfig.h:34
C++-compatible configuration header for fprime configuration.
static void logMsg(const char *fmt, POINTER_CAST a0=0, POINTER_CAST a1=0, POINTER_CAST a2=0, POINTER_CAST a3=0, POINTER_CAST a4=0, POINTER_CAST a5=0, POINTER_CAST a6=0, POINTER_CAST a7=0, POINTER_CAST a8=0, POINTER_CAST a9=0)
Definition: Logger.cpp:18
Fw::SerializeStatus serialize(const U8 *const buffer, const NATIVE_UINT_TYPE size)
NATIVE_UINT_TYPE get_free_size() const
NATIVE_UINT_TYPE get_allocated_size() const
NATIVE_UINT_TYPE get_high_water_mark() const
void setup(U8 *const buffer, const NATIVE_UINT_TYPE size)
NATIVE_UINT_TYPE get_capacity() const
Fw::SerializeStatus peek(char &value, NATIVE_UINT_TYPE offset=0) const
Fw::SerializeStatus rotate(NATIVE_UINT_TYPE amount)
SerializeStatus
forward declaration for string
@ FW_DESERIALIZE_BUFFER_EMPTY
Deserialization buffer was empty when trying to read more data.
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
@ FW_SERIALIZE_NO_ROOM_LEFT
No room left in the buffer to serialize data.