diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 69611842a..662c5ea15 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 1b1356ca4..b58f33f47 100644 --- a/include/message_buffer.h +++ b/include/message_buffer.h @@ -768,6 +768,10 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; * * 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. * @@ -785,6 +789,38 @@ typedef StreamBufferHandle_t MessageBufferHandle_t; xStreamBufferReset( xMessageBuffer ) +/** + * 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} diff --git a/include/stream_buffer.h b/include/stream_buffer.h index 94a0e0cd7..dca9851a5 100644 --- a/include/stream_buffer.h +++ b/include/stream_buffer.h @@ -767,6 +767,10 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED * 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. * @@ -781,6 +785,38 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED */ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; +/** + * 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 * diff --git a/stream_buffer.c b/stream_buffer.c index 44354fba3..17a898d45 100644 --- a/stream_buffer.c +++ b/stream_buffer.c @@ -639,6 +639,68 @@ 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. */ + 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 ) {