heinbali01 wrote on Monday, December 01, 2014:
Same thoughts: try to defer all buffer processing to a normal task.
In one of the ports (for Xilinx/Zynq) you will find:
/* Three ISR's for TX, RX and error handling: */
void emac_send_handler(void *arg)
{
xemacpsif_s *xemacpsif;
long xHigherPriorityTaskWoken = pdFALSE;
xemacpsif = (xemacpsif_s *)(arg);
/* In this port for FreeRTOS+TCP, the EMAC interrupts
will only set a bit in "isr_events". The task in
NetworkInterface will wake-up and do the necessary work. */
xemacpsif->isr_events |= EMACPS_TX_EVENT;
xemacpsif->txBusy = pdFALSE;
if( xEMACEventSemaphore != NULL )
{
xSemaphoreGiveFromISR( xEMACEventSemaphore,
&xHigherPriorityTaskWoken );
}
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
void emac_recv_handler(void *arg)
{
/* Same as above, setting the RX flag */
xemacpsif->isr_events |= EMACPS_RX_EVENT;
...
}
void emac_error_handler(void *arg)
{
/* Same as above, setting the ERR flag */
xemacpsif->isr_events |= EMACPS_ERR_EVENT;
...
}
The task handling the NIC will do the actual work:
for( ; ; )
{
if( ( xemacpsif->isr_events & EMACPS_ALL_EVENT ) == 0 )
{
xSemaphoreTake( xEMACEventSemaphore, 100 );
}
if( ( xemacpsif->isr_events & EMACPS_RX_EVENT ) != 0 )
{
xemacpsif->isr_events &= ~EMACPS_RX_EVENT;
xResult = emacps_check_rx( xemacpsif );
}
if( ( xemacpsif->isr_events & EMACPS_TX_EVENT ) != 0 )
{
xemacpsif->isr_events &= ~EMACPS_TX_EVENT;
emacps_check_tx( xemacpsif );
}
if( ( xemacpsif->isr_events & EMACPS_ERR_EVENT ) != 0 )
{
xemacpsif->isr_events &= ~EMACPS_ERR_EVENT;
emacps_check_errors( xemacpsif );
}
check_phy_link_status( );
}
Note that sending messages always happens from the IP-task.
FreeRTOS+TCP is 100% thread-safe, not interrupt-safe. As you most probably know, there is a very small delay between calling xSemaphoreGiveFromISR() and the waking up from xSemaphoreTake().
The above approach has the advantage that the configured priorities govern the processing, and not the hardware
Personally, I tend to give the highest priority to the NIC task. We don’t want to miss packets due to an RX overflow. The above routine emacps_check_rx() will only put received messages in a queue, and free the DMA buffers.
The second highest priority is for the IP-task, and all other tasks get a lower priority.
Good luck,
Hein