queue.c File Reference

#include <stdlib.h>
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "croutine.h"

Go to the source code of this file.

Data Structures

struct  QueueDefinition

Defines

#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#define prvLockQueue(pxQueue)
#define pxMutexHolder   pcTail
#define queueDONT_BLOCK   ( ( portTickType ) 0 )
#define queueERRONEOUS_UNBLOCK   ( -1 )
#define queueLOCKED_UNMODIFIED   ( ( signed portBASE_TYPE ) 0 )
#define queueMUTEX_GIVE_BLOCK_TIME   ( ( portTickType ) 0 )
#define queueQUEUE_IS_MUTEX   NULL
#define queueSEMAPHORE_QUEUE_ITEM_LENGTH   ( 0 )
#define queueSEND_TO_BACK   ( 0 )
#define queueSEND_TO_FRONT   ( 1 )
#define queueUNLOCKED   ( ( signed portBASE_TYPE ) -1 )
#define uxQueueType   pcHead
#define uxRecursiveCallCount   pcReadFrom

Typedefs

typedef struct QueueDefinition xQUEUE
typedef xQUEUExQueueHandle

Functions

static void prvCopyDataFromQueue (xQUEUE *const pxQueue, const void *pvBuffer)
static void prvCopyDataToQueue (xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition)
static signed portBASE_TYPE prvIsQueueEmpty (const xQueueHandle pxQueue)
static signed portBASE_TYPE prvIsQueueFull (const xQueueHandle pxQueue)
static void prvUnlockQueue (xQueueHandle pxQueue)
unsigned portBASE_TYPE uxQueueMessagesWaiting (const xQueueHandle pxQueue) PRIVILEGED_FUNCTION
unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR (const xQueueHandle pxQueue)
void vQueueDelete (xQueueHandle xQueue) PRIVILEGED_FUNCTION
xQueueHandle xQueueCreate (unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize) PRIVILEGED_FUNCTION
xQueueHandle xQueueCreateMutex (void)
signed portBASE_TYPE xQueueGenericReceive (xQueueHandle pxQueue, void *const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking) PRIVILEGED_FUNCTION
signed portBASE_TYPE xQueueGenericSend (xQueueHandle xQueue, const void *const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition) PRIVILEGED_FUNCTION
signed portBASE_TYPE xQueueGenericSendFromISR (xQueueHandle pxQueue, const void *const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition) PRIVILEGED_FUNCTION
signed portBASE_TYPE xQueueIsQueueEmptyFromISR (const xQueueHandle pxQueue)
signed portBASE_TYPE xQueueIsQueueFullFromISR (const xQueueHandle pxQueue)
signed portBASE_TYPE xQueueReceiveFromISR (xQueueHandle pxQueue, void *const pvBuffer, signed portBASE_TYPE *pxTaskWoken) PRIVILEGED_FUNCTION


Define Documentation

#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE

Definition at line 60 of file queue.c.

#define prvLockQueue ( pxQueue   ) 

Value:

{                                                       \
    taskENTER_CRITICAL();                               \
    {                                                   \
        if( pxQueue->xRxLock == queueUNLOCKED )         \
        {                                               \
            pxQueue->xRxLock = queueLOCKED_UNMODIFIED;  \
        }                                               \
        if( pxQueue->xTxLock == queueUNLOCKED )         \
        {                                               \
            pxQueue->xTxLock = queueLOCKED_UNMODIFIED;  \
        }                                               \
    }                                                   \
    taskEXIT_CRITICAL();                                \
}

Referenced by xQueueGenericReceive(), and xQueueGenericSend().

#define pxMutexHolder   pcTail

Definition at line 83 of file queue.c.

#define queueDONT_BLOCK   ( ( portTickType ) 0 )

Definition at line 91 of file queue.c.

#define queueERRONEOUS_UNBLOCK   ( -1 )

Definition at line 76 of file queue.c.

#define queueLOCKED_UNMODIFIED   ( ( signed portBASE_TYPE ) 0 )

Definition at line 74 of file queue.c.

Referenced by prvUnlockQueue().

#define queueMUTEX_GIVE_BLOCK_TIME   ( ( portTickType ) 0 )

Definition at line 92 of file queue.c.

#define queueQUEUE_IS_MUTEX   NULL

Definition at line 86 of file queue.c.

Referenced by prvCopyDataFromQueue(), prvCopyDataToQueue(), and xQueueGenericReceive().

#define queueSEMAPHORE_QUEUE_ITEM_LENGTH   ( 0 )

