[betatesting] Memory reporting in compiler build

13 Sep 2010 . Edited: 15 Sep 2010

Hi

I'm trying to get an idea of how much RAM my code and libraries are using; it seems different on both code and libraries depending on whether I compile with the beta on or not. I know there is an issue with AHB reporting but I am not sure that can account for it all. Please see the post here; I'm confused about the amount of RAM claimed to be in use by the libraries when using the latest ethernet stack - if in the beta the AHB RAM is no longer used then it doesn't seem right.

Thanks
Daniel

14 Sep 2010

Hi Daniel,

I'll give you some answers that I hope may be useful to what I think is your question!

The beta compiler is improved, and should give improved results over the live one in most cases. Here is the result of a quick test to compile Donatien's EthernetNetIf on the two, with a simple main that just calls eth.setup():

So this shows the same or better results for everything, which is what we hoped for! As you mention, we don't count the AHB RAM under this analysis, as that is a bit specialist. In most cases, it will be dedicated to a particular Ethernet/USB driver etc.

With regard to how much memory is used by Donatien's stack, I guess that is down to the way he implmented things so you'd need to investigate. I think for example the HTTPClient/Server used STL, but not sure the lower parts did. A look through the code will probably show that up.

Simon

 

14 Sep 2010

Hi Simon

I've already had a quick look through the stack code and could not see anything obvious. I have an early version of Donatien's stack from when I was testing the client for him, and that compiles to under 3 kB of RAM, which seems more sensible. That's partly why I was questioning the RAM usage figures - they didn't feel right for the basic stack on its own.

So the question is not just the difference between the current and beta compiler, but also the old and new network stack.

Do you have any suggestions for how I can hunt down what is using the RAM in the stack? Is there an output from the compiler which gives more detail which you could send? I really don't want to hand over half my RAM (when you add in the http client as well) to the stack.

Regards
Daniel

14 Sep 2010

My 2 cents:

The stack has 2 configuration files, which can affect RAM usage significantly. One is lwipopts.h, another is NetCfg.h. In the latest stack code I noticed changes to both files. As a result, when I re-compiled my app with the latest stack, total RAM was above the available RAM. Needless to say the image did not execute at all. I played with lwipopts.h to get RAM total under the limit, and app came back to life. So you may want to look into lwipopts.h to see where your RAM differences come from.

14 Sep 2010

Hi Ilya

Did you compile in Donatien's code from http://mbed.org/users/donatien/programs/NetServicesSource/5zh9t

Simon and I have both used a simple main that just calls eth.setup(), and we end up with RAM usage around 12 or 13 kB.

Could you try your lwipopts and netCfg changes against that, and if you get less than 12 kB then post them? I've just had a play now and couldn't make a real dent in it.

Thanks
Daniel

 

15 Sep 2010

I tried to try, but cannot get the compiler to do anything tonight:

1. When I import Donatien's source, it has no mbed.lib. Trying to add it brings error message "Fatal Application Error: Resource object failed to load.

Please contact support and describe how you get this message." I cannot get past it.

2. When I stage a local copy with mbed.lib, I cannot import it - compiler hangs. I tried both Chrome and FF. It worked before, but not tonight. BTW, I was getting the same error after the import from local file, but it did not cause any apparent problems.

So no luck - I give up.

15 Sep 2010 . Edited: 15 Sep 2010

Hi Ilya

Can you try the following (with compiler in beta mode)?

1)  Go to http://mbed.org/users/donatien/programs/NetServicesSource/5zh9t and click Import into compiler as program. This will create a program NetServicesSource.

2) Right click on NetServicesSource in the compiler and select import library. Enter http://mbed.org/projects/libraries/svn/mbed/trunk as the source URL. This should add the mbed library.

3) Create the following main.cpp.

#include "mbed.h"
#include "EthernetNetIf.h"

EthernetNetIf eth;

int main() {

    EthernetErr ethErr = eth.setup();
    return 0;

}

4) Compile ... I get 13 kB Code and 0.6 kB Libraries RAM.

5) Fiddle with lwipopts and netcfg to reduce that footprint.

Thanks
Daniel

Edit ...

I just compiled Donatien's code from May with the beta compiler and I get 2.1 kB Code and 0.6 kB library, which is where my original questioning arises. This is a massive difference to the published stack now, I am not sure it is all down to lwipopts? I'd sure like that 10 kB of RAM back!

 

15 Sep 2010

No need to break it down like to a noob. I have compiler problem at step 2 - can't import. Workaround I found was to drag mbed library from another project. I get the same RAM usage. When I plug mine lwipopts.h/netCfg.h, I'm getting 14kB+6.3kB RAM. I have few increased buffers there, so it is inline. But I agree - RAM usage went up. It is a problem for me too.

15 Sep 2010

Hi Ilya, no offence intended, I am pleased that it is not just my imagination. I'll try and compare against the May code where the RAM usage appears so much less.

Regards
Daniel

17 Sep 2010

Problem solved! Compiled Donatien's new code down to 3.4 kB RAM in total!

Regards
Daniel

17 Sep 2010

