Interrupts with FreeRTOS task causing task overflow

I am getting quite confused with this problem and not too sure why I am running into it. I am getting an error from FreeRTOS that states: HALT: Task overflowed its stack. Note that there is no task name being printed out here. If I dont fire the uart interrupts everything in the task works fine. When I begin entering in characters on the uart, eventually after a random time of entering in commands I get this message coming up. I have increased the stack and heap sizes to be more than 16K and still encounter this problem in pretty much random times. (Its not taking longer to show the problem) I am using fastinterrupts for the uart for the microblaze port. But I dont believe that the interrupts are the issue as I am able to fire them and print to hyperterminal just fine, without the task being executed. When I disable the maintask which is simply toggling a LED with characters being entered I get a stack overflow. I have attached what the task is doing below: ~~~ 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)) maintask, “maintask”, 4096, NULL, 3, &xCreatedTask ); vTaskStartScheduler(); } ~~~ The linker script is below: ~~~ STARTUP(crt0.o) ENTRY(_start) STACKSIZE = 0x4000; HEAPSIZE = 0x4000; MEMORY { mig7series0 : ORIGIN = 0x80000000, LENGTH = 0x10000000 } SECTIONS { .vectors.reset 0x0 : { KEEP (*(.vectors.reset)) } .vectors.swexception 0x8 : { KEEP (*(.vectors.swexception)) } .vectors.interrupt 0x10 : { KEEP (*(.vectors.interrupt)) } .vectors.hwexception 0x20 : { KEEP (*(.vectors.hwexception)) } .text : { (.text) *(.text.) (.gnu.linkonce.t.) } > mig7series0 .rodata : { __rodatastart = .; *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) __rodataend = .; } > mig7series0 .sdata2 : { . = ALIGN(8); __sdata2start = .; *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) . = ALIGN(8); __sdata2end = .; } > mig7series0 .sbss2 : { __sbss2start = .; *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) __sbss2end = .; } > mig7series0 .data : { . = ALIGN(4); __datastart = .; *(.data) *(.data.*) *(.gnu.linkonce.d.*) __dataend = .; } > mig7series0 .sdata : { . = ALIGN(8); __sdatastart = .; *(.sdata) *(.sdata.*) *(.gnu.linkonce.s.*) __sdataend = .; } > mig7series0 .sbss (NOLOAD) : { . = ALIGN(4); __sbssstart = .; *(.sbss) *(.sbss.*) *(.gnu.linkonce.sb.*) . = ALIGN(8); __sbssend = .; } > mig7series0 .tdata : { __tdatastart = .; *(.tdata) *(.tdata.*) *(.gnu.linkonce.td.*) __tdataend = .; } > mig7series0 .tbss : { __tbssstart = .; *(.tbss) *(.tbss.*) *(.gnu.linkonce.tb.*) __tbssend = .; } > mig7series0 .bss (NOLOAD) : { . = ALIGN(4); __bssstart = .; *(.bss) *(.bss.*) *(.gnu.linkonce.b.*) *(COMMON) . = ALIGN(4); __bssend = .; } > mig7series0 SDABASE_ = sdata_start + ((sbss_end – __sdata_start) / 2 ); SDA2BASE_ = sdata2_start + ((sbss2_end – __sdata2_start) / 2 ); /* Generate Stack and Heap definitions */ .heap (NOLOAD) : { . = ALIGN(8); heap = .; _heapstart = .; . += HEAPSIZE; heapend = .; } > mig7series0 .stack (NOLOAD) : { stackend = .; . += STACKSIZE; . = ALIGN(8); _stack = .; __stack = _stack; } > mig_7series_0 _end = .; } ~~~

Interrupts with FreeRTOS task causing task overflow

It sounds like there could be something in the ISR that is stomping over the task’s stack. Assuming you have configCHECKFORSTACK_OVERFLOW set to 2 then the stack overflow will be noted if anything writes over the end of the task stack. Normally that memory will get written too because the task stack has grown too large, but it could be anything that writes to that memory.

Interrupts with FreeRTOS task causing task overflow

I do have the configCHECKFORSTACK_OVERFLOW set to 2. I removed all code in the UART ISR, which I defined as a fast_interrupt. But still getting this. I then moved stack to the blockram, completely away from all other code and still getting the same error… Not sure why this is happening. Will continue debugging, if there is any other suggestions they would be most welcome!

Interrupts with FreeRTOS task causing task overflow

