Queue item size

yevpator75 wrote on Sunday, December 23, 2018:


Just started evaluating FreeRTOS. Sorry if I ask beginners’ questions (-:
I created a queue with the static allocation:

osMessageQId                    g_somHciTaskQueueHandle;
uint8_t                         g_somHciTaskQueueBuffer[ 16 * 20 ];
osStaticMessageQDef_t           g_somHciTaskQueueControlBlock;

 osMessageQStaticDef(g_somHciTaskQueue, 16, 20, g_somHciTaskQueueBuffer, &g_somHciTaskQueueControlBlock);
  g_somHciTaskQueueHandle = osMessageCreate(osMessageQ(g_somHciTaskQueue), NULL);

Then I wanted to send a buffer with 10 numbers [1…10] from a task A to task B. The size of the queue item as I defined above is 10 bytes, but in the receiver task I actually receive only 4 bytes istead of 10 bytes I expected to get. Where is my mistake ?

Here is the sender task:

void StartDefaultTask(void const * argument)

  static uint8_t stamBuff[10] = {1,2,3,4,5,6,7,8,9,10};

		xStatus = xQueueSendToBack (g_somHciTaskQueueHandle,
		if( xStatus != pdPASS )
			for (uint32_t t = 5; t; t--); // just for breakpoint.


Here is the receiver task:

void somHciTask(void const * argument)
  	static uint8_t xMessage[10];

	for( ;; )
		xStatus = xQueueReceive (g_somHciTaskQueueHandle,

		if (xStatus != pdPASS)
			/* Nothing was received from the queue – even after blocking to wait
			for data to arrive. */
			for (uint32_t t = 5; t; t--); // FOR BREAKPOINT

Thank you !

richarddamon wrote on Sunday, December 23, 2018:

There are two parameters needed to create a queue, the size of an element, and the number of elements stored in the queue. Looking up the function you are using (which is a wrapper over FreeRTOS, not provided by FreeRTOS), the macro you are using to define the queue takes as the 3rd argument, the TYPE of the item being put on the queue, and it computes the size of the element using the C sizeof operator. You have passed the value 20 as the type (which doesn’t really make sense), so when it find the size, it does sizeof(20) and gets 4, the size of an int, which is the type of the literal 20.

If you want to be passing arrays of 10 uint8_t’s, then I think you want that parameter to be uint8_t[10]

yevpator75 wrote on Monday, December 24, 2018:

Thank you very much for the help!

yevpator75 wrote on Wednesday, December 26, 2018:

richarddamon wrote on Wednesday, December 26, 2018:

I see you made a comment and deleted it. Just a quick note of what I saw in the message, be careful of queue built with sizeof(struck xx *) as you need to pass a pointer to the pointer to the Send and Receive routines (and since they take void * paramters, sending just the pointer won’t create an error. Also, just the pointer is copied into the queue, and not the contents of the structure, so the sending task needs to make sure the sturcture maintains value until the receiver is done.

yevpator75 wrote on Wednesday, December 26, 2018:

yes, i did delete the message, because during the writing i detected the bug. I did not find a way to delete the message complely, but only the body. I wanted to prevent you and others wasting your time on considering the problem that was already solved. The bug was wrong sizeof.

so the sending task needs to make sure the sturcture maintains value until the receiver is done.
This is something I am thinking right now. I am going to send data to queue from DMA ISR. It will handle 8 UART (!!!), most of them full duplex. The data troughput will be very high so I need to process data very fast and therefore i want to prevent copying data to queue and instead to queue pointers. I am going to have a queue that DMA will use to write data from UART. I think if I have a “data queue” for DMA with a big enough length, then i will ensure that until the queue wraps around, the task that gets a pointer to a queue item will have enough time to handle the data before it gets corrupted. HOWEVER, I think still it would be a good idea to cover the scenaro you pointed out at. Actually this is a classic Producer-Consumer problem with a single producer and a single customer and can be solved for example using 2 counting semaphores.

Thank you very much for your help !

Value “uint8_t[10]” cannot be entered via STM32CubeIDE.
Of course you can do it directly in your code.
Only this will be removed when generating a new code from IDE :frowning: