use is difficult to estimate because it is code dependent, and can vary between runs depending on the code path that the program takes on execution. However, it is possible to manually estimate the extent of stack utilization using the following methods:
Link with --callgraph to produce a static callgraph. This shows information on all functions, including stack use.
Link with --info=stack or --info=summarystack to list the stack usage of all global symbols.
Use the debugger to set a watchpoint on the last available location in the stack and see if the watchpoint is ever hit.
Note
µVision uses ULINK debug adaptors, with the CoreSight interface, which have no performance penalties.
Use the debugger, and:
Allocate space in memory for the stack that is much larger than you expect to require.
Fill the stack space with copies of a known value, for example, 0xDEADDEAD.
Run your application, or a fixed portion of it. Aim to use as much of the stack space as possible in the test run. For example, try to execute the most deeply nested function calls and the worst case path found by the static analysis. Try to generate interrupts where appropriate, so that they are included in the stack trace.
After your application has finished executing, examine the stack space of memory to see how many of the known values have been overwritten. The space has garbage in the used part and the known values in the remainder.
Count the number of garbage values and multiply by sizeof(value), to give their size, in bytes.
The result of the calculation shows how the size of the stack has grown, in bytes.
Use RTSM, and define a region of memory where access is not allowed directly below your stack in memory, with a map file. If the stack overflows into the forbidden region, a data abort occurs, which can be trapped by the debugger.
Methods of reducing stack usage
In general, you can lower the stack requirements of your program by:
writing small functions that only require a small number of variables
avoiding the use of large local structures or arrays
avoiding recursion, for example, by using an alternative algorithm
minimizing the number of variables that are in use at any given time at each point in a function
using C block scope and declaring variables only where they are needed, so overlapping the memory used by distinct scopes.
|