privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
-
-/* Constants used with the xRxLock and xTxLock structure members. */
-#define queueUNLOCKED ( ( BaseType_t ) -1 )
-#define queueLOCKED_UNMODIFIED ( ( BaseType_t ) 0 )
-
/* When the Queue_t structure is used to represent a base queue its pcHead and
pcTail members are used as pointers into the queue storage area. When the
Queue_t structure is used to represent a mutex pcHead and pcTail pointers are
UBaseType_t uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
UBaseType_t uxItemSize; /*< The size of each items that the queue will hold. */
- volatile BaseType_t xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
- volatile BaseType_t xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
-
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxQueueNumber;
uint8_t ucQueueType;
#endif /* configQUEUE_REGISTRY_SIZE */
-/*
- * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not
- * prevent an ISR from adding or removing items to the queue, but does prevent
- * an ISR from removing tasks from the queue event lists. If an ISR finds a
- * queue is locked it will instead increment the appropriate queue lock count
- * to indicate that a task may require unblocking. When the queue in unlocked
- * these lock counts are inspected, and the appropriate action taken.
- */
-static void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION;
/*
* Uses a critical section to determine if there is any data in a queue.
static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;
#endif
-/*-----------------------------------------------------------*/
-
-/*
- * Macro to mark a queue as locked. Locking a queue prevents an ISR from
- * accessing the queue event lists.
- */
-#define prvLockQueue( pxQueue ) \
- taskENTER_CRITICAL(&pxQueue->mux); \
- { \
- if( ( pxQueue )->xRxLock == queueUNLOCKED ) \
- { \
- ( pxQueue )->xRxLock = queueLOCKED_UNMODIFIED; \
- } \
- if( ( pxQueue )->xTxLock == queueUNLOCKED ) \
- { \
- ( pxQueue )->xTxLock = queueLOCKED_UNMODIFIED; \
- } \
- } \
- taskEXIT_CRITICAL(&pxQueue->mux)
-/*-----------------------------------------------------------*/
-
BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue )
{
Queue_t * const pxQueue = ( Queue_t * ) xQueue;
pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U;
pxQueue->pcWriteTo = pxQueue->pcHead;
pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( UBaseType_t ) 1U ) * pxQueue->uxItemSize );
- pxQueue->xRxLock = queueUNLOCKED;
- pxQueue->xTxLock = queueUNLOCKED;
if( xNewQueue == pdFALSE )
{
pxNewQueue->uxMessagesWaiting = ( UBaseType_t ) 0U;
pxNewQueue->uxLength = ( UBaseType_t ) 1U;
pxNewQueue->uxItemSize = ( UBaseType_t ) 0U;
- pxNewQueue->xRxLock = queueUNLOCKED;
- pxNewQueue->xTxLock = queueUNLOCKED;
#if ( configUSE_TRACE_FACILITY == 1 )
{
now the critical section has been exited. */
taskENTER_CRITICAL(&pxQueue->mux);
-// prvLockQueue( pxQueue );
/* Update the timeout state to see if it has expired yet. */
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
traceBLOCKING_ON_QUEUE_SEND( pxQueue );
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
- /* Unlocking the queue means queue events can effect the
- event list. It is possible that interrupts occurring now
- remove this task from the event list again - but as the
- scheduler is suspended the task will go onto the pending
- ready last instead of the actual ready list. */
-// prvUnlockQueue( pxQueue );
-
/* Resuming the scheduler will move tasks from the pending
ready list into the ready list - so it is feasible that this
else
{
/* Try again. */
-// prvUnlockQueue( pxQueue );
taskEXIT_CRITICAL(&pxQueue->mux);
}
}
else
{
/* The timeout has expired. */
-// prvUnlockQueue( pxQueue );
taskEXIT_CRITICAL(&pxQueue->mux);
/* Return to the original privilege level before exiting the
disinheritance here or to clear the mutex holder TCB member. */
( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
- /* The event list is not altered if the queue is locked. This will
- be done when the queue is unlocked later. */
- if( pxQueue->xTxLock == queueUNLOCKED )
+ #if ( configUSE_QUEUE_SETS == 1 )
{
- #if ( configUSE_QUEUE_SETS == 1 )
+ if( pxQueue->pxQueueSetContainer != NULL )
{
- if( pxQueue->pxQueueSetContainer != NULL )
+ if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
{
- if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
+ /* The queue is a member of a queue set, and posting
+ to the queue set caused a higher priority task to
+ unblock. A context switch is required. */
+ if( pxHigherPriorityTaskWoken != NULL )
{
- /* The queue is a member of a queue set, and posting
- to the queue set caused a higher priority task to
- unblock. A context switch is required. */
- if( pxHigherPriorityTaskWoken != NULL )
- {
- *pxHigherPriorityTaskWoken = pdTRUE;
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
+ *pxHigherPriorityTaskWoken = pdTRUE;
}
else
{
}
else
{
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
- {
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
- {
- /* The task waiting has a higher priority so
- record that a context switch is required. */
- if( pxHigherPriorityTaskWoken != NULL )
- {
- *pxHigherPriorityTaskWoken = pdTRUE;
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
+ mtCOVERAGE_TEST_MARKER();
}
}
- #else /* configUSE_QUEUE_SETS */
+ else
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
- /* The task waiting has a higher priority so record that a
- context switch is required. */
+ /* The task waiting has a higher priority so
+ record that a context switch is required. */
if( pxHigherPriorityTaskWoken != NULL )
{
*pxHigherPriorityTaskWoken = pdTRUE;
mtCOVERAGE_TEST_MARKER();
}
}
- #endif /* configUSE_QUEUE_SETS */
}
- else
+ #else /* configUSE_QUEUE_SETS */
{
- /* Increment the lock count so the task that unlocks the queue
- knows that data was posted while it was locked. */
- ++( pxQueue->xTxLock );
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
+ {
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+ {
+ /* The task waiting has a higher priority so record that a
+ context switch is required. */
+ if( pxHigherPriorityTaskWoken != NULL )
+ {
+ *pxHigherPriorityTaskWoken = pdTRUE;
+ }
+ else
+ {
+ mtCOVERAGE_TEST_MARKER();
+ }
+ }
+ else
+ {
+ mtCOVERAGE_TEST_MARKER();
+ }
+ }
+ else
+ {
+ mtCOVERAGE_TEST_MARKER();
+ }
}
-
- xReturn = pdPASS;
+ #endif /* configUSE_QUEUE_SETS */
}
else
{
++( pxQueue->uxMessagesWaiting );
- /* The event list is not altered if the queue is locked. This will
- be done when the queue is unlocked later. */
- if( pxQueue->xTxLock == queueUNLOCKED )
+ #if ( configUSE_QUEUE_SETS == 1 )
{
- #if ( configUSE_QUEUE_SETS == 1 )
+ if( pxQueue->pxQueueSetContainer != NULL )
{
- if( pxQueue->pxQueueSetContainer != NULL )
+ if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE )
{
- if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE )
+ /* The semaphore is a member of a queue set, and
+ posting to the queue set caused a higher priority
+ task to unblock. A context switch is required. */
+ if( pxHigherPriorityTaskWoken != NULL )
{
- /* The semaphore is a member of a queue set, and
- posting to the queue set caused a higher priority
- task to unblock. A context switch is required. */
- if( pxHigherPriorityTaskWoken != NULL )
- {
- *pxHigherPriorityTaskWoken = pdTRUE;
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
+ *pxHigherPriorityTaskWoken = pdTRUE;
}
else
{
}
else
{
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
- {
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
- {
- /* The task waiting has a higher priority so
- record that a context switch is required. */
- if( pxHigherPriorityTaskWoken != NULL )
- {
- *pxHigherPriorityTaskWoken = pdTRUE;
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
+ mtCOVERAGE_TEST_MARKER();
}
}
- #else /* configUSE_QUEUE_SETS */
+ else
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
- /* The task waiting has a higher priority so record that a
- context switch is required. */
+ /* The task waiting has a higher priority so
+ record that a context switch is required. */
if( pxHigherPriorityTaskWoken != NULL )
{
*pxHigherPriorityTaskWoken = pdTRUE;
mtCOVERAGE_TEST_MARKER();
}
}
- #endif /* configUSE_QUEUE_SETS */
}
- else
+ #else /* configUSE_QUEUE_SETS */
{
- /* Increment the lock count so the task that unlocks the queue
- knows that data was posted while it was locked. */
- ++( pxQueue->xTxLock );
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
+ {
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
+ {
+ /* The task waiting has a higher priority so record that a
+ context switch is required. */
+ if( pxHigherPriorityTaskWoken != NULL )
+ {
+ *pxHigherPriorityTaskWoken = pdTRUE;
+ }
+ else
+ {
+ mtCOVERAGE_TEST_MARKER();
+ }
+ }
+ else
+ {
+ mtCOVERAGE_TEST_MARKER();
+ }
+ }
+ else
+ {
+ mtCOVERAGE_TEST_MARKER();
+ }
}
+ #endif /* configUSE_QUEUE_SETS */
xReturn = pdPASS;
}
now the critical section has been exited. */
taskENTER_CRITICAL(&pxQueue->mux);
-// prvLockQueue( pxQueue );
/* Update the timeout state to see if it has expired yet. */
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
#endif
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
-// prvUnlockQueue( pxQueue );
taskEXIT_CRITICAL(&pxQueue->mux);
portYIELD_WITHIN_API();
}
else
{
/* Try again. */
-// prvUnlockQueue( pxQueue );
taskEXIT_CRITICAL(&pxQueue->mux);
}
}
else
{
-// prvUnlockQueue( pxQueue );
taskEXIT_CRITICAL(&pxQueue->mux);
traceQUEUE_RECEIVE_FAILED( pxQueue );
return errQUEUE_EMPTY;
prvCopyDataFromQueue( pxQueue, pvBuffer );
--( pxQueue->uxMessagesWaiting );
- /* If the queue is locked the event list will not be modified.
- Instead update the lock count so the task that unlocks the queue
- will know that an ISR has removed data while the queue was
- locked. */
- if( pxQueue->xRxLock == queueUNLOCKED )
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
+ /* The task waiting has a higher priority than us so
+ force a context switch. */
+ if( pxHigherPriorityTaskWoken != NULL )
{
- /* The task waiting has a higher priority than us so
- force a context switch. */
- if( pxHigherPriorityTaskWoken != NULL )
- {
- *pxHigherPriorityTaskWoken = pdTRUE;
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
+ *pxHigherPriorityTaskWoken = pdTRUE;
}
else
{
}
else
{
- /* Increment the lock count so the task that unlocks the queue
- knows that data was removed while it was locked. */
- ++( pxQueue->xRxLock );
+ mtCOVERAGE_TEST_MARKER();
}
xReturn = pdPASS;
( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */
}
}
-/*-----------------------------------------------------------*/
-
-static void prvUnlockQueue( Queue_t * const pxQueue )
-{
- /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
- /* The lock counts contains the number of extra data items placed or
- removed from the queue while the queue was locked. When a queue is
- locked items can be added or removed, but the event lists cannot be
- updated. */
- taskENTER_CRITICAL(&pxQueue->mux);
- {
- /* See if data was added to the queue while it was locked. */
- while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED )
- {
- /* Data was posted while the queue was locked. Are any tasks
- blocked waiting for data to become available? */
- #if ( configUSE_QUEUE_SETS == 1 )
- {
- if( pxQueue->pxQueueSetContainer != NULL )
- {
- if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE )
- {
- /* The queue is a member of a queue set, and posting to
- the queue set caused a higher priority task to unblock.
- A context switch is required. */
- taskEXIT_CRITICAL(&pxQueue->mux); //ToDo: Is aquire/release needed around any of the bTaskMissedYield calls?
- vTaskMissedYield();
- taskENTER_CRITICAL(&pxQueue->mux);
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
- }
- else
- {
- /* Tasks that are removed from the event list will get added to
- the pending ready list as the scheduler is still suspended. */
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
- {
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
- {
- /* The task waiting has a higher priority so record that a
- context switch is required. */
- taskEXIT_CRITICAL(&pxQueue->mux);
- vTaskMissedYield();
- taskENTER_CRITICAL(&pxQueue->mux);
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
- }
- else
- {
- break;
- }
- }
- }
- #else /* configUSE_QUEUE_SETS */
- {
- /* Tasks that are removed from the event list will get added to
- the pending ready list as the scheduler is still suspended. */
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
- {
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
- {
- /* The task waiting has a higher priority so record that a
- context switch is required. */
- taskEXIT_CRITICAL(&pxQueue->mux);
- vTaskMissedYield();
- taskENTER_CRITICAL(&pxQueue->mux);
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
- }
- else
- {
- break;
- }
- }
- #endif /* configUSE_QUEUE_SETS */
-
- --( pxQueue->xTxLock );
- }
-
- pxQueue->xTxLock = queueUNLOCKED;
- }
- taskEXIT_CRITICAL(&pxQueue->mux);
-
- /* Do the same for the Rx lock. */
- taskENTER_CRITICAL(&pxQueue->mux);
- {
- while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )
- {
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
- {
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
- {
- taskEXIT_CRITICAL(&pxQueue->mux);
- vTaskMissedYield();
- taskENTER_CRITICAL(&pxQueue->mux);
- }
- else
- {
- mtCOVERAGE_TEST_MARKER();
- }
-
- --( pxQueue->xRxLock );
- }
- else
- {
- break;
- }
- }
-
- pxQueue->xRxLock = queueUNLOCKED;
- }
- taskEXIT_CRITICAL(&pxQueue->mux);
-}
/*-----------------------------------------------------------*/
static BaseType_t prvIsQueueEmpty( Queue_t *pxQueue )
/* Only do anything if there are no messages in the queue. This function
will not actually cause the task to block, just place it on a blocked
list. It will not block until the scheduler is unlocked - at which
- time a yield will be performed. If an item is added to the queue while
- the queue is locked, and the calling task blocks on the queue, then the
- calling task will be immediately unblocked when the queue is unlocked. */
-// prvLockQueue( pxQueue );
+ time a yield will be performed. */
+ taskENTER_CRITICAL(&pxQueue->mux);
if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0U )
{
/* There is nothing in the queue, block for the specified period. */
{
mtCOVERAGE_TEST_MARKER();
}
-// prvUnlockQueue( pxQueue );
+ taskEXIT_CRITICAL(&pxQueue->mux);
}
#endif /* configUSE_TIMERS */