I used cscope on the entire v9.0.0 source and demo examples and could not find your message: “HALT: Task overflowed its stack” I had a problem with my tasks being setup with a diiferent stack size than the define for configMINIMALSTACKSIZE variable. The code below helped me find it:
void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCHAR *pcTaskName)
{
    LCD_Write_Cmd(LCD_DISPLAY_CLEAR_CMD);
    LCD_Write_String_Addr((int8_t *)"Stack overflow", LCD_ROW0);
        sprintf((char *)buf1, "Time: %02u:%02u:%02u", (unsigned int)hours, (unsigned int)minutes, (unsigned int)seconds);
    LCD_Write_String_Addr(buf1, LCD_ROW1);
    sprintf((char *)buf2, "TaskHandle:%08x", (int)pxTask);
    LCD_Write_String_Addr(buf2, LCD_ROW2);
    sprintf((char *)buf3, "Task:%s", pcTaskName);
    LCD_Write_String_Addr(buf3, LCD_ROW3);
    while(1);
}
I wrote this to display the registers on unexpected exceptions. I do not use the standard library sprintf. The LCD is a small 4 line (20 character/per line).
int8_t buf0[LCD_CHAR_PER_LINE + 1];
int8_t buf1[LCD_CHAR_PER_LINE + 1];
int8_t buf2[LCD_CHAR_PER_LINE + 1];
int8_t buf3[LCD_CHAR_PER_LINE + 1];

#define R0   0
#define R1   1
#define R2   2
#define R3   3
#define R4   4
#define R5   5
#define R6   6
#define R7   7
#define R8   8
#define R9   9
#define R10 10 
#define R11 11 
#define R12 12 
#define R13 13 
#define R14 14 

int reg[60];
int exception_spsr;

/* 
 * Note:
 * Peripheral interrupt service routines should first clear the peripheral
 * interrupt flag followed by the VIC interrupt flag.
 */

void irq_display(uint8_t irq_code, uint8_t *irq_title_msg)
{
while (1)
{
    /* Display Exception Message */
    LCD_Write_Cmd(LCD_DISPLAY_CLEAR_CMD);
    LCD_Write_String_Addr((int8_t *)irq_title_msg, LCD_ROW0);
    sprintf((char *)buf1, "Time: %02u:%02u:%02u", (unsigned int)hours,
                                                   (unsigned int)minutes,
                                                   (unsigned int)seconds);
    LCD_Write_String_Addr(buf1, LCD_ROW1);
    delay_msec(2000);    
    LCD_Write_Cmd(LCD_DISPLAY_CLEAR_CMD);

    /* Display Registers R0 - R3 */
    sprintf((char *)buf0, "R0 :%08x  ", reg[R0]);
    LCD_Write_String_Addr(buf0, LCD_ROW0);

    sprintf((char *)buf1, "R1 :%08x  ", reg[R1]);
    LCD_Write_String_Addr(buf1, LCD_ROW1);

    sprintf((char *)buf2, "R2 :%08x  ", reg[R2]);
    LCD_Write_String_Addr(buf2, LCD_ROW2);

    sprintf((char *)buf3, "R3 :%08x  ", reg[R3]);
    LCD_Write_String_Addr(buf3, LCD_ROW3);

    LED_Blink_Delay(irq_code, 2500);

    /* Display Registers R4 - R7 */
   LCD_Write_String_Addr(buf3, LCD_ROW3);

    LED_Blink_Delay(irq_code, 2500);

    /* Display Registers R8 - R11 */
    sprintf((char *)buf0, "R8 :%08x  ", reg[R8]);
    LCD_Write_String_Addr(buf0, LCD_ROW0);

    sprintf((char *)buf1, "R9 :%08x  ", reg[R9]);
    LCD_Write_String_Addr(buf1, LCD_ROW1);

    sprintf((char *)buf2, "R10:%08x  ", reg[R10]);
    LCD_Write_String_Addr(buf2, LCD_ROW2);

    sprintf((char *)buf3, "R11:%08x  ", reg[R11]);
    LCD_Write_String_Addr(buf3, LCD_ROW3);

    LED_Blink_Delay(irq_code, 2500);

    /* Display Registers R12 - R14, SPSR */
    sprintf((char *)buf0, "R12:%08x  ", reg[R12]);
    LCD_Write_String_Addr(buf0, LCD_ROW0);

    sprintf((char *)buf1, "R13:%08x  ", reg[R13]);
    LCD_Write_String_Addr(buf1, LCD_ROW1);

    sprintf((char *)buf2, "R14:%08x  ", reg[R14]);
    LCD_Write_String_Addr(buf2, LCD_ROW2);

    sprintf((char *)buf3, "SPSR:%08x  ", exception_spsr);
    LCD_Write_String_Addr(buf3, LCD_ROW3);

    LED_Blink_Delay(irq_code, 2500);
}
}
void data_abort_handler(void)
{
    /* Save registers r0-r14 */
    __asm volatile ( "push {r0}"          );
    __asm volatile ( "ldr   r0, =reg"     );
    __asm volatile ( "stmia r0, {r0-r14}" );
    __asm volatile ( "pop  {r1}"          );
    __asm volatile ( "str   r1, [r0]"     );

    /* Save spsr */
    __asm volatile ( "ldr   r1, =exception_spsr" );
    __asm volatile ( "mrs   r0, spsr"     );
    __asm volatile ( "str   r0, [r1]"     );

    irq_display(LED_DATA_ABORT_IRQ, (uint8_t *)"Data Abort          ");
}