Queues
[RTOS]

Queues allow for thread-safe inter-process communication. More...


Functions

void * QueueCreate (uint length, uint itemSize)
 Create a new queue.
int QueueSendToFront (void *queue, void *itemToQueue, int msToWait)
 Post an item onto the front of a queue.
int QueueSendToBack (void *queue, void *itemToQueue, int msToWait)
 Post an item onto the back of a queue.
int QueueReceive (void *queue, void *buffer, int msToWait)
 Read an item off of a queue.
int QueueMessagesWaiting (void *queue)
 Return the number of messages waiting in a queue.
void QueueDelete (void *queue)
 Delete a queue - freeing all the memory allocated for storing of items placed on the queue.
int QueueSendToFrontFromISR (void *queue, void *itemToSend, int taskPreviouslyWoken)
 Post an item to the front of a queue from within an interrupt service routine.
int QueueSendToBackFromISR (void *queue, void *itemToSend, int taskPreviouslyWoken)
 Post an item to the back of a queue from within an interrupt service routine.
int QueueReceiveFromISR (void *queue, void *buffer, long *taskWoken)
 Receive an item from a queue from within an interrupt service routine.

Detailed Description

Queues allow for thread-safe inter-process communication.

A queue is a list of items that can be passed from one task to another. Items are placed in a queue by copy - not by reference. It is therefore preferable, when queuing large items, to only queue a pointer to the item. Tasks can block on a queue to wait for either data to become available on the queue, or space to become available to write to the queue.

More info at http://www.freertos.org - some documentation here used from the FreeRTOS doc by Richard Barry.


Function Documentation

void* QueueCreate ( uint  length,
uint  itemSize 
)

Create a new queue.

This allocates storage for the queue. It's usually a good idea to pass around pointers on queues as opposed to whole data structures, as that's quite resource intensive.

Parameters:
length The maximum number of items that the queue can contain.
itemSize The number of bytes each item in the queue will require. Items are queued by copy, not by reference, so this is the number of bytes that will be copied for each posted item. Each item on the queue must be the same size.
Returns:
A pointer to the queue on success, 0 if the queue couldn't be created.
Example
  struct myData_
  {
    int count;
    char buffer[100];
  };

  // create a queue that can hold 5 pointers to myData structures
  struct MyData_* myData;
  void* myQueue = QueueCreate( 5, sizeof( myData* ) );
  if( myQueue == 0 )
    // then the queue can't be used.
  else
    // continue processing...

Definition at line 569 of file rtos.c.

void QueueDelete ( void *  queue  ) 

Delete a queue - freeing all the memory allocated for storing of items placed on the queue.

Parameters:
queue The queue to delete.
Example
  QueueDelete( myQueue );

Definition at line 722 of file rtos.c.

int QueueMessagesWaiting ( void *  queue  ) 

Return the number of messages waiting in a queue.

Parameters:
queue The queue to look at.
Returns:
The number of messages waiting.
Example
  int msgs = QueueMessagesWaiting( myQueue );

Definition at line 708 of file rtos.c.

int QueueReceive ( void *  queue,
void *  buffer,
int  msToWait 
)

Read an item off of a queue.

The item is received by copy so a buffer of adequate size must be provided. The number of bytes copied into the buffer was defined when the queue was created. The item will be removed from the queue once it is read.

This function must not be used in an interrupt service routine. See QueueReceiveFromISR( ) for an alternative that can.

Parameters:
queue The queue to receive from.
buffer A pointer to the buffer the item will be read into.
msToWait The maximum number of milliseconds the task should block waiting for an item to show up on the queue, should it be empty.
Returns:
1 on success, 0 on failure.
Example
  struct MyData_
  {
    int count;
    char buffer[100];
  };
  
  void* myQueue;
  
  void SomeTask( void* p )
  {
    // create a queue that can hold 5 pointers to myData structures
    myQueue = QueueCreate( 5, sizeof( myData* ) );
    struct MyData_ myData; // the data we'll be sending
    myData.count = 12;
    myData.buffer = "ABCDEF";
    
    QueueSendToFront( myQueue, &myData, 0 );
  }
  
  void AnotherTask( void* p )
  {
    int dataSize = sizeof( struct MyData_ );
    struct MyData_* rxData; // a pointer to some data
    if( myQueue )
    {
      if( QueueReceive( myQueue, rxData, 100 ) ) // wait up to 100 milliseconds for data
      {
        // now rxData points to the data posted in SomeTask
      }
    }
  }

Definition at line 692 of file rtos.c.

int QueueReceiveFromISR ( void *  queue,
void *  buffer,
long *  taskWoken 
)

Receive an item from a queue from within an interrupt service routine.

You'll need to have enough storage for the queue to copy the item into. Receiving from a queue takes the item off the queue.

Parameters:
queue The queue to receive from.
buffer A pointer to the buffer into which the received item will be copied - ensure that there's enough room.
taskWoken A task may be blocked waiting for an item to be read from the queue, freeing up space. If QueueReceiveFromISR causes such a task to unblock *taskWoken will get set to 1, otherwise *taskWoken will remain unchanged.
Returns:
1 if an item was successfully received from the queue, otherwise 0. switch may be required following the ISR.
Example
  
  int taskWokenByReceive = 0; // be sure to initialize to 0
  void* myQueue = QueueCreate( 5, sizeof( char ) );
  if( myQueue == 0 )
    // queue couldn't be created...
  
  char data;

  while( QueueReceiveFromISR( myQueue, (void*)&data, taskWokenByReceive ) )
  {
    // process new items from queue here
    
    // If removing an item from the queue woke the task that was 
    // posting onto the queue, taskWokenByReceive will have been set to
    // 1.  No matter how many times this loop iterates only one
    // task will be woken.
  }
  if( taskWokenByReceive )
  {
      // We should switch context so the ISR returns to a different task.    
      taskYIELD ();
  }