Definition at line 90 of file queue.c.

#define queueSEND_TO_BACK   ( 0 )

Definition at line 79 of file queue.c.

#define queueSEND_TO_FRONT   ( 1 )

Definition at line 80 of file queue.c.

#define queueUNLOCKED   ( ( signed portBASE_TYPE ) -1 )

Definition at line 73 of file queue.c.

Referenced by prvUnlockQueue(), xQueueGenericSendFromISR(), and xQueueReceiveFromISR().

#define uxQueueType   pcHead

Definition at line 84 of file queue.c.

#define uxRecursiveCallCount   pcReadFrom

Definition at line 85 of file queue.c.


Typedef Documentation

typedef struct QueueDefinition xQUEUE

typedef xQUEUE* xQueueHandle

Definition at line 124 of file queue.c.


Function Documentation

static void prvCopyDataFromQueue ( xQUEUE *const   pxQueue,
const void *  pvBuffer 
) [static]

Definition at line 1088 of file queue.c.

References QueueDefinition::pcHead, QueueDefinition::pcReadFrom, QueueDefinition::pcTail, queueQUEUE_IS_MUTEX, and QueueDefinition::uxItemSize.

Referenced by xQueueGenericReceive(), and xQueueReceiveFromISR().

01088 {
01089     if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
01090     {
01091         pxQueue->pcReadFrom += pxQueue->uxItemSize;
01092         if( pxQueue->pcReadFrom >= pxQueue->pcTail )
01093         {
01094             pxQueue->pcReadFrom = pxQueue->pcHead;
01095         }
01096         memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
01097     }
01098 }
01099 /*-----------------------------------------------------------*/

static void prvCopyDataToQueue ( xQUEUE pxQueue,
const void *  pvItemToQueue,
portBASE_TYPE  xPosition 
) [static]

Definition at line 1050 of file queue.c.

References QueueDefinition::pcHead, QueueDefinition::pcReadFrom, QueueDefinition::pcTail, QueueDefinition::pcWriteTo, queueQUEUE_IS_MUTEX, queueSEND_TO_BACK, QueueDefinition::uxItemSize, QueueDefinition::uxMessagesWaiting, and vTaskPriorityDisinherit().

Referenced by xQueueGenericSend(), and xQueueGenericSendFromISR().

01050 {
01051     if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 )
01052     {
01053         #if ( configUSE_MUTEXES == 1 )
01054         {
01055             if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
01056             {
01057                 /* The mutex is no longer being held. */
01058                 vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );
01059                 pxQueue->pxMutexHolder = NULL;
01060             }
01061         }
01062         #endif
01063     }
01064     else if( xPosition == queueSEND_TO_BACK )
01065     {
01066         memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
01067         pxQueue->pcWriteTo += pxQueue->uxItemSize;
01068         if( pxQueue->pcWriteTo >= pxQueue->pcTail )
01069         {
01070             pxQueue->pcWriteTo = pxQueue->pcHead;
01071         }
01072     }
01073     else
01074     {
01075         memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
01076         pxQueue->pcReadFrom -= pxQueue->uxItemSize;
01077         if( pxQueue->pcReadFrom < pxQueue->pcHead )
01078         {
01079             pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );
01080         }
01081     }
01082 
01083     ++( pxQueue->uxMessagesWaiting );
01084 }
01085 /*-----------------------------------------------------------*/

static signed portBASE_TYPE prvIsQueueEmpty ( const xQueueHandle  pxQueue  )  [static]

Definition at line 1166 of file queue.c.

References taskENTER_CRITICAL, and taskEXIT_CRITICAL.

Referenced by xQueueGenericReceive().

01166 {
01167 signed portBASE_TYPE xReturn;
01168 
01169     taskENTER_CRITICAL();
01170         xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
01171     taskEXIT_CRITICAL();
01172 
01173     return xReturn;
01174 }
01175 /*-----------------------------------------------------------*/

static signed portBASE_TYPE prvIsQueueFull ( const xQueueHandle  pxQueue  )  [static]

Definition at line 1188 of file queue.c.

References taskENTER_CRITICAL, and taskEXIT_CRITICAL.

Referenced by xQueueGenericSend().

01188 {
01189 signed portBASE_TYPE xReturn;
01190 
01191     taskENTER_CRITICAL();
01192         xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
01193     taskEXIT_CRITICAL();
01194 
01195     return xReturn;
01196 }
01197 /*-----------------------------------------------------------*/

static void prvUnlockQueue ( xQueueHandle  pxQueue  )  [static]

Definition at line 1102 of file queue.c.

References listLIST_IS_EMPTY, pdFALSE, queueLOCKED_UNMODIFIED, queueUNLOCKED, taskENTER_CRITICAL, taskEXIT_CRITICAL, vTaskMissedYield(), and xTaskRemoveFromEventList().

Referenced by xQueueGenericReceive(), and xQueueGenericSend().

01102 {
01103     /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
01104 
01105     /* The lock counts contains the number of extra data items placed or
01106     removed from the queue while the queue was locked.  When a queue is
01107     locked items can be added or removed, but the event lists cannot be
01108     updated. */
01109     taskENTER_CRITICAL();
01110     {
01111         /* See if data was added to the queue while it was locked. */
01112         while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED )
01113         {
01114             /* Data was posted while the queue was locked.  Are any tasks
01115             blocked waiting for data to become available? */
01116             if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
01117             {
01118                 /* Tasks that are removed from the event list will get added to
01119                 the pending ready list as the scheduler is still suspended. */
01120                 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
01121                 {
01122                     /* The task waiting has a higher priority so record that a
01123                     context switch is required. */
01124                     vTaskMissedYield();
01125                 }
01126 
01127                 --( pxQueue->xTxLock );
01128             }
01129             else
01130             {
01131                 break;
01132             }
01133         }
01134 
01135         pxQueue->xTxLock = queueUNLOCKED;
01136     }
01137     taskEXIT_CRITICAL();
01138 
01139     /* Do the same for the Rx lock. */
01140     taskENTER_CRITICAL();
01141     {
01142         while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )
01143         {
01144             if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
01145             {
01146                 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
01147                 {
01148                     vTaskMissedYield();
01149                 }
01150 
01151                 --( pxQueue->xRxLock );
01152             }
01153             else
01154             {
01155                 break;
01156             }
01157         }
01158 
01159         pxQueue->xRxLock = queueUNLOCKED;
01160     }
01161     taskEXIT_CRITICAL();
01162 }
01163 /*-----------------------------------------------------------*/

unsigned portBASE_TYPE uxQueueMessagesWaiting ( const xQueueHandle  pxQueue  ) 

unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR ( const xQueueHandle  pxQueue  ) 

Definition at line 1031 of file queue.c.

01031 {
01032 unsigned portBASE_TYPE uxReturn;
01033 
01034     uxReturn = pxQueue->uxMessagesWaiting;
01035 
01036     return uxReturn;
01037 }
01038 /*-----------------------------------------------------------*/

void vQueueDelete ( xQueueHandle  xQueue  ) 

xQueueHandle xQueueCreate ( unsigned portBASE_TYPE  uxQueueLength,
unsigned portBASE_TYPE  uxItemSize 
)

xQueueHandle xQueueCreateMutex ( void   ) 

Definition at line 138 of file queue.c.

