jstoezel wrote on Tuesday, January 04, 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_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…