Advanced Users can post their questions and comments here for the not so Newbie crowd.

Moderator: eriksl

User avatar
By eriksl
#81342 Now I was wondering, I am quite happy the way it works now. What is the advantage of trying to get lwip2 working, besides having ipv6? I think ipv6 is a nice to have in this case, but I don't want to spend many hours of work on it.

And an interesting thing related: as soon as I got completely rid of the espconn interface and the lwip interface was working, my througput for both udp and tcp went up from ~260 kbytes/s to ~750 kbytes/s. Also I have lots of dram memory more spare. I think that say "something" (again) about Espressif coding quality.

I must say I cheat a bit, by having my application code "fragment" oversize data (> udp/tcp payload) itself. The output buffer (4k) is completely filled by the application. It is handed to lwip as "readonly/no-copy" data in payload chunks. Every time a chunk is sent or acknowledged, the next chunk from the same buffer is sent. So lwip doesn't have much left to do, just arp and tcp ack.

Did you all know that udp packets are always sent directly but tcp packets are only sent in the background (never from the code that does tcp_send)? I just found out. The espconn interface hides this fact.
User avatar
By davydnorris
eriksl wrote:...
7) after that, IRAM was overflowed by about 1k, while previously I had 900 bytes spare. Checked ALL lwip source files and add the ICACHE_FLASH_ATTR (well in fact not that, but my own #define which is called "iram" and is, imho, somewhat more clear) to EVERY function I found.
8) for most of the sources I fixed, the IRAM usage did not go down. I found out why: for some of the functions, the ICACHE_FLASH_ATTR is applied to the functions themselves, for some of the functions it's applied to the function declaration (in the header files) and for some of the both. I added the attribute to many functions in the sources where it was already applied to the declaration in the header file (which I didn't spot at that time).
9) after I did ALL functions, IRAM usage was back at 900 bytes spare I had before. The question is how that comes, that I manually need to add "IRAM" attributes to functions, while the precompiled library from Espressif has that to all functions already. It could be that Espressif is using a different source internally, with all functions, marked as IRAM, but I found something else is going on. One of the recent updates of the SDK adds a line like to this the load script:
Code: Select all*liblwip.a:(.literal.* .text.*)
which makes all functions from lwip go to IRAM regardless their section attribute. Now I don't have a "liblwip.a" but three lib*.a files, this line wasn't working anymore. I added explicit lines for all of them in the load script and removed all ICACHE_FLASH_ATTR mentionings from source files (which Espressif should have done themselves) and all is well now.

I found this inconsistency is all over the place in the code and examples. People probably already know this but ICACHE_FLASH_ATTR is only needed on the function implementations, you don't need it on the definitions in header files (unless you're inlining or something I guess). It makes the headers much neater if you can leave it out, and also means you don't have to also include c_types.h
User avatar
By eriksl
#81377 I never did the trick on prototypes in header files. I feel it doesn't belong there. Where the function is linked to is of no concern to the code that calls the function, i.e. it should not be a part of the interface/contract.

That's why I didn't take notice of the the attributes in the header files in the first place.

Anyway, even with the attributes in the header files, it still doesn't cover all functions in LWIP, so you still end up wasting IRAM space. Those who are using the lwip lib compiled by Espressif will have all functions in IROM anyway, by the linker script.

That's one of things that annoys me greatly from Espressif. They tend to do things in one way, switch to another, but never clean up the first way, which makes the whole thing unclear and prone to error. They do this all of the time.

And by the way, you really don't need to include c_types.h to get a function into IROM. Just add a define like this
Code: Select all#define irom __attribute__((section(".irom0_text")))
to your source file or even use the __attribute__ line directly. I hate the long, capitalised and very unclear name they assigned to their version of this macro.

In fact, including c_types.h is never required. It defines integer types it shouldn't define (i.e. uint8 while they should have used the types in <stdint.h>: uint8_t). I go to great lengths to remove Espressif made up integer types from all sources and include files and replace them with the proper stdint.h ones. For LWIP that wasn't such a big deal in the end, because most Espressif's code is gone now (espconn).
User avatar
By eriksl
#81380 Something different. For LWIP2 to get working, I guess one would take the following approach:

- take the sources of Espressif
- remove all files that Espressif has added (Makefiles, espconn)
- remove all Chinese text (can never be original from LWIP)
- remove all Windows newlines (CR), they are in some files, probably added by some daft editor Espressif uses
- remove all invalid nested comments (probably also Espressif's fault)
- find out which lwip version was used to base the Espressif on, the include files have some defines for the version
- check out the original LWIP sources from git, specificly the commit associated with the release of the relevant version (they'll probably have a git annotation for release versions)
- use diff -ur to see what Espressif changed, it'll probably also produce some whitespace / nonfunctional patches, filter them out
- now have a go and try to incorporate the changes into the current LWIP sources. I have a hunch this will be the biggest task.