00169     {
00170         signed char *pcQueueName;
00171         xQueueHandle xHandle;
00172     } xQueueRegistryItem;
00173 
00174     /* The queue registry is simply an array of xQueueRegistryItem structures.
00175     The pcQueueName member of a structure being NULL is indicative of the
00176     array position being vacant. */
00177     xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];
00178 
00179     /* Removes a queue from the registry by simply setting the pcQueueName
00180     member to NULL. */
00181     static void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
00182     void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) PRIVILEGED_FUNCTION;
00183 #endif
00184 
00185 /*
00186  * Unlocks a queue locked by a call to prvLockQueue.  Locking a queue does not
00187  * prevent an ISR from adding or removing items to the queue, but does prevent
00188  * an ISR from removing tasks from the queue event lists.  If an ISR finds a
00189  * queue is locked it will instead increment the appropriate queue lock count
00190  * to indicate that a task may require unblocking.  When the queue in unlocked
00191  * these lock counts are inspected, and the appropriate action taken.
00192  */
00193 static void prvUnlockQueue( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
00194 
00195 /*
00196  * Uses a critical section to determine if there is any data in a queue.
00197  *
00198  * @return pdTRUE if the queue contains no items, otherwise pdFALSE.
00199  */
00200 static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
00201 
00202 /*
00203  * Uses a critical section to determine if there is any space in a queue.
00204  *
00205  * @return pdTRUE if there is no space, otherwise pdFALSE;
00206  */
00207 static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
00208 
00209 /*
00210  * Copies an item into the queue, either at the front of the queue or the
00211  * back of the queue.
00212  */
00213 static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION;
00214 
00215 /*
00216  * Copies an item out of a queue.
00217  */
00218 static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION;
00219 /*-----------------------------------------------------------*/
00220 
00221 /*
00222  * Macro to mark a queue as locked.  Locking a queue prevents an ISR from
00223  * accessing the queue event lists.
00224  */
00225 #define prvLockQueue( pxQueue )                         \
00226 {                                                       \
00227     taskENTER_CRITICAL();                               \
00228     {                                                   \
00229         if( pxQueue->xRxLock == queueUNLOCKED )         \
00230         {                                               \
00231             pxQueue->xRxLock = queueLOCKED_UNMODIFIED;  \
00232         }                                               \
00233         if( pxQueue->xTxLock == queueUNLOCKED )         \
00234         {                                               \
00235             pxQueue->xTxLock = queueLOCKED_UNMODIFIED;  \
00236         }                                               \
00237     }                                                   \
00238     taskEXIT_CRITICAL();                                \
00239 }
00240 /*-----------------------------------------------------------*/
00241 
00242 
00243 /*-----------------------------------------------------------
00244  * PUBLIC QUEUE MANAGEMENT API documented in queue.h
00245  *----------------------------------------------------------*/
00246 
00247 xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize )
00248 {
00249 xQUEUE *pxNewQueue;
00250 size_t xQueueSizeInBytes;
00251 
00252     /* Allocate the new queue structure. */
00253     if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )
00254     {
00255         pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
00256         if( pxNewQueue != NULL )
00257         {
00258             /* Create the list of pointers to queue items.  The queue is one byte
00259             longer than asked for to make wrap checking easier/faster. */
00260             xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1;
00261 
00262             pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes );
00263             if( pxNewQueue->pcHead != NULL )
00264             {
00265                 /* Initialise the queue members as described above where the
00266                 queue type is defined. */
00267                 pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize );
00268                 pxNewQueue->uxMessagesWaiting = 0;
00269                 pxNewQueue->pcWriteTo = pxNewQueue->pcHead;
00270                 pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize );
00271                 pxNewQueue->uxLength = uxQueueLength;
00272                 pxNewQueue->uxItemSize = uxItemSize;
00273                 pxNewQueue->xRxLock = queueUNLOCKED;
00274                 pxNewQueue->xTxLock = queueUNLOCKED;
00275 
00276                 /* Likewise ensure the event queues start with the correct state. */
00277                 vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
00278                 vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
00279 
00280                 traceQUEUE_CREATE( pxNewQueue );
00281                 return  pxNewQueue;
00282             }
00283             else
00284             {
00285                 traceQUEUE_CREATE_FAILED();
00286                 vPortFree( pxNewQueue );
00287             }
00288         }
00289     }
00290 
00291     /* Will only reach here if we could not allocate enough memory or no memory
00292     was required. */
00293     return NULL;
00294 }

signed portBASE_TYPE xQueueGenericReceive ( xQueueHandle  pxQueue,
void *const   pvBuffer,
portTickType  xTicksToWait,
portBASE_TYPE  xJustPeeking 
)

signed portBASE_TYPE xQueueGenericSend ( xQueueHandle  xQueue,
const void *const   pvItemToQueue,
portTickType  xTicksToWait,
portBASE_TYPE  xCopyPosition 
)

signed portBASE_TYPE xQueueGenericSendFromISR ( xQueueHandle  pxQueue,
const void *const   pvItemToQueue,
signed portBASE_TYPE *  pxHigherPriorityTaskWoken,
portBASE_TYPE  xCopyPosition 
)

signed portBASE_TYPE xQueueIsQueueEmptyFromISR ( const xQueueHandle  pxQueue  ) 

Definition at line 1178 of file queue.c.

01178 {
01179 signed portBASE_TYPE xReturn;
01180 
01181     xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
01182 
01183     return xReturn;
01184 }
01185 /*-----------------------------------------------------------*/

signed portBASE_TYPE xQueueIsQueueFullFromISR ( const xQueueHandle  pxQueue  ) 

Definition at line 1200 of file queue.c.

01200 {
01201 signed portBASE_TYPE xReturn;
01202 
01203     xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
01204 
01205     return xReturn;
01206 }
01207 /*-----------------------------------------------------------*/

signed portBASE_TYPE xQueueReceiveFromISR ( xQueueHandle  pxQueue,
void *const   pvBuffer,
signed portBASE_TYPE *  pxTaskWoken 
)


Generated on Thu Dec 17 20:02:01 2009 for AVR32 UC3 - FreeRTOS Real Time Kernel by  doxygen 1.5.5