Why Queue Send Would Time Out

Hi,
I’m using xQueueSendToBack and I wrapped up the current recommended error checking into a function. I don’t know why, but the code I have keeps failing the check:

if(xQueueSendToBack(xPointerToQueue, (void*) &msg, (TickType_t) 100u) != pdPASS)

Whereby “fail” means that the code will hit this branch statement and therefore I can’t retrieve my message. What are the reasons for this? What are things I should look for to keep this from happening? Many thanks in advance!

Data can’t be posted to a full queue. If the queue you are attempting to post to remains full for the entire timeout period, preventing anything else being written to it, then the task attempting to write to the queue will return fail.

Too much details - but if space because available on the queue then it is the highest priority task that is waiting to write to the queue that will succeed in writing to the queue.

As Richard said, likely the queue is full. Can you try increasing the reader task’s (the task that retrieves messages from the queue) priority?

Thank you both. I do have a seperate flag for if the queue overflows, which is not being thrown, so I’m assuming in this case that’s not the issue. For this piece, I’m starting simple. There are only 3 tasks, and one of them is just a heartbeat for the board. The other two are nested, one is called first from main which writes to the queue and itself in turn inits the reader task (if I understand the terms for that correctly where write enqueues and read dequeues the message, which I can always be wrong, please correct me if I am). No idea if that task structure makes any difference. On a seperate note, I would like to be sure I have it right that the higher the number the higher the task priority? Anyways, initially, these 2 tasks were given the same priority of 1. I’ve tried giving the reader task a priority of 2 and just in case I’m wrong, a priority of 0. No effect. Ideas? Again, many thanks in advance.

Can you share code snippets of these 2 tasks?

