help: how to use interrupt in RAW_API mode under Xilinx-V2

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

help: how to use interrupt in RAW_API mode under Xilinx-V2

ye.wu
Hi, all

I\'m using a Xilinx-Viterx2 with PowerPC 405 core@200MHz.

I\'v just start the develop under Xilinx-Viterx2 within a month and now got big problems with the use of lwip in that platform.

At first, i set up a Echo server just follow the example of xilinx\'s echo server under SOCKET_API. As it was discussed a lot in the forum, the trans speed is unbearable, i can get only 10-20kB/s at most, even set the systmr_interval to 1. I\'m not sure about the systmr_interval\'s function for the lwip under SOCKET_API mode, could any one tell me why the speed increased as the value of systmr_interval decrease? And is there any tricks to improve the speen under SOCKET_API mode?

And then i wrote a udp program use RAW_API mode, it works well in the polling mode. As we see, RAW_API are used mainly under standlone kernel, but i think we can use it under xilkernel too. i can get about 300kB/s with that mode. i see in the forum that if we use interrupt instead of polling, we can get much fast, so i write a program (as bellow) but it not work at all, i can not even ping the target from my PC. I don\'t know what wrong, could anyone help me?

1. There were mail messages that use the Standalone Board Support Package for set the interrupt, Can we use the RAW_API in interrupt mode under xilkernel, and registe the irq in xilkernel as we do in SOCKTE_API mode?

2. I\'ve read from the forum that the interupt was used to replase the \'xemacif_input\' in the while loop, so i just set the interupt and cancel the \'xemacif_input\', leave while a null loop to wait for interrupt after setup udp, is that right?

Could anybody help me why it not work? Really appreciate for your help.


the programe is:


void *receiveUDP(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
{
    udp_send(udpstructreceive,p);
    pbuf_free(p);
}

void* main_main()
{    
    char low_mac[3] = {0x00,0x22,0x20};
    char fullmac[6] = {XILINX_MAC_OUI0, XILINX_MAC_OUI1, XILINX_MAC_OUI2,
                      low_mac[0], low_mac[2], low_mac[3]};

    char ip[4] = {192,168,0,102};
    //char remoteIP[4] = {192,168,0,6};
    char subnet[4] = {255,255,255,0};
    char gateway[4] = {192,168,0,254};
    char sendtoip[4] = {192,168,0,2};
    
    u16_t listenport,sendport;
    listenport = 5001;
    sendport = 5001;

    #ifdef STATS
        stats_init();
    #endif /* STATS */
    xil_printf(\"Initializing Memory Structures.\");
    sys_init();
    mem_init();
    xil_printf(\".\");
    memp_init();
    xil_printf(\".\");
    pbuf_init();
    xil_printf(\" done.\\r\\n\");

    xemacif_setmac(0, (u8_t *) fullmac); //Set MAC

    netif_init();
    udp_init();

    XEmacIf_Config *xemacif_ptr = &XEmacIf_ConfigTable[0];

    IP4_ADDR(&gw, 192,168,0,254); //Set gateway
    IP4_ADDR(&ipaddr, ip[0],ip[1],ip[2],ip[3]); //Set ip
    IP4_ADDR(&sendtoipaddr, sendtoip[0],sendtoip[1],sendtoip[2],sendtoip[3]); //Set ip
    IP4_ADDR(&netmask,subnet[0],subnet[1],subnet[2],subnet[3]); //Set subnet msk


    default_netif = mem_malloc(sizeof(struct netif));

    default_netif = netif_add(default_netif, &ipaddr, &netmask, &gw, &XEmacIf_ConfigTable[0], xemacif_init, ip_input);
    netif_set_default(default_netif);

    ret = register_int_handler(XPAR_OPB_INTC_0_ETHERNET_MAC_IP2INTC_IRPT_INTR,
                         (XInterruptHandler)XEmac_IntrHandlerFifo,
                         xemacif_ptr->instance_ptr);

    enable_interrupt(XPAR_OPB_INTC_0_ETHERNET_MAC_IP2INTC_IRPT_INTR);

    udpstructreceive = udp_new();

    udp_bind(udpstructreceive,IP_ADDR_ANY,listenport);

    udp_connect(udpstructreceive,&sendtoipaddr,sendport);

    udp_recv(udpstructreceive, receiveUDP, NULL);

    while(1){
        ;//xemacif_input(default_netif);
    }

    return 0;
}

int main(){
    xilkernel_main();
}


Thanks very much!
Ye Wu
_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: help: how to use interrupt in RAW_API mode under Xilinx-V2

Sathya Thammanur
Hi Ye Wu,
As the current implementation stands, the RAW API cannot be used with xilkernel. The Sockets API is what is supported with xilkernel. Hence, the code written above will not work. The RAW API adapter has been optimized and hence will offer the best performance that you are looking for. The Sockets API is not optimized and hence the data rates seen is very much expected. As it stands today, you can choose to use the RAW API and go for the performance or you can work with Sockets API for ease of use of programming. You will need to make the choice based on your requirements.

Sathya


On 10/19/06, ye wu <[hidden email]> wrote:
Hi, all

I\'m using a Xilinx-Viterx2 with PowerPC 405 core@200MHz.

I\'v just start the develop under Xilinx-Viterx2 within a month and now got big problems with the use of lwip in that platform.

At first, i set up a Echo server just follow the example of xilinx\'s echo server under SOCKET_API. As it was discussed a lot in the forum, the trans speed is unbearable, i can get only 10-20kB/s at most, even set the systmr_interval to 1. I\'m not sure about the systmr_interval\'s function for the lwip under SOCKET_API mode, could any one tell me why the speed increased as the value of systmr_interval decrease? And is there any tricks to improve the speen under SOCKET_API mode?

And then i wrote a udp program use RAW_API mode, it works well in the polling mode. As we see, RAW_API are used mainly under standlone kernel, but i think we can use it under xilkernel too. i can get about 300kB/s with that mode. i see in the forum that if we use interrupt instead of polling, we can get much fast, so i write a program (as bellow) but it not work at all, i can not even ping the target from my PC. I don\'t know what wrong, could anyone help me?

1. There were mail messages that use the Standalone Board Support Package for set the interrupt, Can we use the RAW_API in interrupt mode under xilkernel, and registe the irq in xilkernel as we do in SOCKTE_API mode?

2. I\'ve read from the forum that the interupt was used to replase the \'xemacif_input\' in the while loop, so i just set the interupt and cancel the \'xemacif_input\', leave while a null loop to wait for interrupt after setup udp, is that right?

Could anybody help me why it not work? Really appreciate for your help.


the programe is:


void *receiveUDP(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
{
    udp_send(udpstructreceive,p);
    pbuf_free(p);
}

void* main_main()
{    
    char low_mac[3] = {0x00,0x22,0x20};
    char fullmac[6] = {XILINX_MAC_OUI0, XILINX_MAC_OUI1, XILINX_MAC_OUI2,
                      low_mac[0], low_mac[2], low_mac[3]};

    char ip[4] = {192,168,0,102};
    //char remoteIP[4] = {192,168,0,6};
    char subnet[4] = {255,255,255,0};
    char gateway[4] = {192,168,0,254};
    char sendtoip[4] = {192,168,0,2};
    
    u16_t listenport,sendport;
    listenport = 5001;
    sendport = 5001;

    #ifdef STATS
        stats_init();
    #endif /* STATS */
    xil_printf(\"Initializing Memory Structures.\");
    sys_init();
    mem_init();
    xil_printf(\".\");
    memp_init();
    xil_printf(\".\");
    pbuf_init();
    xil_printf(\" done.\\r\\n\");

    xemacif_setmac(0, (u8_t *) fullmac); //Set MAC

    netif_init();
    udp_init();

    XEmacIf_Config *xemacif_ptr = &XEmacIf_ConfigTable[0];

    IP4_ADDR(&gw, 192,168,0,254); //Set gateway
    IP4_ADDR(&ipaddr, ip[0],ip[1],ip[2],ip[3]); //Set ip
    IP4_ADDR(&sendtoipaddr, sendtoip[0],sendtoip[1],sendtoip[2],sendtoip[3]); //Set ip
    IP4_ADDR(&netmask,subnet[0],subnet[1],subnet[2],subnet[3]); //Set subnet msk


    default_netif = mem_malloc(sizeof(struct netif));

    default_netif = netif_add(default_netif, &ipaddr, &netmask, &gw, &XEmacIf_ConfigTable[0], xemacif_init, ip_input);
    netif_set_default(default_netif);

    ret = register_int_handler(XPAR_OPB_INTC_0_ETHERNET_MAC_IP2INTC_IRPT_INTR,
                         (XInterruptHandler)XEmac_IntrHandlerFifo,
                         xemacif_ptr->instance_ptr);

    enable_interrupt(XPAR_OPB_INTC_0_ETHERNET_MAC_IP2INTC_IRPT_INTR);

    udpstructreceive = udp_new();

    udp_bind(udpstructreceive,IP_ADDR_ANY,listenport);

    udp_connect(udpstructreceive,&sendtoipaddr,sendport);

    udp_recv(udpstructreceive, receiveUDP, NULL);

    while(1){
        ;//xemacif_input(default_netif);
    }

    return 0;
}

int main(){
    xilkernel_main();
}


Thanks very much!
Ye Wu
_______________________________________________
lwip-users mailing list
[hidden email]
<a onclick="return top.js.OpenExtLink(window,event,this)" href="http://lists.nongnu.org/mailman/listinfo/lwip-users" target="_blank"> http://lists.nongnu.org/mailman/listinfo/lwip-users



_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: help: how to use interrupt in RAW_API mode under Xilinx-V2

ye.wu
Sathy,

Thanks very much for your help.

You say that 'the RAW API cannot be used with xilkernel', i still not quite understand. we can use SBS(Standalone Board Support) functions under xilkernel, so why can't we write a application of lwip just use SBS? and the udp program in polling mode work well with xilkernel.

And sorry for the noise, i'm know few about the lwip's mechanism.

Ye Wu



On 10/19/06, Sathya Thammanur <[hidden email]> wrote:
Hi Ye Wu,
As the current implementation stands, the RAW API cannot be used with xilkernel. The Sockets API is what is supported with xilkernel. Hence, the code written above will not work. The RAW API adapter has been optimized and hence will offer the best performance that you are looking for. The Sockets API is not optimized and hence the data rates seen is very much expected. As it stands today, you can choose to use the RAW API and go for the performance or you can work with Sockets API for ease of use of programming. You will need to make the choice based on your requirements.

Sathya



_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: help: how to use interrupt in RAW_API mode under Xilinx-V2

ye.wu
Hi, all
 
I'm now trying to do the interrupt in Standlone, but still without success.
 
It seems that the interrupt work well, i put a print in the handler and we can see the handler was called several times.
 
but when a interrupt come, the handler do nothing.
 
i turned on the debug of lwip and find something strange in the init of lwip, there ware lots of 'pbuf_alloc: allocated pbuf' but i haven't seen any free of them...
i find out latter that this pbuf_alloc hapens at
if (init(netif) != ERR_OK) {
    return NULL;
  }
in the netif_add() function. the init function is the xemacif_init() that given to it.
 
i don't know why this happens, could anybody help me ?
 
Thanks a lot!
 
 
 
the output of my terminal is:

Netif_init Donedefault netif = C0024

netif: before netif_set_addr netif_set_ipaddr: netif address being changed

netif:IP address of interface set to ...

netif: netmask of interface set to ...

netif: GW address of interface set to ...

netif: after netif_set_addr

pbuf_alloc(length=)                                                     // there comes the pbuf_alloc in init process of lwip...

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: all

ocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc

(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

pbuf_alloc(length=)

pbuf_alloc: allocated pbuf

pbuf_alloc(length=) ==

netif: after netif_init

netif: added interface e0 IP addr ... netmask ... gw ...

Netif_Add Done

netif:setting default interface e0

udp_bind(ipaddr = ..., port = )

udp_bind: bound to ..., port

udp_connect: connected to ..., port

entering while...

Handler Called, Status:4               // the interrupt handler do called after i connected the cable of the net. but there seems nothing done after that...
Handler Called, Status:4
Handler Called, Status:4
....


_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: help: how to use interrupt in RAW_API mode under Xilinx-V2

Sathya Thammanur
In reply to this post by ye.wu
Ye Wu,
RAW API does not use any of the kernel services like mailboxes, semaphores. The RAW API works on a callback mechanism as in the application, call back functions should be registered with the lwIP stack for various events associated with a protocol.

Hope this helps in understanding. Attached is a TCP based echo server example which you can use for your understanding. Along similar lines, UDP events need to be registered with stack (depending on whether you use server or client).

Sathya


On 10/19/06, ye wu <[hidden email]> wrote:
Sathy,

Thanks very much for your help.

You say that 'the RAW API cannot be used with xilkernel', i still not quite understand. we can use SBS(Standalone Board Support) functions under xilkernel, so why can't we write a application of lwip just use SBS? and the udp program in polling mode work well with xilkernel.

And sorry for the noise, i'm know few about the lwip's mechanism.

Ye Wu




On 10/19/06, Sathya Thammanur <[hidden email]> wrote:
Hi Ye Wu,
As the current implementation stands, the RAW API cannot be used with xilkernel. The Sockets API is what is supported with xilkernel. Hence, the code written above will not work. The RAW API adapter has been optimized and hence will offer the best performance that you are looking for. The Sockets API is not optimized and hence the data rates seen is very much expected. As it stands today, you can choose to use the RAW API and go for the performance or you can work with Sockets API for ease of use of programming. You will need to make the choice based on your requirements.

Sathya



_______________________________________________
lwip-users mailing list
[hidden email]
<a onclick="return top.js.OpenExtLink(window,event,this)" href="http://lists.nongnu.org/mailman/listinfo/lwip-users" target="_blank"> http://lists.nongnu.org/mailman/listinfo/lwip-users



_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users

tcp_echo_raw.zip (7K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: help: how to use interrupt in RAW_API mode under Xilinx-V2

ye.wu
Sathya,
 
Very appreciate for your help!
 
I tryed the code you give me and it's work fine.
 
I see how interrupt work in a RAW_API mode now!
 
There's one thing i do not understand very much,
in your code, in the while function, we still have xemacif_input(default_netif); in it.
the question is, do we still need that in the interrupt mode ?
as i think before, we use interrupt to replace the xemacif_input that used in the polling mode.
Is that i misunderstood before?
 
the segmentation of code is that:
   while (1) {
      while (waiting_for_timer) {
         xemacif_input(default_netif);
         XTime_GetTime(&ml_new);
         if ( ml_new >= ml_base ) {
            waiting_for_timer = 0;
            ml_base = ml_new + ml_offset;
         }
      }
      // Call my_tmr() every ml_offset cycles
      my_tmr();
      waiting_for_timer = 1;
   }
 
Thanks for your help and looking forward to your replay.
 
Best Regards,
Ye Wu

 
On 10/25/06, Sathya Thammanur <[hidden email]> wrote:
Ye Wu,
RAW API does not use any of the kernel services like mailboxes, semaphores. The RAW API works on a callback mechanism as in the application, call back functions should be registered with the lwIP stack for various events associated with a protocol.

Hope this helps in understanding. Attached is a TCP based echo server example which you can use for your understanding. Along similar lines, UDP events need to be registered with stack (depending on whether you use server or client).

Sathya

_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: help: how to use interrupt in RAW_API mode under Xilinx-V2

Sathya Thammanur
Ye Wu,
You can comment this for the older version of lwIP (0.5.3). In the new version (0.7.2), the lwIP adapter was optimized for performance and this function triggers the packet processing while the interrupt just retrieves the packet.

Sathya


On 10/24/06, ye wu <[hidden email]> wrote:
Sathya,
 
Very appreciate for your help!
 
I tryed the code you give me and it's work fine.
 
I see how interrupt work in a RAW_API mode now!
 
There's one thing i do not understand very much,
in your code, in the while function, we still have xemacif_input(default_netif); in it.
the question is, do we still need that in the interrupt mode ?
as i think before, we use interrupt to replace the xemacif_input that used in the polling mode.
Is that i misunderstood before?
 
the segmentation of code is that:
   while (1) {
      while (waiting_for_timer) {
         xemacif_input(default_netif);
         XTime_GetTime(&ml_new);
         if ( ml_new >= ml_base ) {
            waiting_for_timer = 0;
            ml_base = ml_new + ml_offset;
         }
      }
      // Call my_tmr() every ml_offset cycles
      my_tmr();
      waiting_for_timer = 1;
   }
 
Thanks for your help and looking forward to your replay.
 
Best Regards,
Ye Wu

 
On 10/25/06, Sathya Thammanur <[hidden email]> wrote:
Ye Wu,
RAW API does not use any of the kernel services like mailboxes, semaphores. The RAW API works on a callback mechanism as in the application, call back functions should be registered with the lwIP stack for various events associated with a protocol.

Hope this helps in understanding. Attached is a TCP based echo server example which you can use for your understanding. Along similar lines, UDP events need to be registered with stack (depending on whether you use server or client).

Sathya

_______________________________________________
lwip-users mailing list
[hidden email]
<a onclick="return top.js.OpenExtLink(window,event,this)" href="http://lists.nongnu.org/mailman/listinfo/lwip-users" target="_blank"> http://lists.nongnu.org/mailman/listinfo/lwip-users



_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users
Reply | Threaded
Open this post in threaded view
|

Re: help: how to use interrupt in RAW_API mode under Xilinx-V2

ye.wu
Oh, i see.
 
Thanks a lot, Sathya.
 
I can get a speed of around 1MByte/s now in a UDP packet transmit when working in the interrupt mode and with Cache open.
 
I found that if we put Simple DMA and Cache together, there seems some problem.
And in the document, it is said that the .data can not be cached and they suggest to put it into a BRAM memory for better performance.
i did so, and put it into plb_bram_if_cntlr_1. but the address is just under my Cache region. Can we set the exactly cache region in the SBS?
We can only see XCache_EnableDCache enabled a large range of memory address for cache or need i change the address of  my plb_bram_if_cntlr_1 ?
And i also found that we can't put .data into the docm_cntrl which is connected by a D-COM controller to PPC?
 
By the way, can we use scatter gather DMA? i haven't see in the document that Raw_API support scatter gather DMA.
 
And i found that the speed get a peak about 1.3MB/s when the package length is set to 1470 bytes in my UDP programme. When i try to send a large package, there seems no trans back then. is the package length restricted by the pbuf_pool_size that is set to 1536 or is there anything wrong in my UDP receive function ?
    void *receiveUDP(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) {
          udp_send(udpstructreceive,p);
          pbuf_free(p);
    }
(And my test program is a UDP client that set under Windows and keep on transmit a package of certain length and receive it.)
 
Thanks for your time and patient to help me.
 
Best Regards,
Ye Wu

 
On 10/25/06, Sathya Thammanur <[hidden email]> wrote:
Ye Wu,
You can comment this for the older version of lwIP (0.5.3). In the new version (0.7.2), the lwIP adapter was optimized for performance and this function triggers the packet processing while the interrupt just retrieves the packet.

Sathya

_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users