Stream buffers vs message queues

Clarifying the concepts regarding message buffers and queues.

According to this response, queues are used when there are multiple readers/writers and when you want to send a fixed-sized buffer, whereas, with stream buffers, there has to be a single reader/writer unless you use mutexes and the size of the data passed doesn’t always have to be the same.

Are these points really what set each other apart? What really makes a queue not accommodate variable-sized data? Looks like queues use linked list as an underlying data structure and stream buffers dynamic arrays. Is there a high level visual for each data structure that helps understand better?

I have a “main task” that basically will have some sort of a data structure used to receive stuff from multiple other tasks, and the main task parses it, and executes functionality accordingly.

A Queue will always copy in and out a fixed sized block of data. To handle variable sized chunks, either you need to make multiple calls to send the full buffer (and a mutex to make sure no one else inserts something into the middle of the sequence) or you send a pointer (which is a fixed size).

StreamBuffers can sort of be thought as a Queue of bytes that add the ability to send/receive multiple bytes at once with a count, and the stream buffer will allow for a partial transfer. The single sender/single receiver limitation is added to allow it to be much more light weight, you can add a Mutex to get around this, or just use a regular Queue.

MessageBuffers use most of the same code as StreamBuffers, but automatically add a ‘MessageLength’ to the message, and disables the ability to send a partial message.

you send a pointer (which is a fixed size).

…which is possible by setting the uxItemSize parameter of xQueueCreate to whatever the size of the pointer on the said platform is (on cortex M4, it’s 32 bits so 4 bytes)?

Is the underlying data structure of queues and stream buffers the same though?

Also, I can’t seem to find configSUPPORT_DYNAMIC_ALLOCATION inside FreeRTOSConfig.h. At the top of the file, it says

/*
 * FreeRTOS Kernel V10.0.0
 * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.

For FreeRTOSConfig.h, that is a user created file, so you add whatever definitions you want to it.

The data structures for Queues and StreamBuffers are similar. The actual data-storage part is basically just an array to hold the bytes, and variables keeping track of the current read and write pointers. Queue have a more complicated data structure to handle things needed for the multiple readers and writers, so it can build up a list of task blocked on it. StreamBuffers don’t need that as they can have only a single reader and writer (which makes them more efficient for that case). Queue also need to keep track of their block size, which is always 1 from a StreamBuffer.

I added #define configSUPPORT_DYNAMIC_ALLOCATION 1 in FreeRTOSConfig.h but the second line still remains “highlighted” and I can’t call xQueueCreate()
as shown here

I would first double check that you don’t have two versions of FreeRTOSConfig.h in your project/include path.

Note also, that by default, configSUPPORT_DYNAMIC_ALLOCATION is set to 1 if it doesn’t appear in the file.

Sometimes I will put something that is an intentional error, or a #error directive to make sure that I am in the file that is being used.

Yes, but even if configSUPPORT_DYNAMIC_ALLOCATION is by default set to 1, how come it’s not being recognized in queue.h to enable the usage of xQueueCreate()?

Also I notice that queue.h doesn’t include FreeRTOS.h, rather the source file does it. How does the file know what’s inside FreeRTOSConfig.h?

If you just use xQueueCreate in your code does it compile ?
Or do you mean not recognized by the IDE ? That’s a question for the IDE provider.
However, the IDE usually parses the code on it’s own. If it doesn’t parse FreeRTOS.h (correctly) in the provided FreeRTOS include directory it can’t know the final set of defines and macros.

The build does recognize FreeRTOSConfig.h (added some garbage values and it errored out). Regardless, the default value is set to 1 so I don’t see why the #define xQueueCreate() would be “greyed out”. Calling xQueueCreate errors out yes.

#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) )
#endif

In your application code where using FreeRTOS API you need to include FreeRTOS.h first. It includes FreeRTOSConfig.h internally.

I am already including FreeRTOS.h inside the header file

If the includes and definitions are correct the build should work as in any other FreeRTOS application out there. Maybe verify a demo application as reference how it’s done.
Sometimes it was reported that people had to struggle with an other (2nd) FreeRTOSConfig.h hanging around somewhere which was included unexpectedly.
Temporarily patching some #warning or #error directives into the files would help to track the the correct include files and hierarchy and also the definitions.

Does it matter which FreeRTOSConfig.h is included given configSUPPORT_DYNAMIC_ALLOCATION is enabled by default?

If one of your FreeRTOSConfig.h set it to 0 … yes. Do yourself a favor and use a single configuration.