xQueueReceive stops receiving?

tjohansen wrote on Wednesday, March 06, 2013:

Hi All

I have a TXTask, that uses a queue for receiving data to send. The queue is 5 deep.
2 other task can then send message to this task for transmission.
(And a lot of other tasks doing other stuff)

I had it running the night for testing. But at some point, the xQueueSend returned that the queue was full…

In the TXTask, I have a timeout on the xQueueReceive function, to maintain a watchdog. The task was still running, but the xQueueReceive never returned pdTRUE.

It is a bit difficult to debug, because stepping through the receiving function, a schedule will happen and I will debug some other code/callstack

Any idea what can be wrong with the receive function never get triggered?
How to debug the code without getting re-scheduled?
Could it be a stack overflow somewhere? (I have configCHECK_FOR_STACK_OVERFLOW defined to 1)

Thomas

davedoors wrote on Wednesday, March 06, 2013:

You could use FreeRTOS+Trace to see what is happening. Start a trace recording using a circular buffer, then stop the trace when xQueueSend() returns pdFALSE so you can see what happens immediately before that.

You could also post the code for your receive function here. Without seeing the code there are too many possibilities to go through. For example, it could simply be that a task that has a higher priority is stopping the receive task from ever running so the queue becomes full.

tjohansen wrote on Wednesday, March 06, 2013:

Hi

I will try using the FreeRTOs+Trace next time it happens…

I don’t think another task is stopping it from running.
The timeout on the xQueueReceive works fine, refreshing my watchdog. Also could debug the task, but pdTRUE never returned. Also configGENERATE_RUN_TIME_STATS say that no task a taking to much CPU time.

Receive code that stops receving

void ProtocolTXTask(void *pvParameters)
{
     PROTOCOL_TX sTXData;
     BYTE byRetries = 0;
     BYTE byTXTaskID = 0;
	
     // Create a queue for RX events...
     g_xProtocolTXEvent = xQueueCreate( 5, sizeof(PROTOCOL_TX) );
	
      if( g_xProtocolTXEvent == 0 )
      {
            return;
       }
	
        byTXTaskID = RegisterTaskToWatchdog(xProtocolTXHandle, 10);
	
	while(TRUE)
	{
	   if(pdTRUE == xQueueReceive (g_xProtocolTXEvent, &sTXData, 5000))
	   {
	        ProtocolGetLinkStates();
		
		// Media connected?
		if( bActiveConnection[sTXData.byMedia] )
		{
		   // Send the data
		   if(pdTRUE == (*pTXdata[sTXData.byMedia])(sTXData.ulTXBuffer, sTXData.nSize, sTXData.xTimeout,  
                                              sTXData.bRAW)) // Normal				
                   {
			sTXData.byState = 1;
			break;
		   }
		   else
                   {
		         sTXData.byState = 0;
		   }
                }
             }
            NotifyWatchdog(byTXTaskID);
        } // While(1)
}

Code that post to the g_xProtocolTXEvent queue (Called by different tasks)

BOOL ProtocolSendData(unsigned long ulTXData, int nTXSize, BYTE byMedia, portTickType xTimeOut, BOOL bRAW)
{
	PROTOCOL_TX sTXData;
	
	sTXData.nSize = nTXSize;
	sTXData.ulTXBuffer = (unsigned long)ulTXData; // Address of the TX data
	sTXData.xTimeout= xTimeOut;
	sTXData.bRAW = bRAW;
	sTXData.byMedia = byMedia;
	if(xQueueSend(g_xProtocolTXEvent, (void*)&sTXData, ( portTickType ) 10))
	{
		return TRUE;
	}
	
	return FALSE;
}

davedoors wrote on Wednesday, March 06, 2013:

if( g_xProtocolTXEvent == 0 )
{
return;
}

You must not exit a task like that.  Use vTaskDelete(NULL) instead of return;

Does PROTOCOL_TX  just contain the members shown being accessed in your ProtocolSendData() send function? If so then stack overflow is unlikely. You could set configCHECK_FOR_STACK_OVERFLOW to 2 to be a bit more secure, but I don’t think that is your problem.

Is ProtocolSendData() ever called from an interrupt? If so then you will need to use xQueueSendFromISR() version.

Which compiler are you using? The state viewer plug in available for Eclipse and IAR will show you how many items are in the queue. If there are items in the queue then you can step through the xQueueReceive() function to see why it thinks its empty.

Have you checked all the http://www.freertos.org/FAQHelp.html items?

tjohansen wrote on Wednesday, March 06, 2013:

Yes, PROTOCOL_TX only contains the data shown…
I have configCHECK_FOR_STACK_OVERFLOW to 1 without anything. I know the configCHECK_FOR_STACK_OVERFLOW works. been there :slight_smile:

ProtocolSendData() is never send called from a ISR. It can be called from 3 different tasks.

I’ usin KEIL MDK and I can see the the queue values. There are items in the queue.
I then step into the xQueueReceive(…) function, still with queue item at 5. The call stack also are correct.
Then after “taskENTER_CRITICAL” there was a task switch i guess. The call stack changed to a different part of my application (the call stack contained other functions that also uses xQueueReceive(…)) and the queue item was different as well.

I thin there was a contents switch during the debug steps. Maybe I can make the debugger disable all interrupts while stepping through code?

Thomas