Page 1 of 2

Example of using Queue to pass strings between tasks

Posted: Wed Sep 20, 2017 11:09 pm
by sukeshak
I am looking for an example where a char string is passed between tasks (producer/consumer).
Most of the examples I have seen are using numbers like int.

Thanks in advance :)

Re: Example of using Queue to pass strings between tasks

Posted: Thu Sep 21, 2017 1:34 am
by ESP_Sprite
A queue actually is made for items with a defined length; if you throw in strings it'll waste a bunch of memory. Maybe you want to look at the ringbuffer implementation (in components/freertos/ringbuf.c and components/freertos/include/freertos/ringbuf.h) instead? Unfortunately, I also do not have an example for that (although, if I recall correctly, there should be an unit test for that thing somewhere.)

Re: Example of using Queue to pass strings between tasks

Posted: Thu Sep 21, 2017 9:31 am
by sukeshak
ESP_Sprite wrote:A queue actually is made for items with a defined length; if you throw in strings it'll waste a bunch of memory. Maybe you want to look at the ringbuffer implementation (in components/freertos/ringbuf.c and components/freertos/include/freertos/ringbuf.h) instead? Unfortunately, I also do not have an example for that (although, if I recall correctly, there should be an unit test for that thing somewhere.)
Thank you for the response. Will check ringbuffer. Saw the unit test and will check the code from there.

I started off with Queue since I saw it being used for UART events sample. Is that also a ringbuffer behind the scene?

I am new to electronics, ESP32 & FreeRTOS, so sorry for the newbie questions :)
(Just 2 weeks with ESP32 & FreeRTOS)

Re: Example of using Queue to pass strings between tasks

Posted: Thu Sep 21, 2017 9:41 am
by ESP_Sprite
That is because events only have a limited, fixed size. I think the UART driver uses a ringbuffer as well for the incoming/outgoing data.

Re: Example of using Queue to pass strings between tasks

Posted: Thu Sep 21, 2017 1:32 pm
by kolban
I have used queues to pass strings around in some of my projects. What I do is allocate storage for the string (so that it is not on stack) and then add a pointer to the string into the queue. The reader of the queue then sees a new entry which is a pointer to the string, works with the string and then deletes the allocated storage. The queue elements then become fixed size ... which is of course the size of a memory pointer. The un-written contract then becomes that the storage pointed to by the item on the queue has to be deleted/freed by the consumer.

Re: Example of using Queue to pass strings between tasks

Posted: Thu Sep 21, 2017 4:03 pm
by sukeshak
kolban wrote:I have used queues to pass strings around in some of my projects. What I do is allocate storage for the string (so that it is not on stack) and then add a pointer to the string into the queue. The reader of the queue then sees a new entry which is a pointer to the string, works with the string and then deletes the allocated storage. The queue elements then become fixed size ... which is of course the size of a memory pointer. The un-written contract then becomes that the storage pointed to by the item on the queue has to be deleted/freed by the consumer.
Sounds good. Do you have any code samples for it I can check?

Re: Example of using Queue to pass strings between tasks

Posted: Thu Sep 21, 2017 5:14 pm
by sukeshak
So what I am trying to do is
TCP Socket server on a device (ESP32) emitting string data (not json now but maybe later) coming from different peripherals (3 for now).

Client is more like a wireless display in this scenario:
1. TCP Socket client on another ESP32 device
2. String of information comes through TCP socket
3. Add the string to queue
4. Get one string at a time from queue
5 . Process and display information on TFT

I found a nice sample here... but have not been able to make it work yet, so in the process of writing my own
https://github.com/finger563/esp32-wireless-display

Re: Example of using Queue to pass strings between tasks

Posted: Thu Sep 21, 2017 6:31 pm
by kolban
To create a queue, you would use xQueueCreate ... see http://www.freertos.org/a00116.html

The size parameter would be large enough to hold a pointer to a character string ... for example:

Code: Select all

sizeof(char *)
When you have a string to place on the queue:

Code: Select all

char *myData = "helloWorld";
you could then allocate enough storage for it and copy it in:

Code: Select all

char *myItem = malloc(strlen(myData)+1); 
strcpy(myItem, myData);
You could then push the item onto the queue using xQueueSendToBack() ... see http://www.freertos.org/xQueueSendToBack.html

for example,

Code: Select all

xQueueSendToBack(myQueue, &myItem, portMAX_DELAY);
When you wish to receive an item ...

Code: Select all

char *myReceivedItem;
xQueueReceive(myQueue, &myReceivedItem, portMAX_DELAY);
// Do something with received string and then delete it ...
free(myReceivedItem);
See: http://www.freertos.org/a00118.html

Re: Example of using Queue to pass strings between tasks

Posted: Thu Sep 21, 2017 9:11 pm
by sukeshak
Thank you so much Neil. Will try it out and come back :)

Re: Example of using Queue to pass strings between tasks

Posted: Sat Jun 09, 2018 1:13 pm
by sukeshak
In the interest of people who might be searching for a solution for same kind of requirements...

I ended up using Ring Buffer and the sample over here really helped.
Documentation has really improved.

https://esp-idf.readthedocs.io/en/lates ... ffercreate