2 * FreeRTOS Kernel V10.3.1
\r
3 * Copyright (C) 2020 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
27 /* Standard includes. */
\r
31 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
\r
32 all the API functions to use the MPU wrappers. That should only be done when
\r
33 task.h is included from an application file. */
\r
34 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
\r
36 /* FreeRTOS includes. */
\r
37 #include "FreeRTOS.h"
\r
39 #include "stream_buffer.h"
\r
41 #if( configUSE_TASK_NOTIFICATIONS != 1 )
\r
42 #error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c
\r
45 /* Lint e961, e9021 and e750 are suppressed as a MISRA exception justified
\r
46 because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
\r
47 for the header files above, but not in this file, in order to generate the
\r
48 correct privileged Vs unprivileged linkage and placement. */
\r
49 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */
\r
51 /* If the user has not provided application specific Rx notification macros,
\r
52 or #defined the notification macros away, them provide default implementations
\r
53 that uses task notifications. */
\r
54 /*lint -save -e9026 Function like macros allowed and needed here so they can be overidden. */
\r
55 #ifndef sbRECEIVE_COMPLETED
\r
56 #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \
\r
57 vTaskSuspendAll(); \
\r
59 if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \
\r
61 ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \
\r
64 ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \
\r
67 ( void ) xTaskResumeAll();
\r
68 #endif /* sbRECEIVE_COMPLETED */
\r
70 #ifndef sbRECEIVE_COMPLETED_FROM_ISR
\r
71 #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \
\r
72 pxHigherPriorityTaskWoken ) \
\r
74 UBaseType_t uxSavedInterruptStatus; \
\r
76 uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \
\r
78 if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \
\r
80 ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \
\r
83 pxHigherPriorityTaskWoken ); \
\r
84 ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \
\r
87 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
\r
89 #endif /* sbRECEIVE_COMPLETED_FROM_ISR */
\r
91 /* If the user has not provided an application specific Tx notification macro,
\r
92 or #defined the notification macro away, them provide a default implementation
\r
93 that uses task notifications. */
\r
94 #ifndef sbSEND_COMPLETED
\r
95 #define sbSEND_COMPLETED( pxStreamBuffer ) \
\r
96 vTaskSuspendAll(); \
\r
98 if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \
\r
100 ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive, \
\r
103 ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \
\r
106 ( void ) xTaskResumeAll();
\r
107 #endif /* sbSEND_COMPLETED */
\r
109 #ifndef sbSEND_COMPLETE_FROM_ISR
\r
110 #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
\r
112 UBaseType_t uxSavedInterruptStatus; \
\r
114 uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \
\r
116 if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \
\r
118 ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \
\r
121 pxHigherPriorityTaskWoken ); \
\r
122 ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \
\r
125 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
\r
127 #endif /* sbSEND_COMPLETE_FROM_ISR */
\r
128 /*lint -restore (9026) */
\r
130 /* The number of bytes used to hold the length of a message in the buffer. */
\r
131 #define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) )
\r
133 /* Bits stored in the ucFlags field of the stream buffer. */
\r
134 #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
135 #define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */
\r
137 /*-----------------------------------------------------------*/
\r
139 /* Structure that hold state information on the buffer. */
\r
140 typedef struct StreamBufferDef_t /*lint !e9058 Style convention uses tag. */
\r
142 volatile size_t xTail; /* Index to the next item to read within the buffer. */
\r
143 volatile size_t xHead; /* Index to the next item to write within the buffer. */
\r
144 size_t xLength; /* The length of the buffer pointed to by pucBuffer. */
\r
145 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
146 volatile TaskHandle_t xTaskWaitingToReceive; /* Holds the handle of a task waiting for data, or NULL if no tasks are waiting. */
\r
147 volatile TaskHandle_t xTaskWaitingToSend; /* Holds the handle of a task waiting to send data to a message buffer that is full. */
\r
148 uint8_t *pucBuffer; /* Points to the buffer itself - that is - the RAM that stores the data passed through the buffer. */
\r
151 #if ( configUSE_TRACE_FACILITY == 1 )
\r
152 UBaseType_t uxStreamBufferNumber; /* Used for tracing purposes. */
\r
157 * The number of bytes available to be read from the buffer.
\r
159 static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION;
\r
162 * Add xCount bytes from pucData into the pxStreamBuffer message buffer.
\r
163 * Returns the number of bytes written, which will either equal xCount in the
\r
164 * success case, or 0 if there was not enough space in the buffer (in which case
\r
165 * no data is written into the buffer).
\r
167 static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount ) PRIVILEGED_FUNCTION;
\r
170 * If the stream buffer is being used as a message buffer, then reads an entire
\r
171 * message out of the buffer. If the stream buffer is being used as a stream
\r
172 * buffer then read as many bytes as possible from the buffer.
\r
173 * prvReadBytesFromBuffer() is called to actually extract the bytes from the
\r
174 * buffer's data storage area.
\r
176 static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer,
\r
178 size_t xBufferLengthBytes,
\r
179 size_t xBytesAvailable,
\r
180 size_t xBytesToStoreMessageLength ) PRIVILEGED_FUNCTION;
\r
183 * If the stream buffer is being used as a message buffer, then writes an entire
\r
184 * message to the buffer. If the stream buffer is being used as a stream
\r
185 * buffer then write as many bytes as possible to the buffer.
\r
186 * prvWriteBytestoBuffer() is called to actually send the bytes to the buffer's
\r
187 * data storage area.
\r
189 static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
\r
190 const void * pvTxData,
\r
191 size_t xDataLengthBytes,
\r
193 size_t xRequiredSpace ) PRIVILEGED_FUNCTION;
\r
196 * Read xMaxCount bytes from the pxStreamBuffer message buffer and write them
\r
199 static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer,
\r
202 size_t xBytesAvailable ) PRIVILEGED_FUNCTION;
\r
205 * Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to
\r
206 * initialise the members of the newly created stream buffer structure.
\r
208 static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
\r
209 uint8_t * const pucBuffer,
\r
210 size_t xBufferSizeBytes,
\r
211 size_t xTriggerLevelBytes,
\r
212 uint8_t ucFlags ) PRIVILEGED_FUNCTION;
\r
214 /*-----------------------------------------------------------*/
\r
216 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
\r
218 StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer )
\r
220 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 /* Is a message buffer but not statically allocated. */
\r
230 ucFlags = sbFLAGS_IS_MESSAGE_BUFFER;
\r
231 configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
\r
235 /* Not a message buffer and not statically allocated. */
\r
237 configASSERT( xBufferSizeBytes > 0 );
\r
239 configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );
\r
241 /* A trigger level of 0 would cause a waiting task to unblock even when
\r
242 the buffer was empty. */
\r
243 if( xTriggerLevelBytes == ( size_t ) 0 )
\r
245 xTriggerLevelBytes = ( size_t ) 1;
\r
248 /* A stream buffer requires a StreamBuffer_t structure and a buffer.
\r
249 Both are allocated in a single call to pvPortMalloc(). The
\r
250 StreamBuffer_t structure is placed at the start of the allocated memory
\r
251 and the buffer follows immediately after. The requested size is
\r
252 incremented so the free space is returned as the user would expect -
\r
253 this is a quirk of the implementation that means otherwise the free
\r
254 space would be reported as one byte smaller than would be logically
\r
256 xBufferSizeBytes++;
\r
257 pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */
\r
259 if( pucAllocatedMemory != NULL )
\r
261 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
262 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
264 xTriggerLevelBytes,
\r
267 traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pucAllocatedMemory ), xIsMessageBuffer );
\r
271 traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer );
\r
274 return ( StreamBufferHandle_t ) pucAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */
\r
277 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
\r
278 /*-----------------------------------------------------------*/
\r
280 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
282 StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
\r
283 size_t xTriggerLevelBytes,
\r
284 BaseType_t xIsMessageBuffer,
\r
285 uint8_t * const pucStreamBufferStorageArea,
\r
286 StaticStreamBuffer_t * const pxStaticStreamBuffer )
\r
288 StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */
\r
289 StreamBufferHandle_t xReturn;
\r
292 configASSERT( pucStreamBufferStorageArea );
\r
293 configASSERT( pxStaticStreamBuffer );
\r
294 configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );
\r
296 /* A trigger level of 0 would cause a waiting task to unblock even when
\r
297 the buffer was empty. */
\r
298 if( xTriggerLevelBytes == ( size_t ) 0 )
\r
300 xTriggerLevelBytes = ( size_t ) 1;
\r
303 if( xIsMessageBuffer != pdFALSE )
\r
305 /* Statically allocated message buffer. */
\r
306 ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED;
\r
310 /* Statically allocated stream buffer. */
\r
311 ucFlags = sbFLAGS_IS_STATICALLY_ALLOCATED;
\r
314 /* In case the stream buffer is going to be used as a message buffer
\r
315 (that is, it will hold discrete messages with a little meta data that
\r
316 says how big the next message is) check the buffer will be large enough
\r
317 to hold at least one message. */
\r
318 configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
\r
320 #if( configASSERT_DEFINED == 1 )
\r
322 /* Sanity check that the size of the structure used to declare a
\r
323 variable of type StaticStreamBuffer_t equals the size of the real
\r
324 message buffer structure. */
\r
325 volatile size_t xSize = sizeof( StaticStreamBuffer_t );
\r
326 configASSERT( xSize == sizeof( StreamBuffer_t ) );
\r
327 } /*lint !e529 xSize is referenced is configASSERT() is defined. */
\r
328 #endif /* configASSERT_DEFINED */
\r
330 if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) )
\r
332 prvInitialiseNewStreamBuffer( pxStreamBuffer,
\r
333 pucStreamBufferStorageArea,
\r
335 xTriggerLevelBytes,
\r
338 /* Remember this was statically allocated in case it is ever deleted
\r
340 pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED;
\r
342 traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer );
\r
344 xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */
\r
349 traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer );
\r
355 #endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
\r
356 /*-----------------------------------------------------------*/
\r
358 void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer )
\r
360 StreamBuffer_t * pxStreamBuffer = xStreamBuffer;
\r
362 configASSERT( pxStreamBuffer );
\r
364 traceSTREAM_BUFFER_DELETE( xStreamBuffer );
\r
366 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) pdFALSE )
\r
368 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
\r
370 /* Both the structure and the buffer were allocated using a single call
\r
371 to pvPortMalloc(), hence only one call to vPortFree() is required. */
\r
372 vPortFree( ( void * ) pxStreamBuffer ); /*lint !e9087 Standard free() semantics require void *, plus pxStreamBuffer was allocated by pvPortMalloc(). */
\r
376 /* Should not be possible to get here, ucFlags must be corrupt.
\r
377 Force an assert. */
\r
378 configASSERT( xStreamBuffer == ( StreamBufferHandle_t ) ~0 );
\r
384 /* The structure and buffer were not allocated dynamically and cannot be
\r
385 freed - just scrub the structure so future use will assert. */
\r
386 ( void ) memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) );
\r
389 /*-----------------------------------------------------------*/
\r
391 BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer )
\r
393 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
394 BaseType_t xReturn = pdFAIL;
\r
396 #if( configUSE_TRACE_FACILITY == 1 )
\r
397 UBaseType_t uxStreamBufferNumber;
\r
400 configASSERT( pxStreamBuffer );
\r
402 #if( configUSE_TRACE_FACILITY == 1 )
\r
404 /* Store the stream buffer number so it can be restored after the
\r
406 uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber;
\r
410 /* Can only reset a message buffer if there are no tasks blocked on it. */
\r
411 taskENTER_CRITICAL();
\r
413 if( pxStreamBuffer->xTaskWaitingToReceive == NULL )
\r
415 if( pxStreamBuffer->xTaskWaitingToSend == NULL )
\r
417 prvInitialiseNewStreamBuffer( pxStreamBuffer,
\r
418 pxStreamBuffer->pucBuffer,
\r
419 pxStreamBuffer->xLength,
\r
420 pxStreamBuffer->xTriggerLevelBytes,
\r
421 pxStreamBuffer->ucFlags );
\r
424 #if( configUSE_TRACE_FACILITY == 1 )
\r
426 pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
\r
430 traceSTREAM_BUFFER_RESET( xStreamBuffer );
\r
434 taskEXIT_CRITICAL();
\r
438 /*-----------------------------------------------------------*/
\r
440 BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel )
\r
442 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
443 BaseType_t xReturn;
\r
445 configASSERT( pxStreamBuffer );
\r
447 /* It is not valid for the trigger level to be 0. */
\r
448 if( xTriggerLevel == ( size_t ) 0 )
\r
450 xTriggerLevel = ( size_t ) 1;
\r
453 /* The trigger level is the number of bytes that must be in the stream
\r
454 buffer before a task that is waiting for data is unblocked. */
\r
455 if( xTriggerLevel <= pxStreamBuffer->xLength )
\r
457 pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel;
\r
467 /*-----------------------------------------------------------*/
\r
469 size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer )
\r
471 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
474 configASSERT( pxStreamBuffer );
\r
476 xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail;
\r
477 xSpace -= pxStreamBuffer->xHead;
\r
478 xSpace -= ( size_t ) 1;
\r
480 if( xSpace >= pxStreamBuffer->xLength )
\r
482 xSpace -= pxStreamBuffer->xLength;
\r
486 mtCOVERAGE_TEST_MARKER();
\r
491 /*-----------------------------------------------------------*/
\r
493 size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer )
\r
495 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
498 configASSERT( pxStreamBuffer );
\r
500 xReturn = prvBytesInBuffer( pxStreamBuffer );
\r
503 /*-----------------------------------------------------------*/
\r
505 size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
\r
506 const void *pvTxData,
\r
507 size_t xDataLengthBytes,
\r
508 TickType_t xTicksToWait )
\r
510 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
511 size_t xReturn, xSpace = 0;
\r
512 size_t xRequiredSpace = xDataLengthBytes;
\r
513 TimeOut_t xTimeOut;
\r
515 configASSERT( pvTxData );
\r
516 configASSERT( pxStreamBuffer );
\r
518 /* This send function is used to write to both message buffers and stream
\r
519 buffers. If this is a message buffer then the space needed must be
\r
520 increased by the amount of bytes needed to store the length of the
\r
522 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
524 xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
527 configASSERT( xRequiredSpace > xDataLengthBytes );
\r
531 mtCOVERAGE_TEST_MARKER();
\r
534 if( xTicksToWait != ( TickType_t ) 0 )
\r
536 vTaskSetTimeOutState( &xTimeOut );
\r
540 /* Wait until the required number of bytes are free in the message
\r
542 taskENTER_CRITICAL();
\r
544 xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
\r
546 if( xSpace < xRequiredSpace )
\r
548 /* Clear notification state as going to wait for space. */
\r
549 ( void ) xTaskNotifyStateClear( NULL );
\r
551 /* Should only be one writer. */
\r
552 configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL );
\r
553 pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle();
\r
557 taskEXIT_CRITICAL();
\r
561 taskEXIT_CRITICAL();
\r
563 traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer );
\r
564 ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
\r
565 pxStreamBuffer->xTaskWaitingToSend = NULL;
\r
567 } while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE );
\r
571 mtCOVERAGE_TEST_MARKER();
\r
574 if( xSpace == ( size_t ) 0 )
\r
576 xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
\r
580 mtCOVERAGE_TEST_MARKER();
\r
583 xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );
\r
585 if( xReturn > ( size_t ) 0 )
\r
587 traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn );
\r
589 /* Was a task waiting for the data? */
\r
590 if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
\r
592 sbSEND_COMPLETED( pxStreamBuffer );
\r
596 mtCOVERAGE_TEST_MARKER();
\r
601 mtCOVERAGE_TEST_MARKER();
\r
602 traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer );
\r
607 /*-----------------------------------------------------------*/
\r
609 size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
\r
610 const void *pvTxData,
\r
611 size_t xDataLengthBytes,
\r
612 BaseType_t * const pxHigherPriorityTaskWoken )
\r
614 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
615 size_t xReturn, xSpace;
\r
616 size_t xRequiredSpace = xDataLengthBytes;
\r
618 configASSERT( pvTxData );
\r
619 configASSERT( pxStreamBuffer );
\r
621 /* This send function is used to write to both message buffers and stream
\r
622 buffers. If this is a message buffer then the space needed must be
\r
623 increased by the amount of bytes needed to store the length of the
\r
625 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
627 xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
631 mtCOVERAGE_TEST_MARKER();
\r
634 xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );
\r
635 xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );
\r
637 if( xReturn > ( size_t ) 0 )
\r
639 /* Was a task waiting for the data? */
\r
640 if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
\r
642 sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
\r
646 mtCOVERAGE_TEST_MARKER();
\r
651 mtCOVERAGE_TEST_MARKER();
\r
654 traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn );
\r
658 /*-----------------------------------------------------------*/
\r
660 static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
\r
661 const void * pvTxData,
\r
662 size_t xDataLengthBytes,
\r
664 size_t xRequiredSpace )
\r
666 BaseType_t xShouldWrite;
\r
669 if( xSpace == ( size_t ) 0 )
\r
671 /* Doesn't matter if this is a stream buffer or a message buffer, there
\r
672 is no space to write. */
\r
673 xShouldWrite = pdFALSE;
\r
675 else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) == ( uint8_t ) 0 )
\r
677 /* This is a stream buffer, as opposed to a message buffer, so writing a
\r
678 stream of bytes rather than discrete messages. Write as many bytes as
\r
680 xShouldWrite = pdTRUE;
\r
681 xDataLengthBytes = configMIN( xDataLengthBytes, xSpace );
\r
683 else if( xSpace >= xRequiredSpace )
\r
685 /* This is a message buffer, as opposed to a stream buffer, and there
\r
686 is enough space to write both the message length and the message itself
\r
687 into the buffer. Start by writing the length of the data, the data
\r
688 itself will be written later in this function. */
\r
689 xShouldWrite = pdTRUE;
\r
690 ( void ) prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xDataLengthBytes ), sbBYTES_TO_STORE_MESSAGE_LENGTH );
\r
694 /* There is space available, but not enough space. */
\r
695 xShouldWrite = pdFALSE;
\r
698 if( xShouldWrite != pdFALSE )
\r
700 /* Writes the data itself. */
\r
701 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
710 /*-----------------------------------------------------------*/
\r
712 size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
\r
714 size_t xBufferLengthBytes,
\r
715 TickType_t xTicksToWait )
\r
717 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
718 size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
\r
720 configASSERT( pvRxData );
\r
721 configASSERT( pxStreamBuffer );
\r
723 /* This receive function is used by both message buffers, which store
\r
724 discrete messages, and stream buffers, which store a continuous stream of
\r
725 bytes. Discrete messages include an additional
\r
726 sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the
\r
728 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
730 xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
734 xBytesToStoreMessageLength = 0;
\r
737 if( xTicksToWait != ( TickType_t ) 0 )
\r
739 /* Checking if there is data and clearing the notification state must be
\r
740 performed atomically. */
\r
741 taskENTER_CRITICAL();
\r
743 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
745 /* If this function was invoked by a message buffer read then
\r
746 xBytesToStoreMessageLength holds the number of bytes used to hold
\r
747 the length of the next discrete message. If this function was
\r
748 invoked by a stream buffer read then xBytesToStoreMessageLength will
\r
750 if( xBytesAvailable <= xBytesToStoreMessageLength )
\r
752 /* Clear notification state as going to wait for data. */
\r
753 ( void ) xTaskNotifyStateClear( NULL );
\r
755 /* Should only be one reader. */
\r
756 configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL );
\r
757 pxStreamBuffer->xTaskWaitingToReceive = xTaskGetCurrentTaskHandle();
\r
761 mtCOVERAGE_TEST_MARKER();
\r
764 taskEXIT_CRITICAL();
\r
766 if( xBytesAvailable <= xBytesToStoreMessageLength )
\r
768 /* Wait for data to be available. */
\r
769 traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer );
\r
770 ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
\r
771 pxStreamBuffer->xTaskWaitingToReceive = NULL;
\r
773 /* Recheck the data available after blocking. */
\r
774 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
778 mtCOVERAGE_TEST_MARKER();
\r
783 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
786 /* Whether receiving a discrete message (where xBytesToStoreMessageLength
\r
787 holds the number of bytes used to store the message length) or a stream of
\r
788 bytes (where xBytesToStoreMessageLength is zero), the number of bytes
\r
789 available must be greater than xBytesToStoreMessageLength to be able to
\r
790 read bytes from the buffer. */
\r
791 if( xBytesAvailable > xBytesToStoreMessageLength )
\r
793 xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
\r
795 /* Was a task waiting for space in the buffer? */
\r
796 if( xReceivedLength != ( size_t ) 0 )
\r
798 traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength );
\r
799 sbRECEIVE_COMPLETED( pxStreamBuffer );
\r
803 mtCOVERAGE_TEST_MARKER();
\r
808 traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer );
\r
809 mtCOVERAGE_TEST_MARKER();
\r
812 return xReceivedLength;
\r
814 /*-----------------------------------------------------------*/
\r
816 size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer )
\r
818 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
819 size_t xReturn, xBytesAvailable, xOriginalTail;
\r
820 configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn;
\r
822 configASSERT( pxStreamBuffer );
\r
824 /* Ensure the stream buffer is being used as a message buffer. */
\r
825 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
827 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
828 if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH )
\r
830 /* The number of bytes available is greater than the number of bytes
\r
831 required to hold the length of the next message, so another message
\r
832 is available. Return its length without removing the length bytes
\r
833 from the buffer. A copy of the tail is stored so the buffer can be
\r
834 returned to its prior state as the message is not actually being
\r
835 removed from the buffer. */
\r
836 xOriginalTail = pxStreamBuffer->xTail;
\r
837 ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, xBytesAvailable );
\r
838 xReturn = ( size_t ) xTempReturn;
\r
839 pxStreamBuffer->xTail = xOriginalTail;
\r
843 /* The minimum amount of bytes in a message buffer is
\r
844 ( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is
\r
845 less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid
\r
847 configASSERT( xBytesAvailable == 0 );
\r
858 /*-----------------------------------------------------------*/
\r
860 size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
\r
862 size_t xBufferLengthBytes,
\r
863 BaseType_t * const pxHigherPriorityTaskWoken )
\r
865 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
866 size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
\r
868 configASSERT( pvRxData );
\r
869 configASSERT( pxStreamBuffer );
\r
871 /* This receive function is used by both message buffers, which store
\r
872 discrete messages, and stream buffers, which store a continuous stream of
\r
873 bytes. Discrete messages include an additional
\r
874 sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the
\r
876 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
878 xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
882 xBytesToStoreMessageLength = 0;
\r
885 xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
\r
887 /* Whether receiving a discrete message (where xBytesToStoreMessageLength
\r
888 holds the number of bytes used to store the message length) or a stream of
\r
889 bytes (where xBytesToStoreMessageLength is zero), the number of bytes
\r
890 available must be greater than xBytesToStoreMessageLength to be able to
\r
891 read bytes from the buffer. */
\r
892 if( xBytesAvailable > xBytesToStoreMessageLength )
\r
894 xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );
\r
896 /* Was a task waiting for space in the buffer? */
\r
897 if( xReceivedLength != ( size_t ) 0 )
\r
899 sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
\r
903 mtCOVERAGE_TEST_MARKER();
\r
908 mtCOVERAGE_TEST_MARKER();
\r
911 traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength );
\r
913 return xReceivedLength;
\r
915 /*-----------------------------------------------------------*/
\r
917 static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer,
\r
919 size_t xBufferLengthBytes,
\r
920 size_t xBytesAvailable,
\r
921 size_t xBytesToStoreMessageLength )
\r
923 size_t xOriginalTail, xReceivedLength, xNextMessageLength;
\r
924 configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength;
\r
926 if( xBytesToStoreMessageLength != ( size_t ) 0 )
\r
928 /* A discrete message is being received. First receive the length
\r
929 of the message. A copy of the tail is stored so the buffer can be
\r
930 returned to its prior state if the length of the message is too
\r
931 large for the provided buffer. */
\r
932 xOriginalTail = pxStreamBuffer->xTail;
\r
933 ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable );
\r
934 xNextMessageLength = ( size_t ) xTempNextMessageLength;
\r
936 /* Reduce the number of bytes available by the number of bytes just
\r
938 xBytesAvailable -= xBytesToStoreMessageLength;
\r
940 /* Check there is enough space in the buffer provided by the
\r
942 if( xNextMessageLength > xBufferLengthBytes )
\r
944 /* The user has provided insufficient space to read the message
\r
945 so return the buffer to its previous state (so the length of
\r
946 the message is in the buffer again). */
\r
947 pxStreamBuffer->xTail = xOriginalTail;
\r
948 xNextMessageLength = 0;
\r
952 mtCOVERAGE_TEST_MARKER();
\r
957 /* A stream of bytes is being received (as opposed to a discrete
\r
958 message), so read as many bytes as possible. */
\r
959 xNextMessageLength = xBufferLengthBytes;
\r
962 /* Read the actual data. */
\r
963 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
965 return xReceivedLength;
\r
967 /*-----------------------------------------------------------*/
\r
969 BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer )
\r
971 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
972 BaseType_t xReturn;
\r
975 configASSERT( pxStreamBuffer );
\r
977 /* True if no bytes are available. */
\r
978 xTail = pxStreamBuffer->xTail;
\r
979 if( pxStreamBuffer->xHead == xTail )
\r
990 /*-----------------------------------------------------------*/
\r
992 BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer )
\r
994 BaseType_t xReturn;
\r
995 size_t xBytesToStoreMessageLength;
\r
996 const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
998 configASSERT( pxStreamBuffer );
\r
1000 /* This generic version of the receive function is used by both message
\r
1001 buffers, which store discrete messages, and stream buffers, which store a
\r
1002 continuous stream of bytes. Discrete messages include an additional
\r
1003 sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the message. */
\r
1004 if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
\r
1006 xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
\r
1010 xBytesToStoreMessageLength = 0;
\r
1013 /* True if the available space equals zero. */
\r
1014 if( xStreamBufferSpacesAvailable( xStreamBuffer ) <= xBytesToStoreMessageLength )
\r
1020 xReturn = pdFALSE;
\r
1025 /*-----------------------------------------------------------*/
\r
1027 BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken )
\r
1029 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
1030 BaseType_t xReturn;
\r
1031 UBaseType_t uxSavedInterruptStatus;
\r
1033 configASSERT( pxStreamBuffer );
\r
1035 uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();
\r
1037 if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )
\r
1039 ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive,
\r
1042 pxHigherPriorityTaskWoken );
\r
1043 ( pxStreamBuffer )->xTaskWaitingToReceive = NULL;
\r
1048 xReturn = pdFALSE;
\r
1051 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
\r
1055 /*-----------------------------------------------------------*/
\r
1057 BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken )
\r
1059 StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
\r
1060 BaseType_t xReturn;
\r
1061 UBaseType_t uxSavedInterruptStatus;
\r
1063 configASSERT( pxStreamBuffer );
\r
1065 uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();
\r
1067 if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )
\r
1069 ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend,
\r
1072 pxHigherPriorityTaskWoken );
\r
1073 ( pxStreamBuffer )->xTaskWaitingToSend = NULL;
\r
1078 xReturn = pdFALSE;
\r
1081 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
\r
1085 /*-----------------------------------------------------------*/
\r
1087 static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount )
\r
1089 size_t xNextHead, xFirstLength;
\r
1091 configASSERT( xCount > ( size_t ) 0 );
\r
1093 xNextHead = pxStreamBuffer->xHead;
\r
1095 /* Calculate the number of bytes that can be added in the first write -
\r
1096 which may be less than the total number of bytes that need to be added if
\r
1097 the buffer will wrap back to the beginning. */
\r
1098 xFirstLength = configMIN( pxStreamBuffer->xLength - xNextHead, xCount );
\r
1100 /* Write as many bytes as can be written in the first write. */
\r
1101 configASSERT( ( xNextHead + xFirstLength ) <= pxStreamBuffer->xLength );
\r
1102 ( void ) memcpy( ( void* ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1104 /* If the number of bytes written was less than the number that could be
\r
1105 written in the first write... */
\r
1106 if( xCount > xFirstLength )
\r
1108 /* ...then write the remaining bytes to the start of the buffer. */
\r
1109 configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength );
\r
1110 ( void ) memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1114 mtCOVERAGE_TEST_MARKER();
\r
1117 xNextHead += xCount;
\r
1118 if( xNextHead >= pxStreamBuffer->xLength )
\r
1120 xNextHead -= pxStreamBuffer->xLength;
\r
1124 mtCOVERAGE_TEST_MARKER();
\r
1127 pxStreamBuffer->xHead = xNextHead;
\r
1131 /*-----------------------------------------------------------*/
\r
1133 static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, uint8_t *pucData, size_t xMaxCount, size_t xBytesAvailable )
\r
1135 size_t xCount, xFirstLength, xNextTail;
\r
1137 /* Use the minimum of the wanted bytes and the available bytes. */
\r
1138 xCount = configMIN( xBytesAvailable, xMaxCount );
\r
1140 if( xCount > ( size_t ) 0 )
\r
1142 xNextTail = pxStreamBuffer->xTail;
\r
1144 /* Calculate the number of bytes that can be read - which may be
\r
1145 less than the number wanted if the data wraps around to the start of
\r
1147 xFirstLength = configMIN( pxStreamBuffer->xLength - xNextTail, xCount );
\r
1149 /* Obtain the number of bytes it is possible to obtain in the first
\r
1150 read. Asserts check bounds of read and write. */
\r
1151 configASSERT( xFirstLength <= xMaxCount );
\r
1152 configASSERT( ( xNextTail + xFirstLength ) <= pxStreamBuffer->xLength );
\r
1153 ( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1155 /* If the total number of wanted bytes is greater than the number
\r
1156 that could be read in the first read... */
\r
1157 if( xCount > xFirstLength )
\r
1159 /*...then read the remaining bytes from the start of the buffer. */
\r
1160 configASSERT( xCount <= xMaxCount );
\r
1161 ( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */
\r
1165 mtCOVERAGE_TEST_MARKER();
\r
1168 /* Move the tail pointer to effectively remove the data read from
\r
1170 xNextTail += xCount;
\r
1172 if( xNextTail >= pxStreamBuffer->xLength )
\r
1174 xNextTail -= pxStreamBuffer->xLength;
\r
1177 pxStreamBuffer->xTail = xNextTail;
\r
1181 mtCOVERAGE_TEST_MARKER();
\r
1186 /*-----------------------------------------------------------*/
\r
1188 static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer )
\r
1190 /* Returns the distance between xTail and xHead. */
\r
1193 xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead;
\r
1194 xCount -= pxStreamBuffer->xTail;
\r
1195 if ( xCount >= pxStreamBuffer->xLength )
\r
1197 xCount -= pxStreamBuffer->xLength;
\r
1201 mtCOVERAGE_TEST_MARKER();
\r
1206 /*-----------------------------------------------------------*/
\r
1208 static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
\r
1209 uint8_t * const pucBuffer,
\r
1210 size_t xBufferSizeBytes,
\r
1211 size_t xTriggerLevelBytes,
\r
1214 /* Assert here is deliberately writing to the entire buffer to ensure it can
\r
1215 be written to without generating exceptions, and is setting the buffer to a
\r
1216 known value to assist in development/debugging. */
\r
1217 #if( configASSERT_DEFINED == 1 )
\r
1219 /* The value written just has to be identifiable when looking at the
\r
1220 memory. Don't use 0xA5 as that is the stack fill value and could
\r
1221 result in confusion as to what is actually being observed. */
\r
1222 const BaseType_t xWriteValue = 0x55;
\r
1223 configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer );
\r
1224 } /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */
\r
1227 ( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */
\r
1228 pxStreamBuffer->pucBuffer = pucBuffer;
\r
1229 pxStreamBuffer->xLength = xBufferSizeBytes;
\r
1230 pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes;
\r
1231 pxStreamBuffer->ucFlags = ucFlags;
\r
1234 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1236 UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer )
\r
1238 return xStreamBuffer->uxStreamBufferNumber;
\r
1241 #endif /* configUSE_TRACE_FACILITY */
\r
1242 /*-----------------------------------------------------------*/
\r
1244 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1246 void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber )
\r
1248 xStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
\r
1251 #endif /* configUSE_TRACE_FACILITY */
\r
1252 /*-----------------------------------------------------------*/
\r
1254 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1256 uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer )
\r
1258 return ( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER );
\r
1261 #endif /* configUSE_TRACE_FACILITY */
\r
1262 /*-----------------------------------------------------------*/
\r