Dup echo replies

Hello, i have a question referring to the Webserver Demo for CodeRed. It works fine so far, but if i send ping to the board i always get two echo replys. I can’t see them in the console (only one reply – no dup), but in wireshark i see two replies. On a Linux maschine i see both replies in the console. Has anyone had the same problem? Or a clue why the second reply is sent?
Just to make it sure, the first reply does not get lost or anything…. thanks

Dup echo replies

You will probably find that the uIP network driver is configured to send every packet twice, in which case you are receiving the same number of replies as requests. This is done sometimes as a cheap (if transmission is done by DMA) way of getting around the throughput problems caused by delayed acks when talking from a real time system to a desktop system.

Dup echo replies

I have found the part where the second reply is sent and now there’s only one reply, BUT between the request and the reply there is something on the cable 010101010101…. for one frame like uIP always wants to send two frames and if i take one frame away, it just writes 01010101 for one frame. I want to tell uIP that i only want 1 frame to be send. Any idea what i can adjust?

Dup echo replies

In that particular project the double send is done in the ISR void vEMAC_ISR( void ) in emac.c
    if( ulStatus & INT_TX_DONE )
    {
        if( usSendLen > 0 )
        {
            /* Send the data again, using the second descriptor.  As there are
            only two descriptors the index is set back to 0. */
            TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX );
            TX_DESC_CTRL( ( emacTX_DESC_INDEX + 1 ) ) = ( usSendLen | TCTRL_LAST | TCTRL_INT );
            LPC_EMAC->TxProduceIndex = ( emacTX_DESC_INDEX );
            /* This is the second Tx so set usSendLen to 0 to indicate that the
            Tx descriptors will be free again. */
            usSendLen = 0UL;
        }
        else
        {
            /* The Tx buffer is no longer required. */
            prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );
            TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) NULL;
        }
    }
I haven’t tried this, but it looks like you could remove the double send by changing it to something like this:
    if( ulStatus & INT_TX_DONE )
    {
        /* The Tx buffer is no longer required. */
        prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );
        TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) NULL;
        LPC_EMAC->TxProduceIndex = ( emacTX_DESC_INDEX );
    }
but I’m not 100% confident of that – you would have to look at how the transmit function was using the descriptor too. Regards.

Dup echo replies

I tried it and if i change the code like in your example above, i get no response from target.
This is the transmit function:  void vSendEMACTxData( unsigned short usTxDataLen )
{
unsigned long ulAttempts = 0UL; /* Check to see if the Tx descriptor is free, indicated by its buffer being
NULL. */
while( TX_DESC_PACKET( emacTX_DESC_INDEX ) != ( unsigned long ) NULL )
{
/* Wait for the Tx descriptor to become available. */
vTaskDelay( emacBUFFER_WAIT_DELAY ); ulAttempts++;
if( ulAttempts > emacBUFFER_WAIT_ATTEMPTS )
{
/* Something has gone wrong as the Tx descriptor is still in use.
Clear it down manually, the data it was sending will probably be
lost. */
prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );
break;
}
} /* Setup the Tx descriptor for transmission.  Remember the length of the
data being sent so the second descriptor can be used to send it again from
within the ISR. */
usSendLen = usTxDataLen;
TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) uip_buf;
TX_DESC_CTRL( emacTX_DESC_INDEX ) = ( usTxDataLen | TCTRL_LAST | TCTRL_INT );
LPC_EMAC->TxProduceIndex = ( emacTX_DESC_INDEX + 1 ); /* uip_buf is being sent by the Tx descriptor.  Allocate a new buffer. */
uip_buf = prvGetNextBuffer();
} and this the EMAC_ISR: {
unsigned long ulStatus;
long lHigherPriorityTaskWoken = pdFALSE; ulStatus = LPC_EMAC->IntStatus; /* Clear the interrupt. */
LPC_EMAC->IntClear = ulStatus; if( ulStatus & INT_RX_DONE )
{
/* Ensure the uIP task is not blocked as data has arrived. */
xSemaphoreGiveFromISR( xEMACSemaphore, &lHigherPriorityTaskWoken );
} if( ulStatus & INT_TX_DONE )
{ if( usSendLen > 0 )
{
// Send the data again, using the second descriptor.  As there are
//only two descriptors the index is set back to 0. TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX );
TX_DESC_CTRL( ( emacTX_DESC_INDEX + 1 ) ) = ( usSendLen | TCTRL_LAST | TCTRL_INT );
LPC_EMAC->TxProduceIndex = ( emacTX_DESC_INDEX ); // This is the second Tx so set usSendLen to 0 to indicate that the
// Tx descriptors will be free again.
usSendLen = 0UL;
}
else
{
// The Tx buffer is no longer required.
prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );
            TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) NULL;
} } portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
} If i delete the line: TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX );
in the EMAC_ISR i can ping  and i have only one reply, but the problem remains, that 01010101 on the cable as if the programm has to output two frames…