sanguino/firmwares/arduino-usbserial/Lib/LightweightRingBuff.h

Thu, 07 Jul 2016 12:23:34 +0200

author
mbayer
date
Thu, 07 Jul 2016 12:23:34 +0200
changeset 2
b373b0288715
permissions
-rw-r--r--

added missing sanguino files

2
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
1 /*
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
2 LUFA Library
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
3 Copyright (C) Dean Camera, 2010.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
4
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
5 dean [at] fourwalledcubicle [dot] com
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
6 www.fourwalledcubicle.com
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
7 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
8
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
9 /*
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
10 Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
11
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
12 Permission to use, copy, modify, distribute, and sell this
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
13 software and its documentation for any purpose is hereby granted
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
14 without fee, provided that the above copyright notice appear in
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
15 all copies and that both that the copyright notice and this
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
16 permission notice and warranty disclaimer appear in supporting
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
17 documentation, and that the name of the author not be used in
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
18 advertising or publicity pertaining to distribution of the
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
19 software without specific, written prior permission.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
20
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
21 The author disclaim all warranties with regard to this
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
22 software, including all implied warranties of merchantability
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
23 and fitness. In no event shall the author be liable for any
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
24 special, indirect or consequential damages or any damages
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
25 whatsoever resulting from loss of use, data or profits, whether
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
26 in an action of contract, negligence or other tortious action,
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
27 arising out of or in connection with the use or performance of
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
28 this software.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
29 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
30
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
31 /** \file
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
32 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
33 * Ultra lightweight ring buffer, for fast insertion/deletion.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
34 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
35
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
36 #ifndef _ULW_RING_BUFF_H_
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
37 #define _ULW_RING_BUFF_H_
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
38
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
39 /* Includes: */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
40 #include <util/atomic.h>
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
41
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
42 #include <stdint.h>
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
43 #include <stdbool.h>
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
44
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
45 /* Defines: */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
46 /** Size of each ring buffer, in data elements - must be between 1 and 255. */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
47 #define BUFFER_SIZE 128
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
48
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
49 /** Maximum number of data elements to buffer before forcing a flush.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
50 * Must be less than BUFFER_SIZE
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
51 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
52 #define BUFFER_NEARLY_FULL 96
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
53
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
54 /** Type of data to store into the buffer. */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
55 #define RingBuff_Data_t uint8_t
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
56
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
57 /** Datatype which may be used to store the count of data stored in a buffer, retrieved
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
58 * via a call to \ref RingBuffer_GetCount().
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
59 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
60 #if (BUFFER_SIZE <= 0xFF)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
61 #define RingBuff_Count_t uint8_t
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
62 #else
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
63 #define RingBuff_Count_t uint16_t
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
64 #endif
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
65
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
66 /* Type Defines: */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
67 /** Type define for a new ring buffer object. Buffers should be initialized via a call to
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
68 * \ref RingBuffer_InitBuffer() before use.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
69 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
70 typedef struct
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
71 {
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
72 RingBuff_Data_t Buffer[BUFFER_SIZE]; /**< Internal ring buffer data, referenced by the buffer pointers. */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
73 RingBuff_Data_t* In; /**< Current storage location in the circular buffer */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
74 RingBuff_Data_t* Out; /**< Current retrieval location in the circular buffer */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
75 RingBuff_Count_t Count;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
76 } RingBuff_t;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
77
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
78 /* Inline Functions: */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
79 /** Initializes a ring buffer ready for use. Buffers must be initialized via this function
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
80 * before any operations are called upon them. Already initialized buffers may be reset
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
81 * by re-initializing them using this function.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
82 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
83 * \param[out] Buffer Pointer to a ring buffer structure to initialize
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
84 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
85 static inline void RingBuffer_InitBuffer(RingBuff_t* const Buffer)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
86 {
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
87 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
88 {
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
89 Buffer->In = Buffer->Buffer;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
90 Buffer->Out = Buffer->Buffer;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
91 }
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
92 }
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
93
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
94 /** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
95 * by entering an atomic lock on the buffer while the IN and OUT locations are fetched, so that
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
96 * the buffer cannot be modified while the computation takes place. This value should be cached
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
97 * when reading out the contents of the buffer, so that as small a time as possible is spent
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
98 * in an atomic lock.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
99 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
100 * \note The value returned by this function is guaranteed to only be the minimum number of bytes
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
101 * stored in the given buffer; this value may change as other threads write new data and so
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
102 * the returned number should be used only to determine how many successive reads may safely
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
103 * be performed on the buffer.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
104 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
105 * \param[in] Buffer Pointer to a ring buffer structure whose count is to be computed
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
106 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
107 static inline RingBuff_Count_t RingBuffer_GetCount(RingBuff_t* const Buffer)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
108 {
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
109 RingBuff_Count_t Count;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
110
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
111 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
112 {
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
113 Count = Buffer->Count;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
114 }
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
115
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
116 return Count;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
117 }
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
118
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
119 /** Atomically determines if the specified ring buffer contains any free space. This should
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
120 * be tested before storing data to the buffer, to ensure that no data is lost due to a
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
121 * buffer overrun.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
122 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
123 * \param[in,out] Buffer Pointer to a ring buffer structure to insert into
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
124 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
125 * \return Boolean true if the buffer contains no free space, false otherwise
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
126 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
127 static inline bool RingBuffer_IsFull(RingBuff_t* const Buffer)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
128 {
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
129 return (RingBuffer_GetCount(Buffer) == BUFFER_SIZE);
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
130 }
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
131
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
132 /** Atomically determines if the specified ring buffer contains any data. This should
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
133 * be tested before removing data from the buffer, to ensure that the buffer does not
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
134 * underflow.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
135 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
136 * If the data is to be removed in a loop, store the total number of bytes stored in the
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
137 * buffer (via a call to the \ref RingBuffer_GetCount() function) in a temporary variable
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
138 * to reduce the time spent in atomicity locks.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
139 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
140 * \param[in,out] Buffer Pointer to a ring buffer structure to insert into
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
141 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
142 * \return Boolean true if the buffer contains no free space, false otherwise
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
143 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
144 static inline bool RingBuffer_IsEmpty(RingBuff_t* const Buffer)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
145 {
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
146 return (RingBuffer_GetCount(Buffer) == 0);
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
147 }
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
148
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
149 /** Inserts an element into the ring buffer.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
150 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
151 * \note Only one execution thread (main program thread or an ISR) may insert into a single buffer
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
152 * otherwise data corruption may occur. Insertion and removal may occur from different execution
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
153 * threads.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
154 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
155 * \param[in,out] Buffer Pointer to a ring buffer structure to insert into
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
156 * \param[in] Data Data element to insert into the buffer
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
157 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
158 static inline void RingBuffer_Insert(RingBuff_t* const Buffer,
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
159 const RingBuff_Data_t Data)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
160 {
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
161 *Buffer->In = Data;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
162
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
163 if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE])
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
164 Buffer->In = Buffer->Buffer;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
165
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
166 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
167 {
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
168 Buffer->Count++;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
169 }
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
170 }
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
171
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
172 /** Removes an element from the ring buffer.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
173 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
174 * \note Only one execution thread (main program thread or an ISR) may remove from a single buffer
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
175 * otherwise data corruption may occur. Insertion and removal may occur from different execution
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
176 * threads.
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
177 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
178 * \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
179 *
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
180 * \return Next data element stored in the buffer
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
181 */
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
182 static inline RingBuff_Data_t RingBuffer_Remove(RingBuff_t* const Buffer)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
183 {
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
184 RingBuff_Data_t Data = *Buffer->Out;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
185
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
186 if (++Buffer->Out == &Buffer->Buffer[BUFFER_SIZE])
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
187 Buffer->Out = Buffer->Buffer;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
188
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
189 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
190 {
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
191 Buffer->Count--;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
192 }
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
193
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
194 return Data;
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
195 }
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
196
b373b0288715 added missing sanguino files
mbayer
parents:
diff changeset
197 #endif

mercurial