\r
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
\r
-/*-----------------------------------------------------------\r
- * PUBLIC LIST API documented in list.h\r
- *----------------------------------------------------------*/\r
-\r
/* Constants used with the cRxLock and xTxLock structure members. */\r
#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )\r
#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 )\r
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )\r
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )\r
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )\r
+#define queueQUEUE_TYPE_SET ( 5U )\r
\r
/*\r
* Definition of the queue used by the scheduler.\r
*/\r
typedef struct QueueDefinition\r
{\r
- signed char *pcHead; /*< Points to the beginning of the queue storage area. */\r
- signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */\r
+ signed char *pcHead; /*< Points to the beginning of the queue storage area. */\r
+ signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */\r
\r
- signed char *pcWriteTo; /*< Points to the free next place in the storage area. */\r
- signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */\r
+ signed char *pcWriteTo; /*< Points to the free next place in the storage area. */\r
+ signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */\r
\r
xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */\r
xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */\r
unsigned char ucQueueType;\r
#endif\r
\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ struct QueueDefinition *pxQueueSetContainer;\r
+ #endif\r
+\r
} xQUEUE;\r
/*-----------------------------------------------------------*/\r
\r
* pointer to void.\r
*/\r
typedef xQUEUE * xQueueHandle;\r
+typedef xQUEUE * xQueueSetHandle;\r
\r
/*\r
- * Prototypes for public functions are included here so we don't have to\r
- * include the API header file (as it defines xQueueHandle differently). These\r
- * functions are documented in the API header file.\r
+ * In order to implement strict data hiding, the queue.h header file defines \r
+ * xQueueHandle and xQueueSetHandle as pointers to void. In this file\r
+ * xQueueHandle and xQueueSetHandle are defined as pointers to xQUEUE objects.\r
+ * Therefore the queue.h header file cannot be included in this source file,\r
+ * and the function prototypes are provided directly.\r
*/\r
xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) PRIVILEGED_FUNCTION;\r
signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;\r
xTaskHandle xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;\r
+xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION;\r
+xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION;\r
+portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;\r
+portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* Co-routine queue functions differ from task queue functions. Co-routines are\r
* an optional component.\r
*/\r
-#if configUSE_CO_ROUTINES == 1\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) PRIVILEGED_FUNCTION;\r
signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;\r
signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
* The queue registry is just a means for kernel aware debuggers to locate\r
* queue structures. It has no other purpose so is an optional component.\r
*/\r
-#if configQUEUE_REGISTRY_SIZE > 0\r
+#if ( configQUEUE_REGISTRY_SIZE > 0 )\r
\r
/* The type stored within the queue registry array. This allows a name\r
to be assigned to each queue making kernel aware debugging a little\r
* Copies an item out of a queue.\r
*/\r
static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION;\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+ /*\r
+ * Checks to see if a queue is a member of a queue set, and if so, notifies\r
+ * the queue set that the queue contains data.\r
+ */\r
+ static portBASE_TYPE prvCheckForMembershipOfQueueSet( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition );\r
+#endif\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
taskEXIT_CRITICAL()\r
/*-----------------------------------------------------------*/\r
\r
-\r
-/*-----------------------------------------------------------\r
- * PUBLIC QUEUE MANAGEMENT API documented in queue.h\r
- *----------------------------------------------------------*/\r
-\r
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue )\r
{\r
configASSERT( pxQueue );\r
pxNewQueue->uxLength = uxQueueLength;\r
pxNewQueue->uxItemSize = uxItemSize;\r
xQueueGenericReset( pxNewQueue, pdTRUE );\r
+ \r
#if ( configUSE_TRACE_FACILITY == 1 )\r
{\r
pxNewQueue->ucQueueType = ucQueueType;\r
}\r
#endif /* configUSE_TRACE_FACILITY */\r
\r
+ #if( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ pxNewQueue->pxQueueSetContainer = NULL;\r
+ }\r
+ #endif /* configUSE_QUEUE_SETS */\r
+\r
traceQUEUE_CREATE( pxNewQueue );\r
xReturn = pxNewQueue;\r
}\r
}\r
#endif\r
\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ pxNewQueue->pxQueueSetContainer = NULL;\r
+ }\r
+ #endif\r
+\r
/* Ensure the event queues start with the correct state. */\r
vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );\r
vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
#endif /* configUSE_MUTEXES */\r
/*-----------------------------------------------------------*/\r
\r
-#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xQueueGetMutexHolder == 1 ) )\r
+#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )\r
\r
void* xQueueGetMutexHolder( xQueueHandle xSemaphore )\r
{\r
#endif /* configUSE_RECURSIVE_MUTEXES */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_RECURSIVE_MUTEXES == 1\r
+#if ( configUSE_RECURSIVE_MUTEXES == 1 )\r
\r
portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime )\r
{\r
#endif /* configUSE_RECURSIVE_MUTEXES */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_COUNTING_SEMAPHORES == 1\r
+#if ( configUSE_COUNTING_SEMAPHORES == 1 )\r
\r
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )\r
{\r
portYIELD_WITHIN_API();\r
}\r
}\r
+ else\r
+ {\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ if( prvCheckForMembershipOfQueueSet( pxQueue, xCopyPosition ) == pdTRUE )\r
+ {\r
+ /* The queue is a member of a queue set, and posting to\r
+ the queue set caused a higher priority task to unblock.\r
+ A context switch is required. */\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ #endif /* configUSE_QUEUE_SETS */\r
+ }\r
\r
taskEXIT_CRITICAL();\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_ALTERNATIVE_API == 1\r
+#if ( configUSE_ALTERNATIVE_API == 1 )\r
\r
signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
{\r
#endif /* configUSE_ALTERNATIVE_API */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_ALTERNATIVE_API == 1\r
+#if ( configUSE_ALTERNATIVE_API == 1 )\r
\r
signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
{\r
}\r
}\r
}\r
+ else\r
+ {\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ if( pxQueue->pxQueueSetContainer != NULL )\r
+ {\r
+ xQueueGenericSendFromISR( pxQueue->pxQueueSetContainer, &pxQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK );\r
+ }\r
+ }\r
+ #endif /* configUSE_QUEUE_SETS */\r
+ }\r
}\r
else\r
{\r
{\r
traceQUEUE_PEEK( pxQueue );\r
\r
- /* We are not removing the data, so reset our read\r
+ /* The data is not being removed, so reset the read \r
pointer. */\r
pxQueue->pcReadFrom = pcOriginalReadPosition;\r
\r
portYIELD_WITHIN_API();\r
}\r
}\r
+ else\r
+ {\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ if( pxQueue->pxQueueSetContainer != NULL )\r
+ {\r
+ xQueueGenericSend( pxQueue->pxQueueSetContainer, &pxQueue, 0, queueSEND_TO_BACK );\r
+ }\r
+ }\r
+ #endif /* configUSE_QUEUE_SETS */\r
+ }\r
}\r
\r
taskEXIT_CRITICAL();\r
return pxQueue->ucQueueNumber;\r
}\r
\r
-#endif\r
+#endif /* configUSE_TRACE_FACILITY */\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_TRACE_FACILITY == 1 )\r
pxQueue->ucQueueNumber = ucQueueNumber;\r
}\r
\r
-#endif\r
+#endif /* configUSE_TRACE_FACILITY */\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_TRACE_FACILITY == 1 )\r
return pxQueue->ucQueueType;\r
}\r
\r
-#endif\r
+#endif /* configUSE_TRACE_FACILITY */\r
/*-----------------------------------------------------------*/\r
\r
static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )\r
context switch is required. */\r
vTaskMissedYield();\r
}\r
+ else\r
+ {\r
+ #if ( configUSE_QUEUE_SETS == 1 )\r
+ {\r
+ if( pxQueue->pxQueueSetContainer != NULL )\r
+ {\r
+ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
+ xQueueGenericSendFromISR( pxQueue->pxQueueSetContainer, &pxQueue, &xHigherPriorityTaskWoken, queueSEND_TO_BACK );\r
+ if( xHigherPriorityTaskWoken != pdFALSE )\r
+ {\r
+ vTaskMissedYield();\r
+ }\r
+ }\r
+ }\r
+ #endif /* configUSE_QUEUE_SETS */\r
+ }\r
\r
--( pxQueue->xTxLock );\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
-{\r
-signed portBASE_TYPE xReturn;\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
\r
- /* If the queue is already full we may have to block. A critical section\r
- is required to prevent an interrupt removing something from the queue\r
- between the check to see if the queue is full and blocking on the queue. */\r
- portDISABLE_INTERRUPTS();\r
+ signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
{\r
- if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
+ signed portBASE_TYPE xReturn;\r
+\r
+ /* If the queue is already full we may have to block. A critical section\r
+ is required to prevent an interrupt removing something from the queue\r
+ between the check to see if the queue is full and blocking on the queue. */\r
+ portDISABLE_INTERRUPTS();\r
{\r
- /* The queue is full - do we want to block or just leave without\r
- posting? */\r
- if( xTicksToWait > ( portTickType ) 0 )\r
- {\r
- /* As this is called from a coroutine we cannot block directly, but\r
- return indicating that we need to block. */\r
- vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_BLOCKED;\r
- }\r
- else\r
+ if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
{\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_FULL;\r
+ /* The queue is full - do we want to block or just leave without\r
+ posting? */\r
+ if( xTicksToWait > ( portTickType ) 0 )\r
+ {\r
+ /* As this is called from a coroutine we cannot block directly, but\r
+ return indicating that we need to block. */\r
+ vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_BLOCKED;\r
+ }\r
+ else\r
+ {\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_FULL;\r
+ }\r
}\r
}\r
- }\r
- portENABLE_INTERRUPTS();\r
+ portENABLE_INTERRUPTS();\r
\r
- portNOP();\r
+ portNOP();\r
\r
- portDISABLE_INTERRUPTS();\r
- {\r
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+ portDISABLE_INTERRUPTS();\r
{\r
- /* There is room in the queue, copy the data into the queue. */\r
- prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
- xReturn = pdPASS;\r
-\r
- /* Were any co-routines waiting for data to become available? */\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
{\r
- /* In this instance the co-routine could be placed directly\r
- into the ready list as we are within a critical section.\r
- Instead the same pending ready list mechanism is used as if\r
- the event were caused from within an interrupt. */\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ /* There is room in the queue, copy the data into the queue. */\r
+ prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
+ xReturn = pdPASS;\r
+\r
+ /* Were any co-routines waiting for data to become available? */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
- /* The co-routine waiting has a higher priority so record\r
- that a yield might be appropriate. */\r
- xReturn = errQUEUE_YIELD;\r
+ /* In this instance the co-routine could be placed directly\r
+ into the ready list as we are within a critical section.\r
+ Instead the same pending ready list mechanism is used as if\r
+ the event were caused from within an interrupt. */\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ /* The co-routine waiting has a higher priority so record\r
+ that a yield might be appropriate. */\r
+ xReturn = errQUEUE_YIELD;\r
+ }\r
}\r
}\r
+ else\r
+ {\r
+ xReturn = errQUEUE_FULL;\r
+ }\r
}\r
- else\r
- {\r
- xReturn = errQUEUE_FULL;\r
- }\r
+ portENABLE_INTERRUPTS();\r
+\r
+ return xReturn;\r
}\r
- portENABLE_INTERRUPTS();\r
\r
- return xReturn;\r
-}\r
-#endif\r
+#endif /* configUSE_CO_ROUTINES */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )\r
-{\r
-signed portBASE_TYPE xReturn;\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
\r
- /* If the queue is already empty we may have to block. A critical section\r
- is required to prevent an interrupt adding something to the queue\r
- between the check to see if the queue is empty and blocking on the queue. */\r
- portDISABLE_INTERRUPTS();\r
+ signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )\r
{\r
- if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
+ signed portBASE_TYPE xReturn;\r
+\r
+ /* If the queue is already empty we may have to block. A critical section\r
+ is required to prevent an interrupt adding something to the queue\r
+ between the check to see if the queue is empty and blocking on the queue. */\r
+ portDISABLE_INTERRUPTS();\r
{\r
- /* There are no messages in the queue, do we want to block or just\r
- leave with nothing? */\r
- if( xTicksToWait > ( portTickType ) 0 )\r
+ if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
{\r
- /* As this is a co-routine we cannot block directly, but return\r
- indicating that we need to block. */\r
- vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_BLOCKED;\r
- }\r
- else\r
- {\r
- portENABLE_INTERRUPTS();\r
- return errQUEUE_FULL;\r
+ /* There are no messages in the queue, do we want to block or just\r
+ leave with nothing? */\r
+ if( xTicksToWait > ( portTickType ) 0 )\r
+ {\r
+ /* As this is a co-routine we cannot block directly, but return\r
+ indicating that we need to block. */\r
+ vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_BLOCKED;\r
+ }\r
+ else\r
+ {\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_FULL;\r
+ }\r
}\r
}\r
- }\r
- portENABLE_INTERRUPTS();\r
+ portENABLE_INTERRUPTS();\r
\r
- portNOP();\r
+ portNOP();\r
\r
- portDISABLE_INTERRUPTS();\r
- {\r
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+ portDISABLE_INTERRUPTS();\r
{\r
- /* Data is available from the queue. */\r
- pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
{\r
- pxQueue->pcReadFrom = pxQueue->pcHead;\r
- }\r
- --( pxQueue->uxMessagesWaiting );\r
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+ /* Data is available from the queue. */\r
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
+ if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
+ {\r
+ pxQueue->pcReadFrom = pxQueue->pcHead;\r
+ }\r
+ --( pxQueue->uxMessagesWaiting );\r
+ memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
\r
- xReturn = pdPASS;\r
+ xReturn = pdPASS;\r
\r
- /* Were any co-routines waiting for space to become available? */\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
- {\r
- /* In this instance the co-routine could be placed directly\r
- into the ready list as we are within a critical section.\r
- Instead the same pending ready list mechanism is used as if\r
- the event were caused from within an interrupt. */\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ /* Were any co-routines waiting for space to become available? */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
- xReturn = errQUEUE_YIELD;\r
+ /* In this instance the co-routine could be placed directly\r
+ into the ready list as we are within a critical section.\r
+ Instead the same pending ready list mechanism is used as if\r
+ the event were caused from within an interrupt. */\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ {\r
+ xReturn = errQUEUE_YIELD;\r
+ }\r
}\r
}\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
}\r
- else\r
- {\r
- xReturn = pdFAIL;\r
- }\r
+ portENABLE_INTERRUPTS();\r
+\r
+ return xReturn;\r
}\r
- portENABLE_INTERRUPTS();\r
\r
- return xReturn;\r
-}\r
-#endif\r
+#endif /* configUSE_CO_ROUTINES */\r
/*-----------------------------------------------------------*/\r
\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
\r
-\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )\r
-{\r
- /* Cannot block within an ISR so if there is no space on the queue then\r
- exit without doing anything. */\r
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+ signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )\r
{\r
- prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
-\r
- /* We only want to wake one co-routine per ISR, so check that a\r
- co-routine has not already been woken. */\r
- if( xCoRoutinePreviouslyWoken == pdFALSE )\r
+ /* Cannot block within an ISR so if there is no space on the queue then\r
+ exit without doing anything. */\r
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
{\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
+\r
+ /* We only want to wake one co-routine per ISR, so check that a\r
+ co-routine has not already been woken. */\r
+ if( xCoRoutinePreviouslyWoken == pdFALSE )\r
{\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
- return pdTRUE;\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ return pdTRUE;\r
+ }\r
}\r
}\r
}\r
+\r
+ return xCoRoutinePreviouslyWoken;\r
}\r
\r
- return xCoRoutinePreviouslyWoken;\r
-}\r
-#endif\r
+#endif /* configUSE_CO_ROUTINES */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_CO_ROUTINES == 1\r
-signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )\r
-{\r
-signed portBASE_TYPE xReturn;\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
\r
- /* We cannot block from an ISR, so check there is data available. If\r
- not then just leave without doing anything. */\r
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+ signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )\r
{\r
- /* Copy the data from the queue. */\r
- pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
- {\r
- pxQueue->pcReadFrom = pxQueue->pcHead;\r
- }\r
- --( pxQueue->uxMessagesWaiting );\r
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+ signed portBASE_TYPE xReturn;\r
\r
- if( ( *pxCoRoutineWoken ) == pdFALSE )\r
+ /* We cannot block from an ISR, so check there is data available. If\r
+ not then just leave without doing anything. */\r
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
{\r
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+ /* Copy the data from the queue. */\r
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
+ if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
{\r
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ pxQueue->pcReadFrom = pxQueue->pcHead;\r
+ }\r
+ --( pxQueue->uxMessagesWaiting );\r
+ memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+\r
+ if( ( *pxCoRoutineWoken ) == pdFALSE )\r
+ {\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
- *pxCoRoutineWoken = pdTRUE;\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ {\r
+ *pxCoRoutineWoken = pdTRUE;\r
+ }\r
}\r
}\r
+\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
}\r
\r
- xReturn = pdPASS;\r
- }\r
- else\r
- {\r
- xReturn = pdFAIL;\r
+ return xReturn;\r
}\r
\r
- return xReturn;\r
-}\r
-#endif\r
+#endif /* configUSE_CO_ROUTINES */\r
/*-----------------------------------------------------------*/\r
\r
-#if configQUEUE_REGISTRY_SIZE > 0\r
+#if ( configQUEUE_REGISTRY_SIZE > 0 )\r
\r
void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName )\r
{\r
}\r
}\r
\r
-#endif\r
+#endif /* configQUEUE_REGISTRY_SIZE */\r
/*-----------------------------------------------------------*/\r
\r
-#if configQUEUE_REGISTRY_SIZE > 0\r
+#if ( configQUEUE_REGISTRY_SIZE > 0 )\r
\r
static void vQueueUnregisterQueue( xQueueHandle xQueue )\r
{\r
\r
}\r
\r
-#endif\r
+#endif /* configQUEUE_REGISTRY_SIZE */\r
/*-----------------------------------------------------------*/\r
\r
-#if configUSE_TIMERS == 1\r
+#if ( configUSE_TIMERS == 1 )\r
\r
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait )\r
{\r
prvUnlockQueue( pxQueue );\r
}\r
\r
-#endif\r
+#endif /* configUSE_TIMERS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+\r
+ xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength )\r
+ {\r
+ xQUEUE *pxQueue;\r
+\r
+ pxQueue = xQueueGenericCreate( uxEventQueueLength, sizeof( xQUEUE * ), queueQUEUE_TYPE_SET );\r
+\r
+ return ( xQueueSetHandle ) pxQueue;\r
+ }\r
+\r
+#endif /* configUSE_QUEUE_SETS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+\r
+ portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet )\r
+ {\r
+ portBASE_TYPE xReturn;\r
+\r
+ if( xQueue->pxQueueSetContainer != NULL )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+ else\r
+ {\r
+ taskENTER_CRITICAL();\r
+ {\r
+ xQueue->pxQueueSetContainer = xQueueSet;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+ xReturn = pdPASS;\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configUSE_QUEUE_SETS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+\r
+ portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue )\r
+ {\r
+ portBASE_TYPE xReturn;\r
+\r
+ if( xQueue->pxQueueSetContainer != xQueueSet )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+ else\r
+ {\r
+ taskENTER_CRITICAL();\r
+ {\r
+ xQueue->pxQueueSetContainer = NULL;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+ xReturn = pdPASS;\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configUSE_QUEUE_SETS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+\r
+ xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )\r
+ {\r
+ xQueueHandle xReturn = NULL;\r
+ \r
+ xQueueGenericReceive( ( xQueueHandle ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE );\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configUSE_QUEUE_SETS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_QUEUE_SETS == 1 )\r
+\r
+ static portBASE_TYPE prvCheckForMembershipOfQueueSet( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition )\r
+ {\r
+ xQUEUE *pxQueueSetContainer = pxQueue->pxQueueSetContainer;\r
+ portBASE_TYPE xReturn = pdFALSE;\r
+\r
+ if( pxQueueSetContainer != NULL )\r
+ {\r
+ if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )\r
+ {\r
+ prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );\r
+ if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ {\r
+ if( xTaskRemoveFromEventList( &( pxQueue->pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ /* The task waiting has a higher priority */\r
+ xReturn = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configUSE_QUEUE_SETS */\r
\r