Improve QueueSet.c test coverage by reading the queue set from an ISR to force paths through the queue locking and unlocking.

Add the FreeRTOS+Trace recorder into the Win32 MSVC demo.
Added more functions, including the queue set functions, to the MPU port.
This commit is contained in:
Richard Barry 2013-02-12 10:09:36 +00:00
parent 26152204a4
commit b671bf368a
15 changed files with 1672 additions and 271 deletions

View file

@ -101,6 +101,7 @@ only for ports that are using the MPU. */
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
#define xQueueGenericCreate MPU_xQueueGenericCreate
#define xQueueCreateMutex MPU_xQueueCreateMutex
@ -113,6 +114,11 @@ only for ports that are using the MPU. */
#define xQueueGenericReceive MPU_xQueueGenericReceive
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
#define vQueueDelete MPU_vQueueDelete
#define xQueueGenericReset MPU_xQueueGenericReset
#define xQueueCreateSet MPU_xQueueCreateSet
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
#define xQueueAddToSet MPU_xQueueAddToSet
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
#define pvPortMalloc MPU_pvPortMalloc
#define vPortFree MPU_vPortFree

View file

@ -90,8 +90,8 @@ typedef void * xQueueHandle;
/**
* Type by which queue sets are referenced. For example, a call to
* xQueueSetCreate() returns an xQueueSet variable that can then be used as a
* parameter to xQueueBlockMultiple(), xQueueAddToQueueSet(), etc.
* xQueueCreateSet() returns an xQueueSet variable that can then be used as a
* parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc.
*/
typedef void * xQueueSetHandle;
@ -1309,10 +1309,10 @@ xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
* function.
*
* A queue set must be explicitly created using a call to xQueueSetCreate()
* A queue set must be explicitly created using a call to xQueueCreateSet()
* before it can be used. Once created, standard FreeRTOS queues and semaphores
* can be added to the set using calls to xQueueAddToQueueSet().
* xQueueBlockMultiple() is then used to determine which, if any, of the queues
* can be added to the set using calls to xQueueAddToSet().
* xQueueSelectFromSet() is then used to determine which, if any, of the queues
* or semaphores contained in the set is in a state where a queue read or
* semaphore take operation would be successful.
*
@ -1328,6 +1328,10 @@ xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned
* queue added to a queue set. Therefore counting semaphores with large maximum
* counts should not be added to queue sets.
*
* Note 4: A received (in the case of a queue) or take (in the case of a
* semaphore) operation must not be performed on a member of a queue set unless
* a call to xQueueSelect() has first returned a handle to that set member.
*
* @param uxEventQueueLength Queue sets themselves queue events that occur on
* the queues and semaphores contained in the set. uxEventQueueLength specifies
* the maximum number of events that can be queued at once. To be absolutely
@ -1347,15 +1351,19 @@ xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned
* @return If the queue set is created successfully then a handle to the created
* queue set is returned. Otherwise NULL is returned.
*/
xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength );
xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength );
/*
* Adds a queue or semaphore to a queue set that was previously created by a
* call to xQueueSetCreate().
* call to xQueueCreateSet().
*
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
* function.
*
* Note 1: A received (in the case of a queue) or take (in the case of a
* semaphore) operation must not be performed on a member of a queue set unless
* a call to xQueueSelect() has first returned a handle to that set member.
*
* @param xQueueOrSemaphore The handle of the queue or semaphore being added to
* the queue set (cast to an xQueueSetMemberHandle type).
*
@ -1367,10 +1375,11 @@ xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength );
* queue set because it is already a member of a different queue set then pdFAIL
* is returned.
*/
portBASE_TYPE xQueueAddToQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
/*
* Removes a queue or semaphore from a queue set.
* Removes a queue or semaphore from a queue set. A queue can only be removed
* from a set when it is empty.
*
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
* function.
@ -1385,11 +1394,14 @@ portBASE_TYPE xQueueAddToQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQue
* then pdPASS is returned. If the queue was not in the queue set then pdFAIL
* is returned.
*/
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
/*
* xQueueBlockMultiple() allows a task to block (pend) on a read operation on
* all the queues and semaphores in a queue set simultaneously.
* xQueueSelectFromSet() selects from the members of a queue set a queue or
* semaphore that either contains data (in the case of a queue) or is available
* to take (in the case of a semaphore). xQueueSelectFromSet() effectively
* allows a task to block (pend) on a read operation on all the queues and
* semaphores in a queue set simultaneously.
*
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
* function.
@ -1402,6 +1414,10 @@ portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore,
* Note 2: Blocking on a queue set that contains a mutex will not cause the
* mutex holder to inherit the priority of the blocked task.
*
* Note 3: A received (in the case of a queue) or take (in the case of a
* semaphore) operation must not be performed on a member of a queue set unless
* a call to xQueueSelect() has first returned a handle to that set member.
*
* @param xQueueSet The queue set on which the task will (potentially) block.
*
* @param xBlockTimeTicks The maximum time, in ticks, that the calling task will
@ -1409,13 +1425,18 @@ portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore,
* of the queue set to be ready for a successful queue read or semaphore take
* operation.
*
* @return xQueueBlockMultiple() will return the handle of a queue (cast to
* @return xQueueSelectFromSet() will return the handle of a queue (cast to
* a xQueueSetMemberHandle type) contained in the queue set that contains data,
* or the handle of a semaphore (cast to a xQueueSetMemberHandle type) contained
* in the queue set that is available, or NULL if no such queue or semaphore
* exists before before the specified block time expires.
*/
xQueueSetMemberHandle xQueueBlockMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks );
xQueueSetMemberHandle xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks );
/*
* A version of xQueueSelectFromSet() that can be used from an ISR.
*/
xQueueSetMemberHandle xQueueSelectFromSetFromISR( xQueueSetHandle xQueueSet );
/* Not public API functions. */
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait );

View file

@ -196,8 +196,10 @@ portBASE_TYPE MPU_xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParam
unsigned portBASE_TYPE MPU_uxTaskGetStackHighWaterMark( xTaskHandle xTask );
xTaskHandle MPU_xTaskGetCurrentTaskHandle( void );
portBASE_TYPE MPU_xTaskGetSchedulerState( void );
xTaskHandle MPU_xTaskGetIdleTaskHandle( void );
xQueueHandle MPU_xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType );
signed portBASE_TYPE MPU_xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
portBASE_TYPE MPU_xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue );
unsigned portBASE_TYPE MPU_uxQueueMessagesWaiting( const xQueueHandle pxQueue );
signed portBASE_TYPE MPU_xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
xQueueHandle MPU_xQueueCreateMutex( void );
@ -212,6 +214,10 @@ void *MPU_pvPortMalloc( size_t xSize );
void MPU_vPortFree( void *pv );
void MPU_vPortInitialiseBlocks( void );
size_t MPU_xPortGetFreeHeapSize( void );
xQueueSetHandle MPU_xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength );
xQueueSetMemberHandle MPU_xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks );
portBASE_TYPE MPU_xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
portBASE_TYPE MPU_xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
/*-----------------------------------------------------------*/
@ -749,6 +755,19 @@ portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
#endif
/*-----------------------------------------------------------*/
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
xTaskHandle MPU_xTaskGetIdleTaskHandle( void )
{
xTaskHandle xReturn;
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
xReturn = xTaskGetIdleTaskHandle();
portRESET_PRIVILEGE( xRunningPrivileged );
return eReturn;
}
#endif
/*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskSuspend == 1 )
void MPU_vTaskSuspend( xTaskHandle pxTaskToSuspend )
{
@ -935,6 +954,17 @@ portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
}
/*-----------------------------------------------------------*/
portBASE_TYPE MPU_xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue )
{
portBASE_TYPE xReturn;
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
xReturn = xQueueGenericReset( pxQueue, xNewQueue );
portRESET_PRIVILEGE( xRunningPrivileged );
return xReturn;
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE MPU_xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
{
signed portBASE_TYPE xReturn;
@ -1020,6 +1050,58 @@ signed portBASE_TYPE xReturn;
#endif
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
xQueueSetHandle MPU_xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength )
{
xQueueSetHandle xReturn;
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
xReturn = xQueueCreateSet( uxEventQueueLength );
portRESET_PRIVILEGE( xRunningPrivileged );
return xReturn;
}
#endif
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
xQueueSetMemberHandle MPU_xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )
{
xQueueSetMemberHandle xReturn;
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks );
portRESET_PRIVILEGE( xRunningPrivileged );
return xReturn;
}
#endif
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
portBASE_TYPE MPU_xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
{
portBASE_TYPE xReturn;
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet );
portRESET_PRIVILEGE( xRunningPrivileged );
return xReturn;
}
#endif
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
portBASE_TYPE MPU_xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
{
portBASE_TYPE xReturn;
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet );
portRESET_PRIVILEGE( xRunningPrivileged );
return xReturn;
}
#endif
/*-----------------------------------------------------------*/
#if configUSE_ALTERNATIVE_API == 1
signed portBASE_TYPE MPU_xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
{

View file

@ -111,7 +111,7 @@ zero. */
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )
#define queueQUEUE_TYPE_SET ( 5U )
#define queueQUEUE_TYPE_SET ( 0U )
/*
* Definition of the queue used by the scheduler.
@ -191,10 +191,10 @@ void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber ) P
unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;
xTaskHandle xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;
xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION;
xQueueSetMemberHandle xQueueBlockMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION;
portBASE_TYPE xQueueAddToQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION;
xQueueSetMemberHandle xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION;
portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
/*
* Co-routine queue functions differ from task queue functions. Co-routines are
@ -630,36 +630,52 @@ xTimeOutType xTimeOut;
traceQUEUE_SEND( pxQueue );
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
/* If there was a task waiting for data to arrive on the
queue then unblock it now. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
#if ( configUSE_QUEUE_SETS == 1 )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
if( pxQueue->pxQueueSetContainer != NULL )
{
/* The unblocked task has a priority higher than
our own so yield immediately. Yes it is ok to do
this from within the critical section - the kernel
takes care of that. */
portYIELD_WITHIN_API();
}
}
else
{
#if ( configUSE_QUEUE_SETS == 1 )
{
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. */
portYIELD_WITHIN_API();
}
}
else
{
/* If there was a task waiting for data to arrive on the
queue then unblock it now. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == 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. */
/* The unblocked task has a priority higher than
our own so yield immediately. Yes it is ok to
do this from within the critical section - the
kernel takes care of that. */
portYIELD_WITHIN_API();
}
}
}
#endif /* configUSE_QUEUE_SETS */
}
#else /* configUSE_QUEUE_SETS */
{
/* If there was a task waiting for data to arrive on the
queue then unblock it now. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
{
/* The unblocked task has a priority higher than
our own so yield immediately. Yes it is ok to do
this from within the critical section - the kernel
takes care of that. */
portYIELD_WITHIN_API();
}
}
}
#endif /* configUSE_QUEUE_SETS */
taskEXIT_CRITICAL();
@ -977,29 +993,29 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
be done when the queue is unlocked later. */
if( pxQueue->xTxLock == queueUNLOCKED )
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
#if ( configUSE_QUEUE_SETS == 1 )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
if( pxQueue->pxQueueSetContainer != NULL )
{
/* The task waiting has a higher priority so record that a
context switch is required. */
if( pxHigherPriorityTaskWoken != NULL )
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
{
*pxHigherPriorityTaskWoken = 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 )
{
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
}
}
else
{
#if ( configUSE_QUEUE_SETS == 1 )
else
{
if( pxQueue->pxQueueSetContainer != NULL )
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* 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. */
/* The task waiting has a higher priority so record that a
context switch is required. */
if( pxHigherPriorityTaskWoken != NULL )
{
*pxHigherPriorityTaskWoken = pdTRUE;
@ -1007,8 +1023,23 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
}
}
}
#endif /* configUSE_QUEUE_SETS */
}
#else /* configUSE_QUEUE_SETS */
{
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;
}
}
}
}
#endif /* configUSE_QUEUE_SETS */
}
else
{
@ -1371,52 +1402,58 @@ static void prvUnlockQueue( xQueueHandle pxQueue )
{
/* Data was posted while the queue was locked. Are any tasks
blocked waiting for data to become available? */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
#if ( configUSE_QUEUE_SETS == 1 )
{
/* Tasks that are removed from the event list will get added to
the pending ready list as the scheduler is still suspended. */
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
if( pxQueue->pxQueueSetContainer != NULL )
{
/* The task waiting has a higher priority so record that a
context switch is required. */
vTaskMissedYield();
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. */
vTaskMissedYield();
}
}
else
{
#if ( configUSE_QUEUE_SETS == 1 )
/* 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 )
{
/* It is highly unlikely that this code will ever run,
for the following reason:
+ A task will only lock a queue that is part of a
queue set when it is blocking on a write to the
queue.
+ An interrupt can only add something to a queue
while the queue is locked (resulting in the
following code executing when the queue is unlocked)
if the queue is not full, meaning a task will never
have blocked on a write in the first place.
The code could execute if an interrupt is also removing
items from a queue. */
if( pxQueue->pxQueueSetContainer != NULL )
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
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. */
vTaskMissedYield();
}
/* The task waiting has a higher priority so record that a
context switch is required. */
vTaskMissedYield();
}
}
#endif /* configUSE_QUEUE_SETS */
else
{
break;
}
}
--( pxQueue->xTxLock );
}
else
#else /* configUSE_QUEUE_SETS */
{
break;
/* 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. */
vTaskMissedYield();
}
}
else
{
break;
}
}
#endif /* configUSE_QUEUE_SETS */
--( pxQueue->xTxLock );
}
pxQueue->xTxLock = queueUNLOCKED;
@ -1791,7 +1828,7 @@ signed portBASE_TYPE xReturn;
#if ( configUSE_QUEUE_SETS == 1 )
xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength )
xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength )
{
xQUEUE *pxQueue;
@ -1805,7 +1842,7 @@ signed portBASE_TYPE xReturn;
#if ( configUSE_QUEUE_SETS == 1 )
portBASE_TYPE xQueueAddToQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
{
portBASE_TYPE xReturn;
@ -1831,18 +1868,27 @@ signed portBASE_TYPE xReturn;
#if ( configUSE_QUEUE_SETS == 1 )
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
{
portBASE_TYPE xReturn;
if( xQueueOrSemaphore->pxQueueSetContainer != xQueueSet )
{
/* The queue was not a member of the set. */
xReturn = pdFAIL;
}
else if( xQueueOrSemaphore->uxMessagesWaiting != 0 )
{
/* It is dangerous to remove a queue from a set when the queue is
not empty because the queue set will still hold pending events for
the queue. */
xReturn = pdFAIL;
}
else
{
taskENTER_CRITICAL();
{
/* The queue is no longer contained in the set. */
xQueueOrSemaphore->pxQueueSetContainer = NULL;
}
taskEXIT_CRITICAL();
@ -1857,7 +1903,7 @@ signed portBASE_TYPE xReturn;
#if ( configUSE_QUEUE_SETS == 1 )
xQueueSetMemberHandle xQueueBlockMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )
xQueueSetMemberHandle xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )
{
xQueueSetMemberHandle xReturn = NULL;
@ -1868,6 +1914,19 @@ signed portBASE_TYPE xReturn;
#endif /* configUSE_QUEUE_SETS */
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
xQueueSetMemberHandle xQueueSelectFromSetFromISR( xQueueSetHandle xQueueSet )
{
xQueueSetMemberHandle xReturn = NULL;
xQueueReceiveFromISR( ( xQueueHandle ) xQueueSet, &xReturn, NULL );
return xReturn;
}
#endif /* configUSE_QUEUE_SETS */
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
static portBASE_TYPE prvNotifyQueueSetContainer( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition )
@ -1880,6 +1939,8 @@ signed portBASE_TYPE xReturn;
if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )
{
traceQUEUE_SEND( pxQueueSetContainer );
/* The data copies is the handle of the queue that contains data. */
prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );
if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )
{

View file

@ -974,7 +974,11 @@ tskTCB * pxNewTCB;
/* Remember the ready list the task might be referenced from
before its uxPriority member is changed so the
taskRESET_READY_PRIORITY() macro can function correctly. */
uxPriorityUsedOnEntry = pxTCB->uxPriority;
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION != 0 )
{
uxPriorityUsedOnEntry = pxTCB->uxPriority;
}
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
#if ( configUSE_MUTEXES == 1 )
{
@ -1274,11 +1278,13 @@ portBASE_TYPE xReturn;
/* Should only reach here if a task calls xTaskEndScheduler(). */
}
}
/* This line will only be reached if the kernel could not be started, or
vTaskEndScheduler() was called (vTaskEndScheduler() is not implemented for
most ports). */
configASSERT( xReturn );
else
{
/* This line will only be reached if the kernel could not be started,
because there was not enough FreeRTOS heap to create the idle task
or the timer task. */
configASSERT( xReturn );
}
}
/*-----------------------------------------------------------*/