FreeRTOS task stack overflow issue

1.9k views Asked by At

I am using a freertos port of microblaze and I have some simple code that blinks a light in a task and I am getting a "Task overflowed its stack call". Note the error message doesnt actually print out the task name, but considering I only have one task I think there may be a problem there.

I do also have a uart interrupt firing everytime a character is received as well, but that works well. In the linker script I attached I increased the stack and heap size to be quite large and I am still running into this problem. If I disable the main_task I dont get a stack overflow, which means its something to do with the task possibly? I should also say it works normally but if I keep hitting enter in the uart which will be issuing interrupts I eventually get this error.

Any help would be really helpful as I am at my wits end here. Thanks in advance.

void
main_task()
{
   int counter = 0;
   while( 1 )
   {
      if ( (counter++%2) == 0 )
      {
         *(volatile unsigned int*)0x40000000 &= ~0x1;
      }
      else
      {
         *(volatile unsigned int*)0x40000000 |= 0x1;
      }
      vTaskDelay(200);
   }
}

int main()
{
   xTaskCreate( (void(*)(void*)) main_task, "main_task", 4096, NULL, 3, &xCreatedTask );
   vTaskStartScheduler();
}

This is the linker script I am using:

STARTUP(crt0.o)
ENTRY(_start)

_STACK_SIZE = 0x4000;
_HEAP_SIZE = 0x4000;

MEMORY
{
   mig_7series_0 : ORIGIN = 0x80000000, LENGTH = 0x10000000
}

SECTIONS
{
.vectors.reset 0x0 : {
   KEEP (*(.vectors.reset))
} 

.vectors.sw_exception 0x8 : {
   KEEP (*(.vectors.sw_exception))
} 

.vectors.interrupt 0x10 : {
   KEEP (*(.vectors.interrupt))
} 

.vectors.hw_exception 0x20 : {
   KEEP (*(.vectors.hw_exception))
} 

.text : {
   *(.text)
   *(.text.*)
   *(.gnu.linkonce.t.*)
} > mig_7series_0

.rodata : {
   __rodata_start = .;
   *(.rodata)
   *(.rodata.*)
   *(.gnu.linkonce.r.*)
   __rodata_end = .;
} > mig_7series_0

.sdata2 : {
   . = ALIGN(8);
   __sdata2_start = .;
   *(.sdata2)
   *(.sdata2.*)
   *(.gnu.linkonce.s2.*)
   . = ALIGN(8);
   __sdata2_end = .;
} > mig_7series_0

.sbss2 : {
   __sbss2_start = .;
   *(.sbss2)
   *(.sbss2.*)
   *(.gnu.linkonce.sb2.*)
   __sbss2_end = .;
} > mig_7series_0

.data : {
   . = ALIGN(4);
   __data_start = .;
   *(.data)
   *(.data.*)
   *(.gnu.linkonce.d.*)
   __data_end = .;
} > mig_7series_0

.sdata : {
   . = ALIGN(8);
   __sdata_start = .;
   *(.sdata)
   *(.sdata.*)
   *(.gnu.linkonce.s.*)
   __sdata_end = .;
} > mig_7series_0

.sbss (NOLOAD) : {
   . = ALIGN(4);
   __sbss_start = .;
   *(.sbss)
   *(.sbss.*)
   *(.gnu.linkonce.sb.*)
   . = ALIGN(8);
   __sbss_end = .;
} > mig_7series_0

.tdata : {
   __tdata_start = .;
   *(.tdata)
   *(.tdata.*)
   *(.gnu.linkonce.td.*)
   __tdata_end = .;
} > mig_7series_0

.tbss : {
   __tbss_start = .;
   *(.tbss)
   *(.tbss.*)
   *(.gnu.linkonce.tb.*)
   __tbss_end = .;
} > mig_7series_0

.bss (NOLOAD) : {
   . = ALIGN(4);
   __bss_start = .;
   *(.bss)
   *(.bss.*)
   *(.gnu.linkonce.b.*)
   *(COMMON)
   . = ALIGN(4);
   __bss_end = .;
} > mig_7series_0

_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );

_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );

/* Generate Stack and Heap definitions */

.heap (NOLOAD) : {
   . = ALIGN(8);
   _heap = .;
   _heap_start = .;
   . += _HEAP_SIZE;
   _heap_end = .;
} > mig_7series_0

.stack (NOLOAD) : {
   _stack_end = .;
   . += _STACK_SIZE;
   . = ALIGN(8);
   _stack = .;
   __stack = _stack;
} > mig_7series_0

_end = .;
}
1

There are 1 answers

1
Richard On

Do you have configCHECK_FOR_STACK_OVERFLOW set to 1 or 2? If 2 then the stack overflow checking works by inspecting the end of the task stack to see if a pattern that was written there when the task was created has been overwritten. Therefore it is possible that its not actually the stack of the task overwriting that memory, but that something else is corrupting that memory by writing over it. The problem you describe with the uart interrupt under heavy load (holding down a key) might be a clue to there being a problem in the interrupt service routine.

Do you have configASSERT() defined?