Forum Discussion
Altera 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
Fixed it! The bug occurred because (MEM_SIZE < TCP_SND_BUF), this makes a write function block forever if the write (length > MEM_SIZE) I'll fill a bug report when nongnu.org is up again. New release will be released today! Now off to re check the entire config, make it more logical and do some final testing, later today / this evening I'll create a GitHub repository with all the sources and a TODO / Wishlist :lol:
- Altera_Forum
Honored Contributor
Created a git repository with the latest sources has been created. https://github.com/engineeringspirit/freelwip-nios-ii this version works stable but is far from optimized.
- Altera_Forum
Honored Contributor
--- Quote Start --- Created a git repository with the latest sources has been created. https://github.com/engineeringspirit/freelwip-nios-ii this version works stable but is far from optimized. --- Quote End --- Thank you for the link. I have played a bit with your package - very convenient and easy to use. The example works, but it constantly prints "Error: BlockQ.". What may be the reason? Web- and echo-servers work fine. AUTOIP doesn't work - lwip_main.c misses# include <lwip/autoip.h>. Also, if you expose LWIP_AUTOIP to BSP Editor, than, probably, LWIP_DHCP_AUTOIP_COOP and LWIP_DHCP_AUTOIP_COOP_TRIES should also be here. Regards, Igor - Altera_Forum
Honored Contributor
--- Quote Start --- Hmm disabling the timer task was a bad idea, it makes the stack run quite unstable... enabled it again. --- Quote End --- DipSwitch, How to reproduce this instability? I run with# define MY_TIMER=0 and everything seems to be fine. It looks like in your implementation lwip timers are called both from native tcpip_thread and from your timer task. Is this intended behavior? - Altera_Forum
Honored Contributor
Sorry, I am a bit busy with all kinds of stuff.
First thanks for trying the release. That 'error' comes from an FreeRTOS demo task and I have no idea what it means... Didn't really have time yet to find out where it came from. AUTOIP wasn't tested yet so it would be possible it doesn't work. Maybe it will be fixed in a next release. Never worked with AUTOIP before so need to do some research work first. :) The timer issue was fixed. I know both tasks are calling the LwIP timers, but the response time seams faster that way... maybe there is something else missing which leads to this? Regards, Nick - Altera_Forum
Honored Contributor
A small issue on-topic:
I am trying to get MAC address from a known IP address device. LwIP allows to query the device for its address and then search the ARP table for particular address: arp_query = etharp_query(&alteraTseNetif, &alteraTseNetif.gw, NULL); arp_find = etharp_find_addr(&alteraTseNetif, &alteraTseNetif.gw, &ret_eth_addr, &ret_ip_addr); As You can see, I am trying to get the MAC address of my gateway. The first command sends gratuitous ARP, then ARP request and finaly, the stack receives ARP reply (returns ERR_OK, which means no errors) - everything is OK here. Then I issue a search using etharp_find_addr(), which returns me -1. Let's check what's inside: s8_t etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr **eth_ret, ip_addr_t **ip_ret) { s8_t i; LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL", eth_ret != NULL && ip_ret != NULL); LWIP_UNUSED_ARG(netif); i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); if((i >= 0) && arp_table.state == etharp_state_stable) {*eth_ret = &arp_table.ethaddr; *ip_ret = &arp_table[i].ipaddr; return i; } return -1; } I see that I receive table index i=0, which is fine, but the table state is not ETHARP_STATE_STABLE. I've checked that no matter what I try, I always get ETHARP_STATE_PENDING, which returns me MAC 00:00:00:00:00:00. How can I find the MAC address of the requested IP? I believe I am on the right way, but I don't know how to move state from pending to stable. Any ideas? Thanks.
- Altera_Forum
Honored Contributor
You must force an MAC resolve first, this can be accomplished by sending an UDP or ICMP packet to the address you are trying to resolve. How we are doing this is by sending ping packets to the host we want to resolve.
Here is the peace of code we use to resolve the mac address of the destination:while (mac->mac == 0 && --nRetries) { // avoid context switching which could result in ARP entry cleanup and cause invalid data while memcoping portENTER_CRITICAL(); // if result is positive we found a match if (etharp_find_addr(netif_default, &ip_req, ð_mac, &ip_ret) >= 0) memcpy(mac->bytes, eth_mac->addr, MAC_ADDRESS_SIZE); // enable interrupts back on portEXIT_CRITICAL(); // only sleep if we don't have a MAC yet if (mac->mac == 0) { lwip_ping_target_data(ipaddr, 1, 1, (u8_t*)"hello", (sizeof("hello") - 1)); Sleep(100); } } - Altera_Forum
Honored Contributor
Hmm, seems like lwip_ping_target_data() is a custom procedure?
- Altera_Forum
Honored Contributor
Yeah it's in the LwIP/FreeRTOS port I wrote, but it uses the socket interface so it will only work if you use that. What it basically does, is sending an ICMP ping packet to the target. What you could do is write a function which sends an UDP packet to the requested target and then start processing the input for a while. When 10ms (in case of slow networks) or so has passed the target's mac is probably in your ARP table ready to be found :)
- Altera_Forum
Honored Contributor
Hmm, so ping or other packet sending is the only option? Basically, it's quite strange, since LwIP already sends gratuitous arp, then arp request and finally gets arp reply. Table is filled with data, but state is pending. I just don't understand when the entry is set to be pending and when it's stable?