Check available RAM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Check available RAM

1,318 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Muis on Sun Jan 20 04:29:00 MST 2013
Im getting a lot of hard-faults in my project lately, and I suspect its because of the system running out of RAM (I dont know how to see some kind of reason-code for the hard-fault, so I can only assume).

Is there an ARM instruction that returns how much memory the system has left? So I can periodically print that out for debug purposes, and see if its getting too low? I know I could write wrappers for the malloc()/free() functions, but that doesnt tell me anything, because RAM will also be occupied by static arrays in my code, which would not be counted with a malloc-wrapper.
0 Kudos
12 Replies

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Brutte on Mon Jan 21 16:19:58 MST 2013

Quote: muis
Im getting a lot of hard-faults in my project lately,
Is there an ARM instruction that returns how much memory the system has left?



You need to set a data breakpoint on access write then.
That works in both halting and monitor modes.
The functionality sits in DWT (ARMv7).
Breakpoints' locations are modifiable in software (by the core, at runtime) so if you want to know when stack crashes over heap or ram function, etc. then it is doable but quite complicated (as it would require malloc wrapper to move the boundary at run-time).
That is why you should try setting a data breakpoints (possibly with range) on some fixed locations first (you can do it by the dongle or by the core), to make sure stack collision is the actual problem. This is called "high water mark".
ARMv7 support up to 4 of these data breakpoints (sometimes called watchpoints) with fancy read/write/read_or_write, within some range etc. It will notify you whenever a suspicious location is accessed.
0 Kudos

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by micrio on Mon Jan 21 10:19:59 MST 2013
One further problem is that even if you find out how much memory is
available at one time it may not be available when you need it.   You may
be better off by taking the memory that you want for this optional
feature first.   If some other more important code has a malloc fail then
release the optional block and turn off the special feature.

Using malloc in limited memory environments can get tricky.   Often it is
better to allocate everything statically.   If it all fits then you are done.   If
it does not fit then you can workout some reuse scheme.   This is much
safer than attempting to make malloc work in your code where it may
often fail.   Is your code robust enough that any malloc may fail and
it will continue to run?

Isn't programming in a limited memory environment fun!

Pete.
0 Kudos

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Mon Jan 21 05:15:25 MST 2013
I don't think this information is available. It is information that is internal to the C library and is different for each one.

I don't know how it is implemented, but would guess that the free and allocated memory are stored in a series of linked-lists. You would have to traverse all linked lists to find out how much was available 'in total'. It may even be that the library doesn't know if any particular block size is available as many memory managers will only attempt recombine free memory blocks when a block of the requested size is not available.

I think you are asking for the impossible and you will need to find a different way to achieve your aims.
0 Kudos

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Mon Jan 21 05:12:11 MST 2013
[FONT=Tahoma][SIZE=1]Why not write a function such as (btw my "C" is a bit rusty)

