F´ Flight Software - C/C++ Documentation
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 namespace Types {
20 
22  m_store(nullptr),
23  m_store_size(0),
24  m_head_idx(0),
25  m_allocated_size(0),
26  m_high_water_mark(0)
27 {
28 
29 }
30 
32  m_store(nullptr),
33  m_store_size(0),
34  m_head_idx(0),
35  m_allocated_size(0),
36  m_high_water_mark(0)
37 {
38  setup(buffer, size);
39 }
40 
41 void CircularBuffer :: setup(U8* const buffer, const NATIVE_UINT_TYPE size) {
42  FW_ASSERT(size > 0);
43  FW_ASSERT(buffer != nullptr);
44  FW_ASSERT(m_store == nullptr && m_store_size == 0); // Not already setup
45 
46  // Initialize buffer data
47  m_store = buffer;
48  m_store_size = size;
49  m_head_idx = 0;
50  m_allocated_size = 0;
51  m_high_water_mark = 0;
52 }
53 
55  return m_allocated_size;
56 }
57 
59  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
60  FW_ASSERT(m_allocated_size <= m_store_size, static_cast<FwAssertArgType>(m_allocated_size));
61  return m_store_size - m_allocated_size;
62 }
63 
64 NATIVE_UINT_TYPE CircularBuffer :: advance_idx(NATIVE_UINT_TYPE idx, NATIVE_UINT_TYPE amount) const {
65  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
66  return (idx + amount) % m_store_size;
67 }
68 
70  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
71  FW_ASSERT(buffer != nullptr);
72  // Check there is sufficient space
73  if (size > get_free_size()) {
75  }
76  // Copy in all the supplied data
77  NATIVE_UINT_TYPE idx = advance_idx(m_head_idx, m_allocated_size);
78  for (U32 i = 0; i < size; i++) {
79  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
80  m_store[idx] = buffer[i];
81  idx = advance_idx(idx);
82  }
83  m_allocated_size += size;
84  FW_ASSERT(m_allocated_size <= this->get_capacity(), static_cast<FwAssertArgType>(m_allocated_size));
85  m_high_water_mark = (m_high_water_mark > m_allocated_size) ? m_high_water_mark : m_allocated_size;
86  return Fw::FW_SERIALIZE_OK;
87 }
88 
90  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
91  return peek(reinterpret_cast<U8&>(value), offset);
92 }
93 
95  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
96  // Check there is sufficient data
97  if ((sizeof(U8) + offset) > m_allocated_size) {
99  }
100  const NATIVE_UINT_TYPE idx = advance_idx(m_head_idx, offset);
101  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
102  value = m_store[idx];
103  return Fw::FW_SERIALIZE_OK;
104 }
105 
107  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
108  // Check there is sufficient data
109  if ((sizeof(U32) + offset) > m_allocated_size) {
111  }
112  value = 0;
113  NATIVE_UINT_TYPE idx = advance_idx(m_head_idx, offset);
114 
115  // Deserialize all the bytes from network format
116  for (NATIVE_UINT_TYPE i = 0; i < sizeof(U32); i++) {
117  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
118  value = (value << 8) | static_cast<U32>(m_store[idx]);
119  idx = advance_idx(idx);
120  }
121  return Fw::FW_SERIALIZE_OK;
122 }
123 
125  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
126  FW_ASSERT(buffer != nullptr);
127  // Check there is sufficient data
128  if ((size + offset) > m_allocated_size) {
130  }
131  NATIVE_UINT_TYPE idx = advance_idx(m_head_idx, offset);
132  // Deserialize all the bytes from network format
133  for (NATIVE_UINT_TYPE i = 0; i < size; i++) {
134  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
135  buffer[i] = m_store[idx];
136  idx = advance_idx(idx);
137  }
138  return Fw::FW_SERIALIZE_OK;
139 }
140 
142  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
143  // Check there is sufficient data
144  if (amount > m_allocated_size) {
146  }
147  m_head_idx = advance_idx(m_head_idx, amount);
148  m_allocated_size -= amount;
149  return Fw::FW_SERIALIZE_OK;
150 }
151 
153  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
154  return m_store_size;
155 }
156 
158  return m_high_water_mark;
159 }
160 
162  m_high_water_mark = 0;
163 }
164 
165 } //End Namespace Types
PlatformUIntType NATIVE_UINT_TYPE
Definition: BasicTypes.h:56
Serialization/Deserialization operation was successful.
NATIVE_UINT_TYPE get_capacity() const
Deserialization buffer was empty when trying to read more data.
void setup(U8 *const buffer, const NATIVE_UINT_TYPE size)
No room left in the buffer to serialize data.
NATIVE_UINT_TYPE get_high_water_mark() const
NATIVE_UINT_TYPE get_allocated_size() const
SerializeStatus
forward declaration for string
Fw::SerializeStatus serialize(const U8 *const buffer, const NATIVE_UINT_TYPE size)
Fw::SerializeStatus rotate(NATIVE_UINT_TYPE amount)
C++-compatible configuration header for fprime configuration.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:30
NATIVE_UINT_TYPE get_free_size() const
Fw::SerializeStatus peek(char &value, NATIVE_UINT_TYPE offset=0) const
#define FW_ASSERT(...)
Definition: Assert.hpp:14