lwip-users
[Top][All Lists]
Advanced

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

Re: [lwip-users] lwip performance goes down if running with FreeRTOS


From: vincent cui
Subject: Re: [lwip-users] lwip performance goes down if running with FreeRTOS
Date: Fri, 11 May 2012 05:49:05 +0000

Hi all:

 

I found root cause now , it is ST CORTEX M3 DMA problem when receive a large of file..

I trace the code, after lwIP performance is down, the Rx Buffer unavailable flag is always set. It means that DMA is in unknown status..

 

It should be enthernet driver problem ..anyone know how to fix  ? thank you

 

 

static struct pbuf * low_level_input(struct netif *netif)

{

  struct pbuf *p, *q;

  u16_t len;

  uint32_t l=0,i =0;

  FrameTypeDef frame;

  u8 *buffer;

  __IO ETH_DMADESCTypeDef *DMARxNextDesc;

 

  p = NULL;

 

  /* Get received frame */

  frame = ETH_Get_Received_Frame_interrupt();

 

  /* check that frame has no error */

  if ((frame.descriptor->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET)

  {

   

    /* Obtain the size of the packet and put it into the "len" variable. */

    len = frame.length;

    buffer = (u8 *)frame.buffer;

 

    /* We allocate a pbuf chain of pbufs from the pool. */

    p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);

 

    /* Copy received frame from ethernet driver buffer to stack buffer */

    if (p != NULL)

    {

                  

      for (q = p; q != NULL; q = q->next)

      {

        memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len);

        l = l + q->len;

      }

    }

 

  }

 

  /* Release descriptors to DMA */

  /* Check if received frame with multiple DMA buffer segments */

  if (DMA_RX_FRAME_infos->Seg_Count > 1)

  {

    DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc;

  }

  else

  {

    DMARxNextDesc = frame.descriptor;

  }

 

  /* Set Own bit in Rx descriptors: gives the buffers back to DMA */

  for (i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)

  { 

    DMARxNextDesc->Status = ETH_DMARxDesc_OWN;

    DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr);

  }

 

  /* Clear Segment_Count */

  DMA_RX_FRAME_infos->Seg_Count =0;

 

 

  /* When Rx Buffer unavailable flag is set: clear it and resume reception */

  if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET) 

  {

         printf(" RX buffer unavailable flag set \n");

    /* Clear RBUS ETHERNET DMA flag */

    ETH->DMASR = ETH_DMASR_RBUS;

     

    /* Resume DMA reception */

    ETH->DMARPDR = 0;

 

  }

  return p;

}

 

 

 

From: lwip-users-bounces+address@hidden [mailto:lwip-users-bounces+address@hidden On Behalf Of vincent cui
Sent: 2012
511 13:24
To: Mailing list for lwIP users
Subject: Re: [lwip-users] lwip performance goes down if running with FreeRTOS

 

Hi :

 

I found it maybe enthernet driver problem. Cortex m3 use DMA channel to receive and send data. And also, it link

Receive and send buffer as chain to speed up. The default ETH_TXBUFNB value is 5, when I change it to 1. The lwip

Performance is stable,but not fast as same as ETH_TXBUFNB == 5.

In enthernet interrupt handler, it will check input frame and give semaphore and force task witch, then, ethernetif_input take the semaphore

To handle the receive packet.

 

Why lWIP performance goes down when ETH_TXBUFNB is 5 ?

 

 

static void low_level_init(struct netif *netif)

{

  uint32_t i;

  uint8_t mac_buffer[8];

 

  /* set netif MAC hardware address length */

  netif->hwaddr_len = ETHARP_HWADDR_LEN;

   

  /* set netif MAC hardware address */

 

  pdu_mac_init(mac_buffer);

 

  netif->hwaddr[0] =  mac_buffer[0];

  netif->hwaddr[1] =  mac_buffer[1];

  netif->hwaddr[2] =  mac_buffer[2];

  netif->hwaddr[3] =  mac_buffer[3];

  netif->hwaddr[4] =  mac_buffer[4];

  netif->hwaddr[5] =  mac_buffer[5];

 

  /* set netif maximum transfer unit */

  netif->mtu = 1500;

 

  /* Accept broadcast address and ARP traffic */

  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;

 

  s_pxNetIf =netif;

 

  /* create binary semaphore used for informing ethernetif of frame reception */

  if (s_xSemaphore == NULL)

  {

    s_xSemaphore= xSemaphoreCreateCounting(32,0);

  }

 

  /* initialize MAC address in ethernet MAC */

  ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr);

 

  /* Initialize Tx Descriptors list: Chain Mode */

  ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);

  /* Initialize Rx Descriptors list: Chain Mode  */

  ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);

 

  /* Enable Ethernet Rx interrrupt */

  {

    for(i=0; i<ETH_RXBUFNB; i++)

    {

      ETH_DMARxDescReceiveITConfig(&DMARxDscrTab[i], ENABLE);

    }

  }

 

#ifdef CHECKSUM_GEN_ICMP

  /* Enable the checksum insertion for the Tx frames */

  {

    for(i=0; i<ETH_TXBUFNB; i++)

    {

      ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);

    }

  }

#endif

 

  /* create the task that handles the ETH_MAC */

  xTaskCreate(ethernetif_input, (signed char*) "Eth_if", netifINTERFACE_TASK_STACK_SIZE, NULL,

              netifINTERFACE_TASK_PRIORITY,NULL);

 

  /* Enable MAC and DMA transmission and reception */

  ETH_Start();  

}

 

 

void ETH_IRQHandler(void)

{

  portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

 

  /* Frame received */

  if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET)

  {

    /* Give the semaphore to wakeup LwIP task */

 

    xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );  

  }

   

  /* Clear the interrupt flags. */

  /* Clear the Eth DMA Rx IT pending bits */

  ETH_DMAClearITPendingBit(ETH_DMA_IT_R);

  ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);

   

  /* Switch tasks if necessary. */ 

  if( xHigherPriorityTaskWoken != pdFALSE )

  {

 

    portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );

  }

 

}

 

void ethernetif_input( void * pvParameters )

{

  struct pbuf *p;

 

  for( ;; )

  {

    if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE)

    {

      p = low_level_input( s_pxNetIf );

      if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf))

      {

        pbuf_free(p);

        p=NULL;

      }

    }

  }

 

 

From: lwip-users-bounces+address@hidden [mailto:lwip-users-bounces+address@hidden On Behalf Of vincent cui
Sent: 2012
511 8:20
To: Mailing list for lwIP users
Subject: Re: [lwip-users] lwip performance goes down if running with FreeRTOS

 

Hi :

 

When lwIP performance goes to down, I capture the TCP packet as attached files.

I also extend PBUF_POOL_BUFSIZE to enough size. It seems no use.

Anyone can give any help ?

 

Vincent

 

From: lwip-users-bounces+address@hidden [mailto:lwip-users-bounces+address@hidden On Behalf Of vincent cui
Sent: 2012
510 21:01
To: Mailing list for lwIP users
Subject: [lwip-users] lwip performance goes down if running with FreeRTOS

 

Hi:

 

I found a odd strange in Cortex M3, running LWIP1.4.0 + FreeRTOS.

I write a TCP server to accept large file, the code works well if running in LWIP standalone. The performance is high and stable.

But when I create the task in FreeRTOS, the whole LWIP performance goes to down after the task accept file for a while

 

It seems that switch task in FreeRTOS cause it down, but I don’t know how to bypass. I even try to “define LWIP_TCP_CORE_LOCKING’

To disable TCP task switch, but still got same result .

 

Anyone can give help ?

 

 

vincent

 

 


reply via email to

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