mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Thu Nov 08 11:46:34 2018 +0000
Revision:
188:bcfe06ba3d64
Parent:
187:0387e8f68319
Child:
189:f392fc9709a3
mbed-dev library. Release version 164

Who changed what in which revision?

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