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: Darius Babrauskas
Subject: Re: [lwip-users] lwip performance goes down if running with FreeRTOS
Date: Fri, 11 May 2012 12:39:08 +0300

Maybe, try init in callback

   struct tcp_pcb *pcb;
static void server_init_callback(void)  {
   pcb = tcp_new();
   tcp_bind(pcb, IP_ADDR_ANY, 8081);
   pcb = tcp_listen(pcb);
   tcp_accept(pcb, server_accept);
}

static void server_init(void)
{

....tcp_callback(server_init_callback);

for (;;)
{
vTaskDelay(50);
}
}


tcp_accept

----- Original Message ----- From: "vincent cui" <address@hidden>
To: "Mailing list for lwIP users" <address@hidden>
Sent: Friday, May 11, 2012 12:01 PM
Subject: Re: [lwip-users] lwip performance goes down if running with FreeRTOS


Hi Darius:

I am always using tcp_callback functions.

static void close_conn(struct tcp_pcb *pcb)
{
     tcp_arg(pcb, NULL);
     tcp_sent(pcb, NULL);
     tcp_recv(pcb, NULL);
     tcp_close(pcb);
}

static err_t server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
     if (err == ERR_OK && p != NULL) {

           tcp_recved(pcb, p->tot_len);
           pbuf_free(p);
     }

     if (err == ERR_OK && p == NULL) {
  pbuf_free(p);
           close_conn(pcb);
     }
     return ERR_OK;
}

static err_t server_accept(void *arg, struct tcp_pcb *pcb, err_t err){
     LWIP_UNUSED_ARG(arg);
     LWIP_UNUSED_ARG(err);

     tcp_recv(pcb, server_recv);
     tcp_err(pcb, NULL);
  tcp_sent(pcb, NULL);
     tcp_poll(pcb, NULL, 0);
     return ERR_OK;
}

static void server_init(void)
{
   struct tcp_pcb *pcb;

   pcb = tcp_new();
   tcp_bind(pcb, IP_ADDR_ANY, 8081);
pcb = tcp_listen(pcb);

tcp_accept(pcb, server_accept);

for (;;)
{
vTaskDelay(50);
}
}



-----Original Message-----
From: address@hidden [mailto:address@hidden On Behalf Of Darius Babrauskas
Sent: 2012年5月11日 16:50
To: Mailing list for lwIP users
Subject: Re: [lwip-users] lwip performance goes down if running with FreeRTOS


I think it is . .as DMA is in unavailable status once LWIP performance goes
to down .
I try it with LWIP standalone. The performance is stable and DMA is never
in unavailable status .
(LWIP functions must work in one tread contects ), So, I think, need  in
FreeRTOS use LWIP tcp_callback functions, that your code work like
"standalone".

Darius



From: address@hidden
[mailto:address@hidden On Behalf
Of bernard
Sent: 2012年5月11日 14:48
To: Mailing list for lwIP users
Subject: Re: [lwip-users] lwip performance goes down if running with
FreeRTOS

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
<address@hidden<mailto:address@hidden>>
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:
address@hidden<mailto:address@hidden>
[mailto:lwip-users-bounces+vincent.cui<mailto:lwip-users-bounces%2Bvincent.cui>address@hidden<mailto:address@hidden>]
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:
address@hidden<mailto:address@hidden>
[mailto:lwip-users-bounces+vincent.cui<mailto:lwip-users-bounces%2Bvincent.cui>address@hidden<mailto:address@hidden>]
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:
address@hidden<mailto:address@hidden>
[mailto:lwip-users-bounces+vincent.cui<mailto:lwip-users-bounces%2Bvincent.cui>address@hidden<mailto:address@hidden>]
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
address@hidden<mailto:address@hidden>
https://lists.nongnu.org/mailman/listinfo/lwip-users




--------------------------------------------------------------------------------


_______________________________________________
lwip-users mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/lwip-users


_______________________________________________
lwip-users mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/lwip-users
_______________________________________________
lwip-users mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/lwip-users




reply via email to

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