Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Failed to understand the pointers movement in Queue related operations

Posted by luauto on January 27, 2016

Hi all, When I trying to clarify the pointers movement in queue operations, I found that I fell in confusion. Below is my current understanding about queue operation, please point out my mis-undestanding points.

1) First call xQueueGenericCreate() API to create a new Queue, the API will set pcHead pointer and then call xQueueGenericReset() to set the pcTail, pcReadFrom and pcWriteTo pointers, etc. 2) After step 1), there will be pcHead == pcWriteTo, pcReadFrom + uxItemSize == pcTail; 3) Then, I call xQueueGenericSend() to send one item to the BACK of the queue, it will call prvCopyDataToQueue() API. In prvCopyDataToQueue(), the pointer pcWriteTo is incremented. 4) Finally, I want to read the stored item using API xQueueGenericReceive(). In this API, it will call prvCopyDataFromQueue() to retrieve the stored item. But it only increments pointer pcReadFrom and read its pointed data to buffer.

My questions are below: (1) Which position is the Back of the Queue? Is it pointed by pcTail? (2) Since when sending items to the Back of the Queue, it only changes pointer pcWriteTo; However, when I want to receive the stored items, it changes pointer pcReadFrom, but seems the pcReadFrom never changes after calling xQueueGenericReset() and maybe far from the position of the stored item.

I think my understanding is wrong, but I still cannot figure out the root cause. I'm reading the code of V8.2.1;

Hope someone can help me about the confusion, thanks in advance! Best regards!


Failed to understand the pointers movement in Queue related operations

Posted by rtel on January 27, 2016

This is all internal implementation detail - I assume you are only looking at it out of interest.

As far as I can see the write to pointer points to the next space to be written to, so gets incremented after it has been written, while the read from pointer points to the last item read, so gets incremented before an item is read from the queue.


Failed to understand the pointers movement in Queue related operations

Posted by luauto on January 28, 2016

Hi, yes, I'm reading the code for interest, but I just cannot understand the internal mechanism. Could you please point out the code how the pcReadFrom changes to point to the last item to read? Seems I didn't see the code specify it.


Failed to understand the pointers movement in Queue related operations

Posted by heinbali01 on January 28, 2016

Have a look at xQueueGenericReset() :

~~~~~ pxQueue->pcWriteTo = pxQueue->pcHead; pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( UBaseType_t ) 1U ) * pxQueue->uxItemSize ); ~~~~~

When the queue is created, the pcReadFrom member will point to the last item in the queue (to N-1)

After that the code will:

~~~~~ read from ++pcReadFrom ( pre-increment ) write to pcWriteTo++ ( post increment )

~~~~~

Does that make it clear?


Failed to understand the pointers movement in Queue related operations

Posted by luauto on January 29, 2016

Hi Hein, Thank you for your reply. Let's specify a model to illustrate it. 1) Say, I will create a queue with uxLength == 10, which will hold item 1 to 10. So, after calling xQueueGenericCreate() API, the pcReadFrom will point to item 9, pcWriteTo will point to item 1, but remember the queue has no data now. 2) Then, I call xQueueGenericSend() to send one item to the BACK of the queue, it will increment the pointer pcWriteTo with one item step, but won't change pcReadFrom, right? 3) Finally, I call xQueueGenericReceive(), it only increments pointer pcReadFrom and read its pointed data to buffer. But you know, now pcReadFrom is pointing to item 9, with no valid data, the valid data is at item 1 position.

Above is my confusion, am I describe it clearly to you?


Failed to understand the pointers movement in Queue related operations

Posted by rtel on January 29, 2016

I think this has been described twice already, you can see in the source code how this works, and if it is not clear from the source code you can step through the source code in the debugger to view what is happening:

the pcReadFrom will point to item 9

Yes.

it only increments pointer pcReadFrom

Yes.

But you know, now pcReadFrom is pointing to item 9

No. If it starts pointing at 9, and is then incremented, it is no longer pointing at item 9.


Failed to understand the pointers movement in Queue related operations

Posted by heinbali01 on January 29, 2016

Not sure if this examples helps:

~~~~~ queueSENDTOBACK : the normal way, using a queue as a FIFO queueSENDTOFRONT : add an item that will be read firstly (more like a STACK)

This queue has 10 items. Their positions are numbered 0 to 9 (not 1 to 10).

pcWriteTo		|	 pcReadFrom

Initial situation:

0				|	 9

queueSENDTOBACK :

write at 0		|	 9
1				|

queueSENDTOBACK :

write at 1		|	 9
2				|

queueSENDTOFRONT :

2				|	 write at 9
                                 |	 9 -> 8

Read all 3 times :

2				|	 8 -> 9 read from 9
2				|	 9 -> 0 read from 0
2				|	 0 -> 1 read from 1

~~~~~


Failed to understand the pointers movement in Queue related operations

Posted by luauto on January 29, 2016

Hi Hein, Thank you for your detailed explanation and patience. I have noticed my wrong point.

Last question, please. About the concept of "Front" and "Back". The "Front" means the pcTail side, and the "Back" means the "pcHead" side, am I right?

Best regards!


Failed to understand the pointers movement in Queue related operations

Posted by heinbali01 on January 29, 2016

The "Front" means the pcTail side, and the "Back" means the "pcHead" side, am I right?

No, not necessarily. pcHead and pcTail are a kind of const pointers that define the beginning and the end of the queue space. Items are written at the position pcWriteTo or pcReadFrom, depending on the value of xCopyPosition (resp BACK or FRONT).

As I said, adding items to the BACK is the usual way. That works like a fifo. Add items a-b-c, and you can read them back in the same order a-b-c.

When you add items a-b-c at with SEND_TO_FRONT, you will read back c-b-a. The last item comes out first.

In some situations, a mixture of SEND_TO_BACK and SEND_TO_FRONT can be very useful: the first one is used for all normal messages, the latter is used to send an emergency message, which will be treated first.

Regards.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS