- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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. BillLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Basically yes.
What about memcpy optimizations? Maybe worth adding a dma?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That might be a good idea :)
Currently trying to debug the large chunk issue but there is still a big problem though... let's first focus on that. :p- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Great, I think this project could be maintained by more people than only You. Github maybe?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yeah, that was the idea :) I wanted to make the installer automatically download the latest version of LwIP and FreeRTOS but that wouldn't be possible on windows systems since they don't have curl and wget by default. Maybe I can implement this for the dev tree on github though... I'll be back Tuesday...
Further more, I think I found the possible cause of the bug, was just about to mail the mailing list for any advice. Hopefully I'm on to something ;)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One part of the bug solved, the input task first used the raw input method now input is inserted into the tcp stack via tcpip_input. Now I can send 14KB with one write... when I try to send more in one go the write function doesn't return, hope to fix it today!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hmm, seems like lwip_ping_target_data() is a custom procedure?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 :)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Pending indicates that an ARP query has been send, but no response has been received yet.
By the look of it, it's also possible to force an ARP request via 'etharp_query', however you need to make sure you call 'ethernetif_input(&alteraTseNetif)' after if you are running without OS. Since the ARP replies are only updated if you process the newly received packages after 'etharp_query' has been called. You should also take into account that there is a slight delay between the send / receive so if you place both calls without delay between them the response probably hasn't been received yet. Another thing to take in account is that you can't call 'etharp_query' directly when you are using an OS since this function uses the raw API without thread safety support. This means your ARP and PBUF table isn't protected against cross thread actions.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oh, that was the issue - I haven't done ethernetif_input(&alteraTseNetif) call. Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Btw, is it possible to redefine LWIP_DEBUGF() to use printf() somehow? That native debug use some interesting variables types.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In cc.h you should
# define LWIP_DEBUG
# define LWIP_PLATFORM_DIAG(x) printf(x)
and in lwipopts.h you should scroll down (approx line: 1290) there you can find all debug defines so you can enable / disable different functionality's. This is done because if you would enable all at once it would cost quite much processor time :p
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- In cc.h you should
# define LWIP_DEBUG# define LWIP_PLATFORM_DIAG(x) printf(x)
--- Quote End --- printf should be without parenthesis, something like #define LWIP_PLATFORM_DIAG(x) do { printf x; } while(0)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
DipSwitch,
I think there is a problem in your (and Bill’s) driver. low_level_input() in altera_tse_ethernetif.c allocates pbufs for incoming packets with pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL). By default PBUF_POOL_BUFSIZE evaluates to 1080 and, consequently, longer packets corrupt memory. In my code I simply redefine PBUF_POOL_BUFSIZE to be 2000, but for universal driver, like yours, some more elegant way should be found.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page