mbed source development branch

Fork of mbed-dev by mbed official

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