Idle task stack overflow

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

Idle task stack overflow

Oups, looks like this has already been handled here: https://sourceforge.net/projects/freertos/forums/forum/382005/topic/3301950 Sorry for the double post…

Idle task stack overflow

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_t data = 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…

Idle task stack overflow

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.

Idle task stack overflow

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.

Idle task stack overflow

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.