Skip to content

Add IRQ safe API for message buffer reset #1033

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions include/FreeRTOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
36 changes: 36 additions & 0 deletions include/message_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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}
Expand Down
36 changes: 36 additions & 0 deletions include/stream_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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
*
Expand Down
62 changes: 62 additions & 0 deletions stream_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
{
Expand Down
Loading