[/SIZE][/FONT][FONT=Tahoma][SIZE=1]
[/SIZE][/FONT]
long GetBiggestMalloc(void)
{
    long probe = 0x10000; // 1MB  or whatever you think as a maximum
    void * result;

    while (1)
   {
        result = malloc(probe);
        if (result != NULL)
        {
             free(result);
             return(probe);
        }
       probe >>= 1;
       if (probe < 0x400)          // 1K or whatever you think as a minimum
            return(0);
}
[FONT=Tahoma][SIZE=1]
Should only go round the loop a max 7 times.

Also read the map file (set prefs to generate if neccessary). That is what it is for!

Regards, Mike


[/SIZE][/FONT]
0 Kudos

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Muis on Mon Jan 21 04:54:06 MST 2013

Quote: TheFallGuy
I'm not sure that is something you can ever actually know reliably. Assuming you are using malloc AND free, then memory will get fragmented, so it is not all in one "chunk" that can be queried - it will be all over the heap.



Even knowing what the largest "chunk" that is available is, would tell me more than I know now. If the largest free chunk is >2 KB I feel comfortable that my program doesn't run out of RAM somewhere.
0 Kudos

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Mon Jan 21 04:41:31 MST 2013
I'm not sure that is something you can ever actually know reliably. Assuming you are using malloc AND free, then memory will get fragmented, so it is not all in one "chunk" that can be queried - it will be all over the heap.
0 Kudos

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Muis on Mon Jan 21 04:14:25 MST 2013

Quote: CodeRedSupport
Are you actually checking the value returned by any of your calls to malloc() ??



Yes.. But I just wanted to have some kind of information about the amount of free memory. When I know my current firmware has 4KB free RAM left while running, I can enable extra features of my program (like long filename support for FAT for example). But currently I haven't got a clue if Im close to the limit or not. My only option is to enable features until I get weird bugs from stackoverflow or hardfaults, and I would feel safer if I just know in advance how much is left.
0 Kudos

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Mon Jan 21 03:25:51 MST 2013

Quote: muis
I know, but to check the amount of available RAM it would require me to run malloc(1) in and endless loop untill it returns an error. There must be some more efficient way?



Are you actually checking the value returned by any of your calls to malloc() ??

A good reference for malloc() is the following page...

http://www.cplusplus.com/reference/cstdlib/malloc/

There are also some notes on heap usage with Redlib in the following FAQ:

http://support.code-red-tech.com/CodeRedWiki/redlib_v2_notes

Generally information on application memory usage can be found in this FAQ:

http://support.code-red-tech.com/CodeRedWiki/FlashRamSize

And information on debugging hard faults (which can be done with LPC-Link) in this FAQ:

http://support.code-red-tech.com/CodeRedWiki/DebugHardFault

Regards,
CodeRedSupport
0 Kudos

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Sun Jan 20 13:04:51 MST 2013
Muis,

the short answer is no. There is no ARM instruction to check for the available memory. For dynamic allocated memory using malloc() this is done during run-time and for all global or static variables this done during compile time.
The compiler uses a set of .ld files that describe the memory layout and which part of code or data is placed in which memory section.

If you look in the <project>_Debug.ld you'll find a number of memory sections: .text for code, .data for pre-initialized data and .bss for zero initialized data.
The rest of the RAM is used for heap and stack, growing towards each other.

One thing you could do is to initialize the section of memory from _pvHeapStart all the way up to _vStackTop with a known pattern (e.g. 0xbaddfood). Then you can examine the memory after a hard fault occured to see if at some point in time the stack touches the top of the used heap.

O... make sure that you do this initialization of memory inside the ResetISR() routine in the startup code or leave some memory free to prevent overwriting part of the stack that is already in use.

Rob
0 Kudos

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by micrio on Sun Jan 20 09:36:05 MST 2013
If you are checking the return code from malloc then that is probably not your
problem.   Have you looked at your map file?   Does the layout of your RAM
seem resonable?

To check if you have a stack overflow just look at the RAM above your
heap.   You have not said what processor so I will use my environment,
LPC1114/301, for reference.   My top of heap is defined my something
called "_pvHeapStart".   My map has it at 0x100007B0.   That means all
RAM below that address is used for heap and above is stack.   The
"_vsStackTop" defines the top of the stack and the top of RAM too.   Since the
stack grows down it had better not hit the heap address.   There is no hardware
protection for this in my CPU.   If I look at RAM just above this address
I had better see zeros.   The init code zeros all RAM not otherwise initialized.

If I see something other than zeros it is highly likely that the stack has
grown into my heap.   This is a disaster and produces really hard to find
errors.

Some things to check in your code;

*   Are you putting really big things in your stack?   Not necessarily a wrong
thing to do but in a limited RAM environment it could be a problem.   Try
making them a global as a test.   You could go through your code and
change your automatic variables into globals step by step.   You may
find your problem.

*   Are you recursing?   That is always a fun problem to debug.   If you
recurse try some limiting counter and exit if you go too deep.

*   Are interrupts re-entering?   Try changing interrupt priorities.   Perhaps
run them at all the same priority.

*   To catch a stack overflow put a write watchpoint just above your heap.

Hope this helps;
Pete.
0 Kudos

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Muis on Sun Jan 20 07:31:27 MST 2013

Quote: micrio
Presumably malloc returns an error is you run out of memory.



I know, but to check the amount of available RAM it would require me to run malloc(1) in and endless loop untill it returns an error. There must be some more efficient way?


Quote: micrio

When you get your hard fault has your stack grown down into your heap?



I don't know how to check that, and Im not even sure the hard-fault has anything to do with memory usage. It would be really helpfull to know the last executed line (or some reason code), but I cant find any information on how to debug hardfaults. The only thing thats on the wiki is that if you buy red-probe you get more information, but I hope there is something for the normal LPC-link too.
0 Kudos

1,018 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by micrio on Sun Jan 20 06:27:03 MST 2013
Presumably malloc returns an error is you run out of memory.   You are
checking the return code?   More likely would be a stack overflow.
When you get your hard fault has your stack grown down into your heap?

Pete.
0 Kudos