2022-02-24 07:14:22 -05:00
/*
2024-01-05 04:14:26 -05:00
* FreeRTOS Kernel V11 .0 .1
* Copyright ( C ) 2021 Amazon . com , Inc . or its affiliates . All Rights Reserved .
*
* SPDX - FileCopyrightText : 2021 Amazon . com , Inc . or its affiliates
*
* SPDX - License - Identifier : MIT
*
* SPDX - FileContributor : 2023 - 2024 Espressif Systems ( Shanghai ) CO LTD
2022-02-24 07:14:22 -05:00
*
* 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 <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
2024-01-05 04:14:26 -05:00
# if ( INCLUDE_xTaskGetCurrentTaskHandle != 1 )
# error INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 to build stream_buffer.c
# endif
/* The MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
2022-02-24 07:14:22 -05:00
* for the header files above , but not in this file , in order to generate the
* correct privileged Vs unprivileged linkage and placement . */
2024-01-05 04:14:26 -05:00
# undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
2022-02-24 07:14:22 -05:00
/* If the user has not provided application specific Rx notification macros,
* or # defined the notification macros away , then provide default implementations
* that uses task notifications . */
# ifndef sbRECEIVE_COMPLETED
2024-01-05 04:14:26 -05:00
# define sbRECEIVE_COMPLETED( pxStreamBuffer ) \
do \
{ \
vTaskSuspendAll ( ) ; \
{ \
if ( ( pxStreamBuffer ) - > xTaskWaitingToSend ! = NULL ) \
{ \
( void ) xTaskNotify ( ( pxStreamBuffer ) - > xTaskWaitingToSend , \
( uint32_t ) 0 , \
eNoAction ) ; \
( pxStreamBuffer ) - > xTaskWaitingToSend = NULL ; \
} \
} \
( void ) xTaskResumeAll ( ) ; \
} while ( 0 )
2022-02-24 07:14:22 -05:00
# endif /* sbRECEIVE_COMPLETED */
2024-01-05 04:14:26 -05:00
/* If user has provided a per-instance receive complete callback, then
* invoke the callback else use the receive complete macro which is provided by default for all instances .
*/
# if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
# define prvRECEIVE_COMPLETED( pxStreamBuffer ) \
do { \
if ( ( pxStreamBuffer ) - > pxReceiveCompletedCallback ! = NULL ) \
{ \
( pxStreamBuffer ) - > pxReceiveCompletedCallback ( ( pxStreamBuffer ) , pdFALSE , NULL ) ; \
} \
else \
{ \
sbRECEIVE_COMPLETED ( ( pxStreamBuffer ) ) ; \
} \
} while ( 0 )
# else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
# define prvRECEIVE_COMPLETED( pxStreamBuffer ) sbRECEIVE_COMPLETED( ( pxStreamBuffer ) )
# endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
2022-02-24 07:14:22 -05:00
# ifndef sbRECEIVE_COMPLETED_FROM_ISR
# define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \
pxHigherPriorityTaskWoken ) \
2024-01-05 04:14:26 -05:00
do { \
2022-02-24 07:14:22 -05:00
UBaseType_t uxSavedInterruptStatus ; \
\
2024-01-05 04:14:26 -05:00
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR ( ) ; \
2022-02-24 07:14:22 -05:00
{ \
if ( ( pxStreamBuffer ) - > xTaskWaitingToSend ! = NULL ) \
{ \
( void ) xTaskNotifyFromISR ( ( pxStreamBuffer ) - > xTaskWaitingToSend , \
( uint32_t ) 0 , \
eNoAction , \
2024-01-05 04:14:26 -05:00
( pxHigherPriorityTaskWoken ) ) ; \
2022-02-24 07:14:22 -05:00
( pxStreamBuffer ) - > xTaskWaitingToSend = NULL ; \
} \
} \
2024-01-05 04:14:26 -05:00
taskEXIT_CRITICAL_FROM_ISR ( uxSavedInterruptStatus ) ; \
} while ( 0 )
2022-02-24 07:14:22 -05:00
# endif /* sbRECEIVE_COMPLETED_FROM_ISR */
2024-01-05 04:14:26 -05:00
# if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
# define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \
pxHigherPriorityTaskWoken ) \
do { \
if ( ( pxStreamBuffer ) - > pxReceiveCompletedCallback ! = NULL ) \
{ \
( pxStreamBuffer ) - > pxReceiveCompletedCallback ( ( pxStreamBuffer ) , pdTRUE , ( pxHigherPriorityTaskWoken ) ) ; \
} \
else \
{ \
sbRECEIVE_COMPLETED_FROM_ISR ( ( pxStreamBuffer ) , ( pxHigherPriorityTaskWoken ) ) ; \
} \
} while ( 0 )
# else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
# define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
sbRECEIVE_COMPLETED_FROM_ISR ( ( pxStreamBuffer ) , ( pxHigherPriorityTaskWoken ) )
# endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
2022-02-24 07:14:22 -05:00
/* If the user has not provided an application specific Tx notification macro,
2024-01-05 04:14:26 -05:00
* or # defined the notification macro away , then provide a default
* implementation that uses task notifications .
*/
2022-02-24 07:14:22 -05:00
# ifndef sbSEND_COMPLETED
# define sbSEND_COMPLETED( pxStreamBuffer ) \
vTaskSuspendAll ( ) ; \
{ \
if ( ( pxStreamBuffer ) - > xTaskWaitingToReceive ! = NULL ) \
{ \
( void ) xTaskNotify ( ( pxStreamBuffer ) - > xTaskWaitingToReceive , \
( uint32_t ) 0 , \
eNoAction ) ; \
( pxStreamBuffer ) - > xTaskWaitingToReceive = NULL ; \
} \
} \
2024-01-05 04:14:26 -05:00
( void ) xTaskResumeAll ( )
2022-02-24 07:14:22 -05:00
# endif /* sbSEND_COMPLETED */
2024-01-05 04:14:26 -05:00
/* If user has provided a per-instance send completed callback, then
* invoke the callback else use the send complete macro which is provided by default for all instances .
*/
# if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
# define prvSEND_COMPLETED( pxStreamBuffer ) \
do { \
if ( ( pxStreamBuffer ) - > pxSendCompletedCallback ! = NULL ) \
{ \
( pxStreamBuffer ) - > pxSendCompletedCallback ( ( pxStreamBuffer ) , pdFALSE , NULL ) ; \
} \
else \
{ \
sbSEND_COMPLETED ( ( pxStreamBuffer ) ) ; \
} \
} while ( 0 )
# else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
# define prvSEND_COMPLETED( pxStreamBuffer ) sbSEND_COMPLETED( ( pxStreamBuffer ) )
# endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
2022-02-24 07:14:22 -05:00
# ifndef sbSEND_COMPLETE_FROM_ISR
# define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
2024-01-05 04:14:26 -05:00
do { \
2022-02-24 07:14:22 -05:00
UBaseType_t uxSavedInterruptStatus ; \
\
2024-01-05 04:14:26 -05:00
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR ( ) ; \
2022-02-24 07:14:22 -05:00
{ \
if ( ( pxStreamBuffer ) - > xTaskWaitingToReceive ! = NULL ) \
{ \
( void ) xTaskNotifyFromISR ( ( pxStreamBuffer ) - > xTaskWaitingToReceive , \
( uint32_t ) 0 , \
eNoAction , \
2024-01-05 04:14:26 -05:00
( pxHigherPriorityTaskWoken ) ) ; \
2022-02-24 07:14:22 -05:00
( pxStreamBuffer ) - > xTaskWaitingToReceive = NULL ; \
} \
} \
2024-01-05 04:14:26 -05:00
taskEXIT_CRITICAL_FROM_ISR ( uxSavedInterruptStatus ) ; \
} while ( 0 )
2022-02-24 07:14:22 -05:00
# endif /* sbSEND_COMPLETE_FROM_ISR */
2024-01-05 04:14:26 -05:00
# if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
# define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
do { \
if ( ( pxStreamBuffer ) - > pxSendCompletedCallback ! = NULL ) \
{ \
( pxStreamBuffer ) - > pxSendCompletedCallback ( ( pxStreamBuffer ) , pdTRUE , ( pxHigherPriorityTaskWoken ) ) ; \
} \
else \
{ \
sbSEND_COMPLETE_FROM_ISR ( ( pxStreamBuffer ) , ( pxHigherPriorityTaskWoken ) ) ; \
} \
} while ( 0 )
# else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
# define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
sbSEND_COMPLETE_FROM_ISR ( ( pxStreamBuffer ) , ( pxHigherPriorityTaskWoken ) )
# endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
2022-02-24 07:14:22 -05:00
/* 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. */
2024-01-05 04:14:26 -05:00
typedef struct StreamBufferDef_t
2022-02-24 07:14:22 -05:00
{
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
2024-01-05 04:14:26 -05:00
# if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
StreamBufferCallbackFunction_t pxSendCompletedCallback ; /* Optional callback called on send complete. sbSEND_COMPLETED is called if this is NULL. */
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ; /* Optional callback called on receive complete. sbRECEIVE_COMPLETED is called if this is NULL. */
# endif
2022-02-24 07:14:22 -05:00
} StreamBuffer_t ;
/*
* The number of bytes available to be read from the buffer .
*/
static size_t prvBytesInBuffer ( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION ;
/*
2024-01-05 04:14:26 -05:00
* Add xCount bytes from pucData into the pxStreamBuffer ' s data storage area .
* This function does not update the buffer ' s xHead pointer , so multiple writes
* may be chained together " atomically " . This is useful for Message Buffers where
* the length and data bytes are written in two separate chunks , and we don ' t want
* the reader to see the buffer as having grown until after all data is copied over .
* This function takes a custom xHead value to indicate where to write to ( necessary
* for chaining ) and returns the the resulting xHead position .
* To mark the write as complete , manually set the buffer ' s xHead field with the
* returned xHead from this function .
2022-02-24 07:14:22 -05:00
*/
static size_t prvWriteBytesToBuffer ( StreamBuffer_t * const pxStreamBuffer ,
const uint8_t * pucData ,
2024-01-05 04:14:26 -05:00
size_t xCount ,
size_t xHead ) PRIVILEGED_FUNCTION ;
2022-02-24 07:14:22 -05:00
/*
* 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 ,
2024-01-05 04:14:26 -05:00
size_t xBytesAvailable ) PRIVILEGED_FUNCTION ;
2022-02-24 07:14:22 -05:00
/*
* 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 ;
/*
2024-01-05 04:14:26 -05:00
* Copies xCount bytes from the pxStreamBuffer ' s data storage area to pucData .
* This function does not update the buffer ' s xTail pointer , so multiple reads
* may be chained together " atomically " . This is useful for Message Buffers where
* the length and data bytes are read in two separate chunks , and we don ' t want
* the writer to see the buffer as having more free space until after all data is
* copied over , especially if we have to abort the read due to insufficient receiving space .
* This function takes a custom xTail value to indicate where to read from ( necessary
* for chaining ) and returns the the resulting xTail position .
* To mark the read as complete , manually set the buffer ' s xTail field with the
* returned xTail from this function .
2022-02-24 07:14:22 -05:00
*/
static size_t prvReadBytesFromBuffer ( StreamBuffer_t * pxStreamBuffer ,
uint8_t * pucData ,
2024-01-05 04:14:26 -05:00
size_t xCount ,
size_t xTail ) PRIVILEGED_FUNCTION ;
2022-02-24 07:14:22 -05:00
/*
* 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 ,
2024-01-05 04:14:26 -05:00
uint8_t ucFlags ,
StreamBufferCallbackFunction_t pxSendCompletedCallback ,
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION ;
2022-02-24 07:14:22 -05:00
/*-----------------------------------------------------------*/
# if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
StreamBufferHandle_t xStreamBufferGenericCreate ( size_t xBufferSizeBytes ,
size_t xTriggerLevelBytes ,
2024-01-05 04:14:26 -05:00
BaseType_t xIsMessageBuffer ,
StreamBufferCallbackFunction_t pxSendCompletedCallback ,
StreamBufferCallbackFunction_t pxReceiveCompletedCallback )
2022-02-24 07:14:22 -05:00
{
2024-01-05 04:14:26 -05:00
void * pvAllocatedMemory ;
2022-02-24 07:14:22 -05:00
uint8_t ucFlags ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferGenericCreate ( xBufferSizeBytes , xTriggerLevelBytes , xIsMessageBuffer , pxSendCompletedCallback , pxReceiveCompletedCallback ) ;
2022-02-24 07:14:22 -05:00
/* 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 . */
2024-01-05 04:14:26 -05:00
if ( xBufferSizeBytes < ( xBufferSizeBytes + 1U + sizeof ( StreamBuffer_t ) ) )
2022-02-24 07:14:22 -05:00
{
xBufferSizeBytes + + ;
2024-01-05 04:14:26 -05:00
pvAllocatedMemory = pvPortMalloc ( xBufferSizeBytes + sizeof ( StreamBuffer_t ) ) ;
2022-02-24 07:14:22 -05:00
}
else
{
2024-01-05 04:14:26 -05:00
pvAllocatedMemory = NULL ;
2022-02-24 07:14:22 -05:00
}
2024-01-05 04:14:26 -05:00
if ( pvAllocatedMemory ! = NULL )
2022-02-24 07:14:22 -05:00
{
2024-01-05 04:14:26 -05:00
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
prvInitialiseNewStreamBuffer ( ( StreamBuffer_t * ) pvAllocatedMemory , /* Structure at the start of the allocated memory. */
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
( ( uint8_t * ) pvAllocatedMemory ) + sizeof ( StreamBuffer_t ) , /* Storage area follows. */
2022-02-24 07:14:22 -05:00
xBufferSizeBytes ,
xTriggerLevelBytes ,
2024-01-05 04:14:26 -05:00
ucFlags ,
pxSendCompletedCallback ,
pxReceiveCompletedCallback ) ;
2022-02-24 07:14:22 -05:00
2024-01-05 04:14:26 -05:00
traceSTREAM_BUFFER_CREATE ( ( ( StreamBuffer_t * ) pvAllocatedMemory ) , xIsMessageBuffer ) ;
2022-02-24 07:14:22 -05:00
}
else
{
traceSTREAM_BUFFER_CREATE_FAILED ( xIsMessageBuffer ) ;
}
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferGenericCreate ( pvAllocatedMemory ) ;
2022-02-24 07:14:22 -05:00
2024-01-05 04:14:26 -05:00
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
return ( StreamBufferHandle_t ) pvAllocatedMemory ;
}
2022-02-24 07:14:22 -05:00
# 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 ,
2024-01-05 04:14:26 -05:00
StaticStreamBuffer_t * const pxStaticStreamBuffer ,
StreamBufferCallbackFunction_t pxSendCompletedCallback ,
StreamBufferCallbackFunction_t pxReceiveCompletedCallback )
2022-02-24 07:14:22 -05:00
{
2024-01-05 04:14:26 -05:00
/* MISRA Ref 11.3.1 [Misaligned access] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */
/* coverity[misra_c_2012_rule_11_3_violation] */
StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer ;
2022-02-24 07:14:22 -05:00
StreamBufferHandle_t xReturn ;
uint8_t ucFlags ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferGenericCreateStatic ( xBufferSizeBytes , xTriggerLevelBytes , xIsMessageBuffer , pucStreamBufferStorageArea , pxStaticStreamBuffer , pxSendCompletedCallback , pxReceiveCompletedCallback ) ;
2022-02-24 07:14:22 -05:00
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 ;
}
2024-01-05 04:14:26 -05:00
/* 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 . */
2022-02-24 07:14:22 -05:00
if ( xIsMessageBuffer ! = pdFALSE )
{
/* Statically allocated message buffer. */
ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED ;
2024-01-05 04:14:26 -05:00
configASSERT ( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ) ;
2022-02-24 07:14:22 -05:00
}
else
{
/* Statically allocated stream buffer. */
ucFlags = sbFLAGS_IS_STATICALLY_ALLOCATED ;
}
# if ( configASSERT_DEFINED == 1 )
2024-01-05 04:14:26 -05:00
{
/* 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 ) ) ;
}
2022-02-24 07:14:22 -05:00
# endif /* configASSERT_DEFINED */
if ( ( pucStreamBufferStorageArea ! = NULL ) & & ( pxStaticStreamBuffer ! = NULL ) )
{
prvInitialiseNewStreamBuffer ( pxStreamBuffer ,
pucStreamBufferStorageArea ,
xBufferSizeBytes ,
xTriggerLevelBytes ,
2024-01-05 04:14:26 -05:00
ucFlags ,
pxSendCompletedCallback ,
pxReceiveCompletedCallback ) ;
2022-02-24 07:14:22 -05:00
/* Remember this was statically allocated in case it is ever deleted
* again . */
pxStreamBuffer - > ucFlags | = sbFLAGS_IS_STATICALLY_ALLOCATED ;
traceSTREAM_BUFFER_CREATE ( pxStreamBuffer , xIsMessageBuffer ) ;
2024-01-05 04:14:26 -05:00
/* MISRA Ref 11.3.1 [Misaligned access] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */
/* coverity[misra_c_2012_rule_11_3_violation] */
xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer ;
2022-02-24 07:14:22 -05:00
}
else
{
xReturn = NULL ;
traceSTREAM_BUFFER_CREATE_STATIC_FAILED ( xReturn , xIsMessageBuffer ) ;
}
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferGenericCreateStatic ( xReturn ) ;
2022-02-24 07:14:22 -05:00
return xReturn ;
}
# endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
/*-----------------------------------------------------------*/
2023-03-21 09:29:52 -04:00
# if ( configSUPPORT_STATIC_ALLOCATION == 1 )
BaseType_t xStreamBufferGetStaticBuffers ( StreamBufferHandle_t xStreamBuffer ,
uint8_t * * ppucStreamBufferStorageArea ,
StaticStreamBuffer_t * * ppxStaticStreamBuffer )
{
BaseType_t xReturn ;
2024-01-05 04:14:26 -05:00
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer ;
traceENTER_xStreamBufferGetStaticBuffers ( xStreamBuffer , ppucStreamBufferStorageArea , ppxStaticStreamBuffer ) ;
2023-03-21 09:29:52 -04:00
configASSERT ( pxStreamBuffer ) ;
configASSERT ( ppucStreamBufferStorageArea ) ;
configASSERT ( ppxStaticStreamBuffer ) ;
if ( ( pxStreamBuffer - > ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) ! = ( uint8_t ) 0 )
{
* ppucStreamBufferStorageArea = pxStreamBuffer - > pucBuffer ;
2024-01-05 04:14:26 -05:00
/* MISRA Ref 11.3.1 [Misaligned access] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */
/* coverity[misra_c_2012_rule_11_3_violation] */
2023-03-21 09:29:52 -04:00
* ppxStaticStreamBuffer = ( StaticStreamBuffer_t * ) pxStreamBuffer ;
xReturn = pdTRUE ;
}
else
{
xReturn = pdFALSE ;
}
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferGetStaticBuffers ( xReturn ) ;
2023-03-21 09:29:52 -04:00
return xReturn ;
}
# endif /* configSUPPORT_STATIC_ALLOCATION */
/*-----------------------------------------------------------*/
2022-02-24 07:14:22 -05:00
void vStreamBufferDelete ( StreamBufferHandle_t xStreamBuffer )
{
StreamBuffer_t * pxStreamBuffer = xStreamBuffer ;
2024-01-05 04:14:26 -05:00
traceENTER_vStreamBufferDelete ( xStreamBuffer ) ;
2022-02-24 07:14:22 -05:00
configASSERT ( pxStreamBuffer ) ;
traceSTREAM_BUFFER_DELETE ( xStreamBuffer ) ;
if ( ( pxStreamBuffer - > ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) = = ( uint8_t ) pdFALSE )
{
# if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
2024-01-05 04:14:26 -05:00
{
/* 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 ) ;
}
2022-02-24 07:14:22 -05:00
# else
2024-01-05 04:14:26 -05:00
{
/* Should not be possible to get here, ucFlags must be corrupt.
* Force an assert . */
configASSERT ( xStreamBuffer = = ( StreamBufferHandle_t ) ~ 0 ) ;
}
2022-02-24 07:14:22 -05:00
# 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 ) ) ;
}
2024-01-05 04:14:26 -05:00
traceRETURN_vStreamBufferDelete ( ) ;
2022-02-24 07:14:22 -05:00
}
/*-----------------------------------------------------------*/
BaseType_t xStreamBufferReset ( StreamBufferHandle_t xStreamBuffer )
{
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer ;
BaseType_t xReturn = pdFAIL ;
2024-01-05 04:14:26 -05:00
StreamBufferCallbackFunction_t pxSendCallback = NULL , pxReceiveCallback = NULL ;
2022-02-24 07:14:22 -05:00
# if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxStreamBufferNumber ;
# endif
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferReset ( xStreamBuffer ) ;
2022-02-24 07:14:22 -05:00
configASSERT ( pxStreamBuffer ) ;
# if ( configUSE_TRACE_FACILITY == 1 )
2024-01-05 04:14:26 -05:00
{
/* Store the stream buffer number so it can be restored after the
* reset . */
uxStreamBufferNumber = pxStreamBuffer - > uxStreamBufferNumber ;
}
2022-02-24 07:14:22 -05:00
# endif
/* Can only reset a message buffer if there are no tasks blocked on it. */
taskENTER_CRITICAL ( ) ;
{
2024-01-05 04:14:26 -05:00
if ( ( pxStreamBuffer - > xTaskWaitingToReceive = = NULL ) & & ( pxStreamBuffer - > xTaskWaitingToSend = = NULL ) )
2022-02-24 07:14:22 -05:00
{
2024-01-05 04:14:26 -05:00
# if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
{
pxSendCallback = pxStreamBuffer - > pxSendCompletedCallback ;
pxReceiveCallback = pxStreamBuffer - > pxReceiveCompletedCallback ;
}
# endif
prvInitialiseNewStreamBuffer ( pxStreamBuffer ,
pxStreamBuffer - > pucBuffer ,
pxStreamBuffer - > xLength ,
pxStreamBuffer - > xTriggerLevelBytes ,
pxStreamBuffer - > ucFlags ,
pxSendCallback ,
pxReceiveCallback ) ;
# if ( configUSE_TRACE_FACILITY == 1 )
2022-02-24 07:14:22 -05:00
{
2024-01-05 04:14:26 -05:00
pxStreamBuffer - > uxStreamBufferNumber = uxStreamBufferNumber ;
2022-02-24 07:14:22 -05:00
}
2024-01-05 04:14:26 -05:00
# endif
traceSTREAM_BUFFER_RESET ( xStreamBuffer ) ;
xReturn = pdPASS ;
2022-02-24 07:14:22 -05:00
}
}
taskEXIT_CRITICAL ( ) ;
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferReset ( xReturn ) ;
2022-02-24 07:14:22 -05:00
return xReturn ;
}
/*-----------------------------------------------------------*/
BaseType_t xStreamBufferSetTriggerLevel ( StreamBufferHandle_t xStreamBuffer ,
size_t xTriggerLevel )
{
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer ;
BaseType_t xReturn ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferSetTriggerLevel ( xStreamBuffer , xTriggerLevel ) ;
2022-02-24 07:14:22 -05:00
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 ;
}
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferSetTriggerLevel ( xReturn ) ;
2022-02-24 07:14:22 -05:00
return xReturn ;
}
/*-----------------------------------------------------------*/
size_t xStreamBufferSpacesAvailable ( StreamBufferHandle_t xStreamBuffer )
{
const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer ;
size_t xSpace ;
2024-01-05 04:14:26 -05:00
size_t xOriginalTail ;
traceENTER_xStreamBufferSpacesAvailable ( xStreamBuffer ) ;
2022-02-24 07:14:22 -05:00
configASSERT ( pxStreamBuffer ) ;
2024-01-05 04:14:26 -05:00
/* The code below reads xTail and then xHead. This is safe if the stream
* buffer is updated once between the two reads - but not if the stream buffer
* is updated more than once between the two reads - hence the loop . */
do
{
xOriginalTail = pxStreamBuffer - > xTail ;
xSpace = pxStreamBuffer - > xLength + pxStreamBuffer - > xTail ;
xSpace - = pxStreamBuffer - > xHead ;
} while ( xOriginalTail ! = pxStreamBuffer - > xTail ) ;
2022-02-24 07:14:22 -05:00
xSpace - = ( size_t ) 1 ;
if ( xSpace > = pxStreamBuffer - > xLength )
{
xSpace - = pxStreamBuffer - > xLength ;
}
else
{
mtCOVERAGE_TEST_MARKER ( ) ;
}
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferSpacesAvailable ( xSpace ) ;
2022-02-24 07:14:22 -05:00
return xSpace ;
}
/*-----------------------------------------------------------*/
size_t xStreamBufferBytesAvailable ( StreamBufferHandle_t xStreamBuffer )
{
const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer ;
size_t xReturn ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferBytesAvailable ( xStreamBuffer ) ;
2022-02-24 07:14:22 -05:00
configASSERT ( pxStreamBuffer ) ;
xReturn = prvBytesInBuffer ( pxStreamBuffer ) ;
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferBytesAvailable ( xReturn ) ;
2022-02-24 07:14:22 -05:00
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 ;
size_t xMaxReportedSpace = 0 ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferSend ( xStreamBuffer , pvTxData , xDataLengthBytes , xTicksToWait ) ;
2022-02-24 07:14:22 -05:00
configASSERT ( pvTxData ) ;
configASSERT ( pxStreamBuffer ) ;
/* The maximum amount of space a stream buffer will ever report is its length
* minus 1. */
xMaxReportedSpace = pxStreamBuffer - > xLength - ( size_t ) 1 ;
/* 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 )
{
2024-01-05 04:14:26 -05:00
prvSEND_COMPLETED ( pxStreamBuffer ) ;
2022-02-24 07:14:22 -05:00
}
else
{
mtCOVERAGE_TEST_MARKER ( ) ;
}
}
else
{
mtCOVERAGE_TEST_MARKER ( ) ;
traceSTREAM_BUFFER_SEND_FAILED ( xStreamBuffer ) ;
}
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferSend ( xReturn ) ;
2022-02-24 07:14:22 -05:00
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 ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferSendFromISR ( xStreamBuffer , pvTxData , xDataLengthBytes , pxHigherPriorityTaskWoken ) ;
2022-02-24 07:14:22 -05:00
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 )
{
2024-01-05 04:14:26 -05:00
prvSEND_COMPLETE_FROM_ISR ( pxStreamBuffer , pxHigherPriorityTaskWoken ) ;
2022-02-24 07:14:22 -05:00
}
else
{
mtCOVERAGE_TEST_MARKER ( ) ;
}
}
else
{
mtCOVERAGE_TEST_MARKER ( ) ;
}
traceSTREAM_BUFFER_SEND_FROM_ISR ( xStreamBuffer , xReturn ) ;
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferSendFromISR ( xReturn ) ;
2022-02-24 07:14:22 -05:00
return xReturn ;
}
/*-----------------------------------------------------------*/
static size_t prvWriteMessageToBuffer ( StreamBuffer_t * const pxStreamBuffer ,
const void * pvTxData ,
size_t xDataLengthBytes ,
size_t xSpace ,
size_t xRequiredSpace )
{
2024-01-05 04:14:26 -05:00
size_t xNextHead = pxStreamBuffer - > xHead ;
configMESSAGE_BUFFER_LENGTH_TYPE xMessageLength ;
2022-02-24 07:14:22 -05:00
2024-01-05 04:14:26 -05:00
if ( ( pxStreamBuffer - > ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) ! = ( uint8_t ) 0 )
2022-02-24 07:14:22 -05:00
{
2024-01-05 04:14:26 -05:00
/* This is a message buffer, as opposed to a stream buffer. */
/* Convert xDataLengthBytes to the message length type. */
xMessageLength = ( configMESSAGE_BUFFER_LENGTH_TYPE ) xDataLengthBytes ;
/* Ensure the data length given fits within configMESSAGE_BUFFER_LENGTH_TYPE. */
configASSERT ( ( size_t ) xMessageLength = = xDataLengthBytes ) ;
if ( xSpace > = xRequiredSpace )
{
/* 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 . */
xNextHead = prvWriteBytesToBuffer ( pxStreamBuffer , ( const uint8_t * ) & ( xMessageLength ) , sbBYTES_TO_STORE_MESSAGE_LENGTH , xNextHead ) ;
}
else
{
/* Not enough space, so do not write data to the buffer. */
xDataLengthBytes = 0 ;
}
2022-02-24 07:14:22 -05:00
}
2024-01-05 04:14:26 -05:00
else
2022-02-24 07:14:22 -05:00
{
/* This is a stream buffer, as opposed to a message buffer, so writing a
2024-01-05 04:14:26 -05:00
* stream of bytes rather than discrete messages . Plan to write as many
* bytes as possible . */
2022-02-24 07:14:22 -05:00
xDataLengthBytes = configMIN ( xDataLengthBytes , xSpace ) ;
}
2024-01-05 04:14:26 -05:00
if ( xDataLengthBytes ! = ( size_t ) 0 )
2022-02-24 07:14:22 -05:00
{
2024-01-05 04:14:26 -05:00
/* Write the data to the buffer. */
/* MISRA Ref 11.5.5 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxStreamBuffer - > xHead = prvWriteBytesToBuffer ( pxStreamBuffer , ( const uint8_t * ) pvTxData , xDataLengthBytes , xNextHead ) ;
2022-02-24 07:14:22 -05:00
}
2024-01-05 04:14:26 -05:00
return xDataLengthBytes ;
2022-02-24 07:14:22 -05:00
}
/*-----------------------------------------------------------*/
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 ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferReceive ( xStreamBuffer , pvRxData , xBufferLengthBytes , xTicksToWait ) ;
2022-02-24 07:14:22 -05:00
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 )
{
2024-01-05 04:14:26 -05:00
xReceivedLength = prvReadMessageFromBuffer ( pxStreamBuffer , pvRxData , xBufferLengthBytes , xBytesAvailable ) ;
2022-02-24 07:14:22 -05:00
/* Was a task waiting for space in the buffer? */
if ( xReceivedLength ! = ( size_t ) 0 )
{
traceSTREAM_BUFFER_RECEIVE ( xStreamBuffer , xReceivedLength ) ;
2024-01-05 04:14:26 -05:00
prvRECEIVE_COMPLETED ( xStreamBuffer ) ;
2022-02-24 07:14:22 -05:00
}
else
{
mtCOVERAGE_TEST_MARKER ( ) ;
}
}
else
{
traceSTREAM_BUFFER_RECEIVE_FAILED ( xStreamBuffer ) ;
mtCOVERAGE_TEST_MARKER ( ) ;
}
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferReceive ( xReceivedLength ) ;
2022-02-24 07:14:22 -05:00
return xReceivedLength ;
}
/*-----------------------------------------------------------*/
size_t xStreamBufferNextMessageLengthBytes ( StreamBufferHandle_t xStreamBuffer )
{
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer ;
2024-01-05 04:14:26 -05:00
size_t xReturn , xBytesAvailable ;
2022-02-24 07:14:22 -05:00
configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferNextMessageLengthBytes ( xStreamBuffer ) ;
2022-02-24 07:14:22 -05:00
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
2024-01-05 04:14:26 -05:00
* is available . */
( void ) prvReadBytesFromBuffer ( pxStreamBuffer , ( uint8_t * ) & xTempReturn , sbBYTES_TO_STORE_MESSAGE_LENGTH , pxStreamBuffer - > xTail ) ;
2022-02-24 07:14:22 -05:00
xReturn = ( size_t ) xTempReturn ;
}
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 ;
}
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferNextMessageLengthBytes ( xReturn ) ;
2022-02-24 07:14:22 -05:00
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 ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferReceiveFromISR ( xStreamBuffer , pvRxData , xBufferLengthBytes , pxHigherPriorityTaskWoken ) ;
2022-02-24 07:14:22 -05:00
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 )
{
2024-01-05 04:14:26 -05:00
xReceivedLength = prvReadMessageFromBuffer ( pxStreamBuffer , pvRxData , xBufferLengthBytes , xBytesAvailable ) ;
2022-02-24 07:14:22 -05:00
/* Was a task waiting for space in the buffer? */
if ( xReceivedLength ! = ( size_t ) 0 )
{
2024-01-05 04:14:26 -05:00
prvRECEIVE_COMPLETED_FROM_ISR ( pxStreamBuffer , pxHigherPriorityTaskWoken ) ;
2022-02-24 07:14:22 -05:00
}
else
{
mtCOVERAGE_TEST_MARKER ( ) ;
}
}
else
{
mtCOVERAGE_TEST_MARKER ( ) ;
}
traceSTREAM_BUFFER_RECEIVE_FROM_ISR ( xStreamBuffer , xReceivedLength ) ;
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferReceiveFromISR ( xReceivedLength ) ;
2022-02-24 07:14:22 -05:00
return xReceivedLength ;
}
/*-----------------------------------------------------------*/
static size_t prvReadMessageFromBuffer ( StreamBuffer_t * pxStreamBuffer ,
void * pvRxData ,
size_t xBufferLengthBytes ,
2024-01-05 04:14:26 -05:00
size_t xBytesAvailable )
2022-02-24 07:14:22 -05:00
{
2024-01-05 04:14:26 -05:00
size_t xCount , xNextMessageLength ;
2022-02-24 07:14:22 -05:00
configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength ;
2024-01-05 04:14:26 -05:00
size_t xNextTail = pxStreamBuffer - > xTail ;
2022-02-24 07:14:22 -05:00
2024-01-05 04:14:26 -05:00
if ( ( pxStreamBuffer - > ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) ! = ( uint8_t ) 0 )
2022-02-24 07:14:22 -05:00
{
/* A discrete message is being received. First receive the length
2024-01-05 04:14:26 -05:00
* of the message . */
xNextTail = prvReadBytesFromBuffer ( pxStreamBuffer , ( uint8_t * ) & xTempNextMessageLength , sbBYTES_TO_STORE_MESSAGE_LENGTH , xNextTail ) ;
2022-02-24 07:14:22 -05:00
xNextMessageLength = ( size_t ) xTempNextMessageLength ;
/* Reduce the number of bytes available by the number of bytes just
* read out . */
2024-01-05 04:14:26 -05:00
xBytesAvailable - = sbBYTES_TO_STORE_MESSAGE_LENGTH ;
2022-02-24 07:14:22 -05:00
/* Check there is enough space in the buffer provided by the
* user . */
if ( xNextMessageLength > xBufferLengthBytes )
{
2024-01-05 04:14:26 -05:00
/* The user has provided insufficient space to read the message. */
2022-02-24 07:14:22 -05:00
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 ;
}
2024-01-05 04:14:26 -05:00
/* Use the minimum of the wanted bytes and the available bytes. */
xCount = configMIN ( xNextMessageLength , xBytesAvailable ) ;
2022-02-24 07:14:22 -05:00
2024-01-05 04:14:26 -05:00
if ( xCount ! = ( size_t ) 0 )
{
/* Read the actual data and update the tail to mark the data as officially consumed. */
/* MISRA Ref 11.5.5 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxStreamBuffer - > xTail = prvReadBytesFromBuffer ( pxStreamBuffer , ( uint8_t * ) pvRxData , xCount , xNextTail ) ;
}
return xCount ;
2022-02-24 07:14:22 -05:00
}
/*-----------------------------------------------------------*/
BaseType_t xStreamBufferIsEmpty ( StreamBufferHandle_t xStreamBuffer )
{
const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer ;
BaseType_t xReturn ;
size_t xTail ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferIsEmpty ( xStreamBuffer ) ;
2022-02-24 07:14:22 -05:00
configASSERT ( pxStreamBuffer ) ;
/* True if no bytes are available. */
xTail = pxStreamBuffer - > xTail ;
if ( pxStreamBuffer - > xHead = = xTail )
{
xReturn = pdTRUE ;
}
else
{
xReturn = pdFALSE ;
}
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferIsEmpty ( xReturn ) ;
2022-02-24 07:14:22 -05:00
return xReturn ;
}
/*-----------------------------------------------------------*/
BaseType_t xStreamBufferIsFull ( StreamBufferHandle_t xStreamBuffer )
{
BaseType_t xReturn ;
size_t xBytesToStoreMessageLength ;
const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferIsFull ( xStreamBuffer ) ;
2022-02-24 07:14:22 -05:00
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 ;
}
2024-01-05 04:14:26 -05:00
traceRETURN_xStreamBufferIsFull ( xReturn ) ;
2022-02-24 07:14:22 -05:00
return xReturn ;
}
/*-----------------------------------------------------------*/
BaseType_t xStreamBufferSendCompletedFromISR ( StreamBufferHandle_t xStreamBuffer ,
BaseType_t * pxHigherPriorityTaskWoken )
{
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer ;
BaseType_t xReturn ;
UBaseType_t uxSavedInterruptStatus ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferSendCompletedFromISR ( xStreamBuffer , pxHigherPriorityTaskWoken ) ;
2022-02-24 07:14:22 -05:00
configASSERT ( pxStreamBuffer ) ;
2024-01-05 04:14:26 -05:00
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR ( ) ;
2022-02-24 07:14:22 -05:00
{
if ( ( pxStreamBuffer ) - > xTaskWaitingToReceive ! = NULL )
{
( void ) xTaskNotifyFromISR ( ( pxStreamBuffer ) - > xTaskWaitingToReceive ,
( uint32_t ) 0 ,
eNoAction ,
pxHigherPriorityTaskWoken ) ;
( pxStreamBuffer ) - > xTaskWaitingToReceive = NULL ;
xReturn = pdTRUE ;
}
else
{
xReturn = pdFALSE ;
}
}
2024-01-05 04:14:26 -05:00
taskEXIT_CRITICAL_FROM_ISR ( uxSavedInterruptStatus ) ;
traceRETURN_xStreamBufferSendCompletedFromISR ( xReturn ) ;
2022-02-24 07:14:22 -05:00
return xReturn ;
}
/*-----------------------------------------------------------*/
BaseType_t xStreamBufferReceiveCompletedFromISR ( StreamBufferHandle_t xStreamBuffer ,
BaseType_t * pxHigherPriorityTaskWoken )
{
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer ;
BaseType_t xReturn ;
UBaseType_t uxSavedInterruptStatus ;
2024-01-05 04:14:26 -05:00
traceENTER_xStreamBufferReceiveCompletedFromISR ( xStreamBuffer , pxHigherPriorityTaskWoken ) ;
2022-02-24 07:14:22 -05:00
configASSERT ( pxStreamBuffer ) ;
2024-01-05 04:14:26 -05:00
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR ( ) ;
2022-02-24 07:14:22 -05:00
{
if ( ( pxStreamBuffer ) - > xTaskWaitingToSend ! = NULL )
{
( void ) xTaskNotifyFromISR ( ( pxStreamBuffer ) - > xTaskWaitingToSend ,
( uint32_t ) 0 ,
eNoAction ,
pxHigherPriorityTaskWoken ) ;
( pxStreamBuffer ) - > xTaskWaitingToSend = NULL ;
xReturn = pdTRUE ;
}
else
{
xReturn = pdFALSE ;
}
}
2024-01-05 04:14:26 -05:00
taskEXIT_CRITICAL_FROM_ISR ( uxSavedInterruptStatus ) ;
traceRETURN_xStreamBufferReceiveCompletedFromISR ( xReturn ) ;
2022-02-24 07:14:22 -05:00
return xReturn ;
}
/*-----------------------------------------------------------*/
static size_t prvWriteBytesToBuffer ( StreamBuffer_t * const pxStreamBuffer ,
const uint8_t * pucData ,
2024-01-05 04:14:26 -05:00
size_t xCount ,
size_t xHead )
2022-02-24 07:14:22 -05:00
{
2024-01-05 04:14:26 -05:00
size_t xFirstLength ;
2022-02-24 07:14:22 -05:00
configASSERT ( xCount > ( size_t ) 0 ) ;
/* 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 . */
2024-01-05 04:14:26 -05:00
xFirstLength = configMIN ( pxStreamBuffer - > xLength - xHead , xCount ) ;
2022-02-24 07:14:22 -05:00
/* Write as many bytes as can be written in the first write. */
2024-01-05 04:14:26 -05:00
configASSERT ( ( xHead + xFirstLength ) < = pxStreamBuffer - > xLength ) ;
( void ) memcpy ( ( void * ) ( & ( pxStreamBuffer - > pucBuffer [ xHead ] ) ) , ( const void * ) pucData , xFirstLength ) ;
2022-02-24 07:14:22 -05:00
/* 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 ) ;
2024-01-05 04:14:26 -05:00
( void ) memcpy ( ( void * ) pxStreamBuffer - > pucBuffer , ( const void * ) & ( pucData [ xFirstLength ] ) , xCount - xFirstLength ) ;
2022-02-24 07:14:22 -05:00
}
else
{
mtCOVERAGE_TEST_MARKER ( ) ;
}
2024-01-05 04:14:26 -05:00
xHead + = xCount ;
2022-02-24 07:14:22 -05:00
2024-01-05 04:14:26 -05:00
if ( xHead > = pxStreamBuffer - > xLength )
2022-02-24 07:14:22 -05:00
{
2024-01-05 04:14:26 -05:00
xHead - = pxStreamBuffer - > xLength ;
2022-02-24 07:14:22 -05:00
}
else
{
mtCOVERAGE_TEST_MARKER ( ) ;
}
2024-01-05 04:14:26 -05:00
return xHead ;
2022-02-24 07:14:22 -05:00
}
/*-----------------------------------------------------------*/
static size_t prvReadBytesFromBuffer ( StreamBuffer_t * pxStreamBuffer ,
uint8_t * pucData ,
2024-01-05 04:14:26 -05:00
size_t xCount ,
size_t xTail )
2022-02-24 07:14:22 -05:00
{
2024-01-05 04:14:26 -05:00
size_t xFirstLength ;
2022-02-24 07:14:22 -05:00
2024-01-05 04:14:26 -05:00
configASSERT ( xCount ! = ( size_t ) 0 ) ;
2022-02-24 07:14:22 -05:00
2024-01-05 04:14:26 -05:00
/* 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 - xTail , xCount ) ;
2022-02-24 07:14:22 -05:00
2024-01-05 04:14:26 -05:00
/* Obtain the number of bytes it is possible to obtain in the first
* read . Asserts check bounds of read and write . */
configASSERT ( xFirstLength < = xCount ) ;
configASSERT ( ( xTail + xFirstLength ) < = pxStreamBuffer - > xLength ) ;
( void ) memcpy ( ( void * ) pucData , ( const void * ) & ( pxStreamBuffer - > pucBuffer [ xTail ] ) , xFirstLength ) ;
2022-02-24 07:14:22 -05:00
2024-01-05 04:14:26 -05:00
/* 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. */
( void ) memcpy ( ( void * ) & ( pucData [ xFirstLength ] ) , ( void * ) ( pxStreamBuffer - > pucBuffer ) , xCount - xFirstLength ) ;
2022-02-24 07:14:22 -05:00
}
else
{
mtCOVERAGE_TEST_MARKER ( ) ;
}
2024-01-05 04:14:26 -05:00
/* Move the tail pointer to effectively remove the data read from the buffer. */
xTail + = xCount ;
if ( xTail > = pxStreamBuffer - > xLength )
{
xTail - = pxStreamBuffer - > xLength ;
}
return xTail ;
2022-02-24 07:14:22 -05:00
}
/*-----------------------------------------------------------*/
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 ,
2024-01-05 04:14:26 -05:00
uint8_t ucFlags ,
StreamBufferCallbackFunction_t pxSendCompletedCallback ,
StreamBufferCallbackFunction_t pxReceiveCompletedCallback )
2022-02-24 07:14:22 -05:00
{
/* 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 )
2024-01-05 04:14:26 -05:00
{
/* 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 . */
# define STREAM_BUFFER_BUFFER_WRITE_VALUE ( 0x55 )
configASSERT ( memset ( pucBuffer , ( int ) STREAM_BUFFER_BUFFER_WRITE_VALUE , xBufferSizeBytes ) = = pucBuffer ) ;
}
2022-02-24 07:14:22 -05:00
# endif
2024-01-05 04:14:26 -05:00
( void ) memset ( ( void * ) pxStreamBuffer , 0x00 , sizeof ( StreamBuffer_t ) ) ;
2022-02-24 07:14:22 -05:00
pxStreamBuffer - > pucBuffer = pucBuffer ;
pxStreamBuffer - > xLength = xBufferSizeBytes ;
pxStreamBuffer - > xTriggerLevelBytes = xTriggerLevelBytes ;
pxStreamBuffer - > ucFlags = ucFlags ;
2024-01-05 04:14:26 -05:00
# if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
{
pxStreamBuffer - > pxSendCompletedCallback = pxSendCompletedCallback ;
pxStreamBuffer - > pxReceiveCompletedCallback = pxReceiveCompletedCallback ;
}
# else
{
/* MISRA Ref 11.1.1 [Object type casting] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-111 */
/* coverity[misra_c_2012_rule_11_1_violation] */
( void ) pxSendCompletedCallback ;
/* MISRA Ref 11.1.1 [Object type casting] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-111 */
/* coverity[misra_c_2012_rule_11_1_violation] */
( void ) pxReceiveCompletedCallback ;
}
# endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
2022-02-24 07:14:22 -05:00
}
# if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxStreamBufferGetStreamBufferNumber ( StreamBufferHandle_t xStreamBuffer )
{
2024-01-05 04:14:26 -05:00
traceENTER_uxStreamBufferGetStreamBufferNumber ( xStreamBuffer ) ;
traceRETURN_uxStreamBufferGetStreamBufferNumber ( xStreamBuffer - > uxStreamBufferNumber ) ;
2022-02-24 07:14:22 -05:00
return xStreamBuffer - > uxStreamBufferNumber ;
}
# endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/
# if ( configUSE_TRACE_FACILITY == 1 )
void vStreamBufferSetStreamBufferNumber ( StreamBufferHandle_t xStreamBuffer ,
UBaseType_t uxStreamBufferNumber )
{
2024-01-05 04:14:26 -05:00
traceENTER_vStreamBufferSetStreamBufferNumber ( xStreamBuffer , uxStreamBufferNumber ) ;
2022-02-24 07:14:22 -05:00
xStreamBuffer - > uxStreamBufferNumber = uxStreamBufferNumber ;
2024-01-05 04:14:26 -05:00
traceRETURN_vStreamBufferSetStreamBufferNumber ( ) ;
2022-02-24 07:14:22 -05:00
}
# endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/
# if ( configUSE_TRACE_FACILITY == 1 )
uint8_t ucStreamBufferGetStreamBufferType ( StreamBufferHandle_t xStreamBuffer )
{
2024-01-05 04:14:26 -05:00
traceENTER_ucStreamBufferGetStreamBufferType ( xStreamBuffer ) ;
traceRETURN_ucStreamBufferGetStreamBufferType ( ( uint8_t ) ( xStreamBuffer - > ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) ) ;
return ( ( uint8_t ) ( xStreamBuffer - > ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) ) ;
2022-02-24 07:14:22 -05:00
}
# endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/