Definition at line 845 of file rtos.c.

int QueueSendToBack ( void *  queue,
void *  itemToQueue,
int  msToWait 
)

Post an item onto the back of a queue.

The item is queued by copy, not by reference. This function must not be called from an interrupt service routine. See xQueueSendFromISR () for an alternative which may be used in an ISR.

Parameters:
queue The queue to send to.
itemToQueue A pointer to the item to send on the queue.
msToWait The maximum number of milliseconds the task should block waiting for space to become available on the queue, should it already be full. The call will return immediately if this is set to 0.
Returns:
1 on success, 0 on failure.
Example
  struct MyData_
  {
    int count;
    char buffer[100];
  };

  // create a queue that can hold 5 pointers to myData structures
  struct MyData_* myData;
  void* myQueue = QueueCreate( 5, sizeof( myData* ) );
  if( myQueue )
  {
    if( QueueSendToBack( myQueue, (void*)&myData, 10 ) ) // wait 10 ms to send if queue is full
      // then we're all set
    else
      // deal with an unsuccessful send
  }

Definition at line 639 of file rtos.c.

int QueueSendToBackFromISR ( void *  queue,
void *  itemToSend,
int  taskPreviouslyWoken 
)

Post an item to the back of a queue from within an interrupt service routine.

Items are queued by copy not reference so it is preferable to only queue small items, especially when called from an ISR. In most cases it would be preferable to store a pointer to the item being queued.

Parameters:
queue The queue to send to.
itemToSend A pointer to the item to send on the queue. The size of the items the queue will hold was defined when the queue was created, so this many bytes will be copied from itemToSend into the queue storage area.
taskPreviouslyWoken This is included so an ISR can post onto the same queue multiple times from a single interrupt. The first call should always pass in 0. Subsequent calls should pass in the value returned from the previous call.
Returns:
1 if a task was woken by posting onto the queue. This is used by the ISR to determine if a context switch may be required following the ISR.
Example
  struct MyData_
  {
    int count;
    char buffer[100];
  };
  
  int taskWokenByPost = 0; // be sure to initialize to 0

  // create a queue that can hold 5 pointers to myData structures
  struct MyData_ myData;
  void* myQueue = QueueCreate( 5, sizeof( myData* ) );
  if( myQueue )
  {
    taskWokenByPost = QueueSendToBackFromISR( myQueue, (void*)&myData, taskWokenByPost )
    if( taskWokenByPost )
    {
        // We should switch context so the ISR returns to a different task.    
        portYIELD_FROM_ISR( );
    }
  }

Definition at line 804 of file rtos.c.

int QueueSendToFront ( void *  queue,
void *  itemToQueue,
int  msToWait 
)

Post an item onto the front of a queue.

The item is queued by copy, not by reference. This function must not be called from an interrupt service routine. See xQueueSendFromISR () for an alternative which may be used in an ISR.

Parameters:
queue The queue to send to.
itemToQueue A pointer to the item to send on the queue.
msToWait The maximum number of milliseconds the task should block waiting for space to become available on the queue, should it already be full. The call will return immediately if this is set to 0.
Returns:
1 on success, 0 on failure.
Example
  struct MyData_
  {
    int count;
    char buffer[100];
  };

  // create a queue that can hold 5 pointers to myData structures
  struct MyData_* myData;
  void* myQueue = QueueCreate( 5, sizeof( myData* ) );
  if( myQueue )
  {
    if( QueueSendToFront( myQueue, (void*)&myData, 10 ) ) // wait 10 ms to send if queue is full
      // then we're all set
    else
      // deal with an unsuccessful send
  }

Definition at line 604 of file rtos.c.

int QueueSendToFrontFromISR ( void *  queue,
void *  itemToSend,
int  taskPreviouslyWoken 
)

Post an item to the front of a queue from within an interrupt service routine.

Items are queued by copy not reference so it is preferable to only queue small items, especially when called from an ISR. In most cases it would be preferable to store a pointer to the item being queued.

Parameters:
queue The queue to send to.
itemToSend A pointer to the item to send on the queue. The size of the items the queue will hold was defined when the queue was created, so this many bytes will be copied from itemToSend into the queue storage area.
taskPreviouslyWoken This is included so an ISR can post onto the same queue multiple times from a single interrupt. The first call should always pass in 0. Subsequent calls should pass in the value returned from the previous call.
Returns:
1 if a task was woken by posting onto the queue. This is used by the ISR to determine if a context switch may be required following the ISR.
Example
  struct MyData_
  {
    int count;
    char buffer[100];
  };
  
  int taskWokenByPost = 0; // be sure to initialize to 0

  // create a queue that can hold 5 pointers to myData structures
  struct MyData_ myData;
  void* myQueue = QueueCreate( 5, sizeof( myData* ) );
  if( myQueue )
  {
    taskWokenByPost = QueueSendToFrontFromISR( myQueue, (void*)&myData, taskWokenByPost )
    if( taskWokenByPost )
    {
        // We should switch context so the ISR returns to a different task.    
        portYIELD_FROM_ISR( );
    }
  }

Definition at line 763 of file rtos.c.