| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314 | /* * FreeRTOS Kernel V10.4.3 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * *//* Standard includes. */#include <stdint.h>#include <string.h>/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining * all the API functions to use the MPU wrappers.  That should only be done when * task.h is included from an application file. */#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE/* FreeRTOS includes. */#include "FreeRTOS.h"#include "task.h"#include "stream_buffer.h"#if ( configUSE_TASK_NOTIFICATIONS != 1 )    #error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c#endif/* Lint e961, e9021 and e750 are suppressed as a MISRA exception justified * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * for the header files above, but not in this file, in order to generate the * correct privileged Vs unprivileged linkage and placement. */#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. *//* If the user has not provided application specific Rx notification macros, * or #defined the notification macros away, them provide default implementations * that uses task notifications. *//*lint -save -e9026 Function like macros allowed and needed here so they can be overridden. */#ifndef sbRECEIVE_COMPLETED    #define sbRECEIVE_COMPLETED( pxStreamBuffer )                         \    vTaskSuspendAll();                                                    \    {                                                                     \        if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )              \        {                                                                 \            ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \                                  ( uint32_t ) 0,                         \                                  eNoAction );                            \            ( pxStreamBuffer )->xTaskWaitingToSend = NULL;                \        }                                                                 \    }                                                                     \    ( void ) xTaskResumeAll();#endif /* sbRECEIVE_COMPLETED */#ifndef sbRECEIVE_COMPLETED_FROM_ISR    #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer,                            \                                          pxHigherPriorityTaskWoken )                \    {                                                                                \        UBaseType_t uxSavedInterruptStatus;                                          \                                                                                     \        uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();  \        {                                                                            \            if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )                     \            {                                                                        \                ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \                                             ( uint32_t ) 0,                         \                                             eNoAction,                              \                                             pxHigherPriorityTaskWoken );            \                ( pxStreamBuffer )->xTaskWaitingToSend = NULL;                       \            }                                                                        \        }                                                                            \        portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );                 \    }#endif /* sbRECEIVE_COMPLETED_FROM_ISR *//* If the user has not provided an application specific Tx notification macro, * or #defined the notification macro away, them provide a default implementation * that uses task notifications. */#ifndef sbSEND_COMPLETED    #define sbSEND_COMPLETED( pxStreamBuffer )                               \    vTaskSuspendAll();                                                       \    {                                                                        \        if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )              \        {                                                                    \            ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive, \                                  ( uint32_t ) 0,                            \                                  eNoAction );                               \            ( pxStreamBuffer )->xTaskWaitingToReceive = NULL;                \        }                                                                    \    }                                                                        \    ( void ) xTaskResumeAll();#endif /* sbSEND_COMPLETED */#ifndef sbSEND_COMPLETE_FROM_ISR    #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken )       \    {                                                                                   \        UBaseType_t uxSavedInterruptStatus;                                             \                                                                                        \        uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();     \        {                                                                               \            if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )                     \            {                                                                           \                ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \                                             ( uint32_t ) 0,                            \                                             eNoAction,                                 \                                             pxHigherPriorityTaskWoken );               \                ( pxStreamBuffer )->xTaskWaitingToReceive = NULL;                       \            }                                                                           \        }                                                                               \        portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );                    \    }#endif /* sbSEND_COMPLETE_FROM_ISR *//*lint -restore (9026) *//* The number of bytes used to hold the length of a message in the buffer. */#define sbBYTES_TO_STORE_MESSAGE_LENGTH    ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) )/* Bits stored in the ucFlags field of the stream buffer. */#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. */#define sbFLAGS_IS_STATICALLY_ALLOCATED    ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. *//*-----------------------------------------------------------*//* Structure that hold state information on the buffer. */typedef struct StreamBufferDef_t                 /*lint !e9058 Style convention uses tag. */{    volatile size_t xTail;                       /* Index to the next item to read within the buffer. */    volatile size_t xHead;                       /* Index to the next item to write within the buffer. */    size_t xLength;                              /* The length of the buffer pointed to by pucBuffer. */    size_t xTriggerLevelBytes;                   /* The number of bytes that must be in the stream buffer before a task that is waiting for data is unblocked. */    volatile TaskHandle_t xTaskWaitingToReceive; /* Holds the handle of a task waiting for data, or NULL if no tasks are waiting. */    volatile TaskHandle_t xTaskWaitingToSend;    /* Holds the handle of a task waiting to send data to a message buffer that is full. */    uint8_t * pucBuffer;                         /* Points to the buffer itself - that is - the RAM that stores the data passed through the buffer. */    uint8_t ucFlags;    #if ( configUSE_TRACE_FACILITY == 1 )        UBaseType_t uxStreamBufferNumber; /* Used for tracing purposes. */    #endif} StreamBuffer_t;/* * The number of bytes available to be read from the buffer. */static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION;/* * Add xCount bytes from pucData into the pxStreamBuffer message buffer. * Returns the number of bytes written, which will either equal xCount in the * success case, or 0 if there was not enough space in the buffer (in which case * no data is written into the buffer). */static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer,                                     const uint8_t * pucData,                                     size_t xCount ) PRIVILEGED_FUNCTION;/* * If the stream buffer is being used as a message buffer, then reads an entire * message out of the buffer.  If the stream buffer is being used as a stream * buffer then read as many bytes as possible from the buffer. * prvReadBytesFromBuffer() is called to actually extract the bytes from the * buffer's data storage area. */static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer,                                        void * pvRxData,                                        size_t xBufferLengthBytes,                                        size_t xBytesAvailable,                                        size_t xBytesToStoreMessageLength ) PRIVILEGED_FUNCTION;/* * If the stream buffer is being used as a message buffer, then writes an entire * message to the buffer.  If the stream buffer is being used as a stream * buffer then write as many bytes as possible to the buffer. * prvWriteBytestoBuffer() is called to actually send the bytes to the buffer's * data storage area. */static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,                                       const void * pvTxData,                                       size_t xDataLengthBytes,                                       size_t xSpace,                                       size_t xRequiredSpace ) PRIVILEGED_FUNCTION;/* * Read xMaxCount bytes from the pxStreamBuffer message buffer and write them * to pucData. */static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer,                                      uint8_t * pucData,                                      size_t xMaxCount,                                      size_t xBytesAvailable ) PRIVILEGED_FUNCTION;/* * Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to * initialise the members of the newly created stream buffer structure. */static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,                                          uint8_t * const pucBuffer,                                          size_t xBufferSizeBytes,                                          size_t xTriggerLevelBytes,                                          uint8_t ucFlags ) PRIVILEGED_FUNCTION;/*-----------------------------------------------------------*/#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )    StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,                                                     size_t xTriggerLevelBytes,                                                     BaseType_t xIsMessageBuffer )    {        uint8_t * pucAllocatedMemory;        uint8_t ucFlags;        /* In case the stream buffer is going to be used as a message buffer         * (that is, it will hold discrete messages with a little meta data that         * says how big the next message is) check the buffer will be large enough         * to hold at least one message. */        if( xIsMessageBuffer == pdTRUE )        {            /* Is a message buffer but not statically allocated. */            ucFlags = sbFLAGS_IS_MESSAGE_BUFFER;            configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );        }        else        {            /* Not a message buffer and not statically allocated. */            ucFlags = 0;            configASSERT( xBufferSizeBytes > 0 );        }        configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );        /* A trigger level of 0 would cause a waiting task to unblock even when         * the buffer was empty. */        if( xTriggerLevelBytes == ( size_t ) 0 )        {            xTriggerLevelBytes = ( size_t ) 1;        }        /* A stream buffer requires a StreamBuffer_t structure and a buffer.         * Both are allocated in a single call to pvPortMalloc().  The         * StreamBuffer_t structure is placed at the start of the allocated memory         * and the buffer follows immediately after.  The requested size is         * incremented so the free space is returned as the user would expect -         * this is a quirk of the implementation that means otherwise the free         * space would be reported as one byte smaller than would be logically         * expected. */        if( xBufferSizeBytes < ( xBufferSizeBytes + 1 + sizeof( StreamBuffer_t ) ) )        {            xBufferSizeBytes++;            pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */        }        else        {            pucAllocatedMemory = NULL;        }        if( pucAllocatedMemory != NULL )        {            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. */                                          pucAllocatedMemory + sizeof( StreamBuffer_t ), /* Storage area follows. */ /*lint !e9016 Indexing past structure valid for uint8_t pointer, also storage area has no alignment requirement. */                                          xBufferSizeBytes,                                          xTriggerLevelBytes,                                          ucFlags );            traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pucAllocatedMemory ), xIsMessageBuffer );        }        else        {            traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer );        }        return ( StreamBufferHandle_t ) pucAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */    }#endif /* configSUPPORT_DYNAMIC_ALLOCATION *//*-----------------------------------------------------------*/#if ( configSUPPORT_STATIC_ALLOCATION == 1 )    StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,                                                           size_t xTriggerLevelBytes,                                                           BaseType_t xIsMessageBuffer,                                                           uint8_t * const pucStreamBufferStorageArea,                                                           StaticStreamBuffer_t * const pxStaticStreamBuffer )    {        StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */        StreamBufferHandle_t xReturn;        uint8_t ucFlags;        configASSERT( pucStreamBufferStorageArea );        configASSERT( pxStaticStreamBuffer );        configASSERT( xTriggerLevelBytes <= xBufferSizeBytes );        /* A trigger level of 0 would cause a waiting task to unblock even when         * the buffer was empty. */        if( xTriggerLevelBytes == ( size_t ) 0 )        {            xTriggerLevelBytes = ( size_t ) 1;        }        if( xIsMessageBuffer != pdFALSE )        {            /* Statically allocated message buffer. */            ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED;        }        else        {            /* Statically allocated stream buffer. */            ucFlags = sbFLAGS_IS_STATICALLY_ALLOCATED;        }        /* In case the stream buffer is going to be used as a message buffer         * (that is, it will hold discrete messages with a little meta data that         * says how big the next message is) check the buffer will be large enough         * to hold at least one message. */        configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );        #if ( configASSERT_DEFINED == 1 )            {                /* Sanity check that the size of the structure used to declare a                 * variable of type StaticStreamBuffer_t equals the size of the real                 * message buffer structure. */                volatile size_t xSize = sizeof( StaticStreamBuffer_t );                configASSERT( xSize == sizeof( StreamBuffer_t ) );            } /*lint !e529 xSize is referenced is configASSERT() is defined. */        #endif /* configASSERT_DEFINED */        if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) )        {            prvInitialiseNewStreamBuffer( pxStreamBuffer,                                          pucStreamBufferStorageArea,                                          xBufferSizeBytes,                                          xTriggerLevelBytes,                                          ucFlags );            /* Remember this was statically allocated in case it is ever deleted             * again. */            pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED;            traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer );            xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */        }        else        {            xReturn = NULL;            traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer );        }        return xReturn;    }#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) *//*-----------------------------------------------------------*/void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ){    StreamBuffer_t * pxStreamBuffer = xStreamBuffer;    configASSERT( pxStreamBuffer );    traceSTREAM_BUFFER_DELETE( xStreamBuffer );    if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) pdFALSE )    {        #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )            {                /* Both the structure and the buffer were allocated using a single call                * to pvPortMalloc(), hence only one call to vPortFree() is required. */                vPortFree( ( void * ) pxStreamBuffer ); /*lint !e9087 Standard free() semantics require void *, plus pxStreamBuffer was allocated by pvPortMalloc(). */            }        #else            {                /* Should not be possible to get here, ucFlags must be corrupt.                 * Force an assert. */                configASSERT( xStreamBuffer == ( StreamBufferHandle_t ) ~0 );            }        #endif    }    else    {        /* The structure and buffer were not allocated dynamically and cannot be         * freed - just scrub the structure so future use will assert. */        ( void ) memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) );    }}/*-----------------------------------------------------------*/BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ){    StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    BaseType_t xReturn = pdFAIL;    #if ( configUSE_TRACE_FACILITY == 1 )        UBaseType_t uxStreamBufferNumber;    #endif    configASSERT( pxStreamBuffer );    #if ( configUSE_TRACE_FACILITY == 1 )        {            /* Store the stream buffer number so it can be restored after the             * reset. */            uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber;        }    #endif    /* Can only reset a message buffer if there are no tasks blocked on it. */    taskENTER_CRITICAL();    {        if( pxStreamBuffer->xTaskWaitingToReceive == NULL )        {            if( pxStreamBuffer->xTaskWaitingToSend == NULL )            {                prvInitialiseNewStreamBuffer( pxStreamBuffer,                                              pxStreamBuffer->pucBuffer,                                              pxStreamBuffer->xLength,                                              pxStreamBuffer->xTriggerLevelBytes,                                              pxStreamBuffer->ucFlags );                xReturn = pdPASS;                #if ( configUSE_TRACE_FACILITY == 1 )                    {                        pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;                    }                #endif                traceSTREAM_BUFFER_RESET( xStreamBuffer );            }        }    }    taskEXIT_CRITICAL();    return xReturn;}/*-----------------------------------------------------------*/BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,                                         size_t xTriggerLevel ){    StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    BaseType_t xReturn;    configASSERT( pxStreamBuffer );    /* It is not valid for the trigger level to be 0. */    if( xTriggerLevel == ( size_t ) 0 )    {        xTriggerLevel = ( size_t ) 1;    }    /* The trigger level is the number of bytes that must be in the stream     * buffer before a task that is waiting for data is unblocked. */    if( xTriggerLevel <= pxStreamBuffer->xLength )    {        pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel;        xReturn = pdPASS;    }    else    {        xReturn = pdFALSE;    }    return xReturn;}/*-----------------------------------------------------------*/size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ){    const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    size_t xSpace;    configASSERT( pxStreamBuffer );    xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail;    xSpace -= pxStreamBuffer->xHead;    xSpace -= ( size_t ) 1;    if( xSpace >= pxStreamBuffer->xLength )    {        xSpace -= pxStreamBuffer->xLength;    }    else    {        mtCOVERAGE_TEST_MARKER();    }    return xSpace;}/*-----------------------------------------------------------*/size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ){    const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    size_t xReturn;    configASSERT( pxStreamBuffer );    xReturn = prvBytesInBuffer( pxStreamBuffer );    return xReturn;}/*-----------------------------------------------------------*/size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,                          const void * pvTxData,                          size_t xDataLengthBytes,                          TickType_t xTicksToWait ){    StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    size_t xReturn, xSpace = 0;    size_t xRequiredSpace = xDataLengthBytes;    TimeOut_t xTimeOut;    /* The maximum amount of space a stream buffer will ever report is its length     * minus 1. */    const size_t xMaxReportedSpace = pxStreamBuffer->xLength - ( size_t ) 1;    configASSERT( pvTxData );    configASSERT( pxStreamBuffer );    /* This send function is used to write to both message buffers and stream     * buffers.  If this is a message buffer then the space needed must be     * increased by the amount of bytes needed to store the length of the     * message. */    if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )    {        xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;        /* Overflow? */        configASSERT( xRequiredSpace > xDataLengthBytes );        /* If this is a message buffer then it must be possible to write the         * whole message. */        if( xRequiredSpace > xMaxReportedSpace )        {            /* The message would not fit even if the entire buffer was empty,             * so don't wait for space. */            xTicksToWait = ( TickType_t ) 0;        }        else        {            mtCOVERAGE_TEST_MARKER();        }    }    else    {        /* If this is a stream buffer then it is acceptable to write only part         * of the message to the buffer.  Cap the length to the total length of         * the buffer. */        if( xRequiredSpace > xMaxReportedSpace )        {            xRequiredSpace = xMaxReportedSpace;        }        else        {            mtCOVERAGE_TEST_MARKER();        }    }    if( xTicksToWait != ( TickType_t ) 0 )    {        vTaskSetTimeOutState( &xTimeOut );        do        {            /* Wait until the required number of bytes are free in the message             * buffer. */            taskENTER_CRITICAL();            {                xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );                if( xSpace < xRequiredSpace )                {                    /* Clear notification state as going to wait for space. */                    ( void ) xTaskNotifyStateClear( NULL );                    /* Should only be one writer. */                    configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL );                    pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle();                }                else                {                    taskEXIT_CRITICAL();                    break;                }            }            taskEXIT_CRITICAL();            traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer );            ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );            pxStreamBuffer->xTaskWaitingToSend = NULL;        } while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE );    }    else    {        mtCOVERAGE_TEST_MARKER();    }    if( xSpace == ( size_t ) 0 )    {        xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );    }    else    {        mtCOVERAGE_TEST_MARKER();    }    xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );    if( xReturn > ( size_t ) 0 )    {        traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn );        /* Was a task waiting for the data? */        if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )        {            sbSEND_COMPLETED( pxStreamBuffer );        }        else        {            mtCOVERAGE_TEST_MARKER();        }    }    else    {        mtCOVERAGE_TEST_MARKER();        traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer );    }    return xReturn;}/*-----------------------------------------------------------*/size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,                                 const void * pvTxData,                                 size_t xDataLengthBytes,                                 BaseType_t * const pxHigherPriorityTaskWoken ){    StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    size_t xReturn, xSpace;    size_t xRequiredSpace = xDataLengthBytes;    configASSERT( pvTxData );    configASSERT( pxStreamBuffer );    /* This send function is used to write to both message buffers and stream     * buffers.  If this is a message buffer then the space needed must be     * increased by the amount of bytes needed to store the length of the     * message. */    if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )    {        xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;    }    else    {        mtCOVERAGE_TEST_MARKER();    }    xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer );    xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace );    if( xReturn > ( size_t ) 0 )    {        /* Was a task waiting for the data? */        if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )        {            sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );        }        else        {            mtCOVERAGE_TEST_MARKER();        }    }    else    {        mtCOVERAGE_TEST_MARKER();    }    traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn );    return xReturn;}/*-----------------------------------------------------------*/static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,                                       const void * pvTxData,                                       size_t xDataLengthBytes,                                       size_t xSpace,                                       size_t xRequiredSpace ){    BaseType_t xShouldWrite;    size_t xReturn;    if( xSpace == ( size_t ) 0 )    {        /* Doesn't matter if this is a stream buffer or a message buffer, there         * is no space to write. */        xShouldWrite = pdFALSE;    }    else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) == ( uint8_t ) 0 )    {        /* This is a stream buffer, as opposed to a message buffer, so writing a         * stream of bytes rather than discrete messages.  Write as many bytes as         * possible. */        xShouldWrite = pdTRUE;        xDataLengthBytes = configMIN( xDataLengthBytes, xSpace );    }    else if( xSpace >= xRequiredSpace )    {        /* This is a message buffer, as opposed to a stream buffer, and there         * is enough space to write both the message length and the message itself         * into the buffer.  Start by writing the length of the data, the data         * itself will be written later in this function. */        xShouldWrite = pdTRUE;        ( void ) prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xDataLengthBytes ), sbBYTES_TO_STORE_MESSAGE_LENGTH );    }    else    {        /* There is space available, but not enough space. */        xShouldWrite = pdFALSE;    }    if( xShouldWrite != pdFALSE )    {        /* Writes the data itself. */        xReturn = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alignment and access. */    }    else    {        xReturn = 0;    }    return xReturn;}/*-----------------------------------------------------------*/size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,                             void * pvRxData,                             size_t xBufferLengthBytes,                             TickType_t xTicksToWait ){    StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;    configASSERT( pvRxData );    configASSERT( pxStreamBuffer );    /* This receive function is used by both message buffers, which store     * discrete messages, and stream buffers, which store a continuous stream of     * bytes.  Discrete messages include an additional     * sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the     * message. */    if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )    {        xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;    }    else    {        xBytesToStoreMessageLength = 0;    }    if( xTicksToWait != ( TickType_t ) 0 )    {        /* Checking if there is data and clearing the notification state must be         * performed atomically. */        taskENTER_CRITICAL();        {            xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );            /* If this function was invoked by a message buffer read then             * xBytesToStoreMessageLength holds the number of bytes used to hold             * the length of the next discrete message.  If this function was             * invoked by a stream buffer read then xBytesToStoreMessageLength will             * be 0. */            if( xBytesAvailable <= xBytesToStoreMessageLength )            {                /* Clear notification state as going to wait for data. */                ( void ) xTaskNotifyStateClear( NULL );                /* Should only be one reader. */                configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL );                pxStreamBuffer->xTaskWaitingToReceive = xTaskGetCurrentTaskHandle();            }            else            {                mtCOVERAGE_TEST_MARKER();            }        }        taskEXIT_CRITICAL();        if( xBytesAvailable <= xBytesToStoreMessageLength )        {            /* Wait for data to be available. */            traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer );            ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );            pxStreamBuffer->xTaskWaitingToReceive = NULL;            /* Recheck the data available after blocking. */            xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );        }        else        {            mtCOVERAGE_TEST_MARKER();        }    }    else    {        xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );    }    /* Whether receiving a discrete message (where xBytesToStoreMessageLength     * holds the number of bytes used to store the message length) or a stream of     * bytes (where xBytesToStoreMessageLength is zero), the number of bytes     * available must be greater than xBytesToStoreMessageLength to be able to     * read bytes from the buffer. */    if( xBytesAvailable > xBytesToStoreMessageLength )    {        xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );        /* Was a task waiting for space in the buffer? */        if( xReceivedLength != ( size_t ) 0 )        {            traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength );            sbRECEIVE_COMPLETED( pxStreamBuffer );        }        else        {            mtCOVERAGE_TEST_MARKER();        }    }    else    {        traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer );        mtCOVERAGE_TEST_MARKER();    }    return xReceivedLength;}/*-----------------------------------------------------------*/size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ){    StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    size_t xReturn, xBytesAvailable, xOriginalTail;    configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn;    configASSERT( pxStreamBuffer );    /* Ensure the stream buffer is being used as a message buffer. */    if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )    {        xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );        if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH )        {            /* The number of bytes available is greater than the number of bytes             * required to hold the length of the next message, so another message             * is available.  Return its length without removing the length bytes             * from the buffer.  A copy of the tail is stored so the buffer can be             * returned to its prior state as the message is not actually being             * removed from the buffer. */            xOriginalTail = pxStreamBuffer->xTail;            ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, xBytesAvailable );            xReturn = ( size_t ) xTempReturn;            pxStreamBuffer->xTail = xOriginalTail;        }        else        {            /* The minimum amount of bytes in a message buffer is             * ( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is             * less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid             * value is 0. */            configASSERT( xBytesAvailable == 0 );            xReturn = 0;        }    }    else    {        xReturn = 0;    }    return xReturn;}/*-----------------------------------------------------------*/size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,                                    void * pvRxData,                                    size_t xBufferLengthBytes,                                    BaseType_t * const pxHigherPriorityTaskWoken ){    StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;    configASSERT( pvRxData );    configASSERT( pxStreamBuffer );    /* This receive function is used by both message buffers, which store     * discrete messages, and stream buffers, which store a continuous stream of     * bytes.  Discrete messages include an additional     * sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the     * message. */    if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )    {        xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;    }    else    {        xBytesToStoreMessageLength = 0;    }    xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );    /* Whether receiving a discrete message (where xBytesToStoreMessageLength     * holds the number of bytes used to store the message length) or a stream of     * bytes (where xBytesToStoreMessageLength is zero), the number of bytes     * available must be greater than xBytesToStoreMessageLength to be able to     * read bytes from the buffer. */    if( xBytesAvailable > xBytesToStoreMessageLength )    {        xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength );        /* Was a task waiting for space in the buffer? */        if( xReceivedLength != ( size_t ) 0 )        {            sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );        }        else        {            mtCOVERAGE_TEST_MARKER();        }    }    else    {        mtCOVERAGE_TEST_MARKER();    }    traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength );    return xReceivedLength;}/*-----------------------------------------------------------*/static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer,                                        void * pvRxData,                                        size_t xBufferLengthBytes,                                        size_t xBytesAvailable,                                        size_t xBytesToStoreMessageLength ){    size_t xOriginalTail, xReceivedLength, xNextMessageLength;    configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength;    if( xBytesToStoreMessageLength != ( size_t ) 0 )    {        /* A discrete message is being received.  First receive the length         * of the message.  A copy of the tail is stored so the buffer can be         * returned to its prior state if the length of the message is too         * large for the provided buffer. */        xOriginalTail = pxStreamBuffer->xTail;        ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable );        xNextMessageLength = ( size_t ) xTempNextMessageLength;        /* Reduce the number of bytes available by the number of bytes just         * read out. */        xBytesAvailable -= xBytesToStoreMessageLength;        /* Check there is enough space in the buffer provided by the         * user. */        if( xNextMessageLength > xBufferLengthBytes )        {            /* The user has provided insufficient space to read the message             * so return the buffer to its previous state (so the length of             * the message is in the buffer again). */            pxStreamBuffer->xTail = xOriginalTail;            xNextMessageLength = 0;        }        else        {            mtCOVERAGE_TEST_MARKER();        }    }    else    {        /* A stream of bytes is being received (as opposed to a discrete         * message), so read as many bytes as possible. */        xNextMessageLength = xBufferLengthBytes;    }    /* Read the actual data. */    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. */    return xReceivedLength;}/*-----------------------------------------------------------*/BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ){    const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    BaseType_t xReturn;    size_t xTail;    configASSERT( pxStreamBuffer );    /* True if no bytes are available. */    xTail = pxStreamBuffer->xTail;    if( pxStreamBuffer->xHead == xTail )    {        xReturn = pdTRUE;    }    else    {        xReturn = pdFALSE;    }    return xReturn;}/*-----------------------------------------------------------*/BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ){    BaseType_t xReturn;    size_t xBytesToStoreMessageLength;    const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    configASSERT( pxStreamBuffer );    /* This generic version of the receive function is used by both message     * buffers, which store discrete messages, and stream buffers, which store a     * continuous stream of bytes.  Discrete messages include an additional     * sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the message. */    if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )    {        xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;    }    else    {        xBytesToStoreMessageLength = 0;    }    /* True if the available space equals zero. */    if( xStreamBufferSpacesAvailable( xStreamBuffer ) <= xBytesToStoreMessageLength )    {        xReturn = pdTRUE;    }    else    {        xReturn = pdFALSE;    }    return xReturn;}/*-----------------------------------------------------------*/BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer,                                              BaseType_t * pxHigherPriorityTaskWoken ){    StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    BaseType_t xReturn;    UBaseType_t uxSavedInterruptStatus;    configASSERT( pxStreamBuffer );    uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();    {        if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )        {            ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive,                                         ( uint32_t ) 0,                                         eNoAction,                                         pxHigherPriorityTaskWoken );            ( pxStreamBuffer )->xTaskWaitingToReceive = NULL;            xReturn = pdTRUE;        }        else        {            xReturn = pdFALSE;        }    }    portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );    return xReturn;}/*-----------------------------------------------------------*/BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,                                                 BaseType_t * pxHigherPriorityTaskWoken ){    StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;    BaseType_t xReturn;    UBaseType_t uxSavedInterruptStatus;    configASSERT( pxStreamBuffer );    uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR();    {        if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )        {            ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend,                                         ( uint32_t ) 0,                                         eNoAction,                                         pxHigherPriorityTaskWoken );            ( pxStreamBuffer )->xTaskWaitingToSend = NULL;            xReturn = pdTRUE;        }        else        {            xReturn = pdFALSE;        }    }    portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );    return xReturn;}/*-----------------------------------------------------------*/static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer,                                     const uint8_t * pucData,                                     size_t xCount ){    size_t xNextHead, xFirstLength;    configASSERT( xCount > ( size_t ) 0 );    xNextHead = pxStreamBuffer->xHead;    /* Calculate the number of bytes that can be added in the first write -     * which may be less than the total number of bytes that need to be added if     * the buffer will wrap back to the beginning. */    xFirstLength = configMIN( pxStreamBuffer->xLength - xNextHead, xCount );    /* Write as many bytes as can be written in the first write. */    configASSERT( ( xNextHead + xFirstLength ) <= pxStreamBuffer->xLength );    ( void ) memcpy( ( void * ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */    /* If the number of bytes written was less than the number that could be     * written in the first write... */    if( xCount > xFirstLength )    {        /* ...then write the remaining bytes to the start of the buffer. */        configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength );        ( void ) memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */    }    else    {        mtCOVERAGE_TEST_MARKER();    }    xNextHead += xCount;    if( xNextHead >= pxStreamBuffer->xLength )    {        xNextHead -= pxStreamBuffer->xLength;    }    else    {        mtCOVERAGE_TEST_MARKER();    }    pxStreamBuffer->xHead = xNextHead;    return xCount;}/*-----------------------------------------------------------*/static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer,                                      uint8_t * pucData,                                      size_t xMaxCount,                                      size_t xBytesAvailable ){    size_t xCount, xFirstLength, xNextTail;    /* Use the minimum of the wanted bytes and the available bytes. */    xCount = configMIN( xBytesAvailable, xMaxCount );    if( xCount > ( size_t ) 0 )    {        xNextTail = pxStreamBuffer->xTail;        /* Calculate the number of bytes that can be read - which may be         * less than the number wanted if the data wraps around to the start of         * the buffer. */        xFirstLength = configMIN( pxStreamBuffer->xLength - xNextTail, xCount );        /* Obtain the number of bytes it is possible to obtain in the first         * read.  Asserts check bounds of read and write. */        configASSERT( xFirstLength <= xMaxCount );        configASSERT( ( xNextTail + xFirstLength ) <= pxStreamBuffer->xLength );        ( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */        /* If the total number of wanted bytes is greater than the number         * that could be read in the first read... */        if( xCount > xFirstLength )        {            /*...then read the remaining bytes from the start of the buffer. */            configASSERT( xCount <= xMaxCount );            ( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */        }        else        {            mtCOVERAGE_TEST_MARKER();        }        /* Move the tail pointer to effectively remove the data read from         * the buffer. */        xNextTail += xCount;        if( xNextTail >= pxStreamBuffer->xLength )        {            xNextTail -= pxStreamBuffer->xLength;        }        pxStreamBuffer->xTail = xNextTail;    }    else    {        mtCOVERAGE_TEST_MARKER();    }    return xCount;}/*-----------------------------------------------------------*/static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ){/* Returns the distance between xTail and xHead. */    size_t xCount;    xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead;    xCount -= pxStreamBuffer->xTail;    if( xCount >= pxStreamBuffer->xLength )    {        xCount -= pxStreamBuffer->xLength;    }    else    {        mtCOVERAGE_TEST_MARKER();    }    return xCount;}/*-----------------------------------------------------------*/static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,                                          uint8_t * const pucBuffer,                                          size_t xBufferSizeBytes,                                          size_t xTriggerLevelBytes,                                          uint8_t ucFlags ){    /* Assert here is deliberately writing to the entire buffer to ensure it can     * be written to without generating exceptions, and is setting the buffer to a     * known value to assist in development/debugging. */    #if ( configASSERT_DEFINED == 1 )        {            /* The value written just has to be identifiable when looking at the             * memory.  Don't use 0xA5 as that is the stack fill value and could             * result in confusion as to what is actually being observed. */            const BaseType_t xWriteValue = 0x55;            configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer );        } /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */    #endif    ( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */    pxStreamBuffer->pucBuffer = pucBuffer;    pxStreamBuffer->xLength = xBufferSizeBytes;    pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes;    pxStreamBuffer->ucFlags = ucFlags;}#if ( configUSE_TRACE_FACILITY == 1 )    UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer )    {        return xStreamBuffer->uxStreamBufferNumber;    }#endif /* configUSE_TRACE_FACILITY *//*-----------------------------------------------------------*/#if ( configUSE_TRACE_FACILITY == 1 )    void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer,                                             UBaseType_t uxStreamBufferNumber )    {        xStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;    }#endif /* configUSE_TRACE_FACILITY *//*-----------------------------------------------------------*/#if ( configUSE_TRACE_FACILITY == 1 )    uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer )    {        return( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER );    }#endif /* configUSE_TRACE_FACILITY *//*-----------------------------------------------------------*/
 |