Queues and pointers problem

Hi All!
I have problems with pointing data in queue.
I have got two task and one queue
intnertask communication based on the following structre:

typedef struct MesNode_
{
char* message;
size_t size;
} MesNode;

And I have some problems with receiving- I receive unknown strings which got from ram(but after the first right)

Shortly, the code:

#define configTOTAL_HEAP_SIZE                   ((size_t)102400)// ((size_t)98304)//
#define BUFFER_SIZE 4096// 11264 //2048
#define Middle_BUFFER_SIZE 1024


/* Definitions for thread1 */
osThreadId_t thread1;
const osThreadAttr_t uartM3gProc_attributes = {
  .name = "thread1",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};

/* Definitions for thread2 */
osThreadId_t thread2;
const osThreadAttr_t TCPProc_attributes = {
  .name = "thread2",
  .stack_size = 256 * 8,//4,//384 * 10,//8,//4,
  .priority = (osPriority_t) osPriorityHigh,//osPriorityNormal,
};

/* Definitions for logging */
osThreadId_t loggingHandle2;
const osThreadAttr_t logging2_attributes = {
  .name = "logging2",
  .stack_size = 256 * 16,
  .priority = (osPriority_t) osPriorityNormal,//,
};
void thread1(void *argument)
{

	for(;;)
{
 		if(req_enable >=2)
	 	 {
	 		 mss = msgNode->size;
	 		if(uxQueueSpacesAvailable(quMsgLogHandle)!=0)
		  	  {xQueueSendToBack(quMsgLogHandle, &msgNode, NULL);
	 		 vTaskResume(loggingHandle2);}
	 	 }

 osDelay(10);
}
}

