How static and dynamic RAM are calculated?

General discussion on mikroPascal PRO for dsPIC30/33 and PIC24.
Post Reply
Author
Message
VCC
Posts: 463
Joined: 08 Jun 2009 18:31
Location: Romania

How static and dynamic RAM are calculated?

#1 Post by VCC » 05 Feb 2021 17:07

Hi,
can somebody explain please, how the compiler calculates static RAM and dynamic RAM? I am troubleshooting some stack overflow in a big project, and don't have any clue about how the RAM is reused (or not) when calling functions. To some extent, it is visible that dynamic RAM usage increases when adding local variables to functions and decreases when making them global. Static RAM goes vice versa.
However, when adding up the reported amount of static RAM, dynamic RAM and Heap, they are far from the total available RAM in the microcontroller.

The mentioned application targets PIC24EP518GU810 and is compiled with mikroPascal v.7.1.0.
For example, on one instance, static RAM is 19119 bytes, dynamic RAM is 1872 bytes, and heap is 10800 bytes.
When moving some variables to be global, static RAM is 20517 bytes, dynamic RAM is 474 bytes, and heap is the same, 10800 bytes.
Pushing variables to be local, static RAM is 10735 bytes, dynamic RAM is 5664 bytes, and heap is the same, 10800 bytes.

At this point, if I disable the "Dynamic link for string literals" from compiler options, the static RAM usage goes to 11243 (vs 10735), but the dynamic RAM stays at 5664.

In all of the above cases, the application goes into a stack overflow trap, and this is not caused by some deep nested calls path, but simply by the size of local variables. Sorry I can't post the code. Anyway, it is too big too look at.
So, no matter how the reported RAM usage is, adding up static RAM, dynamic RAM and heap, does not amount to the total available, which is 52k for this PIC. I expect that the available (unreported) RAM would be used to properly handle "stack allocation", but I guess it is something else.
Is it also possible that calling these big functions, using function pointers, to make the compiler lose track of the memory usage?

Thank you :)

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: How static and dynamic RAM are calculated?

#2 Post by filip » 11 Feb 2021 09:20

Hi,

Static RAM is used for objects with static duration such as global and static variables. Dynamic RAM is used for function frames (parameters, local variables and call stack).
Dynamic basically shows the amount that is left for Stack usage (function frames which holds locals, parameters, return address...)

Since stack must be contiguous (can not be fragmented), if RAM is broken by some absolutes, size available for stack can be smaller than whole dynamic size that is reported.
The largest chunk of continuous free ram is used for Dynamic RAM. So, basically, the compiler splits the Dynamic RAM by the amount of HEAP RAM and adds this to the Static RAM.

Regards,
Filip.

VCC
Posts: 463
Joined: 08 Jun 2009 18:31
Location: Romania

Re: How static and dynamic RAM are calculated?

#3 Post by VCC » 11 Feb 2021 10:55

Thank you, this is useful information. It makes sense now, kind of. One of the functions in this app, takes more than 8KB of local variables. Probably that is the one, which if pushed to stack would result in stack overflow.

VCC
Posts: 463
Joined: 08 Jun 2009 18:31
Location: Romania

Re: How static and dynamic RAM are calculated?

#4 Post by VCC » 21 Apr 2021 07:18

Hi,
going back and forth between projects, so I'm at this one again.
I've managed to move those big local variables into heap, so they would not be pushed to stack on function call, only some pointers to them. However, the reported usage of dynamic memory seems to be close to the old values.
What doesn't make sense is that out of the 52KB (53248 bytes) of available RAM, about half is not used, so it's not part of the required dynamic memory.
Simply adding static, dynamic and heap, does not add up to the total available RAM. What is the proper way of calculating the available RAM?

Here are some calculations of two experiments, one with 20400 bytes of heap, and the other with 400 bytes. Of course, setting the heap to 400 bytes, would not be enough for the application, it is only for reporting purposes.

Code: Select all

Static RAM (bytes): 3008   Dynamic RAM (bytes): 5216     Heap: 20400  (14896 free words from 0x00006BA1 to end of RAM.  = 29792 bytes)
Static RAM (bytes): 3008   Dynamic RAM (bytes): 25216    Heap: 400    (24896 free words from 0x00001D81 to end of RAM.  = 49792 bytes)

Code: Select all

3008 + 5216 + 20400 = 28624.     3008 + 20400 + 29792 = 53200.   Anyway, 5216 bytes of dynamic RAM are not enough to have a working code.
3008 + 25216 + 400  = 28624.     3008 + 400 + 49792   = 53200.
Now, compare 5216 to 29792 for the first case, then 25216 to 49792 for the second one. In both cases, 24576 bytes seem to be available (not used at all).

At a first look, I thought it's because of having recursion, the dynamic RAM would be reported smaller than what it seems to be available, but even removing the recursive calls, the reported dynamic RAM stays the same.
The recursion goes one or two levels deep, so the stack should not grow that much, but I'm not sure the compiler is able to figure that out.
For the graph below, I used PIC24MemoryStatistics. The green areas are the heap sections. Blue areas are the remaining used RAM, while the white areas represent unused/available RAM.

Heap.png
Heap.png (6.5 KiB) Viewed 1618 times
Thank you :)

Post Reply

Return to “mikroPascal PRO for dsPIC30/33 and PIC24 General”