Mistake on this page?
Report an issue in GitHub or email us
CircularBuffer.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2015 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 "platform/mbed_critical.h"
21 #include "platform/mbed_assert.h"
22 
23 namespace mbed {
24 
25 namespace internal {
26 /* Detect if CounterType of the Circular buffer is of unsigned type. */
27 template<typename T>
28 struct is_unsigned {
29  static const bool value = false;
30 };
31 template<>
32 struct is_unsigned<unsigned char> {
33  static const bool value = true;
34 };
35 template<>
36 struct is_unsigned<unsigned short> {
37  static const bool value = true;
38 };
39 template<>
40 struct is_unsigned<unsigned int> {
41  static const bool value = true;
42 };
43 template<>
44 struct is_unsigned<unsigned long> {
45  static const bool value = true;
46 };
47 template<>
48 struct is_unsigned<unsigned long long> {
49  static const bool value = true;
50 };
51 };
52 
53 /** \addtogroup platform */
54 /** @{*/
55 /**
56  * \defgroup platform_CircularBuffer CircularBuffer functions
57  * @{
58  */
59 
60 /** Templated Circular buffer class
61  *
62  * @note Synchronization level: Interrupt safe
63  * @note CounterType must be unsigned and consistent with BufferSize
64  */
65 template<typename T, uint32_t BufferSize, typename CounterType = uint32_t>
67 public:
68  CircularBuffer() : _head(0), _tail(0), _full(false)
69  {
72  "CounterType must be unsigned"
73  );
74 
76  (sizeof(CounterType) >= sizeof(uint32_t)) ||
77  (BufferSize < (((uint64_t) 1) << (sizeof(CounterType) * 8))),
78  "Invalid BufferSize for the CounterType"
79  );
80  }
81 
83  {
84  }
85 
86  /** Push the transaction to the buffer. This overwrites the buffer if it's
87  * full
88  *
89  * @param data Data to be pushed to the buffer
90  */
91  void push(const T &data)
92  {
94  if (full()) {
95  _tail++;
96  if (_tail == BufferSize) {
97  _tail = 0;
98  }
99  }
100  _pool[_head++] = data;
101  if (_head == BufferSize) {
102  _head = 0;
103  }
104  if (_head == _tail) {
105  _full = true;
106  }
108  }
109 
110  /** Pop the transaction from the buffer
111  *
112  * @param data Data to be popped from the buffer
113  * @return True if the buffer is not empty and data contains a transaction, false otherwise
114  */
115  bool pop(T &data)
116  {
117  bool data_popped = false;
119  if (!empty()) {
120  data = _pool[_tail++];
121  if (_tail == BufferSize) {
122  _tail = 0;
123  }
124  _full = false;
125  data_popped = true;
126  }
128  return data_popped;
129  }
130 
131  /** Check if the buffer is empty
132  *
133  * @return True if the buffer is empty, false if not
134  */
135  bool empty() const
136  {
138  bool is_empty = (_head == _tail) && !_full;
140  return is_empty;
141  }
142 
143  /** Check if the buffer is full
144  *
145  * @return True if the buffer is full, false if not
146  */
147  bool full() const
148  {
150  bool full = _full;
152  return full;
153  }
154 
155  /** Reset the buffer
156  *
157  */
158  void reset()
159  {
161  _head = 0;
162  _tail = 0;
163  _full = false;
165  }
166 
167  /** Get the number of elements currently stored in the circular_buffer */
168  CounterType size() const
169  {
171  CounterType elements;
172  if (!_full) {
173  if (_head < _tail) {
174  elements = BufferSize + _head - _tail;
175  } else {
176  elements = _head - _tail;
177  }
178  } else {
179  elements = BufferSize;
180  }
182  return elements;
183  }
184 
185  /** Peek into circular buffer without popping
186  *
187  * @param data Data to be peeked from the buffer
188  * @return True if the buffer is not empty and data contains a transaction, false otherwise
189  */
190  bool peek(T &data) const
191  {
192  bool data_updated = false;
194  if (!empty()) {
195  data = _pool[_tail];
196  data_updated = true;
197  }
199  return data_updated;
200  }
201 
202 private:
203  T _pool[BufferSize];
204  CounterType _head;
205  CounterType _tail;
206  bool _full;
207 };
208 
209 /**@}*/
210 
211 /**@}*/
212 
213 }
214 
215 #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: AnalogIn.h:28
#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:110
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.