test

Dependencies:   mbed Watchdog

Dependents:   STM32-MC_node

Committer:
ommpy
Date:
Mon Jul 06 17:18:59 2020 +0530
Revision:
0:d383e2dee0f7
first commit

Who changed what in which revision?

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