Daniel, Great! Can you post what was the mystery?

18 Sep 2010 . Edited: 18 Sep 2010

In thinking how to write this up, I just discovered more of a mystery, which perhaps still needs addressing (pun intended?).

When Rolf did the original lwip port, he wrote "To leave more RAM to the application it shares the network RAM space with the lowlevel driver (..., AHBSRAM1 on LPC1768)."

This can be seen in his version of lwipopts.h:

#define MEM_POSITION                    __attribute((section("AHBSRAM1"),aligned))

Igor's post here clarifies that AHBSRAM1 is indeed the memory reserved for ethernet.

In Donatien's lwipopts.h, for some reason he has switched to using AHBSRAM0 (this is the space reserved for USB):

#define MEM_POSITION __attribute((section("AHBSRAM0")))

Perhaps this is to avoid clashes between the low level ethernet RAM required and that used by the networking stack code, so it was easier to separate them between AHBSRAM0 and AHBSRAM1. It does beg the question though, how much space is free in AHBSRAM1 and why can't it be used, when you have a project that needs to use AHBSRAM0 for USB (or other purposes).

To the specific problem with the 5 Aug 2010 version of the networking stack, I think this has occurred because Donatien has upgraded to a later version of the core lwip code, and not put the MEM_POSITION macros back in the core files mem.c and memp.c. If you go back to Donatien's 11 Jun 2010 version (using an earlier version of the core lwip code), you'll see the right place for MEM_POSITION (once in mem.c and three times in memp.c).

Making these changes to the 5 Aug 2010 code and recompiling results in the main RAM usage dropping to 3.6 kB (at the expense of AHBSRAM0 RAM of course).

I would still ask though, can the networking stack revert to making use of AHBSRAM1 as with Rolf's original port or was there a good reason to switch to AHBSRAM0?

I would also ask that we get some indication of RAM usage in AHBSRAM0 and AHBSRAM1 after a compilation (hence the reason to keep this discussion on this thread about memory reporting). Simon wrote "I agree we could make it more comprehensive, but hopefully this is a start!" Can I suggest now is a good time; I spent quite a few hours tracking down this issue in Donatien's code and it would have been immediately obvious with a view of the AHB RAM usage alongside the main RAM. I also want to use AHB RAM for other things (like my scmRTOS stacks and data acquisition buffers), so I would really like to be able to manage it carefully. RAM is the most precious resource on the mbed, and I don't share Simon's view above that "we don't count the AHB RAM under this analysis, as that is a bit specialist". I'm just a noob, and I'm asking for it (again after this experience), so that should be a good reason ;-). Could it at least be an option when viewing the build statistics (off by default to avoid confusion)? Is this too late to add before the beta goes live?

Regards
Daniel

21 Sep 2010

Hi Simon

I hope you don't mind if I bump this? I'd rather know whether issues relating to the networking stack are of interest.

Regards
Daniel

21 Sep 2010

If I understand your question, additional memory reporting features won't go in this release, but i'll make sure I pencil them in to be looked at in a subsequent release.

Thanks for the feedback!

Simon

21 Sep 2010

Hi Simon

Hehe that was one part of the question, but I'll be more explicit with the other parts:

1) Should the networking stack be using AHBSRAM0 or AHBSRAM1? The latest release uses neither, Rolf's stack used AHBSRAM1 and earlier versions of Donatien's used AHBSRAM0.

2) If you decide the answer to question 1 is yes, then will you fix the code (mem.c and memp.c), recompile Donatien's stack and do a new release?

Regards
Daniel

 

07 Oct 2010

Hi everyone,

I'll try to take the time to fix the missing AHBSRAM* stuff in the lwip core files.

It's usually more efficient to use these memory banks because the heap can't access it, and soforth using these leaves more dynamic memory free to allocate by the application.

Regards

Donatien

07 Oct 2010

Hi Donatien

Welcome back! In compiling the code myself, I took the decision to use AHBSRAM1 as with Rolf's original stack (since it is meant to be reserved for ethernet) rather than AHBSRAM0. Was there a reason why you were using AHBSRAM0 in earlier versions of the stack. I'm being extra careful with memory management because I'm using scmRTOS where you need to statically allocate separate stacks for each process; I'm putting those stacks in AHBSRAM1 at the moment and don't fancy a collision when I hopefully switch back to using your precompiled stack.

Regards
Daniel

 

 

09 Nov 2010 . Edited: 25 Nov 2010
user Donatien Garnier wrote:
I'll try to take the time to fix the missing AHBSRAM* stuff in the lwip core files.

Until Donatien has time to do this, I've made the changes available in a library, as well as a few other things. Documentation in the cookbook here.

Regards

 

08 Feb 2011

Added my "vote" for this on the suggestions page. My workaround at the moment is to just define a pointer to the base of AHBSRAM1 and reference in a C struct like fashion. Putting a class in there seems easy enough. Rather than having a constructor init it, I create a method called .init() (which does the same thing as the constructor would do). Then call init() via the base pointer and bingo, you get all 16k without the compiler usage stats noticing. Just have to remember to reference it via the base pointer.