fanlex wrote on Thursday, January 15, 2009:
Hi Richard,
I have made some more tests on my application : removing all tasks excepted 2 for uarts.
I have noticed that uart1 looses one character when uart0 has finished sending the last byte of a frame within the same time the reception occurs on uart1, and at that time there is a call to xQueueSendFromISR for the transmit event of uart0. If I remove that call to xQueueSendFromISR, I don’t loose any data. if I only remove call to portYIELD_FROM_ISR, uart1 looses a byte.
here is the code (the same code for both uarts)
there is a call to xQueueSendFromISR at the end of Receive or transmit for each uart.
time spent in these fonctions is very short, I don’t know what is happening.
When I recompile with all the tasks running, but avoid calling the xQueueSendFromISR only when I have got the uart0 tx event while uart1 is still receiving data, all works perfectly. even high traffic with the webserver does not disturb uart1. But sometimes I need to get that event, it’s not the solution.
avoiding only the call to portYIELD_FROM_ISR when TX event has no effect : uart1 still misses characters.
//---------------------------------------------------------------------------
// Common Interrupt processing for UART0 & UART1
//---------------------------------------------------------------------------
void process_Interrupt(T_Serialport* aSp)
{
portBASE_TYPE xHigherPriorityTaskWoken = FALSE;
int event = FALSE;
T_Serialport* laSp;
// read the channel status register
aSp->uartstatus = aSp->pUSART->US_CSR & aSp->pUSART->US_IMR;
if (aSp->uartstatus & AT91C_US_RXRDY)
{
event = proto_intReceive(aSp);
}
if (aSp->uartstatus & AT91C_US_TXRDY)
{
event = event + proto_intTransmit(aSp);
}
// reset error status bits
aSp->pUSART->US_CR = AT91C_US_RSTSTA;
/* Clear AIC to complete ISR processing */
AT91C_BASE_AIC->AIC_EOICR = 0;
/* if necessary, Post ISR data to queue for task-level processing */
//…
if (event)
{
laSp = aSp;
xQueueSendFromISR( aSp->xUARTInterruptQueue, &laSp, &xHigherPriorityTaskWoken );
}
/* Do a task switch if needed */
if( xHigherPriorityTaskWoken )
{
/* This call will ensure that the unblocked task will be executed
immediately upon completion of the ISR if it has a priority higher
than the interrupted task. */
portYIELD_FROM_ISR();
}
}
what else should I check ?