FreeRTOS hangs in prvIdleTask

dsorrent10 wrote on Wednesday, November 16, 2011:

Hi,

I am running 3 tasks (including the idle task) in an 32-bit ATMEL UC3A.
After startup and under normal operation the picture is as follows:

Task A (priority 2): Switching from Running to Delayed. That is: running for a while, then waiting on a vTaskDelay()
Task B (priority 3): Blocked on a semaphore take
Idle task (priority 0)

I also have some event handlers (interrupts) running at the same priority as the RTOS tick (0) that do not interact with the kernel.

My application runs for a while and then hangs. If I break in with the debugger the picture is the following:

- Execution is at the Idle Task (for ever)
- Task A is in the DelayedTaskList1. Which makes sense in that the tick counter is less than the task wake up time
- vTick is not called anymore (which explains why the tick counter does not increment and Task A is switched back in)

Digging further into the CPU registers I noticed that, in this ‘hanged’ state, the idle task is running from an interrupt!  (According to the CPU status register the execution mode is ‘Interrupt Level 0’  and interrupts in this level are masked). The latter masks my timer interrupts causing the tick not to interrupt ever again effectively hanging the system.

Something exotic about this issue is that when I check where the tick counter froze and when Task A should have came out from the delayed tasks list the difference is always 20 ticks while the absolute counts vary quite a bit.

The problem seems to be somewhere in the context switching but I cannot tell where. I enabled the stack overflow detection with no results (no overflows).

I increased the idle task stack size from 256 to 512 and that only helped extending the running time until it hanged again. Maybe that is a clue.

How can the idle task end up running in INT_0 mode? Is the RTOS messing up the context switching?  What does the 20 tick difference mean? Anybody has a clue?

Thanks!
Diego

davedoors wrote on Thursday, November 17, 2011:

Where did you get the RTOS code from? The one in the FeeRTOS download supports the older ES AVR32 parts. Atmel have their own version for the newer parts in their Atmel software framework.

dsorrent10 wrote on Thursday, November 17, 2011:

Hi davedoors,

I started with v7.0.1 downloaded directly from the FreeRTOS site but with “exception.S” replaced with “exception.x” from the ATMEL SWF 1.7.0. The ‘exception.S’ provided by FreeRTOS just does not compile as it contain invalid references (now that you mentioned it, it is possible those are just old references, ex. ‘AVR32_INTC_IPR0_INTLEV_OFFSET’).

So, I then rolled back to v7.0.0 that comes in the ATMEL ASF 2.0 (including the ASF 2.0 exception.S that I had renamed to exception.x and added the ‘ipr_val’ definition as in exception.x from INTC driver  to make it work). The problem persisted.

Something I haven’t mentioned in the issue description is that before getting hanged at the idle task it was hanging at an “Instruction Address (alignment) Exception”. After disabling size optimization on the FreeRTOS files that exception went away.

Now, I am looking at the “old” exception.S provided with the latest FreeRTOS release and if has a portion of code that has no equivalent in the ATMEL provided exception.S that reads:

#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
  mfsr    r12, AVR32_SR
  bfextu  r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
  cp.w    r12, 0b110
  brlo    _int0_normal
  lddsp   r12, sp[0 * 4]
  stdsp   sp[6 * 4], r12
  lddsp   r12, sp[1 * 4]
  stdsp   sp[7 * 4], r12
  lddsp   r12, sp[3 * 4]
  sub     sp, -6 * 4
  rete
_int0_normal:
#endif
...normal interrupt code follows

wondering if not having this code in place is masking another problem that may not have completely gone by disabling optimization.

I am now trying to match the compile options used in the FreeRTOS example with the ones in my project.

Thanks!
Diego