mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-10 04:43:33 +00:00
feat(freertos/smp): Update SMP FreeRTOS files to V11.1.0
This commit updates the source files of Amazon SMP FreeRTOS to upstream V11.1.0 (https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/V11.1.0). This version contains some new features and bugfixes. See upstream V11.1.0 release notes for more details. Note: ESP-IDF specific changes to the source file have been preserved
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V11.0.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* FreeRTOS Kernel V11.1.0
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Amazon.com, Inc. or its affiliates
|
||||
*
|
||||
@@ -56,32 +56,39 @@
|
||||
* correct privileged Vs unprivileged linkage and placement. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/* This entire source file will be skipped if the application is not configured
|
||||
* to include stream buffer functionality. This #if is closed at the very bottom
|
||||
* of this file. If you want to include stream buffers then ensure
|
||||
* configUSE_STREAM_BUFFERS is set to 1 in FreeRTOSConfig.h. */
|
||||
#if ( configUSE_STREAM_BUFFERS == 1 )
|
||||
|
||||
/* 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
|
||||
#define sbRECEIVE_COMPLETED( pxStreamBuffer ) \
|
||||
do \
|
||||
{ \
|
||||
vTaskSuspendAll(); \
|
||||
{ \
|
||||
if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \
|
||||
{ \
|
||||
( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \
|
||||
( uint32_t ) 0, \
|
||||
eNoAction ); \
|
||||
( pxStreamBuffer )->xTaskWaitingToSend = NULL; \
|
||||
} \
|
||||
} \
|
||||
( void ) xTaskResumeAll(); \
|
||||
#ifndef sbRECEIVE_COMPLETED
|
||||
#define sbRECEIVE_COMPLETED( pxStreamBuffer ) \
|
||||
do \
|
||||
{ \
|
||||
vTaskSuspendAll(); \
|
||||
{ \
|
||||
if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \
|
||||
{ \
|
||||
( void ) xTaskNotifyIndexed( ( pxStreamBuffer )->xTaskWaitingToSend, \
|
||||
( pxStreamBuffer )->uxNotificationIndex, \
|
||||
( uint32_t ) 0, \
|
||||
eNoAction ); \
|
||||
( pxStreamBuffer )->xTaskWaitingToSend = NULL; \
|
||||
} \
|
||||
} \
|
||||
( void ) xTaskResumeAll(); \
|
||||
} while( 0 )
|
||||
#endif /* sbRECEIVE_COMPLETED */
|
||||
#endif /* sbRECEIVE_COMPLETED */
|
||||
|
||||
/* 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 ) \
|
||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
#define prvRECEIVE_COMPLETED( pxStreamBuffer ) \
|
||||
do { \
|
||||
if( ( pxStreamBuffer )->pxReceiveCompletedCallback != NULL ) \
|
||||
{ \
|
||||
@@ -92,34 +99,35 @@
|
||||
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 ) */
|
||||
#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
|
||||
#define prvRECEIVE_COMPLETED( pxStreamBuffer ) sbRECEIVE_COMPLETED( ( pxStreamBuffer ) )
|
||||
#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
|
||||
|
||||
#ifndef sbRECEIVE_COMPLETED_FROM_ISR
|
||||
#define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \
|
||||
pxHigherPriorityTaskWoken ) \
|
||||
do { \
|
||||
UBaseType_t uxSavedInterruptStatus; \
|
||||
\
|
||||
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \
|
||||
{ \
|
||||
if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \
|
||||
{ \
|
||||
( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \
|
||||
( uint32_t ) 0, \
|
||||
eNoAction, \
|
||||
( pxHigherPriorityTaskWoken ) ); \
|
||||
( pxStreamBuffer )->xTaskWaitingToSend = NULL; \
|
||||
} \
|
||||
} \
|
||||
taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \
|
||||
#ifndef sbRECEIVE_COMPLETED_FROM_ISR
|
||||
#define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \
|
||||
pxHigherPriorityTaskWoken ) \
|
||||
do { \
|
||||
UBaseType_t uxSavedInterruptStatus; \
|
||||
\
|
||||
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \
|
||||
{ \
|
||||
if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \
|
||||
{ \
|
||||
( void ) xTaskNotifyIndexedFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \
|
||||
( pxStreamBuffer )->uxNotificationIndex, \
|
||||
( uint32_t ) 0, \
|
||||
eNoAction, \
|
||||
( pxHigherPriorityTaskWoken ) ); \
|
||||
( pxStreamBuffer )->xTaskWaitingToSend = NULL; \
|
||||
} \
|
||||
} \
|
||||
taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \
|
||||
} while( 0 )
|
||||
#endif /* sbRECEIVE_COMPLETED_FROM_ISR */
|
||||
#endif /* sbRECEIVE_COMPLETED_FROM_ISR */
|
||||
|
||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
#define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \
|
||||
pxHigherPriorityTaskWoken ) \
|
||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
#define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \
|
||||
pxHigherPriorityTaskWoken ) \
|
||||
do { \
|
||||
if( ( pxStreamBuffer )->pxReceiveCompletedCallback != NULL ) \
|
||||
{ \
|
||||
@@ -130,35 +138,36 @@
|
||||
sbRECEIVE_COMPLETED_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ); \
|
||||
} \
|
||||
} while( 0 )
|
||||
#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
|
||||
#define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
|
||||
#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 ) */
|
||||
#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
|
||||
|
||||
/* If the user has not provided an application specific Tx notification macro,
|
||||
* or #defined the notification macro away, then 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; \
|
||||
} \
|
||||
} \
|
||||
#ifndef sbSEND_COMPLETED
|
||||
#define sbSEND_COMPLETED( pxStreamBuffer ) \
|
||||
vTaskSuspendAll(); \
|
||||
{ \
|
||||
if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \
|
||||
{ \
|
||||
( void ) xTaskNotifyIndexed( ( pxStreamBuffer )->xTaskWaitingToReceive, \
|
||||
( pxStreamBuffer )->uxNotificationIndex, \
|
||||
( uint32_t ) 0, \
|
||||
eNoAction ); \
|
||||
( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \
|
||||
} \
|
||||
} \
|
||||
( void ) xTaskResumeAll()
|
||||
#endif /* sbSEND_COMPLETED */
|
||||
#endif /* sbSEND_COMPLETED */
|
||||
|
||||
/* 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 ) \
|
||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
#define prvSEND_COMPLETED( pxStreamBuffer ) \
|
||||
do { \
|
||||
if( ( pxStreamBuffer )->pxSendCompletedCallback != NULL ) \
|
||||
{ \
|
||||
@@ -169,34 +178,35 @@
|
||||
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 ) */
|
||||
#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
|
||||
#define prvSEND_COMPLETED( pxStreamBuffer ) sbSEND_COMPLETED( ( pxStreamBuffer ) )
|
||||
#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
|
||||
|
||||
|
||||
#ifndef sbSEND_COMPLETE_FROM_ISR
|
||||
#define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
|
||||
do { \
|
||||
UBaseType_t uxSavedInterruptStatus; \
|
||||
\
|
||||
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \
|
||||
{ \
|
||||
if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \
|
||||
{ \
|
||||
( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \
|
||||
( uint32_t ) 0, \
|
||||
eNoAction, \
|
||||
( pxHigherPriorityTaskWoken ) ); \
|
||||
( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \
|
||||
} \
|
||||
} \
|
||||
taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \
|
||||
#ifndef sbSEND_COMPLETE_FROM_ISR
|
||||
#define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
|
||||
do { \
|
||||
UBaseType_t uxSavedInterruptStatus; \
|
||||
\
|
||||
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \
|
||||
{ \
|
||||
if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \
|
||||
{ \
|
||||
( void ) xTaskNotifyIndexedFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \
|
||||
( pxStreamBuffer )->uxNotificationIndex, \
|
||||
( uint32_t ) 0, \
|
||||
eNoAction, \
|
||||
( pxHigherPriorityTaskWoken ) ); \
|
||||
( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \
|
||||
} \
|
||||
} \
|
||||
taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \
|
||||
} while( 0 )
|
||||
#endif /* sbSEND_COMPLETE_FROM_ISR */
|
||||
#endif /* sbSEND_COMPLETE_FROM_ISR */
|
||||
|
||||
|
||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
#define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
|
||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
#define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
|
||||
do { \
|
||||
if( ( pxStreamBuffer )->pxSendCompletedCallback != NULL ) \
|
||||
{ \
|
||||
@@ -207,17 +217,18 @@
|
||||
sbSEND_COMPLETE_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ); \
|
||||
} \
|
||||
} while( 0 )
|
||||
#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
|
||||
#define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \
|
||||
#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 ) */
|
||||
#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
|
||||
|
||||
/* 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 ) )
|
||||
#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. */
|
||||
#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. */
|
||||
#define sbFLAGS_IS_BATCHING_BUFFER ( ( uint8_t ) 4 ) /* Set if the stream buffer was created as a batching buffer, meaning the receiver task will only unblock when the trigger level exceededs. */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -241,6 +252,7 @@ typedef struct StreamBufferDef_t
|
||||
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
|
||||
UBaseType_t uxNotificationIndex; /* The index we are using for notification, by default tskDEFAULT_INDEX_TO_NOTIFY. */
|
||||
} StreamBuffer_t;
|
||||
|
||||
/*
|
||||
@@ -319,28 +331,34 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer,
|
||||
BaseType_t xStreamBufferType,
|
||||
StreamBufferCallbackFunction_t pxSendCompletedCallback,
|
||||
StreamBufferCallbackFunction_t pxReceiveCompletedCallback )
|
||||
{
|
||||
void * pvAllocatedMemory;
|
||||
uint8_t ucFlags;
|
||||
|
||||
traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback );
|
||||
traceENTER_xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xStreamBufferType, pxSendCompletedCallback, pxReceiveCompletedCallback );
|
||||
|
||||
/* 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 )
|
||||
if( xStreamBufferType == sbTYPE_MESSAGE_BUFFER )
|
||||
{
|
||||
/* Is a message buffer but not statically allocated. */
|
||||
ucFlags = sbFLAGS_IS_MESSAGE_BUFFER;
|
||||
configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
|
||||
}
|
||||
else if( xStreamBufferType == sbTYPE_STREAM_BATCHING_BUFFER )
|
||||
{
|
||||
/* Is a batching buffer but not statically allocated. */
|
||||
ucFlags = sbFLAGS_IS_BATCHING_BUFFER;
|
||||
configASSERT( xBufferSizeBytes > 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not a message buffer and not statically allocated. */
|
||||
@@ -391,11 +409,11 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
pxSendCompletedCallback,
|
||||
pxReceiveCompletedCallback );
|
||||
|
||||
traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pvAllocatedMemory ), xIsMessageBuffer );
|
||||
traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pvAllocatedMemory ), xStreamBufferType );
|
||||
}
|
||||
else
|
||||
{
|
||||
traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer );
|
||||
traceSTREAM_BUFFER_CREATE_FAILED( xStreamBufferType );
|
||||
}
|
||||
|
||||
traceRETURN_xStreamBufferGenericCreate( pvAllocatedMemory );
|
||||
@@ -405,14 +423,14 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||
return ( StreamBufferHandle_t ) pvAllocatedMemory;
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer,
|
||||
BaseType_t xStreamBufferType,
|
||||
uint8_t * const pucStreamBufferStorageArea,
|
||||
StaticStreamBuffer_t * const pxStaticStreamBuffer,
|
||||
StreamBufferCallbackFunction_t pxSendCompletedCallback,
|
||||
@@ -425,7 +443,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
StreamBufferHandle_t xReturn;
|
||||
uint8_t ucFlags;
|
||||
|
||||
traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback );
|
||||
traceENTER_xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xStreamBufferType, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback );
|
||||
|
||||
configASSERT( pucStreamBufferStorageArea );
|
||||
configASSERT( pxStaticStreamBuffer );
|
||||
@@ -443,12 +461,18 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
* says how big the next message is) check the buffer will be large enough
|
||||
* to hold at least one message. */
|
||||
|
||||
if( xIsMessageBuffer != pdFALSE )
|
||||
if( xStreamBufferType == sbTYPE_MESSAGE_BUFFER )
|
||||
{
|
||||
/* Statically allocated message buffer. */
|
||||
ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED;
|
||||
configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH );
|
||||
}
|
||||
else if( xStreamBufferType == sbTYPE_STREAM_BATCHING_BUFFER )
|
||||
{
|
||||
/* Statically allocated batching buffer. */
|
||||
ucFlags = sbFLAGS_IS_BATCHING_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED;
|
||||
configASSERT( xBufferSizeBytes > 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Statically allocated stream buffer. */
|
||||
@@ -479,7 +503,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
* again. */
|
||||
pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED;
|
||||
|
||||
traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer );
|
||||
traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xStreamBufferType );
|
||||
|
||||
/* MISRA Ref 11.3.1 [Misaligned access] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */
|
||||
@@ -489,17 +513,17 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
else
|
||||
{
|
||||
xReturn = NULL;
|
||||
traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer );
|
||||
traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xStreamBufferType );
|
||||
}
|
||||
|
||||
traceRETURN_xStreamBufferGenericCreateStatic( xReturn );
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
||||
#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer,
|
||||
uint8_t ** ppucStreamBufferStorageArea,
|
||||
StaticStreamBuffer_t ** ppxStaticStreamBuffer )
|
||||
@@ -531,7 +555,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer )
|
||||
@@ -632,6 +656,71 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer )
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer )
|
||||
{
|
||||
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
|
||||
BaseType_t xReturn = pdFAIL;
|
||||
StreamBufferCallbackFunction_t pxSendCallback = NULL, pxReceiveCallback = NULL;
|
||||
UBaseType_t uxSavedInterruptStatus;
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxStreamBufferNumber;
|
||||
#endif
|
||||
|
||||
traceENTER_xStreamBufferResetFromISR( xStreamBuffer );
|
||||
|
||||
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. */
|
||||
/* MISRA Ref 4.7.1 [Return value shall be checked] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
|
||||
/* coverity[misra_c_2012_directive_4_7_violation] */
|
||||
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
|
||||
{
|
||||
if( ( pxStreamBuffer->xTaskWaitingToReceive == NULL ) && ( pxStreamBuffer->xTaskWaitingToSend == NULL ) )
|
||||
{
|
||||
#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 )
|
||||
{
|
||||
pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber;
|
||||
}
|
||||
#endif
|
||||
|
||||
traceSTREAM_BUFFER_RESET_FROM_ISR( xStreamBuffer );
|
||||
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
|
||||
|
||||
traceRETURN_xStreamBufferResetFromISR( xReturn );
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
|
||||
size_t xTriggerLevel )
|
||||
{
|
||||
@@ -794,7 +883,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
if( xSpace < xRequiredSpace )
|
||||
{
|
||||
/* Clear notification state as going to wait for space. */
|
||||
( void ) xTaskNotifyStateClear( NULL );
|
||||
( void ) xTaskNotifyStateClearIndexed( NULL, pxStreamBuffer->uxNotificationIndex );
|
||||
|
||||
/* Should only be one writer. */
|
||||
configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL );
|
||||
@@ -809,7 +898,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer );
|
||||
( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
|
||||
( void ) xTaskNotifyWaitIndexed( pxStreamBuffer->uxNotificationIndex, ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
|
||||
pxStreamBuffer->xTaskWaitingToSend = NULL;
|
||||
} while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE );
|
||||
}
|
||||
@@ -890,6 +979,9 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
/* Was a task waiting for the data? */
|
||||
if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes )
|
||||
{
|
||||
/* MISRA Ref 4.7.1 [Return value shall be checked] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
|
||||
/* coverity[misra_c_2012_directive_4_7_violation] */
|
||||
prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
|
||||
}
|
||||
else
|
||||
@@ -984,6 +1076,12 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
{
|
||||
xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH;
|
||||
}
|
||||
else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_BATCHING_BUFFER ) != ( uint8_t ) 0 )
|
||||
{
|
||||
/* Force task to block if the batching buffer contains less bytes than
|
||||
* the trigger level. */
|
||||
xBytesToStoreMessageLength = pxStreamBuffer->xTriggerLevelBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
xBytesToStoreMessageLength = 0;
|
||||
@@ -1001,11 +1099,13 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
* 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. */
|
||||
* be 0. If this function was invoked by a stream batch buffer read
|
||||
* then xBytesToStoreMessageLength will be xTriggerLevelBytes value
|
||||
* for the buffer.*/
|
||||
if( xBytesAvailable <= xBytesToStoreMessageLength )
|
||||
{
|
||||
/* Clear notification state as going to wait for data. */
|
||||
( void ) xTaskNotifyStateClear( NULL );
|
||||
( void ) xTaskNotifyStateClearIndexed( NULL, pxStreamBuffer->uxNotificationIndex );
|
||||
|
||||
/* Should only be one reader. */
|
||||
configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL );
|
||||
@@ -1022,7 +1122,7 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
{
|
||||
/* Wait for data to be available. */
|
||||
traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer );
|
||||
( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
|
||||
( void ) xTaskNotifyWaitIndexed( pxStreamBuffer->uxNotificationIndex, ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
|
||||
pxStreamBuffer->xTaskWaitingToReceive = NULL;
|
||||
|
||||
/* Recheck the data available after blocking. */
|
||||
@@ -1155,6 +1255,9 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
/* Was a task waiting for space in the buffer? */
|
||||
if( xReceivedLength != ( size_t ) 0 )
|
||||
{
|
||||
/* MISRA Ref 4.7.1 [Return value shall be checked] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
|
||||
/* coverity[misra_c_2012_directive_4_7_violation] */
|
||||
prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken );
|
||||
}
|
||||
else
|
||||
@@ -1307,14 +1410,18 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer
|
||||
|
||||
configASSERT( pxStreamBuffer );
|
||||
|
||||
/* MISRA Ref 4.7.1 [Return value shall be checked] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
|
||||
/* coverity[misra_c_2012_directive_4_7_violation] */
|
||||
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
|
||||
{
|
||||
if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL )
|
||||
{
|
||||
( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive,
|
||||
( uint32_t ) 0,
|
||||
eNoAction,
|
||||
pxHigherPriorityTaskWoken );
|
||||
( void ) xTaskNotifyIndexedFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive,
|
||||
( pxStreamBuffer )->uxNotificationIndex,
|
||||
( uint32_t ) 0,
|
||||
eNoAction,
|
||||
pxHigherPriorityTaskWoken );
|
||||
( pxStreamBuffer )->xTaskWaitingToReceive = NULL;
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
@@ -1342,14 +1449,18 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf
|
||||
|
||||
configASSERT( pxStreamBuffer );
|
||||
|
||||
/* MISRA Ref 4.7.1 [Return value shall be checked] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
|
||||
/* coverity[misra_c_2012_directive_4_7_violation] */
|
||||
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
|
||||
{
|
||||
if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL )
|
||||
{
|
||||
( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend,
|
||||
( uint32_t ) 0,
|
||||
eNoAction,
|
||||
pxHigherPriorityTaskWoken );
|
||||
( void ) xTaskNotifyIndexedFromISR( ( pxStreamBuffer )->xTaskWaitingToSend,
|
||||
( pxStreamBuffer )->uxNotificationIndex,
|
||||
( uint32_t ) 0,
|
||||
eNoAction,
|
||||
pxHigherPriorityTaskWoken );
|
||||
( pxStreamBuffer )->xTaskWaitingToSend = NULL;
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
@@ -1458,7 +1569,7 @@ static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer,
|
||||
|
||||
static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer )
|
||||
{
|
||||
/* Returns the distance between xTail and xHead. */
|
||||
/* Returns the distance between xTail and xHead. */
|
||||
size_t xCount;
|
||||
|
||||
xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead;
|
||||
@@ -1493,7 +1604,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
/* 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 )
|
||||
#define STREAM_BUFFER_BUFFER_WRITE_VALUE ( 0x55 )
|
||||
configASSERT( memset( pucBuffer, ( int ) STREAM_BUFFER_BUFFER_WRITE_VALUE, xBufferSizeBytes ) == pucBuffer );
|
||||
}
|
||||
#endif
|
||||
@@ -1503,6 +1614,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
pxStreamBuffer->xLength = xBufferSizeBytes;
|
||||
pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes;
|
||||
pxStreamBuffer->ucFlags = ucFlags;
|
||||
pxStreamBuffer->uxNotificationIndex = tskDEFAULT_INDEX_TO_NOTIFY;
|
||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
{
|
||||
pxStreamBuffer->pxSendCompletedCallback = pxSendCompletedCallback;
|
||||
@@ -1522,8 +1634,45 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
}
|
||||
#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxStreamBufferGetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer )
|
||||
{
|
||||
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
|
||||
|
||||
traceENTER_uxStreamBufferGetStreamBufferNotificationIndex( xStreamBuffer );
|
||||
|
||||
configASSERT( pxStreamBuffer );
|
||||
|
||||
traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex( pxStreamBuffer->uxNotificationIndex );
|
||||
|
||||
return pxStreamBuffer->uxNotificationIndex;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vStreamBufferSetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer,
|
||||
UBaseType_t uxNotificationIndex )
|
||||
{
|
||||
StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
|
||||
|
||||
traceENTER_vStreamBufferSetStreamBufferNotificationIndex( xStreamBuffer, uxNotificationIndex );
|
||||
|
||||
configASSERT( pxStreamBuffer );
|
||||
|
||||
/* There should be no task waiting otherwise we'd never resume them. */
|
||||
configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL );
|
||||
configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL );
|
||||
|
||||
/* Check that the task notification index is valid. */
|
||||
configASSERT( uxNotificationIndex < configTASK_NOTIFICATION_ARRAY_ENTRIES );
|
||||
|
||||
pxStreamBuffer->uxNotificationIndex = uxNotificationIndex;
|
||||
|
||||
traceRETURN_vStreamBufferSetStreamBufferNotificationIndex();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer )
|
||||
{
|
||||
@@ -1534,10 +1683,10 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
return xStreamBuffer->uxStreamBufferNumber;
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer,
|
||||
UBaseType_t uxStreamBufferNumber )
|
||||
@@ -1549,10 +1698,10 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
traceRETURN_vStreamBufferSetStreamBufferNumber();
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer )
|
||||
{
|
||||
@@ -1563,5 +1712,11 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||
return( ( uint8_t ) ( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) );
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* This entire source file will be skipped if the application is not configured
|
||||
* to include stream buffer functionality. This #if is closed at the very bottom
|
||||
* of this file. If you want to include stream buffers then ensure
|
||||
* configUSE_STREAM_BUFFERS is set to 1 in FreeRTOSConfig.h. */
|
||||
#endif /* configUSE_STREAM_BUFFERS == 1 */
|
||||
|
Reference in New Issue
Block a user