How To Copy Queue or Use In Buffer Processing

nobody wrote on Friday, November 18, 2005:

Is there a way to make a copy of the queue or to use the queue contents for buffer processing?

I’d like to know how to make use of the queue vs.
having to copy it to a buffer in order to save

Thanks In Advance.

rtel wrote on Friday, November 18, 2005:

Can you please give a little more detail as to what it is you are trying to achieve as I’m not sure from your question.

Is it that you want to be able to access the queue storage area directly, use the queue without coping data to the queue, or that you want to make a copy of the entire queue including the queue storage area?


nobody wrote on Friday, November 18, 2005:

As a for instance,

say we’re building up a buffer of received data
from a UART function - building it up byte by
byte until CR LF or something similar occurs -

I’d like to be able to use the data in the
queue vs. having to allocate another buffer
in which the data is built up byte by byte until
the CR LF is received.

Just trying to see if there’s a way to save
some memory by being able to access the queue
more directly.


rtel wrote on Friday, November 18, 2005:

It is possible to access the queue directly with a bit of fiddling, but I’m wondering if you are really wanting a queue at all or whether a simple buffer might be more appropriate for your application?

The primary reason for using a queue would be to guarantee the priority at which each received character was processed.  See this thread for more detail:

If you are wanting to buffer characters until a CR LF sequence then you could have a very simple ISR that just

1) reads the character from the peripheral,
2) places it in a buffer (just an array),
3) checks whether it is the end of the message,  4) clears the interrupt
5) if it is the end of the message then optionally signal to a task that a complete message is ready for processing.  This could be done by using xSemaphoreGiveFromISR().  Depending on the relative priorities of your tasks the semaphore could make the data processing task the highest priority task ready to run meaning the ISR returns immediately to the data processing task.

The data processing task would then be something like:

____while( !xSemaphoreTake( Semaphore, MAX_WAIT_TIME ) );

____/* Broke from block loop above so a message
____must be available. */

____/* ProcessMessage() just accesses the message
____buffer directly. */

____/* Go back to block waiting for next complete
____message. */

This would be much more efficient than using a queue.


nobody wrote on Friday, November 18, 2005:

Do you mind going over the fiddling part of how
to access the queue?


rtel wrote on Friday, November 18, 2005:

The queue itself is basically a circular buffer, with pointers to the last item to be inserted, the buffer start and the buffer end.  It can be accessed as such, provided care is taken that interrupts don’t change the queue structure members while you are accessing it.

See for more info.

The fiddle comes from the fact that the queue definition is deliberately hidden from the application code.  Inside queue.c the type xQueueHandle is defined as a pointer to an xQUEUE structure.  Outside queue.c xQueueHandle is defined as a pointer to void.

This means you have two choices:

1) Write an access function within queue.c where you can see the circular buffer details (look at the structure members of xQUEUE).

2) Remove the data hiding by moving the definition of xQUEUE from queue.c to queue.h, and defining xQueueHandle as a pointer to an xQUEUE within queue.h.


nobody wrote on Sunday, November 27, 2005:


I originally asked the question in thread , and wanted to use it for packet filtering of data that comes in on a serial connection. After having implemented the function according to how it was suggested in the thread (it works…) I found out that it is NOT what I wanted.

As this thread also says, the FreeRTOS queue is also for synchronizing tasks (as well as buffer data). If you need a FIFO queue just to buffer input, you are perhaps better off with a simple FIFO queue. If you have only a single reader and a single writer, a non-locking implementation is straight-forward.

Moral of the story: by jumping to code before thinking it through, I have modified FreeRTOS for no good reason, and I am now undoing my previous work by replacing it with a simple non-locking queue.

Keep up the good work,
Thiadmer Riemersma