Add IRQ safe API for message buffer reset (#1033)
* Add API xStreamBufferResetFromISR
Allow reseting the stream buffer from ISR context
Signed-off-by: hagai.moshe <hagaimoshe@outlook.com>
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: hagai.moshe <hagai.moshe@tandemg.com>
Co-authored-by: Rahul Kar <118818625+kar-rahul-aws@users.noreply.github.com>
Co-authored-by: kar-rahul-aws <karahulx@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h
index 6961184..662c5ea 100644
--- a/include/FreeRTOS.h
+++ b/include/FreeRTOS.h
@@ -1001,6 +1001,10 @@
#define traceSTREAM_BUFFER_RESET( xStreamBuffer )
#endif
+#ifndef traceSTREAM_BUFFER_RESET_FROM_ISR
+ #define traceSTREAM_BUFFER_RESET_FROM_ISR( xStreamBuffer )
+#endif
+
#ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND
#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer )
#endif
@@ -2437,6 +2441,14 @@
#define traceRETURN_xStreamBufferReset( xReturn )
#endif
+#ifndef traceENTER_xStreamBufferResetFromISR
+ #define traceENTER_xStreamBufferResetFromISR( xStreamBuffer )
+#endif
+
+#ifndef traceRETURN_xStreamBufferResetFromISR
+ #define traceRETURN_xStreamBufferResetFromISR( xReturn )
+#endif
+
#ifndef traceENTER_xStreamBufferSetTriggerLevel
#define traceENTER_xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel )
#endif
diff --git a/include/message_buffer.h b/include/message_buffer.h
index 1b1356c..b58f33f 100644
--- a/include/message_buffer.h
+++ b/include/message_buffer.h
@@ -768,6 +768,10 @@
*
* A message buffer can only be reset if there are no tasks blocked on it.
*
+ * Use xMessageBufferReset() to reset a message buffer from a task.
+ * Use xMessageBufferResetFromISR() to reset a message buffer from an
+ * interrupt service routine (ISR).
+ *
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
* xMessageBufferReset() to be available.
*
@@ -788,6 +792,38 @@
/**
* message_buffer.h
* @code{c}
+ * BaseType_t xMessageBufferResetFromISR( MessageBufferHandle_t xMessageBuffer );
+ * @endcode
+ *
+ * An interrupt safe version of the API function that resets the message buffer.
+ * Resets a message buffer to its initial empty state, discarding any message it
+ * contained.
+ *
+ * A message buffer can only be reset if there are no tasks blocked on it.
+ *
+ * Use xMessageBufferReset() to reset a message buffer from a task.
+ * Use xMessageBufferResetFromISR() to reset a message buffer from an
+ * interrupt service routine (ISR).
+ *
+ * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
+ * xMessageBufferResetFromISR() to be available.
+ *
+ * @param xMessageBuffer The handle of the message buffer being reset.
+ *
+ * @return If the message buffer was reset then pdPASS is returned. If the
+ * message buffer could not be reset because either there was a task blocked on
+ * the message queue to wait for space to become available, or to wait for a
+ * a message to be available, then pdFAIL is returned.
+ *
+ * \defgroup xMessageBufferResetFromISR xMessageBufferResetFromISR
+ * \ingroup MessageBufferManagement
+ */
+#define xMessageBufferResetFromISR( xMessageBuffer ) \
+ xStreamBufferResetFromISR( xMessageBuffer )
+
+/**
+ * message_buffer.h
+ * @code{c}
* size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer );
* @endcode
* Returns the number of bytes of free space in the message buffer.
diff --git a/include/stream_buffer.h b/include/stream_buffer.h
index 94a0e0c..dca9851 100644
--- a/include/stream_buffer.h
+++ b/include/stream_buffer.h
@@ -767,6 +767,10 @@
* are no tasks blocked waiting to either send to or receive from the stream
* buffer.
*
+ * Use xStreamBufferReset() to reset a stream buffer from a task.
+ * Use xStreamBufferResetFromISR() to reset a stream buffer from an
+ * interrupt service routine (ISR).
+ *
* configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
* xStreamBufferReset() to be available.
*
@@ -785,6 +789,38 @@
* stream_buffer.h
*
* @code{c}
+ * BaseType_t xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer );
+ * @endcode
+ *
+ * An interrupt safe version of the API function that resets the stream buffer.
+ *
+ * Resets a stream buffer to its initial, empty, state. Any data that was in
+ * the stream buffer is discarded. A stream buffer can only be reset if there
+ * are no tasks blocked waiting to either send to or receive from the stream
+ * buffer.
+ *
+ * Use xStreamBufferReset() to reset a stream buffer from a task.
+ * Use xStreamBufferResetFromISR() to reset a stream buffer from an
+ * interrupt service routine (ISR).
+ *
+ * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
+ * xStreamBufferResetFromISR() to be available.
+ *
+ * @param xStreamBuffer The handle of the stream buffer being reset.
+ *
+ * @return If the stream buffer is reset then pdPASS is returned. If there was
+ * a task blocked waiting to send to or read from the stream buffer then the
+ * stream buffer is not reset and pdFAIL is returned.
+ *
+ * \defgroup xStreamBufferResetFromISR xStreamBufferResetFromISR
+ * \ingroup StreamBufferManagement
+ */
+BaseType_t xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
+
+/**
+ * stream_buffer.h
+ *
+ * @code{c}
* size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
* @endcode
*
diff --git a/stream_buffer.c b/stream_buffer.c
index 44354fb..17a898d 100644
--- a/stream_buffer.c
+++ b/stream_buffer.c
@@ -639,6 +639,68 @@
}
/*-----------------------------------------------------------*/
+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. */
+ 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 )
{