Okay, so, I was wrong. I created another flag, and my original problem was that the queue handle was a null pointer and my initialization function was passing by copy instead of by pointer. However, I have another problem. The queue seems to max out the second I add another button to the code (thus I have a problem past sending/receiving 1 message). Thought maybe same problem, passing by copy instead of by pointer except that doesn’t seem to make any difference in queue overflow whatsoever. I’ve never had this problem before what I’ve used the queue, so not exactly sure what is going on. I thought it removed the dequeued message, right or do I have that wrong? Anyways, not including the code to toggle the LED as it is pretty standard, working and not relevant, but including my code for the queue function library and the tasks, I have the following test code (I included the pointer version, the version by copy just lacks the extra *) that is a little messy and where the LEDs are being used to debug functionality, but hopefully illustrates what’s going on :

 //Snips from queue lib
 typedef enum {msgSUCCESS=0, msgFAIL=-1, msgOUTOFBOUNDS, 
 msgFAILTOOMUCHTIME, msgFAILNULLQUEUE} msgSuccess_t;

 msgSuccess_t myQueueEnqueueMsg(QueueHandle_t * xPointerTaskMsgQueue, 
 LED_msg_t msg)
 {
   //defaults to fail
   msgSuccess_t msgStatus = msgFAIL;
   //courtesy of FreeRTOS documentation
   if ((*xPointerTaskMsgQueue) !=0)
    {
 	     if (uxQueueMessagesWaiting((*xPointerTaskMsgQueue)) >= QUEUE_MAX)
	     {
		   return msgOUTOFBOUNDS;
	     }
	     if (xQueueSendToBack( (*xPointerTaskMsgQueue), (void *) &msg, (TickType_t) 1000u) != pdPASS)
	     {
		    msgStatus = msgFAILTOOMUCHTIME;
		    return msgStatus;
	     }
	     else
	     {
		    msgStatus = msgSUCCESS;
		     return msgStatus;
	     }
     }
     else
     {
	   msgStatus = msgFAILNULLQUEUE;
	    return msgStatus;
     }
   } 

 msgSuccess_t myQueueDequeueMsg(QueueHandle_t * xPointerTaskMsgQueue, 
 LED_msg_t * msg_ptr)
  {
//defaults to fail
msgSuccess_t msgStatus = msgFAIL;
if ((*xPointerTaskMsgQueue) !=0)
{
	if (uxQueueMessagesWaiting((*xPointerTaskMsgQueue)) > 0)
	{
		if (xQueueReceive( (*xPointerTaskMsgQueue), msg_ptr, (TickType_t) 10u) != pdPASS)
		{
			msgStatus = msgFAIL;
			return msgStatus;
		}
		else
		{
			msgStatus = msgSUCCESS;
			return msgStatus;
		}
	}
	else
	{
		msgStatus = msgOUTOFBOUNDS;
		return msgStatus;
	}
	
}
else
{
	msgStatus = msgFAIL;
	return msgStatus;
  }
 }

 //Snips from tasks
 void taskMainControl (void * pvParameters)
 {
      //variable for delay length, same as FreeRTOS documentation
      const TickType_t xDebounceDelay = 10 / portTICK_PERIOD_MS;
          //variable for delay length, same as FreeRTOS documentation
       const TickType_t xPollingDelay = 100 / portTICK_PERIOD_MS;
      xPointerTaskMsgQueue = NULL; 
          //IMPORTANT NOTE: xPointerTaskMsgQueue is a global-scoped variable 
          //declared in the header file
      LED_msg_t msgToSend;
          msgSuccess_t msg_success;

       myQueueInitMAXDeepLED(&xPointerTaskMsgQueue);

      TaskHandle_t xLedBlinkHandler = NULL;
      xTaskCreate(ledToggleRecieveMsgQueue,
     "Created Main Handler",
      configMINIMAL_STACK_SIZE,
      NULL,
       0, 
        &xLedBlinkHandler);

	while(1)
	{

		for(uint8_t i = 1; i < 4; i++)
		{
			//statement to see if button is active
			if(readButtonStatus(i) == 1) //1 just means 'true' here
			{
				uint8_t is_button_pressed = i;
				vTaskDelay(xDebounceDelay);
				if(readButtonStatus(is_button_pressed) == 1) //verify change before continuing
				{
					uint8_t button_pressed = is_button_pressed;
					
					//statement for button 1, create led blink tasks
					if(button_pressed == 1)
					{
						msgToSend = DECREASE;
						msg_success = myQueueEnqueueMsg(&xPointerTaskMsgQueue, msgToSend);
						if (msg_success == msgFAILTOOMUCHTIME)
						{
							ledToggleTaskHelper(500, 1);
						}
						if (msg_success == msgFAILNULLQUEUE)
						{
							ledToggleTaskHelper(500, 4);
						}
					} //end of if for button 1
					
					//handler for button 2 press
					else if (button_pressed == 2)
					{
						msgToSend = INCREASE;
						msg_success = myQueueEnqueueMsg(&xPointerTaskMsgQueue, msgToSend);
						if (msg_success == msgFAILTOOMUCHTIME)
						{
							ledToggleTaskHelper(500, 1);
						}
						if (msg_success == msgOUTOFBOUNDS)
						{
							ledToggleTaskHelper(500, 4);
						}
					} //end of if for button 2
					else {} //do-nothing default
				} //end of debounce
			} //end of button number check

			vTaskDelay(xPollingDelay); //delay for polling
			
		} //end of for loop for button poll	
	} //end of while loop for task

 } //end of task

  //second nested task 
    void ledToggleRecieveMsgQueue (void * pvParameters)
    {
           unsigned long int delayLength = 500;
           LED_msg_t msg;
	
       myQueueDequeueMsg(&xPointerTaskMsgQueue, &msg);

	if (msg == DECREASE && delayLength >= 200)
	{
		ledToggleTaskHelper (500, 2);
	}
	else if (msg == INCREASE && delayLength <= 1000)
	{
		ledToggleTaskHelper (500, 3);
	}
	else
	{
		
	}
	
    } //end of while
}

What do you mean by “max out”? Do you mean that the queue becomes full? If yes, how did you verify that?

I assume ledToggleRecieveMsgQueue is the task that receives messages from the queue. Please try increasing its priority.

When I do that, I don’t even get any of my debug led blinks. I get nothing. Same priority or a smaller number, I can get it to do something. Priority of the calling task (maincontrol) is 1 for context. The reason I know the queue is overflowing is that I have an enum msgSuccess_t that I have give the options of msgSuccess, msgFail, msgOutOfBounds, msgFailTooMuchTime, and msgFailNullQueue to. I have the check

if(uxQueueMessagesWaiting(uxPointerTaskMsgQueue) >= QueueMax)
return msgOutOfBounds;

Then in the main task, I have it toggle a different led if this returns compared to another. There are 4 LEDs on an external custom board I have to work with, so I just check the return value after the function finishes executing. I can get it to return msgSuccess for 1 button upon initial execution, after that it will overflow the queue. No clue why.

Dumb question, but how do tasks manage shared code? I removed the debug code, just added a check for if msg was success and the led message functions as expected. But… the debug code uses a function that was shared by the recieving task code. I think that was the problem, but I’m curious why and what are good ways to fix it in the future.

Each task runs separately. The problem might be shared data or other resources or calling functions which internally using shared resources like for instance printf using a UART.

Unless you share the exact piece of code, it is hard to say what is wrong with that and what is the correct fix. As @hs2 said, it may be accessing some shared data (such as global variables) from multiple tasks without protecting access to them.