mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-01 08:54:14 -04:00
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:
parent
26152204a4
commit
b671bf368a
15 changed files with 1672 additions and 271 deletions
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue