Forum Discussion
Altera_Forum
Honored Contributor
16 years agoAltera TSE driver and example program for lwIP (1.3.2)
After many many requests and complaints about lack of support and/or documentation for support of lwIP for the Altera TSE, I have developed a drop-in TSE driver and example program and made this available to the NIOS II community. This was done for NIOS II 8.1 SP0.01. I don't expect difficulty with version 9.x.
This is for the latest version of lwIP (the latest is as of this post) for a minimal program and HTTP server based on the http server in the lwIP contrib folder. The lwIP TSE driver uses the altera_avalon_tse driver and SGDMA as-is. There is a complete (as in 41-step) set of instructions on creating the project and example program. More information and the link to the driver is available here: http://lwip.wikia.com/wiki/available_device_drivers#lwip_1.3.2 Please direct any questions, changes for NIOS II 9.1, or comments to this thread. 12-16-2010 update: This example works with NIOS Version 10.0 with some tweaks to the procedure to create the project. Also, a lwIP 1.4 release candidate has been out for a while and it drops into this example (in place of 1.3) without changes. Bill257 Replies
- Altera_Forum
Honored Contributor
Dear billa:
My board can ping it,But I meet another qusetion,I want to use the udp protocol to send and receive message!Unfortunately I can't send.I want to use the board acts as client and send the message to computer.maybe my code lose someting important,could you help me check it? waiting for your reply,thank you very much! here is my code: /* * Simple lwIP 1.3.1 example program. * * Expects no Operating System (NO_SYS=1) * * lwIP initialization and optional DHCP and WEB server support can be * enabled by setting# defines described below. * * You must plug in your board's MAC address below before compiling! * * Contributed by: Bill Auerbach [email protected] */ # include <stdio.h> # include <unistd.h> # include "system.h" # include "sys/alt_timestamp.h" # include "sys/alt_alarm.h" # include "lwip/init.h" # include "lwip/netif.h" # include "lwip/dhcp.h" # include "lwip/tcp.h" # include "lwip/udp.h" # include "lwip/stats.h" # include "lwip/ip_frag.h" # include "lwip/ip_addr.h" # include "netif/etharp.h" # include "string.h" # include "INC/alteraTseEthernetif.h" # include "alt_types.h" # include "sys/alt_irq.h" # define mSdelay(x) usleep(x*1000) //#define USE_DHCP 1 //#define LWIP_UDP 1 # define STATIC_IP IP4_ADDR(&lwipStaticIp,219,245,66,185) # define STATIC_NM IP4_ADDR(&lwipnetmask,255,255,255,0) # define STATIC_GW IP4_ADDR(&lwipgw,219,245,66,254) # define STATIC_DA IP4_ADDR(&destAddr,219,245,66,112) struct ip_addr lwipStaticIp; struct ip_addr lwipnetmask; struct ip_addr lwipgw; struct ip_addr destAddr; // Define BUILD_HTTPD to 1 to build the httpserver_raw contrib example # define BUILD_HTTPD 1 // Alarm & timer variables - provides a 250mS counter void lwipProcessTimers(void); void Init_UDP(); static alt_alarm lwipAlarm; static alt_u32 lwipProcessTimerFlag; static alt_u32 lwipTicksPer250mS; static alt_u32 lwip250mStimer; // Alarm callback function. alt_u32 lwipAlarmCallback(void* context) { lwipProcessTimerFlag = 1; // Set flag to process timers return lwipTicksPer250mS; } // UDP callback function. void UDP_Receive(void *arg, struct udp_pcb *upcb, struct pbuf *p,struct ip_addr *addr, u16_t port) { struct ip_addr dAddr = *addr; if(p != NULL) { udp_sendto(upcb,p,&dAddr,port); pbuf_free(p); } } // Define netif for lwIP struct netif alteraTseNetif; struct udp_pcb *UdpPcbR; int main() { char udpdata[] = "UDP has Initialed successfully, begin to transfer!\r\n"; static struct ip_addr ip_zero = { 0 }; struct pbuf *psend; struct udp_pcb *UdpPcbS; void httpd_init(void); mSdelay(1000); // test_jtag_uart(); printf("Running...\n"); lwip250mStimer = 0; lwipProcessTimerFlag = 0; lwipTicksPer250mS = alt_ticks_per_second() / 4; if (alt_alarm_start (&lwipAlarm, lwipTicksPer250mS, lwipAlarmCallback, NULL) < 0) { printf ("System clock is required!\n"); for(;; } // Load platform specific MAC address into netif alteraTseNetif.hwaddr[0] = 0x00; alteraTseNetif.hwaddr[1] = 0x1C; alteraTseNetif.hwaddr[2] = 0x23; alteraTseNetif.hwaddr[3] = 0x17; alteraTseNetif.hwaddr[4] = 0x4A; alteraTseNetif.hwaddr[5] = 0xCB; // Initialize lwIP, Altera TSE and the ethernetif lwip_init(); if(netif_add(&alteraTseNetif, &ip_zero, &ip_zero, &ip_zero, alteraTseNetif.state, ethernetif_init, ethernet_input) == NULL) { printf( "Fatal error initializing...\n" ); goto fatal; } netif_set_default(&alteraTseNetif); // Initialize Altera TSE in a loop if waiting for a link printf("Waiting for link..."); while(((struct ethernetif *) alteraTseNetif.state)->link_alive!=1) { mSdelay(1000); putchar('.'); tse_mac_init(0, alteraTseNetif.state); } printf("OK\n"); STATIC_IP; STATIC_NM; STATIC_GW; netif_set_addr(&alteraTseNetif, &lwipStaticIp, &lwipnetmask, &lwipgw); //netif_add(&alteraTseNetif, &lwipStaticIp, &lwipnetmask, &lwipgw, NULL, ethernetif_init, ethernet_input); //netif_set_default(&alteraTseNetif); netif_set_up(&alteraTseNetif); printf("IP address: %s\n", ip_ntoa(&alteraTseNetif.ip_addr)); printf("IP netmask: %s\n", ip_ntoa(&alteraTseNetif.netmask)); printf("IP gateway: %s\n", ip_ntoa(&alteraTseNetif.gw)); # if BUILD_HTTPD httpd_init(); # endif Init_UDP(); STATIC_DA; printf("UDP Dest IP address: %s\n", ip_ntoa(&destAddr)); //psend = pbuf_alloc(PBUF_RAW, sizeof(udpdata), PBUF_POOL); psend = pbuf_alloc(PBUF_RAW, sizeof(udpdata), PBUF_RAM); psend->payload = (void *)udpdata; if (!psend) { printf("Can't allocate buffer.\n"); goto fatal; } UdpPcbS = udp_new(); if (!UdpPcbS) { printf("udp_new() failed.\n"); goto fatal; } udp_bind(UdpPcbS, &lwipStaticIp, 67); if (udp_bind(UdpPcbS, &lwipStaticIp, 67) != ERR_OK) { printf("udp_bind() failed.\n"); goto fatal; } udp_connect(UdpPcbS, &destAddr, 67); if (udp_connect(UdpPcbS, &destAddr, 67) != ERR_OK) { printf("udp_connect() failed.\n"); goto fatal; } // This is the main loop for lwIP - other processing can be done by calling application functions. printf("SUCCESS\n"); while(1) { udp_send(UdpPcbS,psend); mSdelay(1000); } fatal: for(;; /* { // Process lwIP timer dependent code if(lwipProcessTimerFlag) lwipProcessTimers(); // Poll lwIP for incoming packets. ethernetif_input(&alteraTseNetif); } return 0; */ } //UDP Init void Init_UDP() { UdpPcbR = udp_new(); udp_bind(UdpPcbR, IP_ADDR_ANY, 67); udp_recv(UdpPcbR,UDP_Receive,NULL); } // Run this every 250mS to update lwIP timers void lwipProcessTimers(void) { lwipProcessTimerFlag = 0; lwip250mStimer += 250; if( (lwip250mStimer % TCP_TMR_INTERVAL) == 0 ) { tcp_tmr(); } if( (lwip250mStimer % ARP_TMR_INTERVAL) == 0 ) { etharp_tmr(); } # if IP_REASSEMBLY if( (lwip250mStimer % IP_TMR_INTERVAL) == 0 ) { ip_reass_tmr(); } # endif # if LWIP_AUTOIP if( (lwip250mStimer % AUTOIP_TMR_INTERVAL ) == 0 ) { autoip_tmr(); } # endif # if LWIP_IGMP if( (lwip250mStimer % IGMP_TMR_INTERVAL ) == 0 ) { igmp_tmr(); } # endif # if LWIP_DHCP if( (lwip250mStimer % DHCP_FINE_TIMER_MSECS ) == 0 ) { dhcp_fine_tmr(); } if( (lwip250mStimer % (DHCP_COARSE_TIMER_SECS*1000) ) == 0 ) { dhcp_coarse_tmr(); } # endif # if LWIP_DNS if( (lwip250mStimer % DNS_TMR_INTERVAL) == 0 ) { dns_tmr(); } # endif } - Altera_Forum
Honored Contributor
Add Include Path ${workspace_loc:/altera.components/Nios II Software Packages/altera_iniche/UCOSII/inc}
I cannot unstand why? this example use UC/OS??? - Altera_Forum
Honored Contributor
- Altera_Forum
Honored Contributor
- Altera_Forum
Honored Contributor
- Altera_Forum
Honored Contributor
Hi,billa
cannot insert breakpoint 0 is my problem! I use quartus 9.0 and nios 9.0,and I use this example to build the project http://www.alteraforum.com/forum/showthread.php?t=23787&page=3 now I can ping the board,but I can not use UDP to send the packget,so I try to debug step by step,and set the breakpoint at function udpsend().(see in picture1)As I seeing the flow,when it return,until to the function udp_sendto_if() ,pointout wrong(see in picture 2),this problem makes me truble,a week,could you give me some advices. best wishes to you,waiting for your reply.thank you! - Altera_Forum
Honored Contributor
Please stop sending the same question multiple times. It won't get you more answers.
I rarely use the debugger so I can't be of much help here. For starters is 0xe11fc a valid program address, i.e. an address in your main RAM region? IF the address is complete bogus, it could indicate a memory corruption or a head/stack collision. - Altera_Forum
Honored Contributor
--- Quote Start --- Hi BillA (and others !), Really big thanks for your lwip port on altera. I have succefully implemented the webserver template with lwip on a bemicro SDK from arrow. I have a question because i don't know how to do it : actually i have my sgdma Tx and sgdma Rx mapped on a DDR , the same DDR where the CPU data an instruction is mapped. Now imagine i want to use an onchip ram for sgdma tx and sgdmarx instead of DDR. (but CPU still mapped to DDR) I tried direclty but this is not working. if you have any idea . thanks --- Quote End --- I haven't had much luck getting this to port on the BemicroSDK... do you have any pointers on the changes you needed to make to get it to work? - Altera_Forum
Honored Contributor
--- Quote Start --- Hi,billa cannot insert breakpoint 0 is my problem! I use quartus 9.0 and nios 9.0,and I use this example to build the project http://www.alteraforum.com/forum/showthread.php?t=23787&page=3 now I can ping the board,but I can not use UDP to send the packget,so I try to debug step by step,and set the breakpoint at function udpsend().(see in picture1)As I seeing the flow,when it return,until to the function udp_sendto_if() ,pointout wrong(see in picture 2),this problem makes me truble,a week,could you give me some advices. best wishes to you,waiting for your reply.thank you! --- Quote End --- This kind of error typically means the hardware definition is wrong. Something is wrong with memory, clocks, speeds or something. In the past I've told people that have problems with this example to get a standard Altera example running - like Simple Socket Server as-is on your hardware (create app and BSP with that template). If the Simple Socket Server won't run, this lwIP example will never run either. It's pretty hard to test and debug software with unstable hardware. BillA - Altera_Forum
Honored Contributor
--- Quote Start --- I haven't had much luck getting this to port on the BemicroSDK... do you have any pointers on the changes you needed to make to get it to work? --- Quote End --- If an Arrow FAE will comp me a BemicroSDK kit or if you want to send me one, I'll get lwIP running on it. I don't use Cyclone IV at work so have no access to this kit (nor the need to ask the boss to get me one). You will have to get lwIP hooked into the TSE driver used on the IV and configure lwIP for accessing the PHY. Not trivial if you've not done an lwIP port, and it even might not be so trivial if you have. :) BillA