Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

Idle task stack overflow

Posted by ARMinator on December 31, 2010
Hi,

I'm running the latest version of freeRTOS on an LPC2000 and I am getting a stack overflow error with the idle task.

This only occurs after I enable the processing of interrupts for UART0 (RX data available and receive data timeout interrupts enabled only), and after about half a dozen interrupts are serviced.
What is most likely to generate a stack overflow on the idle task? Is this a general corruption of memory, which is reported as a stack overflow for the idle task?

This is how the UART0 isr is implemented (C wrapper for C++ UART driver). No call to the freeRTOS API is made in the m_Uart0.Isr() method.

void Uart0Isr( void ) __attribute__((naked));
void Uart0Isr( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();

m_Uart0.Isr();

/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}

Happy New Year,
JS

RE: Idle task stack overflow

Posted by ARMinator on December 31, 2010
Oups, looks like this has already been handled here:

https://sourceforge.net/projects/freertos/forums/forum/382005/topic/3301950

Sorry for the double post...

RE: Idle task stack overflow

Posted by ARMinator on January 4, 2011
Hi,

I am still getting this error and it seems this happens exclusively when both the tick interrupts and the UART interrupts are enabled and serviced. I use a tick hook.

I do not get this error when the tick interrupts are enabled and my tick hook is called. I do not get this error when the tick hook is not called and UART ISRs are serviced. Somehow it looks like the tick hook and the UART ISR are not compatible...
I have increased the size of the interrupt stack in the linker script but I still get this error.

Here is the code I use in the tick hook:

void CScheduler::Scheduler(
const uint32_t tick // in
)
{
CScheduler::sEntry_t * p_Entry = mp_EntryList;
signed portBASE_TYPE xHigherPriorityTaskWoken;
static CSubsystem::sActivation_t activationPacket;

m_Tick = tick;

while(0 != p_Entry)
{
if( 0 != p_Entry->clkDivider &&
0 == (m_Tick % p_Entry->clkDivider)
)
{
activationPacket.type = CSubsystem::ACTIVATION_TYPE_SCHEDULER;
activationPacket.p_Cmd = CSubsystem::CommandGet();
if(0 != activationPacket.p_Cmd)
{
activationPacket.p_Cmd->id = 0;
activationPacket.p_Cmd->dataLen = 0;
// Activating
xQueueSendFromISR(*(p_Entry->p_ActivationQueue), &activationPacket, &xHigherPriorityTaskWoken);
}
else
{}
}
else
{
// Skipping
}

p_Entry = p_Entry->p_Next;
} // while
} // CScheduler::Scheduler

Here is the UART ISR:


void Uart1ISR( void ) __attribute__((naked));
void Uart1ISR( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
lpc21xxUart1.Isr();
VICVectAddr = 0;
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}

And the actual method

void CLpc21xxUartDev::Isr(void)
{
uint32_t intStatus = LPC214x_REG_READ_8(UxIIR);
uint8_tdata= 0;
portBASE_TYPE higherPriorityTaskWoken = pdFALSE;

intStatus = (intStatus >> 1) & 0x07;

if(0x03 == (intStatus & 0x03))
{
// receive line status
LPC214x_REG_READ_8(UxLSR);
}
else
{}

if((0x02 == (intStatus & 0x02)) ||
(0x06 == (intStatus & 0x06))
)
{
// data received or cti
// cleared by reading all the data
while(LPC214x_REG_READ_8(UxLSR) & 0x01)
{
data = LPC214x_REG_READ_8(UxRBR);
xQueueSendFromISR(m_RxQueue, &data, &higherPriorityTaskWoken);
}
}
else
{}

if(0x01 == (intStatus & 0x01))
{
uint32_t cnt = 0;
while(cnt < LPC214x_HW_FIFO_SIZE)
{
if(pdTRUE == xQueueReceiveFromISR (m_TxQueue, &data, &higherPriorityTaskWoken))
{
LPC214x_REG_WRITE_8(UxTHR, data);
cnt++;
}
else
{
m_TxEmpty = true;
break;
}
} // while
}
else
{}

if(higherPriorityTaskWoken)
portYIELD_FROM_ISR ();
}

Does anybody see something obvious that would generate this error?

As a side note, could somebody clarify when portYIELD_FROM_ISR () should be called?
I realize the 2 pieces of code I provide here are not consistent: the tick hook never bothers to call the method even if a higher level task is woken up.
In the UART ISR, I only call it at the end of the ISR, while it's possible that xQueueReceiveFromISR could be called many times. In that case I also overwrite the value of higherPriorityTaskWoken...

RE: Idle task stack overflow

Posted by ARMinator on January 5, 2011
I fixed this by removing a call to xTaskGetTickCount() from the tick hook. Doesn't seem to bother anything if only the tick interrupt is enabled. But generates task overflows when other interrupts are serviced.

RE: Idle task stack overflow

Posted by Richard Damon on January 5, 2011
getTickHook is called from within an ISR (the timer interrupt), so it can only call FreeRTOS functions with FromISR in their name. xTaskGetTickCount uses an ISR to access the count, and those don't work inside of ISR routines, it can allow improper interrupt nesting.

RE: Idle task stack overflow

Posted by Richard on January 5, 2011
ISRs must not call any FreeRTOS API functions that do not end in "FromISR". Latest versions of FreeRTOS include an xTaskGetTickCountFromISR() function (although this is mentioned in the change history, it has not made it into the documentation yet).

Regards.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists