mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
AnnaBridge
Date:
Thu Apr 19 17:12:19 2018 +0100
Revision:
184:08ed48f1de7f
Parent:
180:96ed750bd169
Child:
186:707f6e361f3e
mbed-dev library. Release version 161

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 184:08ed48f1de7f 27 struct is_unsigned { static const bool value = false; };
AnnaBridge 184:08ed48f1de7f 28 template<>
AnnaBridge 184:08ed48f1de7f 29 struct is_unsigned<unsigned char> { static const bool value = true; };
AnnaBridge 184:08ed48f1de7f 30 template<>
AnnaBridge 184:08ed48f1de7f 31 struct is_unsigned<unsigned short> { static const bool value = true; };
AnnaBridge 184:08ed48f1de7f 32 template<>
AnnaBridge 184:08ed48f1de7f 33 struct is_unsigned<unsigned int> { static const bool value = true; };
AnnaBridge 184:08ed48f1de7f 34 template<>
AnnaBridge 184:08ed48f1de7f 35 struct is_unsigned<unsigned long> { static const bool value = true; };
AnnaBridge 184:08ed48f1de7f 36 template<>
AnnaBridge 184:08ed48f1de7f 37 struct is_unsigned<unsigned long long> { static const bool value = true; };
AnnaBridge 184:08ed48f1de7f 38 };
AnnaBridge 184:08ed48f1de7f 39
<> 149:156823d33999 40 /** \addtogroup platform */
AnnaBridge 178:79309dc6340a 41 /** @{*/
AnnaBridge 178:79309dc6340a 42 /**
AnnaBridge 178:79309dc6340a 43 * \defgroup platform_CircularBuffer CircularBuffer functions
AnnaBridge 178:79309dc6340a 44 * @{
AnnaBridge 178:79309dc6340a 45 */
<> 149:156823d33999 46
<> 149:156823d33999 47 /** Templated Circular buffer class
<> 149:156823d33999 48 *
AnnaBridge 167:e84263d55307 49 * @note Synchronization level: Interrupt safe
AnnaBridge 184:08ed48f1de7f 50 * @note CounterType must be unsigned and consistent with BufferSize
<> 149:156823d33999 51 */
<> 149:156823d33999 52 template<typename T, uint32_t BufferSize, typename CounterType = uint32_t>
<> 149:156823d33999 53 class CircularBuffer {
<> 149:156823d33999 54 public:
<> 149:156823d33999 55 CircularBuffer() : _head(0), _tail(0), _full(false) {
AnnaBridge 184:08ed48f1de7f 56 MBED_STATIC_ASSERT(
AnnaBridge 184:08ed48f1de7f 57 internal::is_unsigned<CounterType>::value,
AnnaBridge 184:08ed48f1de7f 58 "CounterType must be unsigned"
AnnaBridge 184:08ed48f1de7f 59 );
AnnaBridge 184:08ed48f1de7f 60
AnnaBridge 184:08ed48f1de7f 61 MBED_STATIC_ASSERT(
AnnaBridge 184:08ed48f1de7f 62 (sizeof(CounterType) >= sizeof(uint32_t)) ||
AnnaBridge 184:08ed48f1de7f 63 (BufferSize < (((uint64_t) 1) << (sizeof(CounterType) * 8))),
AnnaBridge 184:08ed48f1de7f 64 "Invalid BufferSize for the CounterType"
AnnaBridge 184:08ed48f1de7f 65 );
<> 149:156823d33999 66 }
<> 149:156823d33999 67
<> 149:156823d33999 68 ~CircularBuffer() {
<> 149:156823d33999 69 }
<> 149:156823d33999 70
<> 149:156823d33999 71 /** Push the transaction to the buffer. This overwrites the buffer if it's
<> 149:156823d33999 72 * full
<> 149:156823d33999 73 *
<> 149:156823d33999 74 * @param data Data to be pushed to the buffer
<> 149:156823d33999 75 */
<> 149:156823d33999 76 void push(const T& data) {
<> 149:156823d33999 77 core_util_critical_section_enter();
<> 149:156823d33999 78 if (full()) {
<> 149:156823d33999 79 _tail++;
<> 149:156823d33999 80 _tail %= BufferSize;
<> 149:156823d33999 81 }
<> 149:156823d33999 82 _pool[_head++] = data;
<> 149:156823d33999 83 _head %= BufferSize;
<> 149:156823d33999 84 if (_head == _tail) {
<> 149:156823d33999 85 _full = true;
<> 149:156823d33999 86 }
<> 149:156823d33999 87 core_util_critical_section_exit();
<> 149:156823d33999 88 }
<> 149:156823d33999 89
<> 149:156823d33999 90 /** Pop the transaction from the buffer
<> 149:156823d33999 91 *
<> 149:156823d33999 92 * @param data Data to be pushed to the buffer
<> 149:156823d33999 93 * @return True if the buffer is not empty and data contains a transaction, false otherwise
<> 149:156823d33999 94 */
<> 149:156823d33999 95 bool pop(T& data) {
<> 149:156823d33999 96 bool data_popped = false;
<> 149:156823d33999 97 core_util_critical_section_enter();
<> 149:156823d33999 98 if (!empty()) {
<> 149:156823d33999 99 data = _pool[_tail++];
<> 149:156823d33999 100 _tail %= BufferSize;
<> 149:156823d33999 101 _full = false;
<> 149:156823d33999 102 data_popped = true;
<> 149:156823d33999 103 }
<> 149:156823d33999 104 core_util_critical_section_exit();
<> 149:156823d33999 105 return data_popped;
<> 149:156823d33999 106 }
<> 149:156823d33999 107
<> 149:156823d33999 108 /** Check if the buffer is empty
<> 149:156823d33999 109 *
<> 149:156823d33999 110 * @return True if the buffer is empty, false if not
<> 149:156823d33999 111 */
AnnaBridge 167:e84263d55307 112 bool empty() const {
<> 149:156823d33999 113 core_util_critical_section_enter();
<> 149:156823d33999 114 bool is_empty = (_head == _tail) && !_full;
<> 149:156823d33999 115 core_util_critical_section_exit();
<> 149:156823d33999 116 return is_empty;
<> 149:156823d33999 117 }
<> 149:156823d33999 118
<> 149:156823d33999 119 /** Check if the buffer is full
<> 149:156823d33999 120 *
<> 149:156823d33999 121 * @return True if the buffer is full, false if not
<> 149:156823d33999 122 */
AnnaBridge 167:e84263d55307 123 bool full() const {
<> 149:156823d33999 124 core_util_critical_section_enter();
<> 149:156823d33999 125 bool full = _full;
<> 149:156823d33999 126 core_util_critical_section_exit();
<> 149:156823d33999 127 return full;
<> 149:156823d33999 128 }
<> 149:156823d33999 129
<> 149:156823d33999 130 /** Reset the buffer
<> 149:156823d33999 131 *
<> 149:156823d33999 132 */
<> 149:156823d33999 133 void reset() {
<> 149:156823d33999 134 core_util_critical_section_enter();
<> 149:156823d33999 135 _head = 0;
<> 149:156823d33999 136 _tail = 0;
<> 149:156823d33999 137 _full = false;
<> 149:156823d33999 138 core_util_critical_section_exit();
<> 149:156823d33999 139 }
<> 149:156823d33999 140
Anna Bridge 180:96ed750bd169 141 /** Get the number of elements currently stored in the circular_buffer */
Anna Bridge 180:96ed750bd169 142 CounterType size() const {
Anna Bridge 180:96ed750bd169 143 core_util_critical_section_enter();
Anna Bridge 180:96ed750bd169 144 CounterType elements;
Anna Bridge 180:96ed750bd169 145 if (!_full) {
Anna Bridge 180:96ed750bd169 146 if (_head < _tail) {
Anna Bridge 180:96ed750bd169 147 elements = BufferSize + _head - _tail;
Anna Bridge 180:96ed750bd169 148 } else {
Anna Bridge 180:96ed750bd169 149 elements = _head - _tail;
Anna Bridge 180:96ed750bd169 150 }
Anna Bridge 180:96ed750bd169 151 } else {
Anna Bridge 180:96ed750bd169 152 elements = BufferSize;
Anna Bridge 180:96ed750bd169 153 }
Anna Bridge 180:96ed750bd169 154 core_util_critical_section_exit();
Anna Bridge 180:96ed750bd169 155 return elements;
Anna Bridge 180:96ed750bd169 156 }
Anna Bridge 180:96ed750bd169 157
<> 149:156823d33999 158 private:
<> 149:156823d33999 159 T _pool[BufferSize];
<> 149:156823d33999 160 volatile CounterType _head;
<> 149:156823d33999 161 volatile CounterType _tail;
<> 149:156823d33999 162 volatile bool _full;
<> 149:156823d33999 163 };
<> 149:156823d33999 164
AnnaBridge 178:79309dc6340a 165 /**@}*/
AnnaBridge 178:79309dc6340a 166
AnnaBridge 178:79309dc6340a 167 /**@}*/
AnnaBridge 178:79309dc6340a 168
<> 149:156823d33999 169 }
<> 149:156823d33999 170
<> 149:156823d33999 171 #endif