2017-11-03 10:04 AM
After compiling the codes, my code size is:
Program Size: Code=20140 RO-data=316 RW-data=540 ZI-data=2412
Based on this information, how should I set my 'heap' and 'stack' size?
My first question is the 'heap' and 'stack' size is for Per Function call? Or is it for the entire program?
For example, if all my global variables are added up to, for example, 700 bytes total, then do I need to
set my 'heap' size to be at least 700 bytes? What would happen if I set heap size less than 700 bytes?
Of course each function call will have its own variables, and each function will call other functions so the stack size may not be known in advance. Will the uProcessor crash if the allocated 'stack' size in the .S file is less than needed during runtime?
So I guess my question is how would you determine heap and stack size?
Thanks.<
2017-11-03 10:24 AM
Global variables don't use the heap.
Local/auto variables use the stack (or registers as the compile feels appropriate), and their usage and your call depth will dictate how large the stack needs to be.
If you have something like
void foo(void)
{
uint8_t bar[512];
..
}
You're going to need a stack with over 512 bytes in it.
You can do some static analysis of your own code.
You can look at the .HTML file Keil's Linker generates with respect to stack utilization and call trees.
You can do dynamic analysis by filling the stack with a data pattern you recognize, and then look at how deep into the stack you get via the debugger, and a memory view place over the stack area.
You can have a routine that probes the stack to determine a maximal depth, and review that periodically.
The heap is going to be used by malloc() or new operations, malloc will return a NULL if it is full, you should aggressively check for this in your code.
You can walk the heap to see how much space remains, and the size of the largest contiguous piece.
The heap can have issues with fragmentation and resource leaks, you can wrap the malloc/free routines to monitor or instrument this.
2017-11-03 10:59 AM
Usually a linker will issue a MAP file and try to estimate recursively the stack depth for all things pointed from the interrupt vector table, from reset, from interrupts. This gives a rough idea of the stack size. If you use function pointers and/or malloc, the linker will be unable to give you a reliable figure, you'll have to top the number up.
If using an RTOS, things get worse as in this case you probably need a stack per task...
If short in RAM, check if you can use a buffer for multiple purpose at different time using 'union'
If using floats/double, check if you can use a fractional integer.
Look into the map file for each object file the needs in stack and global variable ram area.
2017-11-07 10:39 AM
Thanks for the information. I looked in the .html to find the function call with the maximum stack size and I guess I can approximate the stack size.
Is there a way to use the debugger to look at the stack size dynamically?
Thanks.
2017-11-07 11:03 AM
'
You can do dynamic analysis by filling the stack with a data pattern you recognize, and then look at how deep into the stack you get via the debugger, and a memory view place over the stack area.
'2017-11-07 06:10 PM
I understand what you said theoretically, but where in the debugger can I view the stack depth?
Do you mean viewing the calling stack?
Thanks.
2017-11-07 06:37 PM
Think of it like the tide going in and out, you fill the 1024 byte stack frame with 0xCD characters, you'll see a bunch of 0xCDCDCDCD words. After you run for a while stop the processor and look at the high water mark.
The stack descends downward, so you look at offset 0 thru N seeing 0xCDCDCDCD words until you don't if this is byte offset 0x80 then you are using 0x400-0x80 bytes
2018-05-07 09:14 AM
Hello,
Rather old thread but I've just found this interesting page:
Julien