Task's State is "eReady", but idle task is running instead

fraza077 wrote on Tuesday, November 12, 2013:

Microcontroller: PSoC 5LP
Compiler: ARM GCC 4.7.3
FreeRTOS version: FreeRTOS V7.5.2

I’ve used FreeRTOS successfully on this architecture for a while now, but I’ve run into this problem with queues.

I have a queue, set up by

   MainRxQueue = xQueueCreate(configMAIN_RX_QUEUE_LENGTH, 1); // where configMAIN_RX_QUEUE_LENGTH is 600

My main task is the only task that reads from this queue, and the only thing that writes to it is the UART ISR. The queue is not protected by a mutex.

The call from the ISR:


The Task takes the characters off the queue here:

		// receive remaining characters from queue
		if (xQueueReceive(MainRxQueue, &singleChar, 500/portTICK_RATE_MS) == pdFAIL)
			text[cnt] = 0;
			return FALSE;

This usually always works fine for a while (data received and processed), then it doesn’t return from xQueueReceive (my interpretation of test_var[0] being 1 greater than test_var[1] and test_var[8] being 0). I can’t work out what the trigger is.

So basically my code mostly sits in the idle task. Other tasks are still running fine. From the idle task, I run this code:

		mystate = eTaskGetState(Main_ReturnTaskHandle());
		myprio = uxTaskPriorityGet(Main_ReturnTaskHandle());

The state after this non-return error is always eReady. The priority is still 2.

I’ve ruled out:
– The queue being full or empty – I’ve observed the xQUEUE variable and it’s neither
– The queue handle being corrupted – it has the same value it has had since creation

There doesn’t seem to be any pattern to when it happens. Sometimes it happens the first few packets I send, sometimes it doesn’t happen at all.

rtel wrote on Wednesday, November 13, 2013:

The queue is not protected by a mutex.

There is no need to protect a queue with a mutex - all the protection is internal to the queue. Queues are completely thread aware.

The first thing to note is generally, unless using very low throughput (for example, using the UART for keyboard IO), it is not a good idea to use a queue to send individual characters from an interrupt to a task. A lot of the demo applications do this, but that is as a simple method of showing queues being used from interrupts, and to also stress test the kernel. A better strategy is to use the hardware to buffer characters using a DMA, if the hardware supports that, or an interrupt to simply transfer groups of characters to a circular buffer - with a single semaphore give being used to unblock a task when either there are multiple characters to process, a complete message has been received, or there is a break in reception.

That said - while doing what you are doing might result in a high processing overhead, and may result in characters being missed, it should not result in error erroneous conditions in the kernel itself. So it doesn’t explain what you are seeing.

In diagnosing your problem I have to start with the basics I’m afraid, although you sound like an experienced user…so

Are you using the latest version of FreeRTOS with configASSERT() defined? http://www.freertos.org/a00110.html#configASSERT The latest version has a few extra configASSERT()s included specifically to catch the most common problems on Cortex-M devices.

I cannot see anything obviously wrong in the code you have posted. Do you also have other code in your system? If so, does the problem still arise when all the other code is removed to leave just the interrupt sending to the queue and the task receiving from the queue? Also, if there is other code, does it comply with the requirements on the following FAQ? http://www.freertos.org/FAQHelp.html

Are you using Eclipse? If so, does the StateViewer plug-in provided by WITTENSTEIN function? If so, please add your queue to the queue registry http://www.freertos.org/vQueueAddToRegistry.html run the application until the issue occurs, then take a screen shot of the environment with the queue and task tables visible. Post the screen shot here.


rtel wrote on Wednesday, November 13, 2013:

Sorry - just noticed you already posted you were using V7.5.2. Please try with V7.5.3, although it is doubtful it would make a difference if you are using xHigherPriorityTaskWoken to context switch from the interrupt.


fraza077 wrote on Wednesday, November 13, 2013:

Thanks for your help Richard.

At one point, changing something in another task (in this case, enabling printing to UART from this other task) stopped the error occurring, which made me suspect it was some sort of error leak that occurred depending on where the linker placed certain bits of memory.

I’ve previously already looked at the resources you linked, but I decided to go through each one again and check my code conformed. In checking the priority of interrupts that use the FreeRTOS API, I noticed that I had incorrectly read the configured configKERNEL_INTERRUPT_PRIORITY as 5, and configMAX_SYSCALL_INTERRUPT_PRIORITY as 3, when in fact they were 7 and 5. I changed my interrupt priorities accordingly, and the issue has ceased.

Do you think that this was the issue? I’m slightly suspicious that it may not have been the underlying cause, and a memory leak was still to blame, but it does seem to fit reasonably well.

I’ve read over interrupt priority documentation again and gained some more understanding of how it works.

Thanks for your help. Thanks also for the suggestion on a more efficient UART input method, I’ll try to implement that.



rtel wrote on Wednesday, November 13, 2013:

Yes, I think it is likely that was the cause of your problem, but not definitely as naturally I don’t know the ins and outs of your application.

Interrupts on Cortex-M are definitely not ‘intuitive’ - which is why in the latest versions we have added more traps with asserts() to try and automate catching some of these things.