diff --git a/Source/include/queue.h b/Source/include/queue.h index 80ee4f11f..d129f64cd 100644 --- a/Source/include/queue.h +++ b/Source/include/queue.h @@ -1234,6 +1234,14 @@ xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime ); portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ); +/* + * Reset a queue back to its original empty state. pdPASS is returned if the + * queue is successfully reset. pdFAIL is returned if the queue could not be + * reset because there are tasks blocked on the queue waiting to either + * receive from the queue or send to the queue. + */ +#define xQueueReset( pxQueue ) xQueueGenericReset( pxQueue, pdFALSE ) + /* * The registry is provided as a means for kernel aware debuggers to * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add @@ -1264,10 +1272,9 @@ portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ); */ xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ); -/* - * Not a public API function, hence the 'Restricted' in the name. - */ +/* Not public API functions. */ void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ); +portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ); #ifdef __cplusplus diff --git a/Source/queue.c b/Source/queue.c index 9dfc6790d..19c51d759 100644 --- a/Source/queue.c +++ b/Source/queue.c @@ -163,6 +163,7 @@ void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksTo unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber ) PRIVILEGED_FUNCTION; unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; +portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION; /* * Co-routine queue functions differ from task queue functions. Co-routines are @@ -261,6 +262,45 @@ static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) * PUBLIC QUEUE MANAGEMENT API documented in queue.h *----------------------------------------------------------*/ +portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) +{ +portBASE_TYPE xReturn = pdPASS; + + configASSERT( pxQueue ); + + /* If the queue being reset has already been used (has not just been + created), then only reset the queue if its event lists are empty. */ + if( xNewQueue != pdTRUE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + xReturn = pdFAIL; + } + + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + xReturn = pdFAIL; + } + } + + if( xReturn == pdPASS ) + { + pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); + pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U; + pxQueue->pcWriteTo = pxQueue->pcHead; + pxQueue->pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize ); + pxQueue->xRxLock = queueUNLOCKED; + pxQueue->xTxLock = queueUNLOCKED; + + /* Ensure the event queues start with the correct state. */ + vListInitialise( &( pxQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) { xQUEUE *pxNewQueue; @@ -286,24 +326,15 @@ xQueueHandle xReturn = NULL; { /* Initialise the queue members as described above where the queue type is defined. */ - pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize ); - pxNewQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U; - pxNewQueue->pcWriteTo = pxNewQueue->pcHead; - pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - ( unsigned portBASE_TYPE ) 1U ) * uxItemSize ); pxNewQueue->uxLength = uxQueueLength; pxNewQueue->uxItemSize = uxItemSize; - pxNewQueue->xRxLock = queueUNLOCKED; - pxNewQueue->xTxLock = queueUNLOCKED; + xQueueGenericReset( pxNewQueue, pdTRUE ); #if ( configUSE_TRACE_FACILITY == 1 ) { pxNewQueue->ucQueueType = ucQueueType; } #endif /* configUSE_TRACE_FACILITY */ - /* Likewise ensure the event queues start with the correct state. */ - vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); - vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); - traceQUEUE_CREATE( pxNewQueue ); xReturn = pxNewQueue; }