summaryrefslogtreecommitdiff
path: root/contrib/FreeRTOS_Library/queue.c
diff options
context:
space:
mode:
authorChristian Pointner <equinox@mur.at>2013-08-04 22:54:56 +0000
committerChristian Pointner <equinox@mur.at>2013-08-04 22:54:56 +0000
commit2b1ba741d5c813df07feb2c37aab7cb2c5c4f947 (patch)
tree3c52b484126d1ed4a4df4c38717c0a04bb392399 /contrib/FreeRTOS_Library/queue.c
parentswitched to chibios 2.6.0 (diff)
remove old FreeRTOS based MPU files
git-svn-id: https://svn.spreadspace.org/mur.sat@824 7de4ea59-55d0-425e-a1af-a3118ea81d4c
Diffstat (limited to 'contrib/FreeRTOS_Library/queue.c')
-rw-r--r--contrib/FreeRTOS_Library/queue.c1465
1 files changed, 0 insertions, 1465 deletions
diff --git a/contrib/FreeRTOS_Library/queue.c b/contrib/FreeRTOS_Library/queue.c
deleted file mode 100644
index 17e37cf..0000000
--- a/contrib/FreeRTOS_Library/queue.c
+++ /dev/null
@@ -1,1465 +0,0 @@
-/*
- FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd.
-
- ***************************************************************************
- * *
- * If you are: *
- * *
- * + New to FreeRTOS, *
- * + Wanting to learn FreeRTOS or multitasking in general quickly *
- * + Looking for basic training, *
- * + Wanting to improve your FreeRTOS skills and productivity *
- * *
- * then take a look at the FreeRTOS books - available as PDF or paperback *
- * *
- * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
- * http://www.FreeRTOS.org/Documentation *
- * *
- * A pdf reference manual is also available. Both are usually delivered *
- * to your inbox within 20 minutes to two hours when purchased between 8am *
- * and 8pm GMT (although please allow up to 24 hours in case of *
- * exceptional circumstances). Thank you for your support! *
- * *
- ***************************************************************************
-
- This file is part of the FreeRTOS distribution.
-
- FreeRTOS is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License (version 2) as published by the
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
- ***NOTE*** The exception to the GPL is included to allow you to distribute
- a combined work that includes FreeRTOS without being obliged to provide the
- source code for proprietary components outside of the FreeRTOS kernel.
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details. You should have received a copy of the GNU General Public
- License and the FreeRTOS license exception along with FreeRTOS; if not it
- can be viewed here: http://www.freertos.org/a00114.html and also obtained
- by writing to Richard Barry, contact details for whom are available on the
- FreeRTOS WEB site.
-
- 1 tab == 4 spaces!
-
- http://www.FreeRTOS.org - Documentation, latest information, license and
- contact details.
-
- http://www.SafeRTOS.com - A version that is certified for use in safety
- critical systems.
-
- http://www.OpenRTOS.com - Commercial support, development, porting,
- licensing and training services.
-*/
-
-#include <stdlib.h>
-#include <string.h>
-
-/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
-all the API functions to use the MPU wrappers. That should only be done when
-task.h is included from an application file. */
-#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
-
-#include "FreeRTOS.h"
-#include "task.h"
-#include "croutine.h"
-
-#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
-
-/*-----------------------------------------------------------
- * PUBLIC LIST API documented in list.h
- *----------------------------------------------------------*/
-
-/* Constants used with the cRxLock and cTxLock structure members. */
-#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )
-#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 )
-
-#define queueERRONEOUS_UNBLOCK ( -1 )
-
-/* For internal use only. */
-#define queueSEND_TO_BACK ( 0 )
-#define queueSEND_TO_FRONT ( 1 )
-
-/* Effectively make a union out of the xQUEUE structure. */
-#define pxMutexHolder pcTail
-#define uxQueueType pcHead
-#define uxRecursiveCallCount pcReadFrom
-#define queueQUEUE_IS_MUTEX NULL
-
-/* Semaphores do not actually store or copy data, so have an items size of
-zero. */
-#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 )
-#define queueDONT_BLOCK ( ( portTickType ) 0 )
-#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0 )
-
-/*
- * Definition of the queue used by the scheduler.
- * Items are queued by copy, not reference.
- */
-typedef struct QueueDefinition
-{
- signed char *pcHead; /*< Points to the beginning of the queue storage area. */
- 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. */
-
- signed char *pcWriteTo; /*< Points to the free next place in the storage area. */
- signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */
-
- xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
- xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
-
- volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */
- unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
- unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */
-
- 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. */
- 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. */
-
-} xQUEUE;
-/*-----------------------------------------------------------*/
-
-/*
- * Inside this file xQueueHandle is a pointer to a xQUEUE structure.
- * To keep the definition private the API header file defines it as a
- * pointer to void.
- */
-typedef xQUEUE * xQueueHandle;
-
-/*
- * Prototypes for public functions are included here so we don't have to
- * include the API header file (as it defines xQueueHandle differently). These
- * functions are documented in the API header file.
- */
-xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) PRIVILEGED_FUNCTION;
-signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
-unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
-void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
-signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
-signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;
-signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;
-xQueueHandle xQueueCreateMutex( void ) PRIVILEGED_FUNCTION;
-xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION;
-portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION;
-portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ) PRIVILEGED_FUNCTION;
-signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
-signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;
-signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
-signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
-unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
-
-/*
- * Co-routine queue functions differ from task queue functions. Co-routines are
- * an optional component.
- */
-#if configUSE_CO_ROUTINES == 1
- signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) PRIVILEGED_FUNCTION;
- signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;
- signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
- signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
-#endif
-
-/*
- * The queue registry is just a means for kernel aware debuggers to locate
- * queue structures. It has no other purpose so is an optional component.
- */
-#if configQUEUE_REGISTRY_SIZE > 0
-
- /* The type stored within the queue registry array. This allows a name
- to be assigned to each queue making kernel aware debugging a little
- more user friendly. */
- typedef struct QUEUE_REGISTRY_ITEM
- {
- signed char *pcQueueName;
- xQueueHandle xHandle;
- } xQueueRegistryItem;
-
- /* The queue registry is simply an array of xQueueRegistryItem structures.
- The pcQueueName member of a structure being NULL is indicative of the
- array position being vacant. */
- xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];
-
- /* Removes a queue from the registry by simply setting the pcQueueName
- member to NULL. */
- static void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
- void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) PRIVILEGED_FUNCTION;
-#endif
-
-/*
- * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not
- * prevent an ISR from adding or removing items to the queue, but does prevent
- * an ISR from removing tasks from the queue event lists. If an ISR finds a
- * queue is locked it will instead increment the appropriate queue lock count
- * to indicate that a task may require unblocking. When the queue in unlocked
- * these lock counts are inspected, and the appropriate action taken.
- */
-static void prvUnlockQueue( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
-
-/*
- * Uses a critical section to determine if there is any data in a queue.
- *
- * @return pdTRUE if the queue contains no items, otherwise pdFALSE.
- */
-static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
-
-/*
- * Uses a critical section to determine if there is any space in a queue.
- *
- * @return pdTRUE if there is no space, otherwise pdFALSE;
- */
-static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
-
-/*
- * Copies an item into the queue, either at the front of the queue or the
- * back of the queue.
- */
-static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION;
-
-/*
- * Copies an item out of a queue.
- */
-static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION;
-/*-----------------------------------------------------------*/
-
-/*
- * Macro to mark a queue as locked. Locking a queue prevents an ISR from
- * accessing the queue event lists.
- */
-#define prvLockQueue( pxQueue ) \
-{ \
- taskENTER_CRITICAL(); \
- { \
- if( pxQueue->xRxLock == queueUNLOCKED ) \
- { \
- pxQueue->xRxLock = queueLOCKED_UNMODIFIED; \
- } \
- if( pxQueue->xTxLock == queueUNLOCKED ) \
- { \
- pxQueue->xTxLock = queueLOCKED_UNMODIFIED; \
- } \
- } \
- taskEXIT_CRITICAL(); \
-}
-/*-----------------------------------------------------------*/
-
-
-/*-----------------------------------------------------------
- * PUBLIC QUEUE MANAGEMENT API documented in queue.h
- *----------------------------------------------------------*/
-
-xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize )
-{
-xQUEUE *pxNewQueue;
-size_t xQueueSizeInBytes;
-
- /* Allocate the new queue structure. */
- if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )
- {
- pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
- if( pxNewQueue != NULL )
- {
- /* Create the list of pointers to queue items. The queue is one byte
- longer than asked for to make wrap checking easier/faster. */
- xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1;
-
- pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes );
- if( pxNewQueue->pcHead != NULL )
- {
- /* Initialise the queue members as described above where the
- queue type is defined. */
- pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize );
- pxNewQueue->uxMessagesWaiting = 0;
- pxNewQueue->pcWriteTo = pxNewQueue->pcHead;
- pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize );
- pxNewQueue->uxLength = uxQueueLength;
- pxNewQueue->uxItemSize = uxItemSize;
- pxNewQueue->xRxLock = queueUNLOCKED;
- pxNewQueue->xTxLock = queueUNLOCKED;
-
- /* Likewise ensure the event queues start with the correct state. */
- vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
- vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
-
- traceQUEUE_CREATE( pxNewQueue );
- return pxNewQueue;
- }
- else
- {
- traceQUEUE_CREATE_FAILED();
- vPortFree( pxNewQueue );
- }
- }
- }
-
- /* Will only reach here if we could not allocate enough memory or no memory
- was required. */
- return NULL;
-}
-/*-----------------------------------------------------------*/
-
-#if ( configUSE_MUTEXES == 1 )
-
- xQueueHandle xQueueCreateMutex( void )
- {
- xQUEUE *pxNewQueue;
-
- /* Allocate the new queue structure. */
- pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
- if( pxNewQueue != NULL )
- {
- /* Information required for priority inheritance. */
- pxNewQueue->pxMutexHolder = NULL;
- pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;
-
- /* Queues used as a mutex no data is actually copied into or out
- of the queue. */
- pxNewQueue->pcWriteTo = NULL;
- pxNewQueue->pcReadFrom = NULL;
-
- /* Each mutex has a length of 1 (like a binary semaphore) and
- an item size of 0 as nothing is actually copied into or out
- of the mutex. */
- pxNewQueue->uxMessagesWaiting = 0;
- pxNewQueue->uxLength = 1;
- pxNewQueue->uxItemSize = 0;
- pxNewQueue->xRxLock = queueUNLOCKED;
- pxNewQueue->xTxLock = queueUNLOCKED;
-
- /* Ensure the event queues start with the correct state. */
- vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
- vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
-
- /* Start with the semaphore in the expected state. */
- xQueueGenericSend( pxNewQueue, NULL, 0, queueSEND_TO_BACK );
-
- traceCREATE_MUTEX( pxNewQueue );
- }
- else
- {
- traceCREATE_MUTEX_FAILED();
- }
-
- return pxNewQueue;
- }
-
-#endif /* configUSE_MUTEXES */
-/*-----------------------------------------------------------*/
-
-#if configUSE_RECURSIVE_MUTEXES == 1
-
- portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex )
- {
- portBASE_TYPE xReturn;
-
- /* If this is the task that holds the mutex then pxMutexHolder will not
- change outside of this task. If this task does not hold the mutex then
- pxMutexHolder can never coincidentally equal the tasks handle, and as
- this is the only condition we are interested in it does not matter if
- pxMutexHolder is accessed simultaneously by another task. Therefore no
- mutual exclusion is required to test the pxMutexHolder variable. */
- if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )
- {
- traceGIVE_MUTEX_RECURSIVE( pxMutex );
-
- /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to
- the task handle, therefore no underflow check is required. Also,
- uxRecursiveCallCount is only modified by the mutex holder, and as
- there can only be one, no mutual exclusion is required to modify the
- uxRecursiveCallCount member. */
- ( pxMutex->uxRecursiveCallCount )--;
-
- /* Have we unwound the call count? */
- if( pxMutex->uxRecursiveCallCount == 0 )
- {
- /* Return the mutex. This will automatically unblock any other
- task that might be waiting to access the mutex. */
- xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );
- }
-
- xReturn = pdPASS;
- }
- else
- {
- /* We cannot give the mutex because we are not the holder. */
- xReturn = pdFAIL;
-
- traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex );
- }
-
- return xReturn;
- }
-
-#endif /* configUSE_RECURSIVE_MUTEXES */
-/*-----------------------------------------------------------*/
-
-#if configUSE_RECURSIVE_MUTEXES == 1
-
- portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime )
- {
- portBASE_TYPE xReturn;
-
- /* Comments regarding mutual exclusion as per those within
- xQueueGiveMutexRecursive(). */
-
- traceTAKE_MUTEX_RECURSIVE( pxMutex );
-
- if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )
- {
- ( pxMutex->uxRecursiveCallCount )++;
- xReturn = pdPASS;
- }
- else
- {
- xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE );
-
- /* pdPASS will only be returned if we successfully obtained the mutex,
- we may have blocked to reach here. */
- if( xReturn == pdPASS )
- {
- ( pxMutex->uxRecursiveCallCount )++;
- }
- }
-
- return xReturn;
- }
-
-#endif /* configUSE_RECURSIVE_MUTEXES */
-/*-----------------------------------------------------------*/
-
-#if configUSE_COUNTING_SEMAPHORES == 1
-
- xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )
- {
- xQueueHandle pxHandle;
-
- pxHandle = xQueueCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH );
-
- if( pxHandle != NULL )
- {
- pxHandle->uxMessagesWaiting = uxInitialCount;
-
- traceCREATE_COUNTING_SEMAPHORE();
- }
- else
- {
- traceCREATE_COUNTING_SEMAPHORE_FAILED();
- }
-
- return pxHandle;
- }
-
-#endif /* configUSE_COUNTING_SEMAPHORES */
-/*-----------------------------------------------------------*/
-
-signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
-{
-signed portBASE_TYPE xEntryTimeSet = pdFALSE;
-xTimeOutType xTimeOut;
-
- /* This function relaxes the coding standard somewhat to allow return
- statements within the function itself. This is done in the interest
- of execution time efficiency. */
- for( ;; )
- {
- taskENTER_CRITICAL();
- {
- /* Is there room on the queue now? To be running we must be
- the highest priority task wanting to access the queue. */
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
- {
- 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( 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();
- }
- }
-
- taskEXIT_CRITICAL();
-
- /* Return to the original privilege level before exiting the
- function. */
- return pdPASS;
- }
- else
- {
- if( xTicksToWait == ( portTickType ) 0 )
- {
- /* The queue was full and no block time is specified (or
- the block time has expired) so leave now. */
- taskEXIT_CRITICAL();
-
- /* Return to the original privilege level before exiting
- the function. */
- traceQUEUE_SEND_FAILED( pxQueue );
- return errQUEUE_FULL;
- }
- else if( xEntryTimeSet == pdFALSE )
- {
- /* The queue was full and a block time was specified so
- configure the timeout structure. */
- vTaskSetTimeOutState( &xTimeOut );
- xEntryTimeSet = pdTRUE;
- }
- }
- }
- taskEXIT_CRITICAL();
-
- /* Interrupts and other tasks can send to and receive from the queue
- now the critical section has been exited. */
-
- vTaskSuspendAll();
- prvLockQueue( pxQueue );
-
- /* Update the timeout state to see if it has expired yet. */
- if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
- {
- if( prvIsQueueFull( pxQueue ) )
- {
- traceBLOCKING_ON_QUEUE_SEND( pxQueue );
- vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
-
- /* Unlocking the queue means queue events can effect the
- event list. It is possible that interrupts occurring now
- remove this task from the event list again - but as the
- scheduler is suspended the task will go onto the pending
- ready last instead of the actual ready list. */
- prvUnlockQueue( pxQueue );
-
- /* Resuming the scheduler will move tasks from the pending
- ready list into the ready list - so it is feasible that this
- task is already in a ready list before it yields - in which
- case the yield will not cause a context switch unless there
- is also a higher priority task in the pending ready list. */
- if( !xTaskResumeAll() )
- {
- portYIELD_WITHIN_API();
- }
- }
- else
- {
- /* Try again. */
- prvUnlockQueue( pxQueue );
- ( void ) xTaskResumeAll();
- }
- }
- else
- {
- /* The timeout has expired. */
- prvUnlockQueue( pxQueue );
- ( void ) xTaskResumeAll();
-
- /* Return to the original privilege level before exiting the
- function. */
- traceQUEUE_SEND_FAILED( pxQueue );
- return errQUEUE_FULL;
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-#if configUSE_ALTERNATIVE_API == 1
-
- signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
- {
- signed portBASE_TYPE xEntryTimeSet = pdFALSE;
- xTimeOutType xTimeOut;
-
- for( ;; )
- {
- taskENTER_CRITICAL();
- {
- /* Is there room on the queue now? To be running we must be
- the highest priority task wanting to access the queue. */
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
- {
- 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( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
- {
- /* The unblocked task has a priority higher than
- our own so yield immediately. */
- portYIELD_WITHIN_API();
- }
- }
-
- taskEXIT_CRITICAL();
- return pdPASS;
- }
- else
- {
- if( xTicksToWait == ( portTickType ) 0 )
- {
- taskEXIT_CRITICAL();
- return errQUEUE_FULL;
- }
- else if( xEntryTimeSet == pdFALSE )
- {
- vTaskSetTimeOutState( &xTimeOut );
- xEntryTimeSet = pdTRUE;
- }
- }
- }
- taskEXIT_CRITICAL();
-
- taskENTER_CRITICAL();
- {
- if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
- {
- if( prvIsQueueFull( pxQueue ) )
- {
- traceBLOCKING_ON_QUEUE_SEND( pxQueue );
- vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
- portYIELD_WITHIN_API();
- }
- }
- else
- {
- taskEXIT_CRITICAL();
- traceQUEUE_SEND_FAILED( pxQueue );
- return errQUEUE_FULL;
- }
- }
- taskEXIT_CRITICAL();
- }
- }
-
-#endif /* configUSE_ALTERNATIVE_API */
-/*-----------------------------------------------------------*/
-
-#if configUSE_ALTERNATIVE_API == 1
-
- signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
- {
- signed portBASE_TYPE xEntryTimeSet = pdFALSE;
- xTimeOutType xTimeOut;
- signed char *pcOriginalReadPosition;
-
- for( ;; )
- {
- taskENTER_CRITICAL();
- {
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
- {
- /* Remember our read position in case we are just peeking. */
- pcOriginalReadPosition = pxQueue->pcReadFrom;
-
- prvCopyDataFromQueue( pxQueue, pvBuffer );
-
- if( xJustPeeking == pdFALSE )
- {
- traceQUEUE_RECEIVE( pxQueue );
-
- /* We are actually removing data. */
- --( pxQueue->uxMessagesWaiting );
-
- #if ( configUSE_MUTEXES == 1 )
- {
- if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
- {
- /* Record the information required to implement
- priority inheritance should it become necessary. */
- pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
- }
- }
- #endif
-
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
- {
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
- {
- portYIELD_WITHIN_API();
- }
- }
- }
- else
- {
- traceQUEUE_PEEK( pxQueue );
-
- /* We are not removing the data, so reset our read
- pointer. */
- pxQueue->pcReadFrom = pcOriginalReadPosition;
-
- /* The data is being left in the queue, so see if there are
- any other tasks waiting for the data. */
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
- {
- /* 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 )
- {
- /* The task waiting has a higher priority than this task. */
- portYIELD_WITHIN_API();
- }
- }
-
- }
-
- taskEXIT_CRITICAL();
- return pdPASS;
- }
- else
- {
- if( xTicksToWait == ( portTickType ) 0 )
- {
- taskEXIT_CRITICAL();
- traceQUEUE_RECEIVE_FAILED( pxQueue );
- return errQUEUE_EMPTY;
- }
- else if( xEntryTimeSet == pdFALSE )
- {
- vTaskSetTimeOutState( &xTimeOut );
- xEntryTimeSet = pdTRUE;
- }
- }
- }
- taskEXIT_CRITICAL();
-
- taskENTER_CRITICAL();
- {
- if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
- {
- if( prvIsQueueEmpty( pxQueue ) )
- {
- traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
-
- #if ( configUSE_MUTEXES == 1 )
- {
- if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
- {
- portENTER_CRITICAL();
- vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
- portEXIT_CRITICAL();
- }
- }
- #endif
-
- vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
- portYIELD_WITHIN_API();
- }
- }
- else
- {
- taskEXIT_CRITICAL();
- traceQUEUE_RECEIVE_FAILED( pxQueue );
- return errQUEUE_EMPTY;
- }
- }
- taskEXIT_CRITICAL();
- }
- }
-
-
-#endif /* configUSE_ALTERNATIVE_API */
-/*-----------------------------------------------------------*/
-
-signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition )
-{
-signed portBASE_TYPE xReturn;
-unsigned portBASE_TYPE uxSavedInterruptStatus;
-
- /* Similar to xQueueGenericSend, except we don't block if there is no room
- in the queue. Also we don't directly wake a task that was blocked on a
- queue read, instead we return a flag to say whether a context switch is
- required or not (i.e. has a task with a higher priority than us been woken
- by this post). */
- uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
- {
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
- {
- traceQUEUE_SEND_FROM_ISR( pxQueue );
-
- prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
-
- /* If the queue is locked we do not alter the event list. This will
- be done when the queue is unlocked later. */
- if( pxQueue->xTxLock == queueUNLOCKED )
- {
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
- {
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
- {
- /* The task waiting has a higher priority so record that a
- context switch is required. */
- *pxHigherPriorityTaskWoken = pdTRUE;
- }
- }
- }
- else
- {
- /* Increment the lock count so the task that unlocks the queue
- knows that data was posted while it was locked. */
- ++( pxQueue->xTxLock );
- }
-
- xReturn = pdPASS;
- }
- else
- {
- traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue );
- xReturn = errQUEUE_FULL;
- }
- }
- portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
-{
-signed portBASE_TYPE xEntryTimeSet = pdFALSE;
-xTimeOutType xTimeOut;
-signed char *pcOriginalReadPosition;
-
- /* This function relaxes the coding standard somewhat to allow return
- statements within the function itself. This is done in the interest
- of execution time efficiency. */
-
- for( ;; )
- {
- taskENTER_CRITICAL();
- {
- /* Is there data in the queue now? To be running we must be
- the highest priority task wanting to access the queue. */
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
- {
- /* Remember our read position in case we are just peeking. */
- pcOriginalReadPosition = pxQueue->pcReadFrom;
-
- prvCopyDataFromQueue( pxQueue, pvBuffer );
-
- if( xJustPeeking == pdFALSE )
- {
- traceQUEUE_RECEIVE( pxQueue );
-
- /* We are actually removing data. */
- --( pxQueue->uxMessagesWaiting );
-
- #if ( configUSE_MUTEXES == 1 )
- {
- if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
- {
- /* Record the information required to implement
- priority inheritance should it become necessary. */
- pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
- }
- }
- #endif
-
- if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
- {
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
- {
- portYIELD_WITHIN_API();
- }
- }
- }
- else
- {
- traceQUEUE_PEEK( pxQueue );
-
- /* We are not removing the data, so reset our read
- pointer. */
- pxQueue->pcReadFrom = pcOriginalReadPosition;
-
- /* The data is being left in the queue, so see if there are
- any other tasks waiting for the data. */
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
- {
- /* 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 )
- {
- /* The task waiting has a higher priority than this task. */
- portYIELD_WITHIN_API();
- }
- }
-
- }
-
- taskEXIT_CRITICAL();
- return pdPASS;
- }
- else
- {
- if( xTicksToWait == ( portTickType ) 0 )
- {
- /* The queue was empty and no block time is specified (or
- the block time has expired) so leave now. */
- taskEXIT_CRITICAL();
- traceQUEUE_RECEIVE_FAILED( pxQueue );
- return errQUEUE_EMPTY;
- }
- else if( xEntryTimeSet == pdFALSE )
- {
- /* The queue was empty and a block time was specified so
- configure the timeout structure. */
- vTaskSetTimeOutState( &xTimeOut );
- xEntryTimeSet = pdTRUE;
- }
- }
- }
- taskEXIT_CRITICAL();
-
- /* Interrupts and other tasks can send to and receive from the queue
- now the critical section has been exited. */
-
- vTaskSuspendAll();
- prvLockQueue( pxQueue );
-
- /* Update the timeout state to see if it has expired yet. */
- if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
- {
- if( prvIsQueueEmpty( pxQueue ) )
- {
- traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
-
- #if ( configUSE_MUTEXES == 1 )
- {
- if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
- {
- portENTER_CRITICAL();
- {
- vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
- }
- portEXIT_CRITICAL();
- }
- }
- #endif
-
- vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
- prvUnlockQueue( pxQueue );
- if( !xTaskResumeAll() )
- {
- portYIELD_WITHIN_API();
- }
- }
- else
- {
- /* Try again. */
- prvUnlockQueue( pxQueue );
- ( void ) xTaskResumeAll();
- }
- }
- else
- {
- prvUnlockQueue( pxQueue );
- ( void ) xTaskResumeAll();
- traceQUEUE_RECEIVE_FAILED( pxQueue );
- return errQUEUE_EMPTY;
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken )
-{
-signed portBASE_TYPE xReturn;
-unsigned portBASE_TYPE uxSavedInterruptStatus;
-
- uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
- {
- /* We cannot block from an ISR, so check there is data available. */
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
- {
- traceQUEUE_RECEIVE_FROM_ISR( pxQueue );
-
- prvCopyDataFromQueue( pxQueue, pvBuffer );
- --( pxQueue->uxMessagesWaiting );
-
- /* If the queue is locked we will not modify the event list. Instead
- we update the lock count so the task that unlocks the queue will know
- that an ISR has removed data while the queue was locked. */
- if( pxQueue->xRxLock == queueUNLOCKED )
- {
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
- {
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
- {
- /* The task waiting has a higher priority than us so
- force a context switch. */
- *pxTaskWoken = pdTRUE;
- }
- }
- }
- else
- {
- /* Increment the lock count so the task that unlocks the queue
- knows that data was removed while it was locked. */
- ++( pxQueue->xRxLock );
- }
-
- xReturn = pdPASS;
- }
- else
- {
- xReturn = pdFAIL;
- traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue );
- }
- }
- portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue )
-{
-unsigned portBASE_TYPE uxReturn;
-
- taskENTER_CRITICAL();
- uxReturn = pxQueue->uxMessagesWaiting;
- taskEXIT_CRITICAL();
-
- return uxReturn;
-}
-/*-----------------------------------------------------------*/
-
-unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue )
-{
-unsigned portBASE_TYPE uxReturn;
-
- uxReturn = pxQueue->uxMessagesWaiting;
-
- return uxReturn;
-}
-/*-----------------------------------------------------------*/
-
-void vQueueDelete( xQueueHandle pxQueue )
-{
- traceQUEUE_DELETE( pxQueue );
- vQueueUnregisterQueue( pxQueue );
- vPortFree( pxQueue->pcHead );
- vPortFree( pxQueue );
-}
-/*-----------------------------------------------------------*/
-
-static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )
-{
- if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 )
- {
- #if ( configUSE_MUTEXES == 1 )
- {
- if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
- {
- /* The mutex is no longer being held. */
- vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );
- pxQueue->pxMutexHolder = NULL;
- }
- }
- #endif
- }
- else if( xPosition == queueSEND_TO_BACK )
- {
- memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
- pxQueue->pcWriteTo += pxQueue->uxItemSize;
- if( pxQueue->pcWriteTo >= pxQueue->pcTail )
- {
- pxQueue->pcWriteTo = pxQueue->pcHead;
- }
- }
- else
- {
- memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
- pxQueue->pcReadFrom -= pxQueue->uxItemSize;
- if( pxQueue->pcReadFrom < pxQueue->pcHead )
- {
- pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );
- }
- }
-
- ++( pxQueue->uxMessagesWaiting );
-}
-/*-----------------------------------------------------------*/
-
-static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
-{
- if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
- {
- pxQueue->pcReadFrom += pxQueue->uxItemSize;
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )
- {
- pxQueue->pcReadFrom = pxQueue->pcHead;
- }
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvUnlockQueue( xQueueHandle pxQueue )
-{
- /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
-
- /* The lock counts contains the number of extra data items placed or
- removed from the queue while the queue was locked. When a queue is
- locked items can be added or removed, but the event lists cannot be
- updated. */
- taskENTER_CRITICAL();
- {
- /* See if data was added to the queue while it was locked. */
- while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED )
- {
- /* Data was posted while the queue was locked. Are any tasks
- blocked waiting for data to become available? */
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
- {
- /* 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 )
- {
- /* The task waiting has a higher priority so record that a
- context switch is required. */
- vTaskMissedYield();
- }
-
- --( pxQueue->xTxLock );
- }
- else
- {
- break;
- }
- }
-
- pxQueue->xTxLock = queueUNLOCKED;
- }
- taskEXIT_CRITICAL();
-
- /* Do the same for the Rx lock. */
- taskENTER_CRITICAL();
- {
- while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )
- {
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
- {
- if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
- {
- vTaskMissedYield();
- }
-
- --( pxQueue->xRxLock );
- }
- else
- {
- break;
- }
- }
-
- pxQueue->xRxLock = queueUNLOCKED;
- }
- taskEXIT_CRITICAL();
-}
-/*-----------------------------------------------------------*/
-
-static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue )
-{
-signed portBASE_TYPE xReturn;
-
- taskENTER_CRITICAL();
- xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
- taskEXIT_CRITICAL();
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue )
-{
-signed portBASE_TYPE xReturn;
-
- xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue )
-{
-signed portBASE_TYPE xReturn;
-
- taskENTER_CRITICAL();
- xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
- taskEXIT_CRITICAL();
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue )
-{
-signed portBASE_TYPE xReturn;
-
- xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-#if configUSE_CO_ROUTINES == 1
-signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
-{
-signed portBASE_TYPE xReturn;
-
- /* If the queue is already full we may have to block. A critical section
- is required to prevent an interrupt removing something from the queue
- between the check to see if the queue is full and blocking on the queue. */
- portDISABLE_INTERRUPTS();
- {
- if( prvIsQueueFull( pxQueue ) )
- {
- /* The queue is full - do we want to block or just leave without
- posting? */
- if( xTicksToWait > ( portTickType ) 0 )
- {
- /* As this is called from a coroutine we cannot block directly, but
- return indicating that we need to block. */
- vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );
- portENABLE_INTERRUPTS();
- return errQUEUE_BLOCKED;
- }
- else
- {
- portENABLE_INTERRUPTS();
- return errQUEUE_FULL;
- }
- }
- }
- portENABLE_INTERRUPTS();
-
- portNOP();
-
- portDISABLE_INTERRUPTS();
- {
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
- {
- /* There is room in the queue, copy the data into the queue. */
- prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
- xReturn = pdPASS;
-
- /* Were any co-routines waiting for data to become available? */
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
- {
- /* In this instance the co-routine could be placed directly
- into the ready list as we are within a critical section.
- Instead the same pending ready list mechanism is used as if
- the event were caused from within an interrupt. */
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
- {
- /* The co-routine waiting has a higher priority so record
- that a yield might be appropriate. */
- xReturn = errQUEUE_YIELD;
- }
- }
- }
- else
- {
- xReturn = errQUEUE_FULL;
- }
- }
- portENABLE_INTERRUPTS();
-
- return xReturn;
-}
-#endif
-/*-----------------------------------------------------------*/
-
-#if configUSE_CO_ROUTINES == 1
-signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )
-{
-signed portBASE_TYPE xReturn;
-
- /* If the queue is already empty we may have to block. A critical section
- is required to prevent an interrupt adding something to the queue
- between the check to see if the queue is empty and blocking on the queue. */
- portDISABLE_INTERRUPTS();
- {
- if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
- {
- /* There are no messages in the queue, do we want to block or just
- leave with nothing? */
- if( xTicksToWait > ( portTickType ) 0 )
- {
- /* As this is a co-routine we cannot block directly, but return
- indicating that we need to block. */
- vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );
- portENABLE_INTERRUPTS();
- return errQUEUE_BLOCKED;
- }
- else
- {
- portENABLE_INTERRUPTS();
- return errQUEUE_FULL;
- }
- }
- }
- portENABLE_INTERRUPTS();
-
- portNOP();
-
- portDISABLE_INTERRUPTS();
- {
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
- {
- /* Data is available from the queue. */
- pxQueue->pcReadFrom += pxQueue->uxItemSize;
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )
- {
- pxQueue->pcReadFrom = pxQueue->pcHead;
- }
- --( pxQueue->uxMessagesWaiting );
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
-
- xReturn = pdPASS;
-
- /* Were any co-routines waiting for space to become available? */
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
- {
- /* In this instance the co-routine could be placed directly
- into the ready list as we are within a critical section.
- Instead the same pending ready list mechanism is used as if
- the event were caused from within an interrupt. */
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
- {
- xReturn = errQUEUE_YIELD;
- }
- }
- }
- else
- {
- xReturn = pdFAIL;
- }
- }
- portENABLE_INTERRUPTS();
-
- return xReturn;
-}
-#endif
-/*-----------------------------------------------------------*/
-
-
-
-#if configUSE_CO_ROUTINES == 1
-signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )
-{
- /* Cannot block within an ISR so if there is no space on the queue then
- exit without doing anything. */
- if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
- {
- prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
-
- /* We only want to wake one co-routine per ISR, so check that a
- co-routine has not already been woken. */
- if( !xCoRoutinePreviouslyWoken )
- {
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
- {
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
- {
- return pdTRUE;
- }
- }
- }
- }
-
- return xCoRoutinePreviouslyWoken;
-}
-#endif
-/*-----------------------------------------------------------*/
-
-#if configUSE_CO_ROUTINES == 1
-signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )
-{
-signed portBASE_TYPE xReturn;
-
- /* We cannot block from an ISR, so check there is data available. If
- not then just leave without doing anything. */
- if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
- {
- /* Copy the data from the queue. */
- pxQueue->pcReadFrom += pxQueue->uxItemSize;
- if( pxQueue->pcReadFrom >= pxQueue->pcTail )
- {
- pxQueue->pcReadFrom = pxQueue->pcHead;
- }
- --( pxQueue->uxMessagesWaiting );
- memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
-
- if( !( *pxCoRoutineWoken ) )
- {
- if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
- {
- if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
- {
- *pxCoRoutineWoken = pdTRUE;
- }
- }
- }
-
- xReturn = pdPASS;
- }
- else
- {
- xReturn = pdFAIL;
- }
-
- return xReturn;
-}
-#endif
-/*-----------------------------------------------------------*/
-
-#if configQUEUE_REGISTRY_SIZE > 0
-
- void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName )
- {
- unsigned portBASE_TYPE ux;
-
- /* See if there is an empty space in the registry. A NULL name denotes
- a free slot. */
- for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ )
- {
- if( xQueueRegistry[ ux ].pcQueueName == NULL )
- {
- /* Store the information on this queue. */
- xQueueRegistry[ ux ].pcQueueName = pcQueueName;
- xQueueRegistry[ ux ].xHandle = xQueue;
- break;
- }
- }
- }
-
-#endif
- /*-----------------------------------------------------------*/
-
-#if configQUEUE_REGISTRY_SIZE > 0
-
- static void vQueueUnregisterQueue( xQueueHandle xQueue )
- {
- unsigned portBASE_TYPE ux;
-
- /* See if the handle of the queue being unregistered in actually in the
- registry. */
- for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ )
- {
- if( xQueueRegistry[ ux ].xHandle == xQueue )
- {
- /* Set the name to NULL to show that this slot if free again. */
- xQueueRegistry[ ux ].pcQueueName = NULL;
- break;
- }
- }
-
- }
-
-#endif
-