lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Windows 7 Startup crashes LwIP and Free RTOS


From: Marco Jakobs
Subject: Re: [lwip-users] Windows 7 Startup crashes LwIP and Free RTOS
Date: Tue, 20 Jul 2010 13:42:53 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.10) Gecko/20100512 Thunderbird/3.0.5

Hi,

i may have found a problem reviewing the EMAC code. The function ulEMACInputLength is called before the EMAC buffers are copied into the pbufs. It sets ulNextRxBuffer to the buffer with a Start Of Frame set and gives back the total length which is written in the last buffer of the frame.

I just assume that some big frames arrive in a very short time. The first frame fits in the EMAC buffers, let's say it needs 10 buffers (each buffer has 128 byte in my EMAC) starting at buffer 0. The second frame is written in the buffers before the first packet is copied away by the EMAC task - after 6 received buffers the EMAC got an overrun as it has no free blocks. We have a fragment of a frame in the buffers 10-15. Now the EMAC task copies away the 10 buffer packet and frees the EMAC buffers 0-9. A next packet of 11 frames is received by EMAC and written in the (now free) buffers 0-9, causing another overrun due to missing space for the 11th frame.

What we will find now are 16 EMAC buffers with the set ownership bit, two of them has a "Start Of Frame" set, but no one has the end frame included with the total frame length, as both end frames were skipped due to the overrun.

If however this situation occurs, the first while loop in the function will happily find a buffer with SOF at its position, so freeing no buffers. The second loop will be infinite as there is no block with a cleared ownership bit and no "last block" with the length in it.

Just theory at the moment, but a possible scenario which may happen sometimes. I will change the second loop in that function, so that after NB_RX_BUFFERS cycle the loop will exit and free all Rx buffers. I will report if i see any crashed in promiscuous mode after this.

Marco





/* See the header file for descriptions of public functions. */
unsigned portLONG
ulEMACInputLength( void )
{
    register unsigned portLONG ulIndex, ulLength = 0;

/* Skip any fragments. We are looking for the first buffer that contains
       data and has the SOF (start of frame) bit set. */
    while( ( xRxDescriptors[ulNextRxBuffer].addr & AT91C_OWNERSHIP_BIT )
&& !( xRxDescriptors[ulNextRxBuffer].U_Status.status & AT91C_SOF ) )
    {
        /* Ignoring this buffer.  Mark it as free again. */
        xRxDescriptors[ulNextRxBuffer].addr &= ~( AT91C_OWNERSHIP_BIT );
        ulNextRxBuffer++;
        if( ulNextRxBuffer >= NB_RX_BUFFERS )
        {
            ulNextRxBuffer = 0;
        }
    }

/* We are going to walk through the descriptors that make up this frame, but don't want to alter ulNextRxBuffer as this would prevent vEMACRead() from finding the data. Therefore use a copy of ulNextRxBuffer instead. */
    ulIndex = ulNextRxBuffer;

    /* Walk through the descriptors until we find the last buffer for this
frame. The last buffer will give us the length of the entire frame. */ while( ( xRxDescriptors[ulIndex].addr & AT91C_OWNERSHIP_BIT ) && !ulLength )
    {
ulLength = xRxDescriptors[ulIndex].U_Status.status & emacRX_LENGTH_FRAME;

        /* Increment to the next buffer, wrapping if necessary. */
        ulIndex++;
        if( ulIndex >= NB_RX_BUFFERS )
        {
            ulIndex = 0;
        }
    }

    return ulLength;
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]