Mistake on this page?
Report an issue in GitHub or email us
CircularBuffer.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2015-2019 ARM Limited
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #ifndef MBED_CIRCULARBUFFER_H
18 #define MBED_CIRCULARBUFFER_H
19 
20 #include <stdint.h>
21 #include "platform/mbed_critical.h"
22 #include "platform/mbed_assert.h"
23 
24 namespace mbed {
25 
26 namespace internal {
27 /* Detect if CounterType of the Circular buffer is of unsigned type. */
28 template<typename T>
29 struct is_unsigned {
30  static const bool value = false;
31 };
32 template<>
33 struct is_unsigned<unsigned char> {
34  static const bool value = true;
35 };
36 template<>
37 struct is_unsigned<unsigned short> {
38  static const bool value = true;
39 };
40 template<>
41 struct is_unsigned<unsigned int> {
42  static const bool value = true;
43 };
44 template<>
45 struct is_unsigned<unsigned long> {
46  static const bool value = true;
47 };
48 template<>
49 struct is_unsigned<unsigned long long> {
50  static const bool value = true;
51 };
52 }
53 
54 /** \addtogroup platform-public-api */
55 /** @{*/
56 /**
57  * \defgroup platform_CircularBuffer CircularBuffer functions
58  * @{
59  */
60 
61 /** Templated Circular buffer class
62  *
63  * @note Synchronization level: Interrupt safe
64  * @note CounterType must be unsigned and consistent with BufferSize
65  */
66 template<typename T, uint32_t BufferSize, typename CounterType = uint32_t>
68 public:
69  CircularBuffer() : _head(0), _tail(0), _full(false)
70  {
73  "CounterType must be unsigned"
74  );
75 
77  (sizeof(CounterType) >= sizeof(uint32_t)) ||
78  (BufferSize < (((uint64_t) 1) << (sizeof(CounterType) * 8))),
79  "Invalid BufferSize for the CounterType"
80  );
81  }
82 
84  {
85  }
86 
87  /** Push the transaction to the buffer. This overwrites the buffer if it's
88  * full
89  *
90  * @param data Data to be pushed to the buffer
91  */
92  void push(const T &data)
93  {
95  if (full()) {
96  _tail++;
97  if (_tail == BufferSize) {
98  _tail = 0;
99  }
100  }
101  _pool[_head++] = data;
102  if (_head == BufferSize) {
103  _head = 0;
104  }
105  if (_head == _tail) {
106  _full = true;
107  }
109  }
110 
111  /** Pop the transaction from the buffer
112  *
113  * @param data Data to be popped from the buffer
114  * @return True if the buffer is not empty and data contains a transaction, false otherwise
115  */
116  bool pop(T &data)
117  {
118  bool data_popped = false;
120  if (!empty()) {
121  data = _pool[_tail++];
122  if (_tail == BufferSize) {
123  _tail = 0;
124  }
125  _full = false;
126  data_popped = true;
127  }
129  return data_popped;
130  }
131 
132  /** Check if the buffer is empty
133  *
134  * @return True if the buffer is empty, false if not
135  */
136  bool empty() const
137  {
139  bool is_empty = (_head == _tail) && !_full;
141  return is_empty;
142  }
143 
144  /** Check if the buffer is full
145  *
146  * @return True if the buffer is full, false if not
147  */
148  bool full() const
149  {
151  bool full = _full;
153  return full;
154  }
155 
156  /** Reset the buffer
157  *
158  */
159  void reset()
160  {
162  _head = 0;
163  _tail = 0;
164  _full = false;
166  }
167 
168  /** Get the number of elements currently stored in the circular_buffer */
169  CounterType size() const
170  {
172  CounterType elements;
173  if (!_full) {
174  if (_head < _tail) {
175  elements = BufferSize + _head - _tail;
176  } else {
177  elements = _head - _tail;
178  }
179  } else {
180  elements = BufferSize;
181  }
183  return elements;
184  }
185 
186  /** Peek into circular buffer without popping
187  *
188  * @param data Data to be peeked from the buffer
189  * @return True if the buffer is not empty and data contains a transaction, false otherwise
190  */
191  bool peek(T &data) const
192  {
193  bool data_updated = false;
195  if (!empty()) {
196  data = _pool[_tail];
197  data_updated = true;
198  }
200  return data_updated;
201  }
202 
203 private:
204  T _pool[BufferSize];
205  CounterType _head;
206  CounterType _tail;
207  bool _full;
208 };
209 
210 /**@}*/
211 
212 /**@}*/
213 
214 }
215 
216 #endif
bool full() const
Check if the buffer is full.
Templated Circular buffer class.
void core_util_critical_section_exit(void)
Mark the end of a critical section.
void push(const T &data)
Push the transaction to the buffer.
CounterType size() const
Get the number of elements currently stored in the circular_buffer.
void core_util_critical_section_enter(void)
Mark the start of a critical section.
bool pop(T &data)
Pop the transaction from the buffer.
bool peek(T &data) const
Peek into circular buffer without popping.
Definition: ATHandler.h:46
#define MBED_STATIC_ASSERT(expr, msg)
MBED_STATIC_ASSERT Declare compile-time assertions, results in compile-time error if condition is fal...
Definition: mbed_assert.h:98
bool empty() const
Check if the buffer is empty.
void reset()
Reset the buffer.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.