2 * FreeRTOS Kernel V10.2.1
\r
3 * Copyright (C) 2019 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 uint8_t ucFlags ) 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
224 /* In case the stream buffer is going to be used as a message buffer
\r
225 (that is, it will hold discrete messages with a little meta data that
\r
226 says how big the next message is) check the buffer will be large enough
\r
227 to hold at least one message. */
\r
228 if( xIsMessageBuffer == pdTRUE )
\r
230 /* Is a message buffer but not statically allocated. */
\r
231 ucFlags = sbFLAGS_IS_MESSAGE_BUFFER;
\r
232 configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
\r
236 /* Not a message buffer and not statically allocated. */
\r
238 configASSERT( xBufferSizeBytes > 0 );
\r
240 configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );
\r
242 /* A trigger level of 0 would cause a waiting task to unblock even when
\r
243 the buffer was empty. */
\r
244 if( xTriggerLevelBytes == ( size_t ) 0 )
\r
246 xTriggerLevelBytes = ( size_t ) 1;
\r
249 /* A stream buffer requires a StreamBuffer_t structure and a buffer.
\r
250 Both are allocated in a single call to pvPortMalloc(). The
\r
251 StreamBuffer_t structure is placed at the start of the allocated memory
\r
252 and the buffer follows immediately after. The requested size is
\r
253 incremented so the free space is returned as the user would expect -
\r
254 this is a quirk of the implementation that means otherwise the free
\r
255 space would be reported as one byte smaller than would be logically
\r
257 xBufferSizeBytes++;
\r
258 pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */
\r
260 if( pucAllocatedMemory != NULL )
\r
262 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
263 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
265 xTriggerLevelBytes,
\r
268 traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pucAllocatedMemory ), xIsMessageBuffer );
\r
272 traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer );
\r
275 return ( StreamBufferHandle_t ) pucAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */
\r
278 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
\r
279 /*-----------------------------------------------------------*/
\r
281 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
283 StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
\r
284 size_t xTriggerLevelBytes,
\r
285 BaseType_t xIsMessageBuffer,
\r
286 uint8_t * const pucStreamBufferStorageArea,
\r
287 StaticStreamBuffer_t * const pxStaticStreamBuffer )
\r
289 StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */
\r
290 StreamBufferHandle_t xReturn;
\r
293 configASSERT( pucStreamBufferStorageArea );
\r
294 configASSERT( pxStaticStreamBuffer );
\r
295 configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );
\r
297 /* A trigger level of 0 would cause a waiting task to unblock even when
\r
298 the buffer was empty. */
\r
299 if( xTriggerLevelBytes == ( size_t ) 0 )
\r
301 xTriggerLevelBytes = ( size_t ) 1;
\r
304 if( xIsMessageBuffer != pdFALSE )
\r
306 /* Statically allocated message buffer. */
\r
307 ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED;
\r
311 /* Statically allocated stream buffer. */
\r
312 ucFlags = sbFLAGS_IS_STATICALLY_ALLOCATED;
\r
315 /* In case the stream buffer is going to be used as a message buffer
\r
316 (that is, it will hold discrete messages with a little meta data that
\r
317 says how big the next message is) check the buffer will be large enough
\r
318 to hold at least one message. */
\r
319 configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
\r
321 #if( configASSERT_DEFINED == 1 )
\r
323 /* Sanity check that the size of the structure used to declare a
\r
324 variable of type StaticStreamBuffer_t equals the size of the real
\r
325 message buffer structure. */
\r
326 volatile size_t xSize = sizeof( StaticStreamBuffer_t );
\r
327 configASSERT( xSize == sizeof( StreamBuffer_t ) );
\r
328 } /*lint !e529 xSize is referenced is configASSERT() is defined. */
\r
329 #endif /* configASSERT_DEFINED */
\r
331 if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) )
\r
333 prvInitialiseNewStreamBuffer( pxStreamBuffer,
\r
334 pucStreamBufferStorageArea,
\r
336 xTriggerLevelBytes,
\r
339 /* Remember this was statically allocated in case it is ever deleted
\r
341 pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED;
\r
343 traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer );
\r
345 xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */
\r
350 traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer );
\r
356 #endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
\r
357 /*-----------------------------------------------------------*/
\r
359 void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer )
\r
361 StreamBuffer_t * pxStreamBuffer = xStreamBuffer;
\r
363 configASSERT( pxStreamBuffer );
\r
365 traceSTREAM_BUFFER_DELETE( xStreamBuffer );
\r
367 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) pdFALSE )
\r
369 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
\r
371 /* Both the structure and the buffer were allocated using a single call
\r
372 to pvPortMalloc(), hence only one call to vPortFree() is required. */
\r
373 vPortFree( ( void * ) pxStreamBuffer ); /*lint !e9087 Standard free() semantics require void *, plus pxStreamBuffer was allocated by pvPortMalloc(). */
\r
377 /* Should not be possible to get here, ucFlags must be corrupt.
\r
378 Force an assert. */
\r
379 configASSERT( xStreamBuffer == ( StreamBufferHandle_t ) ~0 );
\r
385 /* The structure and buffer were not allocated dynamically and cannot be
\r
386 freed - just scrub the structure so future use will assert. */
\r
387 ( void ) memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) );
\r
390 /*-----------------------------------------------------------*/
\r
392 BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer )
\r
394 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
395 BaseType_t xReturn = pdFAIL;
\r
397 #if( configUSE_TRACE_FACILITY == 1 )
\r
398 UBaseType_t uxStreamBufferNumber;
\r
401 configASSERT( pxStreamBuffer );
\r
403 #if( configUSE_TRACE_FACILITY == 1 )
\r
405 /* Store the stream buffer number so it can be restored after the
\r
407 uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber;
\r
411 /* Can only reset a message buffer if there are no tasks blocked on it. */
\r
412 taskENTER_CRITICAL();
\r
414 if( pxStreamBuffer->xTaskWaitingToReceive == NULL )
\r
416 if( pxStreamBuffer->xTaskWaitingToSend == NULL )
\r
418 prvInitialiseNewStreamBuffer( pxStreamBuffer,
\r
419 pxStreamBuffer->pucBuffer,
\r
420 pxStreamBuffer->xLength,
\r
421 pxStreamBuffer->xTriggerLevelBytes,
\r
422 pxStreamBuffer->ucFlags );
\r
425 #if( configUSE_TRACE_FACILITY == 1 )
\r
427 pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
\r
431 traceSTREAM_BUFFER_RESET( xStreamBuffer );
\r
435 taskEXIT_CRITICAL();
\r
439 /*-----------------------------------------------------------*/
\r
441 BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel )
\r
443 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
444 BaseType_t xReturn;
\r
446 configASSERT( pxStreamBuffer );
\r
448 /* It is not valid for the trigger level to be 0. */
\r
449 if( xTriggerLevel == ( size_t ) 0 )
\r
451 xTriggerLevel = ( size_t ) 1;
\r
454 /* The trigger level is the number of bytes that must be in the stream
\r
455 buffer before a task that is waiting for data is unblocked. */
\r
456 if( xTriggerLevel <= pxStreamBuffer->xLength )
\r
458 pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel;
\r
468 /*-----------------------------------------------------------*/
\r
470 size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer )
\r
472 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
475 configASSERT( pxStreamBuffer );
\r
477 xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail;
\r
478 xSpace -= pxStreamBuffer->xHead;
\r
479 xSpace -= ( size_t ) 1;
\r
481 if( xSpace >= pxStreamBuffer->xLength )
\r
483 xSpace -= pxStreamBuffer->xLength;
\r
487 mtCOVERAGE_TEST_MARKER();
\r
492 /*-----------------------------------------------------------*/
\r
494 size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer )
\r
496 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
499 configASSERT( pxStreamBuffer );
\r
501 xReturn = prvBytesInBuffer( pxStreamBuffer );
\r
504 /*-----------------------------------------------------------*/
\r
506 size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
\r
507 const void *pvTxData,
\r
508 size_t xDataLengthBytes,
\r
509 TickType_t xTicksToWait )
\r
511 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
512 size_t xReturn, xSpace = 0;
\r
513 size_t xRequiredSpace = xDataLengthBytes;
\r
514 TimeOut_t xTimeOut;
\r
516 configASSERT( pvTxData );
\r
517 configASSERT( pxStreamBuffer );
\r
519 /* This send function is used to write to both message buffers and stream
\r
520 buffers. If this is a message buffer then the space needed must be
\r
521 increased by the amount of bytes needed to store the length of the
\r
523 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
525 xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
528 configASSERT( xRequiredSpace > xDataLengthBytes );
\r
532 mtCOVERAGE_TEST_MARKER();
\r
535 if( xTicksToWait != ( TickType_t ) 0 )
\r
537 vTaskSetTimeOutState( &xTimeOut );
\r
541 /* Wait until the required number of bytes are free in the message
\r
543 taskENTER_CRITICAL();
\r
545 xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
\r
547 if( xSpace < xRequiredSpace )
\r
549 /* Clear notification state as going to wait for space. */
\r
550 ( void ) xTaskNotifyStateClear( NULL );
\r
552 /* Should only be one writer. */
\r
553 configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL );
\r
554 pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle();
\r
558 taskEXIT_CRITICAL();
\r
562 taskEXIT_CRITICAL();
\r
564 traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer );
\r
565 ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
\r
566 pxStreamBuffer->xTaskWaitingToSend = NULL;
\r
568 } while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE );
\r
572 mtCOVERAGE_TEST_MARKER();
\r
575 if( xSpace == ( size_t ) 0 )
\r
577 xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
\r
581 mtCOVERAGE_TEST_MARKER();
\r
584 xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );
\r
586 if( xReturn > ( size_t ) 0 )
\r
588 traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn );
\r
590 /* Was a task waiting for the data? */
\r
591 if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
\r
593 sbSEND_COMPLETED( pxStreamBuffer );
\r
597 mtCOVERAGE_TEST_MARKER();
\r
602 mtCOVERAGE_TEST_MARKER();
\r
603 traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer );
\r
608 /*-----------------------------------------------------------*/
\r
610 size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
\r
611 const void *pvTxData,
\r
612 size_t xDataLengthBytes,
\r
613 BaseType_t * const pxHigherPriorityTaskWoken )
\r
615 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
616 size_t xReturn, xSpace;
\r
617 size_t xRequiredSpace = xDataLengthBytes;
\r
619 configASSERT( pvTxData );
\r
620 configASSERT( pxStreamBuffer );
\r
622 /* This send function is used to write to both message buffers and stream
\r
623 buffers. If this is a message buffer then the space needed must be
\r
624 increased by the amount of bytes needed to store the length of the
\r
626 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
628 xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
632 mtCOVERAGE_TEST_MARKER();
\r
635 xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
\r
636 xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );
\r
638 if( xReturn > ( size_t ) 0 )
\r
640 /* Was a task waiting for the data? */
\r
641 if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
\r
643 sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
\r
647 mtCOVERAGE_TEST_MARKER();
\r
652 mtCOVERAGE_TEST_MARKER();
\r
655 traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn );
\r
659 /*-----------------------------------------------------------*/
\r
661 static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
\r
662 const void * pvTxData,
\r
663 size_t xDataLengthBytes,
\r
665 size_t xRequiredSpace )
\r
667 BaseType_t xShouldWrite;
\r
670 if( xSpace == ( size_t ) 0 )
\r
672 /* Doesn't matter if this is a stream buffer or a message buffer, there
\r
673 is no space to write. */
\r
674 xShouldWrite = pdFALSE;
\r
676 else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) == ( uint8_t ) 0 )
\r
678 /* This is a stream buffer, as opposed to a message buffer, so writing a
\r
679 stream of bytes rather than discrete messages. Write as many bytes as
\r
681 xShouldWrite = pdTRUE;
\r
682 xDataLengthBytes = configMIN( xDataLengthBytes, xSpace );
\r
684 else if( xSpace >= xRequiredSpace )
\r
686 /* This is a message buffer, as opposed to a stream buffer, and there
\r
687 is enough space to write both the message length and the message itself
\r
688 into the buffer. Start by writing the length of the data, the data
\r
689 itself will be written later in this function. */
\r
690 xShouldWrite = pdTRUE;
\r
691 ( void ) prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xDataLengthBytes ), sbBYTES_TO_STORE_MESSAGE_LENGTH );
\r
695 /* There is space available, but not enough space. */
\r
696 xShouldWrite = pdFALSE;
\r
699 if( xShouldWrite != pdFALSE )
\r
701 /* Writes the data itself. */
\r
702 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
711 /*-----------------------------------------------------------*/
\r
713 size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
\r
715 size_t xBufferLengthBytes,
\r
716 TickType_t xTicksToWait )
\r
718 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
719 size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
\r
721 configASSERT( pvRxData );
\r
722 configASSERT( pxStreamBuffer );
\r
724 /* This receive function is used by both message buffers, which store
\r
725 discrete messages, and stream buffers, which store a continuous stream of
\r
726 bytes. Discrete messages include an additional
\r
727 sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the
\r
729 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
731 xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
735 xBytesToStoreMessageLength = 0;
\r
738 if( xTicksToWait != ( TickType_t ) 0 )
\r
740 /* Checking if there is data and clearing the notification state must be
\r
741 performed atomically. */
\r
742 taskENTER_CRITICAL();
\r
744 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
746 /* If this function was invoked by a message buffer read then
\r
747 xBytesToStoreMessageLength holds the number of bytes used to hold
\r
748 the length of the next discrete message. If this function was
\r
749 invoked by a stream buffer read then xBytesToStoreMessageLength will
\r
751 if( xBytesAvailable <= xBytesToStoreMessageLength )
\r
753 /* Clear notification state as going to wait for data. */
\r
754 ( void ) xTaskNotifyStateClear( NULL );
\r
756 /* Should only be one reader. */
\r
757 configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL );
\r
758 pxStreamBuffer->xTaskWaitingToReceive = xTaskGetCurrentTaskHandle();
\r
762 mtCOVERAGE_TEST_MARKER();
\r
765 taskEXIT_CRITICAL();
\r
767 if( xBytesAvailable <= xBytesToStoreMessageLength )
\r
769 /* Wait for data to be available. */
\r
770 traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer );
\r
771 ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
\r
772 pxStreamBuffer->xTaskWaitingToReceive = NULL;
\r
774 /* Recheck the data available after blocking. */
\r
775 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
779 mtCOVERAGE_TEST_MARKER();
\r
784 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
787 /* Whether receiving a discrete message (where xBytesToStoreMessageLength
\r
788 holds the number of bytes used to store the message length) or a stream of
\r
789 bytes (where xBytesToStoreMessageLength is zero), the number of bytes
\r
790 available must be greater than xBytesToStoreMessageLength to be able to
\r
791 read bytes from the buffer. */
\r
792 if( xBytesAvailable > xBytesToStoreMessageLength )
\r
794 xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
\r
796 /* Was a task waiting for space in the buffer? */
\r
797 if( xReceivedLength != ( size_t ) 0 )
\r
799 traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength );
\r
800 sbRECEIVE_COMPLETED( pxStreamBuffer );
\r
804 mtCOVERAGE_TEST_MARKER();
\r
809 traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer );
\r
810 mtCOVERAGE_TEST_MARKER();
\r
813 return xReceivedLength;
\r
815 /*-----------------------------------------------------------*/
\r
817 size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer )
\r
819 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
820 size_t xReturn, xBytesAvailable, xOriginalTail;
\r
821 configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn;
\r
823 configASSERT( pxStreamBuffer );
\r
825 /* Ensure the stream buffer is being used as a message buffer. */
\r
826 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
828 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
829 if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH )
\r
831 /* The number of bytes available is greater than the number of bytes
\r
832 required to hold the length of the next message, so another message
\r
833 is available. Return its length without removing the length bytes
\r
834 from the buffer. A copy of the tail is stored so the buffer can be
\r
835 returned to its prior state as the message is not actually being
\r
836 removed from the buffer. */
\r
837 xOriginalTail = pxStreamBuffer->xTail;
\r
838 ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, xBytesAvailable );
\r
839 xReturn = ( size_t ) xTempReturn;
\r
840 pxStreamBuffer->xTail = xOriginalTail;
\r
844 /* The minimum amount of bytes in a message buffer is
\r
845 ( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is
\r
846 less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid
\r
848 configASSERT( xBytesAvailable == 0 );
\r
859 /*-----------------------------------------------------------*/
\r
861 size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
\r
863 size_t xBufferLengthBytes,
\r
864 BaseType_t * const pxHigherPriorityTaskWoken )
\r
866 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
867 size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
\r
869 configASSERT( pvRxData );
\r
870 configASSERT( pxStreamBuffer );
\r
872 /* This receive function is used by both message buffers, which store
\r
873 discrete messages, and stream buffers, which store a continuous stream of
\r
874 bytes. Discrete messages include an additional
\r
875 sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the
\r
877 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
879 xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
883 xBytesToStoreMessageLength = 0;
\r
886 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
888 /* Whether receiving a discrete message (where xBytesToStoreMessageLength
\r
889 holds the number of bytes used to store the message length) or a stream of
\r
890 bytes (where xBytesToStoreMessageLength is zero), the number of bytes
\r
891 available must be greater than xBytesToStoreMessageLength to be able to
\r
892 read bytes from the buffer. */
\r
893 if( xBytesAvailable > xBytesToStoreMessageLength )
\r
895 xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
\r
897 /* Was a task waiting for space in the buffer? */
\r
898 if( xReceivedLength != ( size_t ) 0 )
\r
900 sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
\r
904 mtCOVERAGE_TEST_MARKER();
\r
909 mtCOVERAGE_TEST_MARKER();
\r
912 traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength );
\r
914 return xReceivedLength;
\r
916 /*-----------------------------------------------------------*/
\r
918 static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer,
\r
920 size_t xBufferLengthBytes,
\r
921 size_t xBytesAvailable,
\r
922 size_t xBytesToStoreMessageLength )
\r
924 size_t xOriginalTail, xReceivedLength, xNextMessageLength;
\r
925 configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength;
\r
927 if( xBytesToStoreMessageLength != ( size_t ) 0 )
\r
929 /* A discrete message is being received. First receive the length
\r
930 of the message. A copy of the tail is stored so the buffer can be
\r
931 returned to its prior state if the length of the message is too
\r
932 large for the provided buffer. */
\r
933 xOriginalTail = pxStreamBuffer->xTail;
\r
934 ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable );
\r
935 xNextMessageLength = ( size_t ) xTempNextMessageLength;
\r
937 /* Reduce the number of bytes available by the number of bytes just
\r
939 xBytesAvailable -= xBytesToStoreMessageLength;
\r
941 /* Check there is enough space in the buffer provided by the
\r
943 if( xNextMessageLength > xBufferLengthBytes )
\r
945 /* The user has provided insufficient space to read the message
\r
946 so return the buffer to its previous state (so the length of
\r
947 the message is in the buffer again). */
\r
948 pxStreamBuffer->xTail = xOriginalTail;
\r
949 xNextMessageLength = 0;
\r
953 mtCOVERAGE_TEST_MARKER();
\r
958 /* A stream of bytes is being received (as opposed to a discrete
\r
959 message), so read as many bytes as possible. */
\r
960 xNextMessageLength = xBufferLengthBytes;
\r
963 /* Read the actual data. */
\r
964 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
966 return xReceivedLength;
\r
968 /*-----------------------------------------------------------*/
\r
970 BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer )
\r
972 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
973 BaseType_t xReturn;
\r
976 configASSERT( pxStreamBuffer );
\r
978 /* True if no bytes are available. */
\r
979 xTail = pxStreamBuffer->xTail;
\r
980 if( pxStreamBuffer->xHead == xTail )
\r
991 /*-----------------------------------------------------------*/
\r
993 BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer )
\r
995 BaseType_t xReturn;
\r
996 size_t xBytesToStoreMessageLength;
\r
997 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
999 configASSERT( pxStreamBuffer );
\r
1001 /* This generic version of the receive function is used by both message
\r
1002 buffers, which store discrete messages, and stream buffers, which store a
\r
1003 continuous stream of bytes. Discrete messages include an additional
\r
1004 sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the message. */
\r
1005 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
1007 xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
1011 xBytesToStoreMessageLength = 0;
\r
1014 /* True if the available space equals zero. */
\r
1015 if( xStreamBufferSpacesAvailable( xStreamBuffer ) <= xBytesToStoreMessageLength )
\r
1021 xReturn = pdFALSE;
\r
1026 /*-----------------------------------------------------------*/
\r
1028 BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken )
\r
1030 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
1031 BaseType_t xReturn;
\r
1032 UBaseType_t uxSavedInterruptStatus;
\r
1034 configASSERT( pxStreamBuffer );
\r
1036 uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();
\r
1038 if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )
\r
1040 ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive,
\r
1043 pxHigherPriorityTaskWoken );
\r
1044 ( pxStreamBuffer )->xTaskWaitingToReceive = NULL;
\r
1049 xReturn = pdFALSE;
\r
1052 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
\r
1056 /*-----------------------------------------------------------*/
\r
1058 BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken )
\r
1060 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
1061 BaseType_t xReturn;
\r
1062 UBaseType_t uxSavedInterruptStatus;
\r
1064 configASSERT( pxStreamBuffer );
\r
1066 uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();
\r
1068 if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )
\r
1070 ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend,
\r
1073 pxHigherPriorityTaskWoken );
\r
1074 ( pxStreamBuffer )->xTaskWaitingToSend = NULL;
\r
1079 xReturn = pdFALSE;
\r
1082 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
\r
1086 /*-----------------------------------------------------------*/
\r
1088 static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount )
\r
1090 size_t xNextHead, xFirstLength;
\r
1092 configASSERT( xCount > ( size_t ) 0 );
\r
1094 xNextHead = pxStreamBuffer->xHead;
\r
1096 /* Calculate the number of bytes that can be added in the first write -
\r
1097 which may be less than the total number of bytes that need to be added if
\r
1098 the buffer will wrap back to the beginning. */
\r
1099 xFirstLength = configMIN( pxStreamBuffer->xLength - xNextHead, xCount );
\r
1101 /* Write as many bytes as can be written in the first write. */
\r
1102 configASSERT( ( xNextHead + xFirstLength ) <= pxStreamBuffer->xLength );
\r
1103 ( void ) memcpy( ( void* ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1105 /* If the number of bytes written was less than the number that could be
\r
1106 written in the first write... */
\r
1107 if( xCount > xFirstLength )
\r
1109 /* ...then write the remaining bytes to the start of the buffer. */
\r
1110 configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength );
\r
1111 ( void ) memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1115 mtCOVERAGE_TEST_MARKER();
\r
1118 xNextHead += xCount;
\r
1119 if( xNextHead >= pxStreamBuffer->xLength )
\r
1121 xNextHead -= pxStreamBuffer->xLength;
\r
1125 mtCOVERAGE_TEST_MARKER();
\r
1128 pxStreamBuffer->xHead = xNextHead;
\r
1132 /*-----------------------------------------------------------*/
\r
1134 static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, uint8_t *pucData, size_t xMaxCount, size_t xBytesAvailable )
\r
1136 size_t xCount, xFirstLength, xNextTail;
\r
1138 /* Use the minimum of the wanted bytes and the available bytes. */
\r
1139 xCount = configMIN( xBytesAvailable, xMaxCount );
\r
1141 if( xCount > ( size_t ) 0 )
\r
1143 xNextTail = pxStreamBuffer->xTail;
\r
1145 /* Calculate the number of bytes that can be read - which may be
\r
1146 less than the number wanted if the data wraps around to the start of
\r
1148 xFirstLength = configMIN( pxStreamBuffer->xLength - xNextTail, xCount );
\r
1150 /* Obtain the number of bytes it is possible to obtain in the first
\r
1151 read. Asserts check bounds of read and write. */
\r
1152 configASSERT( xFirstLength <= xMaxCount );
\r
1153 configASSERT( ( xNextTail + xFirstLength ) <= pxStreamBuffer->xLength );
\r
1154 ( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1156 /* If the total number of wanted bytes is greater than the number
\r
1157 that could be read in the first read... */
\r
1158 if( xCount > xFirstLength )
\r
1160 /*...then read the remaining bytes from the start of the buffer. */
\r
1161 configASSERT( xCount <= xMaxCount );
\r
1162 ( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1166 mtCOVERAGE_TEST_MARKER();
\r
1169 /* Move the tail pointer to effectively remove the data read from
\r
1171 xNextTail += xCount;
\r
1173 if( xNextTail >= pxStreamBuffer->xLength )
\r
1175 xNextTail -= pxStreamBuffer->xLength;
\r
1178 pxStreamBuffer->xTail = xNextTail;
\r
1182 mtCOVERAGE_TEST_MARKER();
\r
1187 /*-----------------------------------------------------------*/
\r
1189 static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer )
\r
1191 /* Returns the distance between xTail and xHead. */
\r
1194 xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead;
\r
1195 xCount -= pxStreamBuffer->xTail;
\r
1196 if ( xCount >= pxStreamBuffer->xLength )
\r
1198 xCount -= pxStreamBuffer->xLength;
\r
1202 mtCOVERAGE_TEST_MARKER();
\r
1207 /*-----------------------------------------------------------*/
\r
1209 static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
\r
1210 uint8_t * const pucBuffer,
\r
1211 size_t xBufferSizeBytes,
\r
1212 size_t xTriggerLevelBytes,
\r
1215 /* Assert here is deliberately writing to the entire buffer to ensure it can
\r
1216 be written to without generating exceptions, and is setting the buffer to a
\r
1217 known value to assist in development/debugging. */
\r
1218 #if( configASSERT_DEFINED == 1 )
\r
1220 /* The value written just has to be identifiable when looking at the
\r
1221 memory. Don't use 0xA5 as that is the stack fill value and could
\r
1222 result in confusion as to what is actually being observed. */
\r
1223 const BaseType_t xWriteValue = 0x55;
\r
1224 configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer );
\r
1225 } /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */
\r
1228 ( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */
\r
1229 pxStreamBuffer->pucBuffer = pucBuffer;
\r
1230 pxStreamBuffer->xLength = xBufferSizeBytes;
\r
1231 pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes;
\r
1232 pxStreamBuffer->ucFlags = ucFlags;
\r
1235 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1237 UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer )
\r
1239 return xStreamBuffer->uxStreamBufferNumber;
\r
1242 #endif /* configUSE_TRACE_FACILITY */
\r
1243 /*-----------------------------------------------------------*/
\r
1245 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1247 void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber )
\r
1249 xStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
\r
1252 #endif /* configUSE_TRACE_FACILITY */
\r
1253 /*-----------------------------------------------------------*/
\r
1255 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1257 uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer )
\r
1259 return ( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER );
\r
1262 #endif /* configUSE_TRACE_FACILITY */
\r
1263 /*-----------------------------------------------------------*/
\r