2 * FreeRTOS Kernel V10.0.1
\r
3 * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
\r
6 * this software and associated documentation files (the "Software"), to deal in
\r
7 * the Software without restriction, including without limitation the rights to
\r
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
\r
9 * the Software, and to permit persons to whom the Software is furnished to do so,
\r
10 * subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
22 * http://www.FreeRTOS.org
\r
23 * http://aws.amazon.com/freertos
\r
25 * 1 tab == 4 spaces!
\r
28 /* Standard includes. */
\r
32 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
\r
33 all the API functions to use the MPU wrappers. That should only be done when
\r
34 task.h is included from an application file. */
\r
35 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
\r
37 /* FreeRTOS includes. */
\r
38 #include "FreeRTOS.h"
\r
40 #include "stream_buffer.h"
\r
42 #if( configUSE_TASK_NOTIFICATIONS != 1 )
\r
43 #error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c
\r
46 /* Lint e961, e9021 and e750 are suppressed as a MISRA exception justified
\r
47 because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
\r
48 for the header files above, but not in this file, in order to generate the
\r
49 correct privileged Vs unprivileged linkage and placement. */
\r
50 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */
\r
52 /* If the user has not provided application specific Rx notification macros,
\r
53 or #defined the notification macros away, them provide default implementations
\r
54 that uses task notifications. */
\r
55 /*lint -save -e9026 Function like macros allowed and needed here so they can be overidden. */
\r
56 #ifndef sbRECEIVE_COMPLETED
\r
57 #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \
\r
58 vTaskSuspendAll(); \
\r
60 if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \
\r
62 ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \
\r
65 ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \
\r
68 ( void ) xTaskResumeAll();
\r
69 #endif /* sbRECEIVE_COMPLETED */
\r
71 #ifndef sbRECEIVE_COMPLETED_FROM_ISR
\r
72 #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \
\r
73 pxHigherPriorityTaskWoken ) \
\r
75 UBaseType_t uxSavedInterruptStatus; \
\r
77 uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \
\r
79 if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \
\r
81 ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \
\r
84 pxHigherPriorityTaskWoken ); \
\r
85 ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \
\r
88 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
\r
90 #endif /* sbRECEIVE_COMPLETED_FROM_ISR */
\r
92 /* If the user has not provided an application specific Tx notification macro,
\r
93 or #defined the notification macro away, them provide a default implementation
\r
94 that uses task notifications. */
\r
95 #ifndef sbSEND_COMPLETED
\r
96 #define sbSEND_COMPLETED( pxStreamBuffer ) \
\r
97 vTaskSuspendAll(); \
\r
99 if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \
\r
101 ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive, \
\r
104 ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \
\r
107 ( void ) xTaskResumeAll();
\r
108 #endif /* sbSEND_COMPLETED */
\r
110 #ifndef sbSEND_COMPLETE_FROM_ISR
\r
111 #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
\r
113 UBaseType_t uxSavedInterruptStatus; \
\r
115 uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \
\r
117 if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \
\r
119 ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \
\r
122 pxHigherPriorityTaskWoken ); \
\r
123 ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \
\r
126 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
\r
128 #endif /* sbSEND_COMPLETE_FROM_ISR */
\r
129 /*lint -restore (9026) */
\r
131 /* The number of bytes used to hold the length of a message in the buffer. */
\r
132 #define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) )
\r
134 /* Bits stored in the ucFlags field of the stream buffer. */
\r
135 #define sbFLAGS_IS_MESSAGE_BUFFER ( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */
\r
136 #define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */
\r
138 /*-----------------------------------------------------------*/
\r
140 /* Structure that hold state information on the buffer. */
\r
141 typedef struct StreamBufferDef_t /*lint !e9058 Style convention uses tag. */
\r
143 volatile size_t xTail; /* Index to the next item to read within the buffer. */
\r
144 volatile size_t xHead; /* Index to the next item to write within the buffer. */
\r
145 size_t xLength; /* The length of the buffer pointed to by pucBuffer. */
\r
146 size_t xTriggerLevelBytes; /* The number of bytes that must be in the stream buffer before a task that is waiting for data is unblocked. */
\r
147 volatile TaskHandle_t xTaskWaitingToReceive; /* Holds the handle of a task waiting for data, or NULL if no tasks are waiting. */
\r
148 volatile TaskHandle_t xTaskWaitingToSend; /* Holds the handle of a task waiting to send data to a message buffer that is full. */
\r
149 uint8_t *pucBuffer; /* Points to the buffer itself - that is - the RAM that stores the data passed through the buffer. */
\r
152 #if ( configUSE_TRACE_FACILITY == 1 )
\r
153 UBaseType_t uxStreamBufferNumber; /* Used for tracing purposes. */
\r
158 * The number of bytes available to be read from the buffer.
\r
160 static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION;
\r
163 * Add xCount bytes from pucData into the pxStreamBuffer message buffer.
\r
164 * Returns the number of bytes written, which will either equal xCount in the
\r
165 * success case, or 0 if there was not enough space in the buffer (in which case
\r
166 * no data is written into the buffer).
\r
168 static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount ) PRIVILEGED_FUNCTION;
\r
171 * If the stream buffer is being used as a message buffer, then reads an entire
\r
172 * message out of the buffer. If the stream buffer is being used as a stream
\r
173 * buffer then read as many bytes as possible from the buffer.
\r
174 * prvReadBytesFromBuffer() is called to actually extract the bytes from the
\r
175 * buffer's data storage area.
\r
177 static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer,
\r
179 size_t xBufferLengthBytes,
\r
180 size_t xBytesAvailable,
\r
181 size_t xBytesToStoreMessageLength ) PRIVILEGED_FUNCTION;
\r
184 * If the stream buffer is being used as a message buffer, then writes an entire
\r
185 * message to the buffer. If the stream buffer is being used as a stream
\r
186 * buffer then write as many bytes as possible to the buffer.
\r
187 * prvWriteBytestoBuffer() is called to actually send the bytes to the buffer's
\r
188 * data storage area.
\r
190 static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
\r
191 const void * pvTxData,
\r
192 size_t xDataLengthBytes,
\r
194 size_t xRequiredSpace ) PRIVILEGED_FUNCTION;
\r
197 * Read xMaxCount bytes from the pxStreamBuffer message buffer and write them
\r
200 static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer,
\r
203 size_t xBytesAvailable ) PRIVILEGED_FUNCTION;
\r
206 * Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to
\r
207 * initialise the members of the newly created stream buffer structure.
\r
209 static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
\r
210 uint8_t * const pucBuffer,
\r
211 size_t xBufferSizeBytes,
\r
212 size_t xTriggerLevelBytes,
\r
213 BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION;
\r
215 /*-----------------------------------------------------------*/
\r
217 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
\r
219 StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer )
\r
221 uint8_t *pucAllocatedMemory;
\r
223 /* In case the stream buffer is going to be used as a message buffer
\r
224 (that is, it will hold discrete messages with a little meta data that
\r
225 says how big the next message is) check the buffer will be large enough
\r
226 to hold at least one message. */
\r
227 if( xIsMessageBuffer == pdTRUE )
\r
229 configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
\r
233 configASSERT( xBufferSizeBytes > 0 );
\r
235 configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );
\r
237 /* A trigger level of 0 would cause a waiting task to unblock even when
\r
238 the buffer was empty. */
\r
239 if( xTriggerLevelBytes == ( size_t ) 0 )
\r
241 xTriggerLevelBytes = ( size_t ) 1;
\r
244 /* A stream buffer requires a StreamBuffer_t structure and a buffer.
\r
245 Both are allocated in a single call to pvPortMalloc(). The
\r
246 StreamBuffer_t structure is placed at the start of the allocated memory
\r
247 and the buffer follows immediately after. The requested size is
\r
248 incremented so the free space is returned as the user would expect -
\r
249 this is a quirk of the implementation that means otherwise the free
\r
250 space would be reported as one byte smaller than would be logically
\r
252 xBufferSizeBytes++;
\r
253 pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */
\r
255 if( pucAllocatedMemory != NULL )
\r
257 prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) pucAllocatedMemory, /* Structure at the start of the allocated memory. */ /*lint !e9087 Safe cast as allocated memory is aligned. */ /*lint !e826 Area is not too small and alignment is guaranteed provided malloc() behaves as expected and returns aligned buffer. */
\r
258 pucAllocatedMemory + sizeof( StreamBuffer_t ), /* Storage area follows. */ /*lint !e9016 Indexing past structure valid for uint8_t pointer, also storage area has no alignment requirement. */
\r
260 xTriggerLevelBytes,
\r
261 xIsMessageBuffer );
\r
263 traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pucAllocatedMemory ), xIsMessageBuffer );
\r
267 traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer );
\r
270 return ( StreamBufferHandle_t ) pucAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */
\r
273 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
\r
274 /*-----------------------------------------------------------*/
\r
276 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
278 StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
\r
279 size_t xTriggerLevelBytes,
\r
280 BaseType_t xIsMessageBuffer,
\r
281 uint8_t * const pucStreamBufferStorageArea,
\r
282 StaticStreamBuffer_t * const pxStaticStreamBuffer )
\r
284 StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */
\r
285 StreamBufferHandle_t xReturn;
\r
287 configASSERT( pucStreamBufferStorageArea );
\r
288 configASSERT( pxStaticStreamBuffer );
\r
289 configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );
\r
291 /* A trigger level of 0 would cause a waiting task to unblock even when
\r
292 the buffer was empty. */
\r
293 if( xTriggerLevelBytes == ( size_t ) 0 )
\r
295 xTriggerLevelBytes = ( size_t ) 1;
\r
298 /* In case the stream buffer is going to be used as a message buffer
\r
299 (that is, it will hold discrete messages with a little meta data that
\r
300 says how big the next message is) check the buffer will be large enough
\r
301 to hold at least one message. */
\r
302 configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
\r
304 #if( configASSERT_DEFINED == 1 )
\r
306 /* Sanity check that the size of the structure used to declare a
\r
307 variable of type StaticStreamBuffer_t equals the size of the real
\r
308 message buffer structure. */
\r
309 volatile size_t xSize = sizeof( StaticStreamBuffer_t );
\r
310 configASSERT( xSize == sizeof( StreamBuffer_t ) );
\r
311 } /*lint !e529 xSize is referenced is configASSERT() is defined. */
\r
312 #endif /* configASSERT_DEFINED */
\r
314 if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) )
\r
316 prvInitialiseNewStreamBuffer( pxStreamBuffer,
\r
317 pucStreamBufferStorageArea,
\r
319 xTriggerLevelBytes,
\r
320 xIsMessageBuffer );
\r
322 /* Remember this was statically allocated in case it is ever deleted
\r
324 pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED;
\r
326 traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer );
\r
328 xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */
\r
333 traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer );
\r
339 #endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
\r
340 /*-----------------------------------------------------------*/
\r
342 void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer )
\r
344 StreamBuffer_t * pxStreamBuffer = xStreamBuffer;
\r
346 configASSERT( pxStreamBuffer );
\r
348 traceSTREAM_BUFFER_DELETE( xStreamBuffer );
\r
350 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) pdFALSE )
\r
352 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
\r
354 /* Both the structure and the buffer were allocated using a single call
\r
355 to pvPortMalloc(), hence only one call to vPortFree() is required. */
\r
356 vPortFree( ( void * ) pxStreamBuffer ); /*lint !e9087 Standard free() semantics require void *, plus pxStreamBuffer was allocated by pvPortMalloc(). */
\r
360 /* Should not be possible to get here, ucFlags must be corrupt.
\r
361 Force an assert. */
\r
362 configASSERT( xStreamBuffer == ( StreamBufferHandle_t ) ~0 );
\r
368 /* The structure and buffer were not allocated dynamically and cannot be
\r
369 freed - just scrub the structure so future use will assert. */
\r
370 memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) );
\r
373 /*-----------------------------------------------------------*/
\r
375 BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer )
\r
377 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
378 BaseType_t xReturn = pdFAIL, xIsMessageBuffer;
\r
380 #if( configUSE_TRACE_FACILITY == 1 )
\r
381 UBaseType_t uxStreamBufferNumber;
\r
384 configASSERT( pxStreamBuffer );
\r
386 #if( configUSE_TRACE_FACILITY == 1 )
\r
388 /* Store the stream buffer number so it can be restored after the
\r
390 uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber;
\r
394 /* Can only reset a message buffer if there are no tasks blocked on it. */
\r
395 taskENTER_CRITICAL();
\r
397 if( pxStreamBuffer->xTaskWaitingToReceive == NULL )
\r
399 if( pxStreamBuffer->xTaskWaitingToSend == NULL )
\r
401 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
403 xIsMessageBuffer = pdTRUE;
\r
407 xIsMessageBuffer = pdFALSE;
\r
410 prvInitialiseNewStreamBuffer( pxStreamBuffer,
\r
411 pxStreamBuffer->pucBuffer,
\r
412 pxStreamBuffer->xLength,
\r
413 pxStreamBuffer->xTriggerLevelBytes,
\r
414 xIsMessageBuffer );
\r
417 #if( configUSE_TRACE_FACILITY == 1 )
\r
419 pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
\r
423 traceSTREAM_BUFFER_RESET( xStreamBuffer );
\r
427 taskEXIT_CRITICAL();
\r
431 /*-----------------------------------------------------------*/
\r
433 BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel )
\r
435 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
436 BaseType_t xReturn;
\r
438 configASSERT( pxStreamBuffer );
\r
440 /* It is not valid for the trigger level to be 0. */
\r
441 if( xTriggerLevel == ( size_t ) 0 )
\r
443 xTriggerLevel = ( size_t ) 1;
\r
446 /* The trigger level is the number of bytes that must be in the stream
\r
447 buffer before a task that is waiting for data is unblocked. */
\r
448 if( xTriggerLevel <= pxStreamBuffer->xLength )
\r
450 pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel;
\r
460 /*-----------------------------------------------------------*/
\r
462 size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer )
\r
464 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
467 configASSERT( pxStreamBuffer );
\r
469 xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail;
\r
470 xSpace -= pxStreamBuffer->xHead;
\r
471 xSpace -= ( size_t ) 1;
\r
473 if( xSpace >= pxStreamBuffer->xLength )
\r
475 xSpace -= pxStreamBuffer->xLength;
\r
479 mtCOVERAGE_TEST_MARKER();
\r
484 /*-----------------------------------------------------------*/
\r
486 size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer )
\r
488 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
491 configASSERT( pxStreamBuffer );
\r
493 xReturn = prvBytesInBuffer( pxStreamBuffer );
\r
496 /*-----------------------------------------------------------*/
\r
498 size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
\r
499 const void *pvTxData,
\r
500 size_t xDataLengthBytes,
\r
501 TickType_t xTicksToWait )
\r
503 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
504 size_t xReturn, xSpace = 0;
\r
505 size_t xRequiredSpace = xDataLengthBytes;
\r
506 TimeOut_t xTimeOut;
\r
508 configASSERT( pvTxData );
\r
509 configASSERT( pxStreamBuffer );
\r
511 /* This send function is used to write to both message buffers and stream
\r
512 buffers. If this is a message buffer then the space needed must be
\r
513 increased by the amount of bytes needed to store the length of the
\r
515 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
517 xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
520 configASSERT( xRequiredSpace > xDataLengthBytes );
\r
524 mtCOVERAGE_TEST_MARKER();
\r
527 if( xTicksToWait != ( TickType_t ) 0 )
\r
529 vTaskSetTimeOutState( &xTimeOut );
\r
533 /* Wait until the required number of bytes are free in the message
\r
535 taskENTER_CRITICAL();
\r
537 xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
\r
539 if( xSpace < xRequiredSpace )
\r
541 /* Clear notification state as going to wait for space. */
\r
542 ( void ) xTaskNotifyStateClear( NULL );
\r
544 /* Should only be one writer. */
\r
545 configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL );
\r
546 pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle();
\r
550 taskEXIT_CRITICAL();
\r
554 taskEXIT_CRITICAL();
\r
556 traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer );
\r
557 ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
\r
558 pxStreamBuffer->xTaskWaitingToSend = NULL;
\r
560 } while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE );
\r
564 mtCOVERAGE_TEST_MARKER();
\r
567 if( xSpace == ( size_t ) 0 )
\r
569 xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
\r
573 mtCOVERAGE_TEST_MARKER();
\r
576 xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );
\r
578 if( xReturn > ( size_t ) 0 )
\r
580 traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn );
\r
582 /* Was a task waiting for the data? */
\r
583 if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
\r
585 sbSEND_COMPLETED( pxStreamBuffer );
\r
589 mtCOVERAGE_TEST_MARKER();
\r
594 mtCOVERAGE_TEST_MARKER();
\r
595 traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer );
\r
600 /*-----------------------------------------------------------*/
\r
602 size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
\r
603 const void *pvTxData,
\r
604 size_t xDataLengthBytes,
\r
605 BaseType_t * const pxHigherPriorityTaskWoken )
\r
607 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
608 size_t xReturn, xSpace;
\r
609 size_t xRequiredSpace = xDataLengthBytes;
\r
611 configASSERT( pvTxData );
\r
612 configASSERT( pxStreamBuffer );
\r
614 /* This send function is used to write to both message buffers and stream
\r
615 buffers. If this is a message buffer then the space needed must be
\r
616 increased by the amount of bytes needed to store the length of the
\r
618 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
620 xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
624 mtCOVERAGE_TEST_MARKER();
\r
627 xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
\r
628 xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );
\r
630 if( xReturn > ( size_t ) 0 )
\r
632 /* Was a task waiting for the data? */
\r
633 if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
\r
635 sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
\r
639 mtCOVERAGE_TEST_MARKER();
\r
644 mtCOVERAGE_TEST_MARKER();
\r
647 traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn );
\r
651 /*-----------------------------------------------------------*/
\r
653 static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
\r
654 const void * pvTxData,
\r
655 size_t xDataLengthBytes,
\r
657 size_t xRequiredSpace )
\r
659 BaseType_t xShouldWrite;
\r
662 if( xSpace == ( size_t ) 0 )
\r
664 /* Doesn't matter if this is a stream buffer or a message buffer, there
\r
665 is no space to write. */
\r
666 xShouldWrite = pdFALSE;
\r
668 else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) == ( uint8_t ) 0 )
\r
670 /* This is a stream buffer, as opposed to a message buffer, so writing a
\r
671 stream of bytes rather than discrete messages. Write as many bytes as
\r
673 xShouldWrite = pdTRUE;
\r
674 xDataLengthBytes = configMIN( xDataLengthBytes, xSpace );
\r
676 else if( xSpace >= xRequiredSpace )
\r
678 /* This is a message buffer, as opposed to a stream buffer, and there
\r
679 is enough space to write both the message length and the message itself
\r
680 into the buffer. Start by writing the length of the data, the data
\r
681 itself will be written later in this function. */
\r
682 xShouldWrite = pdTRUE;
\r
683 ( void ) prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xDataLengthBytes ), sbBYTES_TO_STORE_MESSAGE_LENGTH );
\r
687 /* There is space available, but not enough space. */
\r
688 xShouldWrite = pdFALSE;
\r
691 if( xShouldWrite != pdFALSE )
\r
693 /* Writes the data itself. */
\r
694 xReturn = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alighment and access. */
\r
703 /*-----------------------------------------------------------*/
\r
705 size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
\r
707 size_t xBufferLengthBytes,
\r
708 TickType_t xTicksToWait )
\r
710 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
711 size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
\r
713 configASSERT( pvRxData );
\r
714 configASSERT( pxStreamBuffer );
\r
716 /* This receive function is used by both message buffers, which store
\r
717 discrete messages, and stream buffers, which store a continuous stream of
\r
718 bytes. Discrete messages include an additional
\r
719 sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the
\r
721 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
723 xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
727 xBytesToStoreMessageLength = 0;
\r
730 if( xTicksToWait != ( TickType_t ) 0 )
\r
732 /* Checking if there is data and clearing the notification state must be
\r
733 performed atomically. */
\r
734 taskENTER_CRITICAL();
\r
736 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
738 /* If this function was invoked by a message buffer read then
\r
739 xBytesToStoreMessageLength holds the number of bytes used to hold
\r
740 the length of the next discrete message. If this function was
\r
741 invoked by a stream buffer read then xBytesToStoreMessageLength will
\r
743 if( xBytesAvailable <= xBytesToStoreMessageLength )
\r
745 /* Clear notification state as going to wait for data. */
\r
746 ( void ) xTaskNotifyStateClear( NULL );
\r
748 /* Should only be one reader. */
\r
749 configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL );
\r
750 pxStreamBuffer->xTaskWaitingToReceive = xTaskGetCurrentTaskHandle();
\r
754 mtCOVERAGE_TEST_MARKER();
\r
757 taskEXIT_CRITICAL();
\r
759 if( xBytesAvailable <= xBytesToStoreMessageLength )
\r
761 /* Wait for data to be available. */
\r
762 traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer );
\r
763 ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
\r
764 pxStreamBuffer->xTaskWaitingToReceive = NULL;
\r
766 /* Recheck the data available after blocking. */
\r
767 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
771 mtCOVERAGE_TEST_MARKER();
\r
776 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
779 /* Whether receiving a discrete message (where xBytesToStoreMessageLength
\r
780 holds the number of bytes used to store the message length) or a stream of
\r
781 bytes (where xBytesToStoreMessageLength is zero), the number of bytes
\r
782 available must be greater than xBytesToStoreMessageLength to be able to
\r
783 read bytes from the buffer. */
\r
784 if( xBytesAvailable > xBytesToStoreMessageLength )
\r
786 xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
\r
788 /* Was a task waiting for space in the buffer? */
\r
789 if( xReceivedLength != ( size_t ) 0 )
\r
791 traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength );
\r
792 sbRECEIVE_COMPLETED( pxStreamBuffer );
\r
796 mtCOVERAGE_TEST_MARKER();
\r
801 traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer );
\r
802 mtCOVERAGE_TEST_MARKER();
\r
805 return xReceivedLength;
\r
807 /*-----------------------------------------------------------*/
\r
809 size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer )
\r
811 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
812 size_t xReturn, xBytesAvailable, xOriginalTail;
\r
813 configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn;
\r
815 configASSERT( pxStreamBuffer );
\r
817 /* Ensure the stream buffer is being used as a message buffer. */
\r
818 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
820 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
821 if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH )
\r
823 /* The number of bytes available is greater than the number of bytes
\r
824 required to hold the length of the next message, so another message
\r
825 is available. Return its length without removing the length bytes
\r
826 from the buffer. A copy of the tail is stored so the buffer can be
\r
827 returned to its prior state as the message is not actually being
\r
828 removed from the buffer. */
\r
829 xOriginalTail = pxStreamBuffer->xTail;
\r
830 ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, xBytesAvailable );
\r
831 xReturn = ( size_t ) xTempReturn;
\r
832 pxStreamBuffer->xTail = xOriginalTail;
\r
836 /* The minimum amount of bytes in a message buffer is
\r
837 ( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is
\r
838 less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid
\r
840 configASSERT( xBytesAvailable == 0 );
\r
851 /*-----------------------------------------------------------*/
\r
853 size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
\r
855 size_t xBufferLengthBytes,
\r
856 BaseType_t * const pxHigherPriorityTaskWoken )
\r
858 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
859 size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
\r
861 configASSERT( pvRxData );
\r
862 configASSERT( pxStreamBuffer );
\r
864 /* This receive function is used by both message buffers, which store
\r
865 discrete messages, and stream buffers, which store a continuous stream of
\r
866 bytes. Discrete messages include an additional
\r
867 sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the
\r
869 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
871 xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
875 xBytesToStoreMessageLength = 0;
\r
878 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
880 /* Whether receiving a discrete message (where xBytesToStoreMessageLength
\r
881 holds the number of bytes used to store the message length) or a stream of
\r
882 bytes (where xBytesToStoreMessageLength is zero), the number of bytes
\r
883 available must be greater than xBytesToStoreMessageLength to be able to
\r
884 read bytes from the buffer. */
\r
885 if( xBytesAvailable > xBytesToStoreMessageLength )
\r
887 xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
\r
889 /* Was a task waiting for space in the buffer? */
\r
890 if( xReceivedLength != ( size_t ) 0 )
\r
892 sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
\r
896 mtCOVERAGE_TEST_MARKER();
\r
901 mtCOVERAGE_TEST_MARKER();
\r
904 traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength );
\r
906 return xReceivedLength;
\r
908 /*-----------------------------------------------------------*/
\r
910 static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer,
\r
912 size_t xBufferLengthBytes,
\r
913 size_t xBytesAvailable,
\r
914 size_t xBytesToStoreMessageLength )
\r
916 size_t xOriginalTail, xReceivedLength, xNextMessageLength;
\r
917 configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength;
\r
919 if( xBytesToStoreMessageLength != ( size_t ) 0 )
\r
921 /* A discrete message is being received. First receive the length
\r
922 of the message. A copy of the tail is stored so the buffer can be
\r
923 returned to its prior state if the length of the message is too
\r
924 large for the provided buffer. */
\r
925 xOriginalTail = pxStreamBuffer->xTail;
\r
926 ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable );
\r
927 xNextMessageLength = ( size_t ) xTempNextMessageLength;
\r
929 /* Reduce the number of bytes available by the number of bytes just
\r
931 xBytesAvailable -= xBytesToStoreMessageLength;
\r
933 /* Check there is enough space in the buffer provided by the
\r
935 if( xNextMessageLength > xBufferLengthBytes )
\r
937 /* The user has provided insufficient space to read the message
\r
938 so return the buffer to its previous state (so the length of
\r
939 the message is in the buffer again). */
\r
940 pxStreamBuffer->xTail = xOriginalTail;
\r
941 xNextMessageLength = 0;
\r
945 mtCOVERAGE_TEST_MARKER();
\r
950 /* A stream of bytes is being received (as opposed to a discrete
\r
951 message), so read as many bytes as possible. */
\r
952 xNextMessageLength = xBufferLengthBytes;
\r
955 /* Read the actual data. */
\r
956 xReceivedLength = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xNextMessageLength, xBytesAvailable ); /*lint !e9079 Data storage area is implemented as uint8_t array for ease of sizing, indexing and alignment. */
\r
958 return xReceivedLength;
\r
960 /*-----------------------------------------------------------*/
\r
962 BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer )
\r
964 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
965 BaseType_t xReturn;
\r
968 configASSERT( pxStreamBuffer );
\r
970 /* True if no bytes are available. */
\r
971 xTail = pxStreamBuffer->xTail;
\r
972 if( pxStreamBuffer->xHead == xTail )
\r
983 /*-----------------------------------------------------------*/
\r
985 BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer )
\r
987 BaseType_t xReturn;
\r
988 size_t xBytesToStoreMessageLength;
\r
989 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
991 configASSERT( pxStreamBuffer );
\r
993 /* This generic version of the receive function is used by both message
\r
994 buffers, which store discrete messages, and stream buffers, which store a
\r
995 continuous stream of bytes. Discrete messages include an additional
\r
996 sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the message. */
\r
997 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
999 xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
1003 xBytesToStoreMessageLength = 0;
\r
1006 /* True if the available space equals zero. */
\r
1007 if( xStreamBufferSpacesAvailable( xStreamBuffer ) <= xBytesToStoreMessageLength )
\r
1013 xReturn = pdFALSE;
\r
1018 /*-----------------------------------------------------------*/
\r
1020 BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken )
\r
1022 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
1023 BaseType_t xReturn;
\r
1024 UBaseType_t uxSavedInterruptStatus;
\r
1026 configASSERT( pxStreamBuffer );
\r
1028 uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();
\r
1030 if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )
\r
1032 ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive,
\r
1035 pxHigherPriorityTaskWoken );
\r
1036 ( pxStreamBuffer )->xTaskWaitingToReceive = NULL;
\r
1041 xReturn = pdFALSE;
\r
1044 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
\r
1048 /*-----------------------------------------------------------*/
\r
1050 BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken )
\r
1052 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
1053 BaseType_t xReturn;
\r
1054 UBaseType_t uxSavedInterruptStatus;
\r
1056 configASSERT( pxStreamBuffer );
\r
1058 uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();
\r
1060 if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )
\r
1062 ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend,
\r
1065 pxHigherPriorityTaskWoken );
\r
1066 ( pxStreamBuffer )->xTaskWaitingToSend = NULL;
\r
1071 xReturn = pdFALSE;
\r
1074 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
\r
1078 /*-----------------------------------------------------------*/
\r
1080 static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount )
\r
1082 size_t xNextHead, xFirstLength;
\r
1084 configASSERT( xCount > ( size_t ) 0 );
\r
1086 xNextHead = pxStreamBuffer->xHead;
\r
1088 /* Calculate the number of bytes that can be added in the first write -
\r
1089 which may be less than the total number of bytes that need to be added if
\r
1090 the buffer will wrap back to the beginning. */
\r
1091 xFirstLength = configMIN( pxStreamBuffer->xLength - xNextHead, xCount );
\r
1093 /* Write as many bytes as can be written in the first write. */
\r
1094 configASSERT( ( xNextHead + xFirstLength ) <= pxStreamBuffer->xLength );
\r
1095 memcpy( ( void* ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1097 /* If the number of bytes written was less than the number that could be
\r
1098 written in the first write... */
\r
1099 if( xCount > xFirstLength )
\r
1101 /* ...then write the remaining bytes to the start of the buffer. */
\r
1102 configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength );
\r
1103 memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1107 mtCOVERAGE_TEST_MARKER();
\r
1110 xNextHead += xCount;
\r
1111 if( xNextHead >= pxStreamBuffer->xLength )
\r
1113 xNextHead -= pxStreamBuffer->xLength;
\r
1117 mtCOVERAGE_TEST_MARKER();
\r
1120 pxStreamBuffer->xHead = xNextHead;
\r
1124 /*-----------------------------------------------------------*/
\r
1126 static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, uint8_t *pucData, size_t xMaxCount, size_t xBytesAvailable )
\r
1128 size_t xCount, xFirstLength, xNextTail;
\r
1130 /* Use the minimum of the wanted bytes and the available bytes. */
\r
1131 xCount = configMIN( xBytesAvailable, xMaxCount );
\r
1133 if( xCount > ( size_t ) 0 )
\r
1135 xNextTail = pxStreamBuffer->xTail;
\r
1137 /* Calculate the number of bytes that can be read - which may be
\r
1138 less than the number wanted if the data wraps around to the start of
\r
1140 xFirstLength = configMIN( pxStreamBuffer->xLength - xNextTail, xCount );
\r
1142 /* Obtain the number of bytes it is possible to obtain in the first
\r
1143 read. Asserts check bounds of read and write. */
\r
1144 configASSERT( xFirstLength <= xMaxCount );
\r
1145 configASSERT( ( xNextTail + xFirstLength ) <= pxStreamBuffer->xLength );
\r
1146 memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1148 /* If the total number of wanted bytes is greater than the number
\r
1149 that could be read in the first read... */
\r
1150 if( xCount > xFirstLength )
\r
1152 /*...then read the remaining bytes from the start of the buffer. */
\r
1153 configASSERT( xCount <= xMaxCount );
\r
1154 memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1158 mtCOVERAGE_TEST_MARKER();
\r
1161 /* Move the tail pointer to effectively remove the data read from
\r
1163 xNextTail += xCount;
\r
1165 if( xNextTail >= pxStreamBuffer->xLength )
\r
1167 xNextTail -= pxStreamBuffer->xLength;
\r
1170 pxStreamBuffer->xTail = xNextTail;
\r
1174 mtCOVERAGE_TEST_MARKER();
\r
1179 /*-----------------------------------------------------------*/
\r
1181 static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer )
\r
1183 /* Returns the distance between xTail and xHead. */
\r
1186 xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead;
\r
1187 xCount -= pxStreamBuffer->xTail;
\r
1188 if ( xCount >= pxStreamBuffer->xLength )
\r
1190 xCount -= pxStreamBuffer->xLength;
\r
1194 mtCOVERAGE_TEST_MARKER();
\r
1199 /*-----------------------------------------------------------*/
\r
1201 static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
\r
1202 uint8_t * const pucBuffer,
\r
1203 size_t xBufferSizeBytes,
\r
1204 size_t xTriggerLevelBytes,
\r
1205 BaseType_t xIsMessageBuffer )
\r
1207 /* Assert here is deliberately writing to the entire buffer to ensure it can
\r
1208 be written to without generating exceptions, and is setting the buffer to a
\r
1209 known value to assist in development/debugging. */
\r
1210 #if( configASSERT_DEFINED == 1 )
\r
1212 /* The value written just has to be identifiable when looking at the
\r
1213 memory. Don't use 0xA5 as that is the stack fill value and could
\r
1214 result in confusion as to what is actually being observed. */
\r
1215 const BaseType_t xWriteValue = 0x55;
\r
1216 configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer );
\r
1217 } /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */
\r
1220 memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */
\r
1221 pxStreamBuffer->pucBuffer = pucBuffer;
\r
1222 pxStreamBuffer->xLength = xBufferSizeBytes;
\r
1223 pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes;
\r
1225 if( xIsMessageBuffer != pdFALSE )
\r
1227 pxStreamBuffer->ucFlags |= sbFLAGS_IS_MESSAGE_BUFFER;
\r
1231 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1233 UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer )
\r
1235 return xStreamBuffer->uxStreamBufferNumber;
\r
1238 #endif /* configUSE_TRACE_FACILITY */
\r
1239 /*-----------------------------------------------------------*/
\r
1241 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1243 void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber )
\r
1245 xStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
\r
1248 #endif /* configUSE_TRACE_FACILITY */
\r
1249 /*-----------------------------------------------------------*/
\r
1251 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1253 uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer )
\r
1255 return ( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER );
\r
1258 #endif /* configUSE_TRACE_FACILITY */
\r
1259 /*-----------------------------------------------------------*/
\r