Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: nRF51_Vdd TextLCD BME280
CircularBuffer.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #ifndef MBED_CIRCULARBUFFER_H 00017 #define MBED_CIRCULARBUFFER_H 00018 00019 #include "platform/mbed_critical.h" 00020 #include "platform/mbed_assert.h" 00021 00022 namespace mbed { 00023 00024 namespace internal { 00025 /* Detect if CounterType of the Circular buffer is of unsigned type. */ 00026 template<typename T> 00027 struct is_unsigned { 00028 static const bool value = false; 00029 }; 00030 template<> 00031 struct is_unsigned<unsigned char> { 00032 static const bool value = true; 00033 }; 00034 template<> 00035 struct is_unsigned<unsigned short> { 00036 static const bool value = true; 00037 }; 00038 template<> 00039 struct is_unsigned<unsigned int> { 00040 static const bool value = true; 00041 }; 00042 template<> 00043 struct is_unsigned<unsigned long> { 00044 static const bool value = true; 00045 }; 00046 template<> 00047 struct is_unsigned<unsigned long long> { 00048 static const bool value = true; 00049 }; 00050 }; 00051 00052 /** \addtogroup platform */ 00053 /** @{*/ 00054 /** 00055 * \defgroup platform_CircularBuffer CircularBuffer functions 00056 * @{ 00057 */ 00058 00059 /** Templated Circular buffer class 00060 * 00061 * @note Synchronization level: Interrupt safe 00062 * @note CounterType must be unsigned and consistent with BufferSize 00063 */ 00064 template<typename T, uint32_t BufferSize, typename CounterType = uint32_t> 00065 class CircularBuffer { 00066 public: 00067 CircularBuffer() : _head(0), _tail(0), _full(false) 00068 { 00069 MBED_STATIC_ASSERT( 00070 internal::is_unsigned<CounterType>::value, 00071 "CounterType must be unsigned" 00072 ); 00073 00074 MBED_STATIC_ASSERT( 00075 (sizeof(CounterType) >= sizeof(uint32_t)) || 00076 (BufferSize < (((uint64_t) 1) << (sizeof(CounterType) * 8))), 00077 "Invalid BufferSize for the CounterType" 00078 ); 00079 } 00080 00081 ~CircularBuffer() 00082 { 00083 } 00084 00085 /** Push the transaction to the buffer. This overwrites the buffer if it's 00086 * full 00087 * 00088 * @param data Data to be pushed to the buffer 00089 */ 00090 void push(const T &data) 00091 { 00092 core_util_critical_section_enter(); 00093 if (full()) { 00094 _tail++; 00095 if (_tail == BufferSize) { 00096 _tail = 0; 00097 } 00098 } 00099 _pool[_head++] = data; 00100 if (_head == BufferSize) { 00101 _head = 0; 00102 } 00103 if (_head == _tail) { 00104 _full = true; 00105 } 00106 core_util_critical_section_exit(); 00107 } 00108 00109 /** Pop the transaction from the buffer 00110 * 00111 * @param data Data to be popped from the buffer 00112 * @return True if the buffer is not empty and data contains a transaction, false otherwise 00113 */ 00114 bool pop(T &data) 00115 { 00116 bool data_popped = false; 00117 core_util_critical_section_enter(); 00118 if (!empty()) { 00119 data = _pool[_tail++]; 00120 if (_tail == BufferSize) { 00121 _tail = 0; 00122 } 00123 _full = false; 00124 data_popped = true; 00125 } 00126 core_util_critical_section_exit(); 00127 return data_popped; 00128 } 00129 00130 /** Check if the buffer is empty 00131 * 00132 * @return True if the buffer is empty, false if not 00133 */ 00134 bool empty() const 00135 { 00136 core_util_critical_section_enter(); 00137 bool is_empty = (_head == _tail) && !_full; 00138 core_util_critical_section_exit(); 00139 return is_empty; 00140 } 00141 00142 /** Check if the buffer is full 00143 * 00144 * @return True if the buffer is full, false if not 00145 */ 00146 bool full() const 00147 { 00148 core_util_critical_section_enter(); 00149 bool full = _full; 00150 core_util_critical_section_exit(); 00151 return full; 00152 } 00153 00154 /** Reset the buffer 00155 * 00156 */ 00157 void reset() 00158 { 00159 core_util_critical_section_enter(); 00160 _head = 0; 00161 _tail = 0; 00162 _full = false; 00163 core_util_critical_section_exit(); 00164 } 00165 00166 /** Get the number of elements currently stored in the circular_buffer */ 00167 CounterType size() const 00168 { 00169 core_util_critical_section_enter(); 00170 CounterType elements; 00171 if (!_full) { 00172 if (_head < _tail) { 00173 elements = BufferSize + _head - _tail; 00174 } else { 00175 elements = _head - _tail; 00176 } 00177 } else { 00178 elements = BufferSize; 00179 } 00180 core_util_critical_section_exit(); 00181 return elements; 00182 } 00183 00184 /** Peek into circular buffer without popping 00185 * 00186 * @param data Data to be peeked from the buffer 00187 * @return True if the buffer is not empty and data contains a transaction, false otherwise 00188 */ 00189 bool peek(T &data) const 00190 { 00191 bool data_updated = false; 00192 core_util_critical_section_enter(); 00193 if (!empty()) { 00194 data = _pool[_tail]; 00195 data_updated = true; 00196 } 00197 core_util_critical_section_exit(); 00198 return data_updated; 00199 } 00200 00201 private: 00202 T _pool[BufferSize]; 00203 CounterType _head; 00204 CounterType _tail; 00205 bool _full; 00206 }; 00207 00208 /**@}*/ 00209 00210 /**@}*/ 00211 00212 } 00213 00214 #endif
Generated on Tue Jul 12 2022 15:15:41 by
