Is it caused by some wrong with STM32 ETH DMA? It's the error handling code
in RT-Thread STM32F107 ETH driver:

/* interrupt service routine for ETH */
void ETH_IRQHandler(void)
{
    ...
    if ((status & ETH_DMA_IT_RBU) != (u32)RESET)
    {
        ETH_ResumeDMAReception();
        ETH->DMASR = (u32)ETH_DMA_IT_RBU;
    }

    if ((status & ETH_DMA_IT_TBU) != (u32)RESET)
    {
        ETH_ResumeDMATransmission();
        ETH->DMASR = (u32)ETH_DMA_IT_TBU;
    }
    ...
}


Regards,
Bernard Xiong
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RT-Thread - An open source RTOS from China.
http://en.rt-thread.org
http://www.rt-thread.org
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2012/5/11 vincent cui <[email protected]>

>  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:* [email protected] [mailto:
> [email protected]] *On Behalf Of *vincent 
> cui
> *Sent:* 2012年5月11日 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:* [email protected] [mailto:
> [email protected]] *On Behalf Of *vincent 
> cui
> *Sent:* 2012年5月11日 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:* [email protected] [mailto:
> [email protected]] *On Behalf Of *vincent 
> cui
> *Sent:* 2012年5月10日 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****
>
>  ****
>
>  ****
>
> _______________________________________________
> lwip-users mailing list
> [email protected]
> https://lists.nongnu.org/mailman/listinfo/lwip-users
>
_______________________________________________
lwip-users mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to