2 FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
\r
4 FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
\r
5 http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
7 ***************************************************************************
\r
9 * FreeRTOS tutorial books are available in pdf and paperback. *
\r
10 * Complete, revised, and edited pdf reference manuals are also *
\r
13 * Purchasing FreeRTOS documentation will not only help you, by *
\r
14 * ensuring you get running as quickly as possible and with an *
\r
15 * in-depth knowledge of how to use FreeRTOS, it will also help *
\r
16 * the FreeRTOS project to continue with its mission of providing *
\r
17 * professional grade, cross platform, de facto standard solutions *
\r
18 * for microcontrollers - completely free of charge! *
\r
20 * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
\r
22 * Thank you for using FreeRTOS, and thank you for your support! *
\r
24 ***************************************************************************
\r
27 This file is part of the FreeRTOS distribution.
\r
29 FreeRTOS is free software; you can redistribute it and/or modify it under
\r
30 the terms of the GNU General Public License (version 2) as published by the
\r
31 Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
\r
32 >>>NOTE<<< The modification to the GPL is included to allow you to
\r
33 distribute a combined work that includes FreeRTOS without being obliged to
\r
34 provide the source code for proprietary components outside of the FreeRTOS
\r
35 kernel. FreeRTOS is distributed in the hope that it will be useful, but
\r
36 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
\r
37 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
38 more details. You should have received a copy of the GNU General Public
\r
39 License and the FreeRTOS license exception along with FreeRTOS; if not it
\r
40 can be viewed here: http://www.freertos.org/a00114.html and also obtained
\r
41 by writing to Richard Barry, contact details for whom are available on the
\r
46 ***************************************************************************
\r
48 * Having a problem? Start by reading the FAQ "My application does *
\r
49 * not run, what could be wrong?" *
\r
51 * http://www.FreeRTOS.org/FAQHelp.html *
\r
53 ***************************************************************************
\r
56 http://www.FreeRTOS.org - Documentation, training, latest versions, license
\r
57 and contact details.
\r
59 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
\r
60 including FreeRTOS+Trace - an indispensable productivity tool.
\r
62 Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
\r
63 the code with commercial support, indemnification, and middleware, under
\r
64 the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
\r
65 provide a safety engineered and independently SIL3 certified version under
\r
66 the SafeRTOS brand: http://www.SafeRTOS.com.
\r
72 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
\r
73 all the API functions to use the MPU wrappers. That should only be done when
\r
74 task.h is included from an application file. */
\r
75 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
\r
77 #include "FreeRTOS.h"
\r
80 #if ( configUSE_CO_ROUTINES == 1 )
\r
81 #include "croutine.h"
\r
84 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
\r
86 /* Constants used with the cRxLock and xTxLock structure members. */
\r
87 #define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )
\r
88 #define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 )
\r
90 #define queueERRONEOUS_UNBLOCK ( -1 )
\r
92 /* For internal use only. */
\r
93 #define queueSEND_TO_BACK ( 0 )
\r
94 #define queueSEND_TO_FRONT ( 1 )
\r
96 /* Effectively make a union out of the xQUEUE structure. */
\r
97 #define pxMutexHolder pcTail
\r
98 #define uxQueueType pcHead
\r
99 #define uxRecursiveCallCount pcReadFrom
\r
100 #define queueQUEUE_IS_MUTEX NULL
\r
102 /* Semaphores do not actually store or copy data, so have an items size of
\r
104 #define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portBASE_TYPE ) 0 )
\r
105 #define queueDONT_BLOCK ( ( portTickType ) 0U )
\r
106 #define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0U )
\r
108 /* These definitions *must* match those in queue.h. */
\r
109 #define queueQUEUE_TYPE_BASE ( 0U )
\r
110 #define queueQUEUE_TYPE_MUTEX ( 1U )
\r
111 #define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )
\r
112 #define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )
\r
113 #define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )
\r
114 #define queueQUEUE_TYPE_SET ( 5U )
\r
117 * Definition of the queue used by the scheduler.
\r
118 * Items are queued by copy, not reference.
\r
120 typedef struct QueueDefinition
\r
122 signed char *pcHead; /*< Points to the beginning of the queue storage area. */
\r
123 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
125 signed char *pcWriteTo; /*< Points to the free next place in the storage area. */
\r
126 signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */
\r
128 xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
\r
129 xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
\r
131 volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */
\r
132 unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
\r
133 unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */
\r
135 volatile signed portBASE_TYPE 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. */
\r
136 volatile signed portBASE_TYPE 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. */
\r
138 #if ( configUSE_TRACE_FACILITY == 1 )
\r
139 unsigned char ucQueueNumber;
\r
140 unsigned char ucQueueType;
\r
143 #if ( configUSE_QUEUE_SETS == 1 )
\r
144 struct QueueDefinition *pxQueueSetContainer;
\r
148 /*-----------------------------------------------------------*/
\r
151 * Inside this file xQueueHandle is a pointer to a xQUEUE structure.
\r
152 * To keep the definition private the API header file defines it as a
\r
155 typedef xQUEUE * xQueueHandle;
\r
156 typedef xQUEUE * xQueueSetHandle;
\r
159 * In order to implement strict data hiding, the queue.h header file defines
\r
160 * xQueueHandle and xQueueSetHandle as pointers to void. In this file
\r
161 * xQueueHandle and xQueueSetHandle are defined as pointers to xQUEUE objects.
\r
162 * Therefore the queue.h header file cannot be included in this source file,
\r
163 * and the function prototypes are provided directly.
\r
165 xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) PRIVILEGED_FUNCTION;
\r
166 signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
\r
167 unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
\r
168 void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
\r
169 signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
\r
170 signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;
\r
171 signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
\r
172 xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ) PRIVILEGED_FUNCTION;
\r
173 xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION;
\r
174 portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION;
\r
175 portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ) PRIVILEGED_FUNCTION;
\r
176 signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
\r
177 signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;
\r
178 signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
\r
179 signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
\r
180 unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
\r
181 void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
\r
182 unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
\r
183 void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber ) PRIVILEGED_FUNCTION;
\r
184 unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
\r
185 portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;
\r
186 xTaskHandle xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;
\r
187 xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION;
\r
188 xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION;
\r
189 portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
\r
190 portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
\r
193 * Co-routine queue functions differ from task queue functions. Co-routines are
\r
194 * an optional component.
\r
196 #if ( configUSE_CO_ROUTINES == 1 )
\r
197 signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) PRIVILEGED_FUNCTION;
\r
198 signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;
\r
199 signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
\r
200 signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
\r
204 * The queue registry is just a means for kernel aware debuggers to locate
\r
205 * queue structures. It has no other purpose so is an optional component.
\r
207 #if ( configQUEUE_REGISTRY_SIZE > 0 )
\r
209 /* The type stored within the queue registry array. This allows a name
\r
210 to be assigned to each queue making kernel aware debugging a little
\r
211 more user friendly. */
\r
212 typedef struct QUEUE_REGISTRY_ITEM
\r
214 signed char *pcQueueName;
\r
215 xQueueHandle xHandle;
\r
216 } xQueueRegistryItem;
\r
218 /* The queue registry is simply an array of xQueueRegistryItem structures.
\r
219 The pcQueueName member of a structure being NULL is indicative of the
\r
220 array position being vacant. */
\r
221 xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];
\r
223 /* Removes a queue from the registry by simply setting the pcQueueName
\r
225 static void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
\r
226 void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) PRIVILEGED_FUNCTION;
\r
230 * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not
\r
231 * prevent an ISR from adding or removing items to the queue, but does prevent
\r
232 * an ISR from removing tasks from the queue event lists. If an ISR finds a
\r
233 * queue is locked it will instead increment the appropriate queue lock count
\r
234 * to indicate that a task may require unblocking. When the queue in unlocked
\r
235 * these lock counts are inspected, and the appropriate action taken.
\r
237 static void prvUnlockQueue( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
\r
240 * Uses a critical section to determine if there is any data in a queue.
\r
242 * @return pdTRUE if the queue contains no items, otherwise pdFALSE.
\r
244 static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
\r
247 * Uses a critical section to determine if there is any space in a queue.
\r
249 * @return pdTRUE if there is no space, otherwise pdFALSE;
\r
251 static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
\r
254 * Copies an item into the queue, either at the front of the queue or the
\r
255 * back of the queue.
\r
257 static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION;
\r
260 * Copies an item out of a queue.
\r
262 static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION;
\r
264 #if ( configUSE_QUEUE_SETS == 1 )
\r
266 * Checks to see if a queue is a member of a queue set, and if so, notifies
\r
267 * the queue set that the queue contains data.
\r
269 static portBASE_TYPE prvCheckForMembershipOfQueueSet( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition );
\r
272 /*-----------------------------------------------------------*/
\r
275 * Macro to mark a queue as locked. Locking a queue prevents an ISR from
\r
276 * accessing the queue event lists.
\r
278 #define prvLockQueue( pxQueue ) \
\r
279 taskENTER_CRITICAL(); \
\r
281 if( ( pxQueue )->xRxLock == queueUNLOCKED ) \
\r
283 ( pxQueue )->xRxLock = queueLOCKED_UNMODIFIED; \
\r
285 if( ( pxQueue )->xTxLock == queueUNLOCKED ) \
\r
287 ( pxQueue )->xTxLock = queueLOCKED_UNMODIFIED; \
\r
290 taskEXIT_CRITICAL()
\r
291 /*-----------------------------------------------------------*/
\r
293 portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue )
\r
295 configASSERT( pxQueue );
\r
297 taskENTER_CRITICAL();
\r
299 pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize );
\r
300 pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;
\r
301 pxQueue->pcWriteTo = pxQueue->pcHead;
\r
302 pxQueue->pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize );
\r
303 pxQueue->xRxLock = queueUNLOCKED;
\r
304 pxQueue->xTxLock = queueUNLOCKED;
\r
306 if( xNewQueue == pdFALSE )
\r
308 /* If there are tasks blocked waiting to read from the queue, then
\r
309 the tasks will remain blocked as after this function exits the queue
\r
310 will still be empty. If there are tasks blocked waiting to write to
\r
311 the queue, then one should be unblocked as after this function exits
\r
312 it will be possible to write to it. */
\r
313 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
\r
315 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
\r
317 portYIELD_WITHIN_API();
\r
323 /* Ensure the event queues start in the correct state. */
\r
324 vListInitialise( &( pxQueue->xTasksWaitingToSend ) );
\r
325 vListInitialise( &( pxQueue->xTasksWaitingToReceive ) );
\r
328 taskEXIT_CRITICAL();
\r
330 /* A value is returned for calling semantic consistency with previous
\r
334 /*-----------------------------------------------------------*/
\r
336 xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType )
\r
338 xQUEUE *pxNewQueue;
\r
339 size_t xQueueSizeInBytes;
\r
340 xQueueHandle xReturn = NULL;
\r
342 /* Remove compiler warnings about unused parameters should
\r
343 configUSE_TRACE_FACILITY not be set to 1. */
\r
344 ( void ) ucQueueType;
\r
346 /* Allocate the new queue structure. */
\r
347 if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )
\r
349 pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
\r
350 if( pxNewQueue != NULL )
\r
352 /* Create the list of pointers to queue items. The queue is one byte
\r
353 longer than asked for to make wrap checking easier/faster. */
\r
354 xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1;
\r
356 pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes );
\r
357 if( pxNewQueue->pcHead != NULL )
\r
359 /* Initialise the queue members as described above where the
\r
360 queue type is defined. */
\r
361 pxNewQueue->uxLength = uxQueueLength;
\r
362 pxNewQueue->uxItemSize = uxItemSize;
\r
363 xQueueGenericReset( pxNewQueue, pdTRUE );
\r
365 #if ( configUSE_TRACE_FACILITY == 1 )
\r
367 pxNewQueue->ucQueueType = ucQueueType;
\r
369 #endif /* configUSE_TRACE_FACILITY */
\r
371 #if( configUSE_QUEUE_SETS == 1 )
\r
373 pxNewQueue->pxQueueSetContainer = NULL;
\r
375 #endif /* configUSE_QUEUE_SETS */
\r
377 traceQUEUE_CREATE( pxNewQueue );
\r
378 xReturn = pxNewQueue;
\r
382 traceQUEUE_CREATE_FAILED( ucQueueType );
\r
383 vPortFree( pxNewQueue );
\r
388 configASSERT( xReturn );
\r
392 /*-----------------------------------------------------------*/
\r
394 #if ( configUSE_MUTEXES == 1 )
\r
396 xQueueHandle xQueueCreateMutex( unsigned char ucQueueType )
\r
398 xQUEUE *pxNewQueue;
\r
400 /* Prevent compiler warnings about unused parameters if
\r
401 configUSE_TRACE_FACILITY does not equal 1. */
\r
402 ( void ) ucQueueType;
\r
404 /* Allocate the new queue structure. */
\r
405 pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
\r
406 if( pxNewQueue != NULL )
\r
408 /* Information required for priority inheritance. */
\r
409 pxNewQueue->pxMutexHolder = NULL;
\r
410 pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;
\r
412 /* Queues used as a mutex no data is actually copied into or out
\r
414 pxNewQueue->pcWriteTo = NULL;
\r
415 pxNewQueue->pcReadFrom = NULL;
\r
417 /* Each mutex has a length of 1 (like a binary semaphore) and
\r
418 an item size of 0 as nothing is actually copied into or out
\r
420 pxNewQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;
\r
421 pxNewQueue->uxLength = ( unsigned portBASE_TYPE ) 1U;
\r
422 pxNewQueue->uxItemSize = ( unsigned portBASE_TYPE ) 0U;
\r
423 pxNewQueue->xRxLock = queueUNLOCKED;
\r
424 pxNewQueue->xTxLock = queueUNLOCKED;
\r
426 #if ( configUSE_TRACE_FACILITY == 1 )
\r
428 pxNewQueue->ucQueueType = ucQueueType;
\r
432 #if ( configUSE_QUEUE_SETS == 1 )
\r
434 pxNewQueue->pxQueueSetContainer = NULL;
\r
438 /* Ensure the event queues start with the correct state. */
\r
439 vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
\r
440 vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
\r
442 traceCREATE_MUTEX( pxNewQueue );
\r
444 /* Start with the semaphore in the expected state. */
\r
445 xQueueGenericSend( pxNewQueue, NULL, ( portTickType ) 0U, queueSEND_TO_BACK );
\r
449 traceCREATE_MUTEX_FAILED();
\r
452 configASSERT( pxNewQueue );
\r
456 #endif /* configUSE_MUTEXES */
\r
457 /*-----------------------------------------------------------*/
\r
459 #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )
\r
461 void* xQueueGetMutexHolder( xQueueHandle xSemaphore )
\r
465 /* This function is called by xSemaphoreGetMutexHolder(), and should not
\r
466 be called directly. Note: This is is a good way of determining if the
\r
467 calling task is the mutex holder, but not a good way of determining the
\r
468 identity of the mutex holder, as the holder may change between the
\r
469 following critical section exiting and the function returning. */
\r
470 taskENTER_CRITICAL();
\r
472 if( xSemaphore->uxQueueType == queueQUEUE_IS_MUTEX )
\r
474 pxReturn = ( void * ) xSemaphore->pxMutexHolder;
\r
481 taskEXIT_CRITICAL();
\r
487 /*-----------------------------------------------------------*/
\r
489 #if ( configUSE_RECURSIVE_MUTEXES == 1 )
\r
491 portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex )
\r
493 portBASE_TYPE xReturn;
\r
495 configASSERT( pxMutex );
\r
497 /* If this is the task that holds the mutex then pxMutexHolder will not
\r
498 change outside of this task. If this task does not hold the mutex then
\r
499 pxMutexHolder can never coincidentally equal the tasks handle, and as
\r
500 this is the only condition we are interested in it does not matter if
\r
501 pxMutexHolder is accessed simultaneously by another task. Therefore no
\r
502 mutual exclusion is required to test the pxMutexHolder variable. */
\r
503 if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )
\r
505 traceGIVE_MUTEX_RECURSIVE( pxMutex );
\r
507 /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to
\r
508 the task handle, therefore no underflow check is required. Also,
\r
509 uxRecursiveCallCount is only modified by the mutex holder, and as
\r
510 there can only be one, no mutual exclusion is required to modify the
\r
511 uxRecursiveCallCount member. */
\r
512 ( pxMutex->uxRecursiveCallCount )--;
\r
514 /* Have we unwound the call count? */
\r
515 if( pxMutex->uxRecursiveCallCount == 0 )
\r
517 /* Return the mutex. This will automatically unblock any other
\r
518 task that might be waiting to access the mutex. */
\r
519 xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );
\r
526 /* We cannot give the mutex because we are not the holder. */
\r
529 traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex );
\r
535 #endif /* configUSE_RECURSIVE_MUTEXES */
\r
536 /*-----------------------------------------------------------*/
\r
538 #if ( configUSE_RECURSIVE_MUTEXES == 1 )
\r
540 portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime )
\r
542 portBASE_TYPE xReturn;
\r
544 configASSERT( pxMutex );
\r
546 /* Comments regarding mutual exclusion as per those within
\r
547 xQueueGiveMutexRecursive(). */
\r
549 traceTAKE_MUTEX_RECURSIVE( pxMutex );
\r
551 if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )
\r
553 ( pxMutex->uxRecursiveCallCount )++;
\r
558 xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE );
\r
560 /* pdPASS will only be returned if we successfully obtained the mutex,
\r
561 we may have blocked to reach here. */
\r
562 if( xReturn == pdPASS )
\r
564 ( pxMutex->uxRecursiveCallCount )++;
\r
568 traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex );
\r
575 #endif /* configUSE_RECURSIVE_MUTEXES */
\r
576 /*-----------------------------------------------------------*/
\r
578 #if ( configUSE_COUNTING_SEMAPHORES == 1 )
\r
580 xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )
\r
582 xQueueHandle pxHandle;
\r
584 pxHandle = xQueueGenericCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE );
\r
586 if( pxHandle != NULL )
\r
588 pxHandle->uxMessagesWaiting = uxInitialCount;
\r
590 traceCREATE_COUNTING_SEMAPHORE();
\r
594 traceCREATE_COUNTING_SEMAPHORE_FAILED();
\r
597 configASSERT( pxHandle );
\r
601 #endif /* configUSE_COUNTING_SEMAPHORES */
\r
602 /*-----------------------------------------------------------*/
\r
604 signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
\r
606 signed portBASE_TYPE xEntryTimeSet = pdFALSE;
\r
607 xTimeOutType xTimeOut;
\r
609 configASSERT( pxQueue );
\r
610 configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
\r
612 /* This function relaxes the coding standard somewhat to allow return
\r
613 statements within the function itself. This is done in the interest
\r
614 of execution time efficiency. */
\r
617 taskENTER_CRITICAL();
\r
619 /* Is there room on the queue now? To be running we must be
\r
620 the highest priority task wanting to access the queue. */
\r
621 if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
\r
623 traceQUEUE_SEND( pxQueue );
\r
624 prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
\r
626 /* If there was a task waiting for data to arrive on the
\r
627 queue then unblock it now. */
\r
628 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
\r
630 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
\r
632 /* The unblocked task has a priority higher than
\r
633 our own so yield immediately. Yes it is ok to do
\r
634 this from within the critical section - the kernel
\r
635 takes care of that. */
\r
636 portYIELD_WITHIN_API();
\r
641 #if ( configUSE_QUEUE_SETS == 1 )
\r
643 if( prvCheckForMembershipOfQueueSet( pxQueue, xCopyPosition ) == pdTRUE )
\r
645 /* The queue is a member of a queue set, and posting to
\r
646 the queue set caused a higher priority task to unblock.
\r
647 A context switch is required. */
\r
648 portYIELD_WITHIN_API();
\r
651 #endif /* configUSE_QUEUE_SETS */
\r
654 taskEXIT_CRITICAL();
\r
656 /* Return to the original privilege level before exiting the
\r
662 if( xTicksToWait == ( portTickType ) 0 )
\r
664 /* The queue was full and no block time is specified (or
\r
665 the block time has expired) so leave now. */
\r
666 taskEXIT_CRITICAL();
\r
668 /* Return to the original privilege level before exiting
\r
670 traceQUEUE_SEND_FAILED( pxQueue );
\r
671 return errQUEUE_FULL;
\r
673 else if( xEntryTimeSet == pdFALSE )
\r
675 /* The queue was full and a block time was specified so
\r
676 configure the timeout structure. */
\r
677 vTaskSetTimeOutState( &xTimeOut );
\r
678 xEntryTimeSet = pdTRUE;
\r
682 taskEXIT_CRITICAL();
\r
684 /* Interrupts and other tasks can send to and receive from the queue
\r
685 now the critical section has been exited. */
\r
688 prvLockQueue( pxQueue );
\r
690 /* Update the timeout state to see if it has expired yet. */
\r
691 if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
\r
693 if( prvIsQueueFull( pxQueue ) != pdFALSE )
\r
695 traceBLOCKING_ON_QUEUE_SEND( pxQueue );
\r
696 vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
\r
698 /* Unlocking the queue means queue events can effect the
\r
699 event list. It is possible that interrupts occurring now
\r
700 remove this task from the event list again - but as the
\r
701 scheduler is suspended the task will go onto the pending
\r
702 ready last instead of the actual ready list. */
\r
703 prvUnlockQueue( pxQueue );
\r
705 /* Resuming the scheduler will move tasks from the pending
\r
706 ready list into the ready list - so it is feasible that this
\r
707 task is already in a ready list before it yields - in which
\r
708 case the yield will not cause a context switch unless there
\r
709 is also a higher priority task in the pending ready list. */
\r
710 if( xTaskResumeAll() == pdFALSE )
\r
712 portYIELD_WITHIN_API();
\r
718 prvUnlockQueue( pxQueue );
\r
719 ( void ) xTaskResumeAll();
\r
724 /* The timeout has expired. */
\r
725 prvUnlockQueue( pxQueue );
\r
726 ( void ) xTaskResumeAll();
\r
728 /* Return to the original privilege level before exiting the
\r
730 traceQUEUE_SEND_FAILED( pxQueue );
\r
731 return errQUEUE_FULL;
\r
735 /*-----------------------------------------------------------*/
\r
737 #if ( configUSE_ALTERNATIVE_API == 1 )
\r
739 signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
\r
741 signed portBASE_TYPE xEntryTimeSet = pdFALSE;
\r
742 xTimeOutType xTimeOut;
\r
744 configASSERT( pxQueue );
\r
745 configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
\r
749 taskENTER_CRITICAL();
\r
751 /* Is there room on the queue now? To be running we must be
\r
752 the highest priority task wanting to access the queue. */
\r
753 if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
\r
755 traceQUEUE_SEND( pxQueue );
\r
756 prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
\r
758 /* If there was a task waiting for data to arrive on the
\r
759 queue then unblock it now. */
\r
760 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
\r
762 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
\r
764 /* The unblocked task has a priority higher than
\r
765 our own so yield immediately. */
\r
766 portYIELD_WITHIN_API();
\r
770 taskEXIT_CRITICAL();
\r
775 if( xTicksToWait == ( portTickType ) 0 )
\r
777 taskEXIT_CRITICAL();
\r
778 return errQUEUE_FULL;
\r
780 else if( xEntryTimeSet == pdFALSE )
\r
782 vTaskSetTimeOutState( &xTimeOut );
\r
783 xEntryTimeSet = pdTRUE;
\r
787 taskEXIT_CRITICAL();
\r
789 taskENTER_CRITICAL();
\r
791 if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
\r
793 if( prvIsQueueFull( pxQueue ) != pdFALSE )
\r
795 traceBLOCKING_ON_QUEUE_SEND( pxQueue );
\r
796 vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
\r
797 portYIELD_WITHIN_API();
\r
802 taskEXIT_CRITICAL();
\r
803 traceQUEUE_SEND_FAILED( pxQueue );
\r
804 return errQUEUE_FULL;
\r
807 taskEXIT_CRITICAL();
\r
811 #endif /* configUSE_ALTERNATIVE_API */
\r
812 /*-----------------------------------------------------------*/
\r
814 #if ( configUSE_ALTERNATIVE_API == 1 )
\r
816 signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
\r
818 signed portBASE_TYPE xEntryTimeSet = pdFALSE;
\r
819 xTimeOutType xTimeOut;
\r
820 signed char *pcOriginalReadPosition;
\r
822 configASSERT( pxQueue );
\r
823 configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
\r
827 taskENTER_CRITICAL();
\r
829 if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
\r
831 /* Remember our read position in case we are just peeking. */
\r
832 pcOriginalReadPosition = pxQueue->pcReadFrom;
\r
834 prvCopyDataFromQueue( pxQueue, pvBuffer );
\r
836 if( xJustPeeking == pdFALSE )
\r
838 traceQUEUE_RECEIVE( pxQueue );
\r
840 /* We are actually removing data. */
\r
841 --( pxQueue->uxMessagesWaiting );
\r
843 #if ( configUSE_MUTEXES == 1 )
\r
845 if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
\r
847 /* Record the information required to implement
\r
848 priority inheritance should it become necessary. */
\r
849 pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
\r
854 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
\r
856 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
\r
858 portYIELD_WITHIN_API();
\r
864 traceQUEUE_PEEK( pxQueue );
\r
866 /* We are not removing the data, so reset our read
\r
868 pxQueue->pcReadFrom = pcOriginalReadPosition;
\r
870 /* The data is being left in the queue, so see if there are
\r
871 any other tasks waiting for the data. */
\r
872 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
\r
874 /* Tasks that are removed from the event list will get added to
\r
875 the pending ready list as the scheduler is still suspended. */
\r
876 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
\r
878 /* The task waiting has a higher priority than this task. */
\r
879 portYIELD_WITHIN_API();
\r
885 taskEXIT_CRITICAL();
\r
890 if( xTicksToWait == ( portTickType ) 0 )
\r
892 taskEXIT_CRITICAL();
\r
893 traceQUEUE_RECEIVE_FAILED( pxQueue );
\r
894 return errQUEUE_EMPTY;
\r
896 else if( xEntryTimeSet == pdFALSE )
\r
898 vTaskSetTimeOutState( &xTimeOut );
\r
899 xEntryTimeSet = pdTRUE;
\r
903 taskEXIT_CRITICAL();
\r
905 taskENTER_CRITICAL();
\r
907 if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
\r
909 if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
\r
911 traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
\r
913 #if ( configUSE_MUTEXES == 1 )
\r
915 if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
\r
917 portENTER_CRITICAL();
\r
919 vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
\r
921 portEXIT_CRITICAL();
\r
926 vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
\r
927 portYIELD_WITHIN_API();
\r
932 taskEXIT_CRITICAL();
\r
933 traceQUEUE_RECEIVE_FAILED( pxQueue );
\r
934 return errQUEUE_EMPTY;
\r
937 taskEXIT_CRITICAL();
\r
942 #endif /* configUSE_ALTERNATIVE_API */
\r
943 /*-----------------------------------------------------------*/
\r
945 signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition )
\r
947 signed portBASE_TYPE xReturn;
\r
948 unsigned portBASE_TYPE uxSavedInterruptStatus;
\r
950 configASSERT( pxQueue );
\r
951 configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
\r
953 /* Similar to xQueueGenericSend, except we don't block if there is no room
\r
954 in the queue. Also we don't directly wake a task that was blocked on a
\r
955 queue read, instead we return a flag to say whether a context switch is
\r
956 required or not (i.e. has a task with a higher priority than us been woken
\r
958 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
\r
960 if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
\r
962 traceQUEUE_SEND_FROM_ISR( pxQueue );
\r
964 prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
\r
966 /* If the queue is locked we do not alter the event list. This will
\r
967 be done when the queue is unlocked later. */
\r
968 if( pxQueue->xTxLock == queueUNLOCKED )
\r
970 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
\r
972 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
\r
974 /* The task waiting has a higher priority so record that a
\r
975 context switch is required. */
\r
976 if( pxHigherPriorityTaskWoken != NULL )
\r
978 *pxHigherPriorityTaskWoken = pdTRUE;
\r
984 #if ( configUSE_QUEUE_SETS == 1 )
\r
986 if( pxQueue->pxQueueSetContainer != NULL )
\r
988 xQueueGenericSendFromISR( pxQueue->pxQueueSetContainer, &pxQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK );
\r
991 #endif /* configUSE_QUEUE_SETS */
\r
996 /* Increment the lock count so the task that unlocks the queue
\r
997 knows that data was posted while it was locked. */
\r
998 ++( pxQueue->xTxLock );
\r
1005 traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue );
\r
1006 xReturn = errQUEUE_FULL;
\r
1009 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
\r
1013 /*-----------------------------------------------------------*/
\r
1015 signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
\r
1017 signed portBASE_TYPE xEntryTimeSet = pdFALSE;
\r
1018 xTimeOutType xTimeOut;
\r
1019 signed char *pcOriginalReadPosition;
\r
1021 configASSERT( pxQueue );
\r
1022 configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
\r
1024 /* This function relaxes the coding standard somewhat to allow return
\r
1025 statements within the function itself. This is done in the interest
\r
1026 of execution time efficiency. */
\r
1030 taskENTER_CRITICAL();
\r
1032 /* Is there data in the queue now? To be running we must be
\r
1033 the highest priority task wanting to access the queue. */
\r
1034 if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
\r
1036 /* Remember our read position in case we are just peeking. */
\r
1037 pcOriginalReadPosition = pxQueue->pcReadFrom;
\r
1039 prvCopyDataFromQueue( pxQueue, pvBuffer );
\r
1041 if( xJustPeeking == pdFALSE )
\r
1043 traceQUEUE_RECEIVE( pxQueue );
\r
1045 /* We are actually removing data. */
\r
1046 --( pxQueue->uxMessagesWaiting );
\r
1048 #if ( configUSE_MUTEXES == 1 )
\r
1050 if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
\r
1052 /* Record the information required to implement
\r
1053 priority inheritance should it become necessary. */
\r
1054 pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
\r
1059 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
\r
1061 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
\r
1063 portYIELD_WITHIN_API();
\r
1069 traceQUEUE_PEEK( pxQueue );
\r
1071 /* The data is not being removed, so reset the read
\r
1073 pxQueue->pcReadFrom = pcOriginalReadPosition;
\r
1075 /* The data is being left in the queue, so see if there are
\r
1076 any other tasks waiting for the data. */
\r
1077 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
\r
1079 /* Tasks that are removed from the event list will get added to
\r
1080 the pending ready list as the scheduler is still suspended. */
\r
1081 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
\r
1083 /* The task waiting has a higher priority than this task. */
\r
1084 portYIELD_WITHIN_API();
\r
1089 #if ( configUSE_QUEUE_SETS == 1 )
\r
1091 if( pxQueue->pxQueueSetContainer != NULL )
\r
1093 xQueueGenericSend( pxQueue->pxQueueSetContainer, &pxQueue, 0, queueSEND_TO_BACK );
\r
1096 #endif /* configUSE_QUEUE_SETS */
\r
1100 taskEXIT_CRITICAL();
\r
1105 if( xTicksToWait == ( portTickType ) 0 )
\r
1107 /* The queue was empty and no block time is specified (or
\r
1108 the block time has expired) so leave now. */
\r
1109 taskEXIT_CRITICAL();
\r
1110 traceQUEUE_RECEIVE_FAILED( pxQueue );
\r
1111 return errQUEUE_EMPTY;
\r
1113 else if( xEntryTimeSet == pdFALSE )
\r
1115 /* The queue was empty and a block time was specified so
\r
1116 configure the timeout structure. */
\r
1117 vTaskSetTimeOutState( &xTimeOut );
\r
1118 xEntryTimeSet = pdTRUE;
\r
1122 taskEXIT_CRITICAL();
\r
1124 /* Interrupts and other tasks can send to and receive from the queue
\r
1125 now the critical section has been exited. */
\r
1127 vTaskSuspendAll();
\r
1128 prvLockQueue( pxQueue );
\r
1130 /* Update the timeout state to see if it has expired yet. */
\r
1131 if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
\r
1133 if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
\r
1135 traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
\r
1137 #if ( configUSE_MUTEXES == 1 )
\r
1139 if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
\r
1141 portENTER_CRITICAL();
\r
1143 vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
\r
1145 portEXIT_CRITICAL();
\r
1150 vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
\r
1151 prvUnlockQueue( pxQueue );
\r
1152 if( xTaskResumeAll() == pdFALSE )
\r
1154 portYIELD_WITHIN_API();
\r
1160 prvUnlockQueue( pxQueue );
\r
1161 ( void ) xTaskResumeAll();
\r
1166 prvUnlockQueue( pxQueue );
\r
1167 ( void ) xTaskResumeAll();
\r
1168 traceQUEUE_RECEIVE_FAILED( pxQueue );
\r
1169 return errQUEUE_EMPTY;
\r
1173 /*-----------------------------------------------------------*/
\r
1175 signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken )
\r
1177 signed portBASE_TYPE xReturn;
\r
1178 unsigned portBASE_TYPE uxSavedInterruptStatus;
\r
1180 configASSERT( pxQueue );
\r
1181 configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
\r
1183 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
\r
1185 /* We cannot block from an ISR, so check there is data available. */
\r
1186 if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
\r
1188 traceQUEUE_RECEIVE_FROM_ISR( pxQueue );
\r
1190 prvCopyDataFromQueue( pxQueue, pvBuffer );
\r
1191 --( pxQueue->uxMessagesWaiting );
\r
1193 /* If the queue is locked we will not modify the event list. Instead
\r
1194 we update the lock count so the task that unlocks the queue will know
\r
1195 that an ISR has removed data while the queue was locked. */
\r
1196 if( pxQueue->xRxLock == queueUNLOCKED )
\r
1198 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
\r
1200 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
\r
1202 /* The task waiting has a higher priority than us so
\r
1203 force a context switch. */
\r
1204 if( pxHigherPriorityTaskWoken != NULL )
\r
1206 *pxHigherPriorityTaskWoken = pdTRUE;
\r
1213 /* Increment the lock count so the task that unlocks the queue
\r
1214 knows that data was removed while it was locked. */
\r
1215 ++( pxQueue->xRxLock );
\r
1223 traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue );
\r
1226 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
\r
1230 /*-----------------------------------------------------------*/
\r
1232 unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue )
\r
1234 unsigned portBASE_TYPE uxReturn;
\r
1236 configASSERT( pxQueue );
\r
1238 taskENTER_CRITICAL();
\r
1239 uxReturn = pxQueue->uxMessagesWaiting;
\r
1240 taskEXIT_CRITICAL();
\r
1244 /*-----------------------------------------------------------*/
\r
1246 unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue )
\r
1248 unsigned portBASE_TYPE uxReturn;
\r
1250 configASSERT( pxQueue );
\r
1252 uxReturn = pxQueue->uxMessagesWaiting;
\r
1256 /*-----------------------------------------------------------*/
\r
1258 void vQueueDelete( xQueueHandle pxQueue )
\r
1260 configASSERT( pxQueue );
\r
1262 traceQUEUE_DELETE( pxQueue );
\r
1263 vQueueUnregisterQueue( pxQueue );
\r
1264 vPortFree( pxQueue->pcHead );
\r
1265 vPortFree( pxQueue );
\r
1267 /*-----------------------------------------------------------*/
\r
1269 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1271 unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue )
\r
1273 return pxQueue->ucQueueNumber;
\r
1276 #endif /* configUSE_TRACE_FACILITY */
\r
1277 /*-----------------------------------------------------------*/
\r
1279 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1281 void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber )
\r
1283 pxQueue->ucQueueNumber = ucQueueNumber;
\r
1286 #endif /* configUSE_TRACE_FACILITY */
\r
1287 /*-----------------------------------------------------------*/
\r
1289 #if ( configUSE_TRACE_FACILITY == 1 )
\r
1291 unsigned char ucQueueGetQueueType( xQueueHandle pxQueue )
\r
1293 return pxQueue->ucQueueType;
\r
1296 #endif /* configUSE_TRACE_FACILITY */
\r
1297 /*-----------------------------------------------------------*/
\r
1299 static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )
\r
1301 if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 )
\r
1303 #if ( configUSE_MUTEXES == 1 )
\r
1305 if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
\r
1307 /* The mutex is no longer being held. */
\r
1308 vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );
\r
1309 pxQueue->pxMutexHolder = NULL;
\r
1314 else if( xPosition == queueSEND_TO_BACK )
\r
1316 memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
\r
1317 pxQueue->pcWriteTo += pxQueue->uxItemSize;
\r
1318 if( pxQueue->pcWriteTo >= pxQueue->pcTail )
\r
1320 pxQueue->pcWriteTo = pxQueue->pcHead;
\r
1325 memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
\r
1326 pxQueue->pcReadFrom -= pxQueue->uxItemSize;
\r
1327 if( pxQueue->pcReadFrom < pxQueue->pcHead )
\r
1329 pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );
\r
1333 ++( pxQueue->uxMessagesWaiting );
\r
1335 /*-----------------------------------------------------------*/
\r
1337 static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
\r
1339 if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
\r
1341 pxQueue->pcReadFrom += pxQueue->uxItemSize;
\r
1342 if( pxQueue->pcReadFrom >= pxQueue->pcTail )
\r
1344 pxQueue->pcReadFrom = pxQueue->pcHead;
\r
1346 memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
\r
1349 /*-----------------------------------------------------------*/
\r
1351 static void prvUnlockQueue( xQueueHandle pxQueue )
\r
1353 /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
\r
1355 /* The lock counts contains the number of extra data items placed or
\r
1356 removed from the queue while the queue was locked. When a queue is
\r
1357 locked items can be added or removed, but the event lists cannot be
\r
1359 taskENTER_CRITICAL();
\r
1361 /* See if data was added to the queue while it was locked. */
\r
1362 while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED )
\r
1364 /* Data was posted while the queue was locked. Are any tasks
\r
1365 blocked waiting for data to become available? */
\r
1366 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
\r
1368 /* Tasks that are removed from the event list will get added to
\r
1369 the pending ready list as the scheduler is still suspended. */
\r
1370 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
\r
1372 /* The task waiting has a higher priority so record that a
\r
1373 context switch is required. */
\r
1374 vTaskMissedYield();
\r
1378 #if ( configUSE_QUEUE_SETS == 1 )
\r
1380 if( pxQueue->pxQueueSetContainer != NULL )
\r
1382 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
\r
1383 xQueueGenericSendFromISR( pxQueue->pxQueueSetContainer, &pxQueue, &xHigherPriorityTaskWoken, queueSEND_TO_BACK );
\r
1384 if( xHigherPriorityTaskWoken != pdFALSE )
\r
1386 vTaskMissedYield();
\r
1390 #endif /* configUSE_QUEUE_SETS */
\r
1393 --( pxQueue->xTxLock );
\r
1401 pxQueue->xTxLock = queueUNLOCKED;
\r
1403 taskEXIT_CRITICAL();
\r
1405 /* Do the same for the Rx lock. */
\r
1406 taskENTER_CRITICAL();
\r
1408 while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )
\r
1410 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
\r
1412 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
\r
1414 vTaskMissedYield();
\r
1417 --( pxQueue->xRxLock );
\r
1425 pxQueue->xRxLock = queueUNLOCKED;
\r
1427 taskEXIT_CRITICAL();
\r
1429 /*-----------------------------------------------------------*/
\r
1431 static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue )
\r
1433 signed portBASE_TYPE xReturn;
\r
1435 taskENTER_CRITICAL();
\r
1436 xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
\r
1437 taskEXIT_CRITICAL();
\r
1441 /*-----------------------------------------------------------*/
\r
1443 signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue )
\r
1445 signed portBASE_TYPE xReturn;
\r
1447 configASSERT( pxQueue );
\r
1448 xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
\r
1452 /*-----------------------------------------------------------*/
\r
1454 static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue )
\r
1456 signed portBASE_TYPE xReturn;
\r
1458 taskENTER_CRITICAL();
\r
1459 xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
\r
1460 taskEXIT_CRITICAL();
\r
1464 /*-----------------------------------------------------------*/
\r
1466 signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue )
\r
1468 signed portBASE_TYPE xReturn;
\r
1470 configASSERT( pxQueue );
\r
1471 xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
\r
1475 /*-----------------------------------------------------------*/
\r
1477 #if ( configUSE_CO_ROUTINES == 1 )
\r
1479 signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
\r
1481 signed portBASE_TYPE xReturn;
\r
1483 /* If the queue is already full we may have to block. A critical section
\r
1484 is required to prevent an interrupt removing something from the queue
\r
1485 between the check to see if the queue is full and blocking on the queue. */
\r
1486 portDISABLE_INTERRUPTS();
\r
1488 if( prvIsQueueFull( pxQueue ) != pdFALSE )
\r
1490 /* The queue is full - do we want to block or just leave without
\r
1492 if( xTicksToWait > ( portTickType ) 0 )
\r
1494 /* As this is called from a coroutine we cannot block directly, but
\r
1495 return indicating that we need to block. */
\r
1496 vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );
\r
1497 portENABLE_INTERRUPTS();
\r
1498 return errQUEUE_BLOCKED;
\r
1502 portENABLE_INTERRUPTS();
\r
1503 return errQUEUE_FULL;
\r
1507 portENABLE_INTERRUPTS();
\r
1511 portDISABLE_INTERRUPTS();
\r
1513 if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
\r
1515 /* There is room in the queue, copy the data into the queue. */
\r
1516 prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
\r
1519 /* Were any co-routines waiting for data to become available? */
\r
1520 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
\r
1522 /* In this instance the co-routine could be placed directly
\r
1523 into the ready list as we are within a critical section.
\r
1524 Instead the same pending ready list mechanism is used as if
\r
1525 the event were caused from within an interrupt. */
\r
1526 if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
\r
1528 /* The co-routine waiting has a higher priority so record
\r
1529 that a yield might be appropriate. */
\r
1530 xReturn = errQUEUE_YIELD;
\r
1536 xReturn = errQUEUE_FULL;
\r
1539 portENABLE_INTERRUPTS();
\r
1544 #endif /* configUSE_CO_ROUTINES */
\r
1545 /*-----------------------------------------------------------*/
\r
1547 #if ( configUSE_CO_ROUTINES == 1 )
\r
1549 signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )
\r
1551 signed portBASE_TYPE xReturn;
\r
1553 /* If the queue is already empty we may have to block. A critical section
\r
1554 is required to prevent an interrupt adding something to the queue
\r
1555 between the check to see if the queue is empty and blocking on the queue. */
\r
1556 portDISABLE_INTERRUPTS();
\r
1558 if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
\r
1560 /* There are no messages in the queue, do we want to block or just
\r
1561 leave with nothing? */
\r
1562 if( xTicksToWait > ( portTickType ) 0 )
\r
1564 /* As this is a co-routine we cannot block directly, but return
\r
1565 indicating that we need to block. */
\r
1566 vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );
\r
1567 portENABLE_INTERRUPTS();
\r
1568 return errQUEUE_BLOCKED;
\r
1572 portENABLE_INTERRUPTS();
\r
1573 return errQUEUE_FULL;
\r
1577 portENABLE_INTERRUPTS();
\r
1581 portDISABLE_INTERRUPTS();
\r
1583 if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
\r
1585 /* Data is available from the queue. */
\r
1586 pxQueue->pcReadFrom += pxQueue->uxItemSize;
\r
1587 if( pxQueue->pcReadFrom >= pxQueue->pcTail )
\r
1589 pxQueue->pcReadFrom = pxQueue->pcHead;
\r
1591 --( pxQueue->uxMessagesWaiting );
\r
1592 memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
\r
1596 /* Were any co-routines waiting for space to become available? */
\r
1597 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
\r
1599 /* In this instance the co-routine could be placed directly
\r
1600 into the ready list as we are within a critical section.
\r
1601 Instead the same pending ready list mechanism is used as if
\r
1602 the event were caused from within an interrupt. */
\r
1603 if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
\r
1605 xReturn = errQUEUE_YIELD;
\r
1614 portENABLE_INTERRUPTS();
\r
1619 #endif /* configUSE_CO_ROUTINES */
\r
1620 /*-----------------------------------------------------------*/
\r
1622 #if ( configUSE_CO_ROUTINES == 1 )
\r
1624 signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )
\r
1626 /* Cannot block within an ISR so if there is no space on the queue then
\r
1627 exit without doing anything. */
\r
1628 if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
\r
1630 prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
\r
1632 /* We only want to wake one co-routine per ISR, so check that a
\r
1633 co-routine has not already been woken. */
\r
1634 if( xCoRoutinePreviouslyWoken == pdFALSE )
\r
1636 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
\r
1638 if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
\r
1646 return xCoRoutinePreviouslyWoken;
\r
1649 #endif /* configUSE_CO_ROUTINES */
\r
1650 /*-----------------------------------------------------------*/
\r
1652 #if ( configUSE_CO_ROUTINES == 1 )
\r
1654 signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )
\r
1656 signed portBASE_TYPE xReturn;
\r
1658 /* We cannot block from an ISR, so check there is data available. If
\r
1659 not then just leave without doing anything. */
\r
1660 if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
\r
1662 /* Copy the data from the queue. */
\r
1663 pxQueue->pcReadFrom += pxQueue->uxItemSize;
\r
1664 if( pxQueue->pcReadFrom >= pxQueue->pcTail )
\r
1666 pxQueue->pcReadFrom = pxQueue->pcHead;
\r
1668 --( pxQueue->uxMessagesWaiting );
\r
1669 memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
\r
1671 if( ( *pxCoRoutineWoken ) == pdFALSE )
\r
1673 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
\r
1675 if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
\r
1677 *pxCoRoutineWoken = pdTRUE;
\r
1692 #endif /* configUSE_CO_ROUTINES */
\r
1693 /*-----------------------------------------------------------*/
\r
1695 #if ( configQUEUE_REGISTRY_SIZE > 0 )
\r
1697 void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName )
\r
1699 unsigned portBASE_TYPE ux;
\r
1701 /* See if there is an empty space in the registry. A NULL name denotes
\r
1703 for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ )
\r
1705 if( xQueueRegistry[ ux ].pcQueueName == NULL )
\r
1707 /* Store the information on this queue. */
\r
1708 xQueueRegistry[ ux ].pcQueueName = pcQueueName;
\r
1709 xQueueRegistry[ ux ].xHandle = xQueue;
\r
1715 #endif /* configQUEUE_REGISTRY_SIZE */
\r
1716 /*-----------------------------------------------------------*/
\r
1718 #if ( configQUEUE_REGISTRY_SIZE > 0 )
\r
1720 static void vQueueUnregisterQueue( xQueueHandle xQueue )
\r
1722 unsigned portBASE_TYPE ux;
\r
1724 /* See if the handle of the queue being unregistered in actually in the
\r
1726 for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ )
\r
1728 if( xQueueRegistry[ ux ].xHandle == xQueue )
\r
1730 /* Set the name to NULL to show that this slot if free again. */
\r
1731 xQueueRegistry[ ux ].pcQueueName = NULL;
\r
1738 #endif /* configQUEUE_REGISTRY_SIZE */
\r
1739 /*-----------------------------------------------------------*/
\r
1741 #if ( configUSE_TIMERS == 1 )
\r
1743 void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait )
\r
1745 /* This function should not be called by application code hence the
\r
1746 'Restricted' in its name. It is not part of the public API. It is
\r
1747 designed for use by kernel code, and has special calling requirements.
\r
1748 It can result in vListInsert() being called on a list that can only
\r
1749 possibly ever have one item in it, so the list will be fast, but even
\r
1750 so it should be called with the scheduler locked and not from a critical
\r
1753 /* Only do anything if there are no messages in the queue. This function
\r
1754 will not actually cause the task to block, just place it on a blocked
\r
1755 list. It will not block until the scheduler is unlocked - at which
\r
1756 time a yield will be performed. If an item is added to the queue while
\r
1757 the queue is locked, and the calling task blocks on the queue, then the
\r
1758 calling task will be immediately unblocked when the queue is unlocked. */
\r
1759 prvLockQueue( pxQueue );
\r
1760 if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0U )
\r
1762 /* There is nothing in the queue, block for the specified period. */
\r
1763 vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
\r
1765 prvUnlockQueue( pxQueue );
\r
1768 #endif /* configUSE_TIMERS */
\r
1769 /*-----------------------------------------------------------*/
\r
1771 #if ( configUSE_QUEUE_SETS == 1 )
\r
1773 xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength )
\r
1777 pxQueue = xQueueGenericCreate( uxEventQueueLength, sizeof( xQUEUE * ), queueQUEUE_TYPE_SET );
\r
1779 return ( xQueueSetHandle ) pxQueue;
\r
1782 #endif /* configUSE_QUEUE_SETS */
\r
1783 /*-----------------------------------------------------------*/
\r
1785 #if ( configUSE_QUEUE_SETS == 1 )
\r
1787 portBASE_TYPE xQueueAddToQueueSet( xQueueHandle xQueue, xQueueSetHandle xQueueSet )
\r
1789 portBASE_TYPE xReturn;
\r
1791 if( xQueue->pxQueueSetContainer != NULL )
\r
1797 taskENTER_CRITICAL();
\r
1799 xQueue->pxQueueSetContainer = xQueueSet;
\r
1801 taskEXIT_CRITICAL();
\r
1808 #endif /* configUSE_QUEUE_SETS */
\r
1809 /*-----------------------------------------------------------*/
\r
1811 #if ( configUSE_QUEUE_SETS == 1 )
\r
1813 portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetHandle xQueueSet, xQueueHandle xQueue )
\r
1815 portBASE_TYPE xReturn;
\r
1817 if( xQueue->pxQueueSetContainer != xQueueSet )
\r
1823 taskENTER_CRITICAL();
\r
1825 xQueue->pxQueueSetContainer = NULL;
\r
1827 taskEXIT_CRITICAL();
\r
1834 #endif /* configUSE_QUEUE_SETS */
\r
1835 /*-----------------------------------------------------------*/
\r
1837 #if ( configUSE_QUEUE_SETS == 1 )
\r
1839 xQueueHandle xQueueReadMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )
\r
1841 xQueueHandle xReturn = NULL;
\r
1843 xQueueGenericReceive( ( xQueueHandle ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE );
\r
1847 #endif /* configUSE_QUEUE_SETS */
\r
1848 /*-----------------------------------------------------------*/
\r
1850 #if ( configUSE_QUEUE_SETS == 1 )
\r
1852 static portBASE_TYPE prvCheckForMembershipOfQueueSet( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition )
\r
1854 xQUEUE *pxQueueSetContainer = pxQueue->pxQueueSetContainer;
\r
1855 portBASE_TYPE xReturn = pdFALSE;
\r
1857 if( pxQueueSetContainer != NULL )
\r
1859 if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )
\r
1861 prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );
\r
1862 if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )
\r
1864 if( xTaskRemoveFromEventList( &( pxQueue->pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE )
\r
1866 /* The task waiting has a higher priority */
\r
1876 #endif /* configUSE_QUEUE_SETS */
\r