void thread2(void *argument)
{

	for(;;)
{

	if(req_enable >=2)
	 {
		 if(uxQueueSpacesAvailable(quMsgLogHandle)!=0)
		 {
		 xQueueSendToBack(qu2, &msgNode, NULL);
		 vTaskResume(loggingHandle2);
		 }
	 }
 osDelay(10);



void startLogging2(void *argument)
{
	
	char CR[4] 	= {"\r\n"};
	
	 osMessageQueueId_t qu2 = quMsgLogHandle;//quTCPHandle;
	

	 FILINFO* fin;
	FRESULT res1;
	FSIZE_t	fz;
	UBaseType_t availb;
	portBASE_TYPE resq;
	
	for(;;)
	{

		

		MessageNode msgNode;

		
		while(uxQueueMessagesWaiting( qu2 )!= 0)
		{
		
			 resq = xQueueReceive(qu2, &msgNode, 100);//100 );//portMAX_DELAY);

			
		if(resq == pdPASS)
		{
			 	 	res1 = f_open(&fil, stringfln, FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
			 		fz = f_size(&fil);
			 		
			 			if( !(fz < (Max_fsize - BUFFER_SIZE)))

			 		{
			 			fnumber++;
			 			  snprintf(stringfln, sizeof(stringfln), "%s/%d.txt",dirname, fnumber);
			 			  res1 = f_open(&fil, stringfln, FA_OPEN_ALWAYS | FA_READ | FA_WRITE);

			 		}else
			 			snprintf(stringfln, sizeof(stringfln), "%s/%d.txt",dirname, fnumber);

			 			if(res1 == FR_OK)
			 			{
			 				
			 				f_lseek(&fil, f_size(&fil));
			 				f_puts(CR, &fil);
			 				f_lseek(&fil, f_size(&fil));
			 				
			 				res1 = f_write(&fil,msgNode.message,mss, NULL);
			 				
			 				mss = 0;
			 				f_close(&fil);
			 				
			 				asm("NOP");
			 				vTaskSuspend(NULL);
			 			}
			 			
 		 



		}



		}
	osDelay(10);
	}

}




}

}

And in debug I have got the following sequence of data:

Send thread1
mNode.message
Details:0x20002748 <ucHeap+1336> “string1”
Default:0x20002748 <ucHeap+1336> “string2”
Decimal:536880968
Hex:0x20002748
Binary:100000000000000010011101001000
Octal:04000023510

receive log thread
Name : mNode.message
Details:0x20005534 <ucHeap+13092> “unknownstring1”
Default:0x20005534 <ucHeap+13092> “unknownstring2”
Decimal:536892724
Hex:0x20005534
Binary:100000000000000101010100110100
Octal:04000052464

send thread1
Name : mNode.message
Details:0x20002780 <ucHeap+1392> “string3”
Default:0x20002780 <ucHeap+1392> “string4”
Decimal:536881024
Hex:0x20002780
Binary:100000000000000010011110000000
Octal:04000023600

send thread1
Name : mNode.message
Details:0x200027b8 <ucHeap+1448> “string5”
Default:0x200027b8 <ucHeap+1448> “string6”
Decimal:536881080
Hex:0x200027b8
Binary:100000000000000010011110111000

send thread1
Name : mNode.message
Details:0x20005600 <ucHeap+13296> “string7”…
Default:0x20005600 <ucHeap+13296> “string8”…
Decimal:536892928
Hex:0x20005600
Binary:100000000000000101011000000000
Octal:04000053000
send thread2
Name : mNode.message
Details:0x200027f0 <ucHeap+1504> “string9”
Default:0x200027f0 <ucHeap+1504> “string10”
Decimal:536881136
Hex:0x200027f0
Binary:100000000000000010011111110000
Octal:04000023760

Octal:04000023670

receive log thread
Name : mNode.message
Details:0x20005534 <ucHeap+13092> “unknownstring3”
Default:0x20005534 <ucHeap+13092> “unknownstring4”
Decimal:536892724
Hex:0x20005534
Binary:100000000000000101010100110100
Octal:04000052464

Please somebody explain in what the problem can be

Addi, I would first like to ask some questions:

I see a function startLogging2() defined within thread2()? Is there a closing bracket missing?

The variable msgNode is declared on stack, without being initialised? Can you show the code that fills the members .message and .size?

One remark: you probably don’t need to call vTaskSuspend() and vTaskResume(). When calling xQueueReceive(), the task already gets suspended for 100 clock-ticks, or it will be woken up as soon as there is a message.

PS. you can use pdMS_TO_TICKS( 100U ) if you want to be sure that 100 ms will be waited.

How do you create the handle ‘quMsgLogHandle’ ?

Thanks Hein for your replay!

Yes, you right about brackets
About filling buffer, here:

MessageNode make_msg(char* begin, char* end)
{
  MessageNode msgNode;
  msgNode.size = end - begin;
  msgNode.message = pvPortMalloc(msgNode.size + 1);
  memcpy(msgNode.message, begin, msgNode.size);
  msgNode.message[msgNode.size] = '\0';
  return msgNode;
}

Im trying to do the cirular buffer

That doesn’t look bad. Well except that you do not check the result of pvPortMalloc(). It might return NULL.
At this moment, I don’t know how to help you further, unless you share more code. If the code is private, you may send it to my email address, which is: hein [at] htibosch [dot] net

thank you very much!!!
About filling additional info:

MesNode msgNode = make_msg_circ(uartBuffer, startPosition, endPosition);
MesNode make_msg_circ(const char* buffer, const char* begin, const char* end)
{
  MesNode msgNode;
  msgNode.size = (end > begin) ? end - begin: BUFFER_SIZE - (begin - end);
  msgNode.message = pvPortMalloc(msgNode.size + 1);
  if (end > begin) {
    memcpy(msgNode.message, begin, msgNode.size);
  }
  else {
    size_t tailSize = buffer + BUFFER_SIZE - begin;
    size_t headSize = end - buffer;
    memcpy(msgNode.message, begin, tailSize);
    memcpy(msgNode.message + tailSize, buffer, headSize);
  }
  msgNode.message[msgNode.size] = '\0';
  return msgNode;
}

Hello Addi, I am not sure about all the consequences of your code. Have you already looked at the FreeRTOS Stream Buffers?

Unless you like to develop your own stream buffer of course! I also wrote a few versions in my life. I would recommend working with numeric indexes in stead of character pointers.

It looks like you are creating a UART driver? Now if there is only one sender and one receiver, a stream buffer is ideal. I don’t think that you also need a queue. You can have xStreamBufferReceive() block while waiting for new data.

Note that the UART interrupt should never block on xStreamBufferSend(). When the buffer is full, the extra data should be dropped.

Thank you for your support!
Unfortunally I based on exist project which was wrote by another engeener
And cause of that Ive got declared above message structure and queues
In my next project im going to use now stream buffers, Thanks!

Maybe you can help , is it necessary to use malloc for message, based on pointer, which is goiung to be stored in queue?

@addi wrote:

is it necessary to use malloc for message, based on pointer, which is going to be stored in queue?

Both can be done. Here below you see two examples:

  1. Create a queue big enough to contain N objects.
  2. Create a queue to contain N pointers to objects.
#define BYTE_COUNT      100
#define QUEUE_LENGTH      4

typedef struct
{
    uint8_t ucBytes[ BYTE_COUNT ];
}
MyMessage_t;


/*-----------------------------------------------------------*/

QueueHandle_t xQueue1, xQueue2;

void init1( void )
{
    /* Create a queue that can hold at most 4 objects
     * of the type "MyMessage_t".
     * At least 4 x 100 bytes will be reserved. */
    xQueue1 = xQueueCreate( QUEUE_LENGTH, sizeof( MyMessage_t ) );
}

void init2( void )
{
    /* Create a queue that holds at most 4 pointers to a "MyMessage_t". */
    xQueue2 = xQueueCreate( QUEUE_LENGTH, sizeof( MyMessage_t * ) );
}
/*-----------------------------------------------------------*/

void send_function1( void )
{
    MyMessage_t xMessage;
    BaseType_t xIndex;
    for( xIndex = 0; xIndex < BYTE_COUNT; xIndex++ )
    {
        xMessage.ucBytes[ xIndex ] = xIndex;
    }

    /* Here an automatic variable is passed, it sits temporarily
     * the stack.
     * However, the contents ( 100 bytes ) is copied to the queue,
     * so there is no problem. */
    xQueueSend( xQueue1, &( xMessage ), 0U );
}

void send_function2( void )
{
    MyMessage_t * pxMessage = ( MyMessage_t * ) pvPortMalloc( sizeof ( MyMessage_t ) );

    if( pxMessage != NULL )
    {
        BaseType_t xIndex;
        for( xIndex = 0; xIndex < BYTE_COUNT; xIndex++ )
        {
            pxMessage->ucBytes[ xIndex ] = xIndex;
        }

        /* Here the value of a pointer is copied to the queue.
         * The object exists sits in the heap.
         * The receiver will be responsible for freeing the memory.
         */
        xQueueSend( xQueue2, &( pxMessage ), 0U );
    }
}
/*-----------------------------------------------------------*/

/* Receive an object: */
void receive_function1( void )
{
    MyMessage_t xMessage;
    if( xQueueReceive( xQueue, &( xMessage ), pdMS_TO_TICKS( 1000U ) ) == pdPASS )
    {
        /* The object has been copied to 'xMessage'.
         * No need to free it. */
    }
}

/* Receive a pointer to an object: */
void receive_function2( void )
{
    MyMessage_t * pxMessage;
    if( xQueueReceive( xQueue, &( pxMessage ), pdMS_TO_TICKS( 1000U ) ) == pdPASS )
    {
        /* Use the object and free it. */
        vPortFree( pxMessage );
    }
}
/*-----------------------------------------------------------*/

Personally I like to pass pointers to objects. These objects my be created by malloc(), or they may be declared in a static array.