F´ Flight Software - C/C++ Documentation NASA-v1.6.0
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
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
23namespace Types {
24
25CircularBuffer :: CircularBuffer() :
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
35CircularBuffer :: CircularBuffer(U8* const buffer, const NATIVE_UINT_TYPE size) :
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
45void 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
58NATIVE_UINT_TYPE CircularBuffer :: get_allocated_size() const {
59 return m_allocated_size;
60}
61
62NATIVE_UINT_TYPE CircularBuffer :: get_free_size() const {
63 FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
64 FW_ASSERT(m_allocated_size <= m_store_size, m_allocated_size);
65 return m_store_size - m_allocated_size;
66}
67
68NATIVE_UINT_TYPE CircularBuffer :: advance_idx(NATIVE_UINT_TYPE idx, NATIVE_UINT_TYPE amount) const {
69 FW_ASSERT(idx < m_store_size, idx);
70 return (idx + amount) % m_store_size;
71}
72
73Fw::SerializeStatus CircularBuffer :: serialize(const U8* const buffer, const NATIVE_UINT_TYPE size) {
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, 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(), m_allocated_size);
89 m_high_water_mark = (m_high_water_mark > m_allocated_size) ? m_high_water_mark : m_allocated_size;
91}
92
93Fw::SerializeStatus CircularBuffer :: peek(char& value, NATIVE_UINT_TYPE offset) const {
94 FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
95 return peek(reinterpret_cast<U8&>(value), offset);
96}
97
98Fw::SerializeStatus CircularBuffer :: peek(U8& value, NATIVE_UINT_TYPE offset) const {
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, idx);
106 value = m_store[idx];
107 return Fw::FW_SERIALIZE_OK;
108}
109
110Fw::SerializeStatus CircularBuffer :: peek(U32& value, NATIVE_UINT_TYPE offset) const {
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, 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
128Fw::SerializeStatus CircularBuffer :: peek(U8* buffer, NATIVE_UINT_TYPE size, NATIVE_UINT_TYPE offset) const {
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, idx);
139 buffer[i] = m_store[idx];
140 idx = advance_idx(idx);
141 }
142 return Fw::FW_SERIALIZE_OK;
143}
144
145Fw::SerializeStatus CircularBuffer :: rotate(NATIVE_UINT_TYPE amount) {
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
156NATIVE_UINT_TYPE CircularBuffer ::get_capacity() const {
157 FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
158 return m_store_size;
159}
160
161NATIVE_UINT_TYPE CircularBuffer ::get_high_water_mark() const {
162 return m_high_water_mark;
163}
164
165void CircularBuffer ::clear_high_water_mark() {
166 m_high_water_mark = 0;
167}
168
169#ifdef CIRCULAR_DEBUG
170void 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:7
uint8_t U8
8-bit unsigned integer
Definition BasicTypes.h:26
PlatformUIntType NATIVE_UINT_TYPE
Definition BasicTypes.h:52
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
void setup(U8 *const buffer, const NATIVE_UINT_TYPE size)
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.