STM32F7 Ethernet interface for nucleo STM32F767

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CircularBuffer.h Source File

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 
00021 namespace mbed {
00022 /** \addtogroup platform */
00023 /** @{*/
00024 /**
00025  * \defgroup platform_CircularBuffer CircularBuffer functions
00026  * @{
00027  */
00028 
00029 /** Templated Circular buffer class
00030  *
00031  *  @note Synchronization level: Interrupt safe
00032  */
00033 template<typename T, uint32_t BufferSize, typename CounterType = uint32_t>
00034 class CircularBuffer {
00035 public:
00036     CircularBuffer() : _head(0), _tail(0), _full(false) {
00037     }
00038 
00039     ~CircularBuffer() {
00040     }
00041 
00042     /** Push the transaction to the buffer. This overwrites the buffer if it's
00043      *  full
00044      *
00045      * @param data Data to be pushed to the buffer
00046      */
00047     void push(const T& data) {
00048         core_util_critical_section_enter();
00049         if (full()) {
00050             _tail++;
00051             _tail %= BufferSize;
00052         }
00053         _pool[_head++] = data;
00054         _head %= BufferSize;
00055         if (_head == _tail) {
00056             _full = true;
00057         }
00058         core_util_critical_section_exit();
00059     }
00060 
00061     /** Pop the transaction from the buffer
00062      *
00063      * @param data Data to be pushed to the buffer
00064      * @return True if the buffer is not empty and data contains a transaction, false otherwise
00065      */
00066     bool pop(T& data) {
00067         bool data_popped = false;
00068         core_util_critical_section_enter();
00069         if (!empty()) {
00070             data = _pool[_tail++];
00071             _tail %= BufferSize;
00072             _full = false;
00073             data_popped = true;
00074         }
00075         core_util_critical_section_exit();
00076         return data_popped;
00077     }
00078 
00079     /** Check if the buffer is empty
00080      *
00081      * @return True if the buffer is empty, false if not
00082      */
00083     bool empty() const {
00084         core_util_critical_section_enter();
00085         bool is_empty = (_head == _tail) && !_full;
00086         core_util_critical_section_exit();
00087         return is_empty;
00088     }
00089 
00090     /** Check if the buffer is full
00091      *
00092      * @return True if the buffer is full, false if not
00093      */
00094     bool full() const {
00095         core_util_critical_section_enter();
00096         bool full = _full;
00097         core_util_critical_section_exit();
00098         return full;
00099     }
00100 
00101     /** Reset the buffer
00102      *
00103      */
00104     void reset() {
00105         core_util_critical_section_enter();
00106         _head = 0;
00107         _tail = 0;
00108         _full = false;
00109         core_util_critical_section_exit();
00110     }
00111 
00112     /** Get the number of elements currently stored in the circular_buffer */
00113     CounterType size() const {
00114         core_util_critical_section_enter();
00115         CounterType elements;
00116         if (!_full) {
00117             if (_head < _tail) {
00118                 elements = BufferSize + _head - _tail;
00119             } else {
00120                 elements = _head - _tail;
00121             }
00122         } else {
00123             elements = BufferSize;
00124         }
00125         core_util_critical_section_exit();
00126         return elements;
00127     }
00128     
00129 private:
00130     T _pool[BufferSize];
00131     volatile CounterType _head;
00132     volatile CounterType _tail;
00133     volatile bool _full;
00134 };
00135 
00136 /**@}*/
00137 
00138 /**@}*/
00139 
00140 }
00141 
00142 #endif
00143