]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h
Added +TCP code to main repo.
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / include / FreeRTOS_Stream_Buffer.h
1 /*\r
2  * FreeRTOS+TCP Labs Build 160919 (C) 2016 Real Time Engineers ltd.\r
3  * Authors include Hein Tibosch and Richard Barry\r
4  *\r
5  *******************************************************************************\r
6  ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***\r
7  ***                                                                         ***\r
8  ***                                                                         ***\r
9  ***   FREERTOS+TCP IS STILL IN THE LAB (mainly because the FTP and HTTP     ***\r
10  ***   demos have a dependency on FreeRTOS+FAT, which is only in the Labs    ***\r
11  ***   download):                                                            ***\r
12  ***                                                                         ***\r
13  ***   FreeRTOS+TCP is functional and has been used in commercial products   ***\r
14  ***   for some time.  Be aware however that we are still refining its       ***\r
15  ***   design, the source code does not yet quite conform to the strict      ***\r
16  ***   coding and style standards mandated by Real Time Engineers ltd., and  ***\r
17  ***   the documentation and testing is not necessarily complete.            ***\r
18  ***                                                                         ***\r
19  ***   PLEASE REPORT EXPERIENCES USING THE SUPPORT RESOURCES FOUND ON THE    ***\r
20  ***   URL: http://www.FreeRTOS.org/contact  Active early adopters may, at   ***\r
21  ***   the sole discretion of Real Time Engineers Ltd., be offered versions  ***\r
22  ***   under a license other than that described below.                      ***\r
23  ***                                                                         ***\r
24  ***                                                                         ***\r
25  ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***\r
26  *******************************************************************************\r
27  *\r
28  * FreeRTOS+TCP can be used under two different free open source licenses.  The\r
29  * license that applies is dependent on the processor on which FreeRTOS+TCP is\r
30  * executed, as follows:\r
31  *\r
32  * If FreeRTOS+TCP is executed on one of the processors listed under the Special\r
33  * License Arrangements heading of the FreeRTOS+TCP license information web\r
34  * page, then it can be used under the terms of the FreeRTOS Open Source\r
35  * License.  If FreeRTOS+TCP is used on any other processor, then it can be used\r
36  * under the terms of the GNU General Public License V2.  Links to the relevant\r
37  * licenses follow:\r
38  *\r
39  * The FreeRTOS+TCP License Information Page: http://www.FreeRTOS.org/tcp_license\r
40  * The FreeRTOS Open Source License: http://www.FreeRTOS.org/license\r
41  * The GNU General Public License Version 2: http://www.FreeRTOS.org/gpl-2.0.txt\r
42  *\r
43  * FreeRTOS+TCP is distributed in the hope that it will be useful.  You cannot\r
44  * use FreeRTOS+TCP unless you agree that you use the software 'as is'.\r
45  * FreeRTOS+TCP is provided WITHOUT ANY WARRANTY; without even the implied\r
46  * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR\r
47  * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they\r
48  * implied, expressed, or statutory.\r
49  *\r
50  * 1 tab == 4 spaces!\r
51  *\r
52  * http://www.FreeRTOS.org\r
53  * http://www.FreeRTOS.org/plus\r
54  * http://www.FreeRTOS.org/labs\r
55  *\r
56  */\r
57 \r
58 /*\r
59  *      FreeRTOS_Stream_Buffer.h\r
60  *\r
61  *      A cicular character buffer\r
62  *      An implementation of a circular buffer without a length field\r
63  *      If LENGTH defines the size of the buffer, a maximum of (LENGT-1) bytes can be stored\r
64  *      In order to add or read data from the buffer, memcpy() will be called at most 2 times\r
65  */\r
66 \r
67 #ifndef FREERTOS_STREAM_BUFFER_H\r
68 #define FREERTOS_STREAM_BUFFER_H\r
69 \r
70 #ifdef __cplusplus\r
71 extern "C" {\r
72 #endif\r
73 \r
74 typedef struct xSTREAM_BUFFER {\r
75         volatile size_t uxTail;         /* next item to read */\r
76         volatile size_t uxMid;          /* iterator within the valid items */\r
77         volatile size_t uxHead;         /* next position store a new item */\r
78         volatile size_t uxFront;        /* iterator within the free space */\r
79         size_t LENGTH;                          /* const value: number of reserved elements */\r
80         uint8_t ucArray[ sizeof( size_t ) ];\r
81 } StreamBuffer_t;\r
82 \r
83 static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer );\r
84 static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer )\r
85 {\r
86         /* Make the circular buffer empty */\r
87         pxBuffer->uxHead = 0u;\r
88         pxBuffer->uxTail = 0u;\r
89         pxBuffer->uxFront = 0u;\r
90         pxBuffer->uxMid = 0u;\r
91 }\r
92 /*-----------------------------------------------------------*/\r
93 \r
94 static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );\r
95 static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )\r
96 {\r
97 /* Returns the space between uxLower and uxUpper, which equals to the distance minus 1 */\r
98 size_t uxCount;\r
99 \r
100         uxCount = pxBuffer->LENGTH + uxUpper - uxLower - 1u;\r
101         if( uxCount >= pxBuffer->LENGTH )\r
102         {\r
103                 uxCount -= pxBuffer->LENGTH;\r
104         }\r
105 \r
106         return uxCount;\r
107 }\r
108 /*-----------------------------------------------------------*/\r
109 \r
110 static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );\r
111 static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )\r
112 {\r
113 /* Returns the distance between uxLower and uxUpper */\r
114 size_t uxCount;\r
115 \r
116         uxCount = pxBuffer->LENGTH + uxUpper - uxLower;\r
117         if ( uxCount >= pxBuffer->LENGTH )\r
118         {\r
119                 uxCount -= pxBuffer->LENGTH;\r
120         }\r
121 \r
122         return uxCount;\r
123 }\r
124 /*-----------------------------------------------------------*/\r
125 \r
126 static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer );\r
127 static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer )\r
128 {\r
129 /* Returns the number of items which can still be added to uxHead\r
130 before hitting on uxTail */\r
131 size_t uxHead = pxBuffer->uxHead;\r
132 size_t uxTail = pxBuffer->uxTail;\r
133 \r
134         return uxStreamBufferSpace( pxBuffer, uxHead, uxTail );\r
135 }\r
136 /*-----------------------------------------------------------*/\r
137 \r
138 static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer );\r
139 static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer )\r
140 {\r
141 /* Distance between uxFront and uxTail\r
142 or the number of items which can still be added to uxFront,\r
143 before hitting on uxTail */\r
144 \r
145 size_t uxFront = pxBuffer->uxFront;\r
146 size_t uxTail = pxBuffer->uxTail;\r
147 \r
148         return uxStreamBufferSpace( pxBuffer, uxFront, uxTail );\r
149 }\r
150 /*-----------------------------------------------------------*/\r
151 \r
152 static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer );\r
153 static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer )\r
154 {\r
155 /* Returns the number of items which can be read from uxTail\r
156 before reaching uxHead */\r
157 size_t uxHead = pxBuffer->uxHead;\r
158 size_t uxTail = pxBuffer->uxTail;\r
159 \r
160         return uxStreamBufferDistance( pxBuffer, uxTail, uxHead );\r
161 }\r
162 /*-----------------------------------------------------------*/\r
163 \r
164 static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer );\r
165 static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer )\r
166 {\r
167 /* Returns the distance between uxHead and uxMid */\r
168 size_t uxHead = pxBuffer->uxHead;\r
169 size_t uxMid = pxBuffer->uxMid;\r
170 \r
171         return uxStreamBufferDistance( pxBuffer, uxMid, uxHead );\r
172 }\r
173 /*-----------------------------------------------------------*/\r
174 \r
175 static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount );\r
176 static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount )\r
177 {\r
178 /* Increment uxMid, but no further than uxHead */\r
179 size_t uxSize = uxStreamBufferMidSpace( pxBuffer );\r
180 \r
181         if( uxCount > uxSize )\r
182         {\r
183                 uxCount = uxSize;\r
184         }\r
185         pxBuffer->uxMid += uxCount;\r
186         if( pxBuffer->uxMid >= pxBuffer->LENGTH )\r
187         {\r
188                 pxBuffer->uxMid -= pxBuffer->LENGTH;\r
189         }\r
190 }\r
191 /*-----------------------------------------------------------*/\r
192 static portINLINE BaseType_t xStreamBufferIsEmpty( const StreamBuffer_t *pxBuffer );\r
193 static portINLINE BaseType_t xStreamBufferIsEmpty( const StreamBuffer_t *pxBuffer )\r
194 {\r
195 BaseType_t xReturn;\r
196 \r
197         /* True if no item is available */\r
198         if( pxBuffer->uxHead == pxBuffer->uxTail )\r
199         {\r
200                 xReturn = pdTRUE;\r
201         }\r
202         else\r
203         {\r
204                 xReturn = pdFALSE;\r
205         }\r
206         return xReturn;\r
207 }\r
208 /*-----------------------------------------------------------*/\r
209 \r
210 static portINLINE BaseType_t xStreamBufferIsFull( const StreamBuffer_t *pxBuffer );\r
211 static portINLINE BaseType_t xStreamBufferIsFull( const StreamBuffer_t *pxBuffer )\r
212 {\r
213         /* True if the available space equals zero. */\r
214         return ( BaseType_t ) ( uxStreamBufferGetSpace( pxBuffer ) == 0u );\r
215 }\r
216 /*-----------------------------------------------------------*/\r
217 \r
218 static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight );\r
219 static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight )\r
220 {\r
221 BaseType_t xReturn;\r
222 size_t uxTail = pxBuffer->uxTail;\r
223 \r
224         /* Returns true if ( uxLeft < uxRight ) */\r
225         if( ( uxLeft < uxTail ) ^ ( uxRight < uxTail ) )\r
226         {\r
227                 if( uxRight < uxTail )\r
228                 {\r
229                         xReturn = pdTRUE;\r
230                 }\r
231                 else\r
232                 {\r
233                         xReturn = pdFALSE;\r
234                 }\r
235         }\r
236         else\r
237         {\r
238                 if( uxLeft <= uxRight )\r
239                 {\r
240                         xReturn = pdTRUE;\r
241                 }\r
242                 else\r
243                 {\r
244                         xReturn = pdFALSE;\r
245                 }\r
246         }\r
247         return xReturn;\r
248 }\r
249 /*-----------------------------------------------------------*/\r
250 \r
251 static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData );\r
252 static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData )\r
253 {\r
254 size_t uxNextTail = pxBuffer->uxTail;\r
255 size_t uxSize = uxStreamBufferGetSize( pxBuffer );\r
256 \r
257         *ppucData = pxBuffer->ucArray + uxNextTail;\r
258 \r
259         return FreeRTOS_min_uint32( uxSize, pxBuffer->LENGTH - uxNextTail );\r
260 }\r
261 \r
262 /*\r
263  * Add bytes to a stream buffer.\r
264  *\r
265  * pxBuffer -   The buffer to which the bytes will be added.\r
266  * uxOffset -   If uxOffset > 0, data will be written at an offset from uxHead\r
267  *                              while uxHead will not be moved yet.\r
268  * pucData -    A pointer to the data to be added.\r
269  * uxCount -    The number of bytes to add.\r
270  */\r
271 size_t uxStreamBufferAdd( StreamBuffer_t *pxBuffer, size_t uxOffset, const uint8_t *pucData, size_t uxCount );\r
272 \r
273 /*\r
274  * Read bytes from a stream buffer.\r
275  *\r
276  * pxBuffer -   The buffer from which the bytes will be read.\r
277  * uxOffset -   Can be used to read data located at a certain offset from 'uxTail'.\r
278  * pucData -    A pointer to the buffer into which data will be read.\r
279  * uxMaxCount - The number of bytes to read.\r
280  * xPeek -              If set to pdTRUE the data will remain in the buffer.\r
281  */\r
282 size_t uxStreamBufferGet( StreamBuffer_t *pxBuffer, size_t uxOffset, uint8_t *pucData, size_t uxMaxCount, BaseType_t xPeek );\r
283 \r
284 #ifdef __cplusplus\r
285 } /* extern "C" */\r
286 #endif\r
287 \r
288 #endif  /* !defined( FREERTOS_STREAM_BUFFER_H ) */\r