mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Thu Sep 06 13:40:20 2018 +0100
Revision:
187:0387e8f68319
Parent:
186:707f6e361f3e
Child:
188:bcfe06ba3d64
mbed-dev library. Release version 163

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++;
<> 149:156823d33999 95 _tail %= BufferSize;
<> 149:156823d33999 96 }
<> 149:156823d33999 97 _pool[_head++] = data;
<> 149:156823d33999 98 _head %= BufferSize;
<> 149:156823d33999 99 if (_head == _tail) {
<> 149:156823d33999 100 _full = true;
<> 149:156823d33999 101 }
<> 149:156823d33999 102 core_util_critical_section_exit();
<> 149:156823d33999 103 }
<> 149:156823d33999 104
<> 149:156823d33999 105 /** Pop the transaction from the buffer
<> 149:156823d33999 106 *
Anna Bridge 186:707f6e361f3e 107 * @param data Data to be popped from the buffer
<> 149:156823d33999 108 * @return True if the buffer is not empty and data contains a transaction, false otherwise
<> 149:156823d33999 109 */
AnnaBridge 187:0387e8f68319 110 bool pop(T &data)
AnnaBridge 187:0387e8f68319 111 {
<> 149:156823d33999 112 bool data_popped = false;
<> 149:156823d33999 113 core_util_critical_section_enter();
<> 149:156823d33999 114 if (!empty()) {
<> 149:156823d33999 115 data = _pool[_tail++];
<> 149:156823d33999 116 _tail %= BufferSize;
<> 149:156823d33999 117 _full = false;
<> 149:156823d33999 118 data_popped = true;
<> 149:156823d33999 119 }
<> 149:156823d33999 120 core_util_critical_section_exit();
<> 149:156823d33999 121 return data_popped;
<> 149:156823d33999 122 }
<> 149:156823d33999 123
<> 149:156823d33999 124 /** Check if the buffer is empty
<> 149:156823d33999 125 *
<> 149:156823d33999 126 * @return True if the buffer is empty, false if not
<> 149:156823d33999 127 */
AnnaBridge 187:0387e8f68319 128 bool empty() const
AnnaBridge 187:0387e8f68319 129 {
<> 149:156823d33999 130 core_util_critical_section_enter();
<> 149:156823d33999 131 bool is_empty = (_head == _tail) && !_full;
<> 149:156823d33999 132 core_util_critical_section_exit();
<> 149:156823d33999 133 return is_empty;
<> 149:156823d33999 134 }
<> 149:156823d33999 135
<> 149:156823d33999 136 /** Check if the buffer is full
<> 149:156823d33999 137 *
<> 149:156823d33999 138 * @return True if the buffer is full, false if not
<> 149:156823d33999 139 */
AnnaBridge 187:0387e8f68319 140 bool full() const
AnnaBridge 187:0387e8f68319 141 {
<> 149:156823d33999 142 core_util_critical_section_enter();
<> 149:156823d33999 143 bool full = _full;
<> 149:156823d33999 144 core_util_critical_section_exit();
<> 149:156823d33999 145 return full;
<> 149:156823d33999 146 }
<> 149:156823d33999 147
<> 149:156823d33999 148 /** Reset the buffer
<> 149:156823d33999 149 *
<> 149:156823d33999 150 */
AnnaBridge 187:0387e8f68319 151 void reset()
AnnaBridge 187:0387e8f68319 152 {
<> 149:156823d33999 153 core_util_critical_section_enter();
<> 149:156823d33999 154 _head = 0;
<> 149:156823d33999 155 _tail = 0;
<> 149:156823d33999 156 _full = false;
<> 149:156823d33999 157 core_util_critical_section_exit();
<> 149:156823d33999 158 }
<> 149:156823d33999 159
Anna Bridge 180:96ed750bd169 160 /** Get the number of elements currently stored in the circular_buffer */
AnnaBridge 187:0387e8f68319 161 CounterType size() const
AnnaBridge 187:0387e8f68319 162 {
Anna Bridge 180:96ed750bd169 163 core_util_critical_section_enter();
Anna Bridge 180:96ed750bd169 164 CounterType elements;
Anna Bridge 180:96ed750bd169 165 if (!_full) {
Anna Bridge 180:96ed750bd169 166 if (_head < _tail) {
Anna Bridge 180:96ed750bd169 167 elements = BufferSize + _head - _tail;
Anna Bridge 180:96ed750bd169 168 } else {
Anna Bridge 180:96ed750bd169 169 elements = _head - _tail;
Anna Bridge 180:96ed750bd169 170 }
Anna Bridge 180:96ed750bd169 171 } else {
Anna Bridge 180:96ed750bd169 172 elements = BufferSize;
Anna Bridge 180:96ed750bd169 173 }
Anna Bridge 180:96ed750bd169 174 core_util_critical_section_exit();
Anna Bridge 180:96ed750bd169 175 return elements;
Anna Bridge 180:96ed750bd169 176 }
Anna Bridge 186:707f6e361f3e 177
Anna Bridge 186:707f6e361f3e 178 /** Peek into circular buffer without popping
Anna Bridge 186:707f6e361f3e 179 *
Anna Bridge 186:707f6e361f3e 180 * @param data Data to be peeked from the buffer
Anna Bridge 186:707f6e361f3e 181 * @return True if the buffer is not empty and data contains a transaction, false otherwise
Anna Bridge 186:707f6e361f3e 182 */
AnnaBridge 187:0387e8f68319 183 bool peek(T &data) const
AnnaBridge 187:0387e8f68319 184 {
Anna Bridge 186:707f6e361f3e 185 bool data_updated = false;
Anna Bridge 186:707f6e361f3e 186 core_util_critical_section_enter();
Anna Bridge 186:707f6e361f3e 187 if (!empty()) {
Anna Bridge 186:707f6e361f3e 188 data = _pool[_tail];
Anna Bridge 186:707f6e361f3e 189 data_updated = true;
Anna Bridge 186:707f6e361f3e 190 }
Anna Bridge 186:707f6e361f3e 191 core_util_critical_section_exit();
Anna Bridge 186:707f6e361f3e 192 return data_updated;
Anna Bridge 186:707f6e361f3e 193 }
AnnaBridge 187:0387e8f68319 194
<> 149:156823d33999 195 private:
<> 149:156823d33999 196 T _pool[BufferSize];
<> 149:156823d33999 197 volatile CounterType _head;
<> 149:156823d33999 198 volatile CounterType _tail;
<> 149:156823d33999 199 volatile bool _full;
<> 149:156823d33999 200 };
<> 149:156823d33999 201
AnnaBridge 178:79309dc6340a 202 /**@}*/
AnnaBridge 178:79309dc6340a 203
AnnaBridge 178:79309dc6340a 204 /**@}*/
AnnaBridge 178:79309dc6340a 205
<> 149:156823d33999 206 }
<> 149:156823d33999 207
<> 149:156823d33999 208 #endif