Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRTOS/FreeRTOS-Kernel.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriele Monaco <32201227+glemco@users.noreply.github.com>2024-01-04 22:43:34 +0300
committerGitHub <noreply@github.com>2024-01-04 22:43:34 +0300
commit1947dd2f94419d368316052e92f4bd396bce5f55 (patch)
treee9f90f910450fca336a91bfbd1b878868f9729fa
parent4568507507f6d34c20beb2b2f7c462f042f8b3ca (diff)
Added ability to change task notification index for streambuffers (#939)
* Added possibility to change notification index for streambuffers * Uncrustify: triggered by comment. * Minor code review suggestions. Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com> --------- Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com> Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
-rw-r--r--include/FreeRTOS.h17
-rw-r--r--include/stream_buffer.h51
-rw-r--r--stream_buffer.c185
3 files changed, 183 insertions, 70 deletions
diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h
index 6eb498cd2..d7c458df2 100644
--- a/include/FreeRTOS.h
+++ b/include/FreeRTOS.h
@@ -2509,6 +2509,22 @@
#define traceRETURN_xStreamBufferReceiveCompletedFromISR( xReturn )
#endif
+#ifndef traceENTER_uxStreamBufferGetStreamBufferNotificationIndex
+ #define traceENTER_uxStreamBufferGetStreamBufferNotificationIndex( xStreamBuffer )
+#endif
+
+#ifndef traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex
+ #define traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex( uxNotificationIndex )
+#endif
+
+#ifndef traceENTER_vStreamBufferSetStreamBufferNotificationIndex
+ #define traceENTER_vStreamBufferSetStreamBufferNotificationIndex( xStreamBuffer, uxNotificationIndex )
+#endif
+
+#ifndef traceRETURN_vStreamBufferSetStreamBufferNotificationIndex
+ #define traceRETURN_vStreamBufferSetStreamBufferNotificationIndex()
+#endif
+
#ifndef traceENTER_uxStreamBufferGetStreamBufferNumber
#define traceENTER_uxStreamBufferGetStreamBufferNumber( xStreamBuffer )
#endif
@@ -3271,6 +3287,7 @@ typedef struct xSTATIC_STREAM_BUFFER
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
void * pvDummy5[ 2 ];
#endif
+ UBaseType_t uxDummy6;
} StaticStreamBuffer_t;
/* Message buffers are built on stream buffers. */
diff --git a/include/stream_buffer.h b/include/stream_buffer.h
index 68d12e08f..2ff584eaf 100644
--- a/include/stream_buffer.h
+++ b/include/stream_buffer.h
@@ -911,6 +911,57 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
+/**
+ * stream_buffer.h
+ *
+ * @code{c}
+ * UBaseType_t uxStreamBufferGetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer );
+ * @endcode
+ *
+ * Get the task notification index used for the supplied stream buffer which can
+ * be set using vStreamBufferSetStreamBufferNotificationIndex. If the task
+ * notification index for the stream buffer is not changed using
+ * vStreamBufferSetStreamBufferNotificationIndex, this function returns the
+ * default value (tskDEFAULT_INDEX_TO_NOTIFY).
+ *
+ * @param xStreamBuffer The handle of the stream buffer for which the task
+ * notification index is retrieved.
+ *
+ * @return The task notification index for the stream buffer.
+ *
+ * \defgroup uxStreamBufferGetStreamBufferNotificationIndex uxStreamBufferGetStreamBufferNotificationIndex
+ * \ingroup StreamBufferManagement
+ */
+UBaseType_t uxStreamBufferGetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * stream_buffer.h
+ *
+ * @code{c}
+ * void vStreamBufferSetStreamBufferNotificationIndex ( StreamBuffer_t xStreamBuffer, UBaseType_t uxNotificationIndex );
+ * @endcode
+ *
+ * Set the task notification index used for the supplied stream buffer.
+ * Successive calls to stream buffer APIs (like xStreamBufferSend or
+ * xStreamBufferReceive) for this stream buffer will use this new index for
+ * their task notifications.
+ *
+ * If this function is not called, the default index (tskDEFAULT_INDEX_TO_NOTIFY)
+ * is used for task notifications. It is recommended to call this function
+ * before attempting to send or receive data from the stream buffer to avoid
+ * inconsistencies.
+ *
+ * @param xStreamBuffer The handle of the stream buffer for which the task
+ * notification index is set.
+ *
+ * @param uxNotificationIndex The task notification index to set.
+ *
+ * \defgroup vStreamBufferSetStreamBufferNotificationIndex vStreamBufferSetStreamBufferNotificationIndex
+ * \ingroup StreamBufferManagement
+ */
+void vStreamBufferSetStreamBufferNotificationIndex( StreamBufferHandle_t xStreamBuffer,
+ UBaseType_t uxNotificationIndex ) PRIVILEGED_FUNCTION;
+
/* Functions below here are not part of the public API. */
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes,
diff --git a/stream_buffer.c b/stream_buffer.c
index 3ea7baa4b..00306fa04 100644
--- a/stream_buffer.c
+++ b/stream_buffer.c
@@ -56,20 +56,21 @@
* 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(); \
+ #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 */
@@ -93,23 +94,24 @@
#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 ); \
+ #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 */
@@ -136,17 +138,18 @@
* 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; \
- } \
- } \
+ #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 */
@@ -171,22 +174,23 @@
#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 ); \
+ #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 */
@@ -237,6 +241,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;
/*
@@ -790,7 +795,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 );
@@ -805,7 +810,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 );
}
@@ -1001,7 +1006,7 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
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 );
@@ -1018,7 +1023,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. */
@@ -1307,10 +1312,11 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer
{
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,10 +1348,11 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf
{
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;
}
@@ -1499,6 +1506,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;
@@ -1518,6 +1526,43 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
}
#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 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 )