FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [December 2010 Threads] Idle task stack overflowPosted 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 overflowPosted 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 overflowPosted 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 overflowPosted 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 overflowPosted 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 overflowPosted 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.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|