PSoC® applications may use more SRAM than you would expect. How do you control SRAM usage in PSoC Applications?
To make application development easy for new users, PSoC Creator™ allocates large amounts of SRAM to the stack and heap. This prevents new users from getting frustrated with memory overflow problems while they are learning about PSoC and PSoC Creator. For example, a new PSoC 4 application targeting the top-of-the-line CY8C4245AXI-483 part allocates 1024 bytes to the stack and 256 bytes to the heap. That is over 31 percent of the total RAM available in the device. If you want to change the way SRAM is allocated, it is simple to change the values in PSoC Creator and rebuild the application.
The heap is used by certain run-time library functions, most notably sprintf(), and also by applications that reserve large amounts of memory using the malloc() function and its related APIs. If you are not using dynamic memory allocation, then this heap is wasted space. You can remove it. In the System tab of the resources editor (cydwr), change the heap size to zero bytes.
Figure 1. Heap and Stack Size Settings
The stack is used for function calling. When a function is called, the stack is used for the return address, to pass arguments to the called function, and for return values. The amount of stack you need depends on how deeply nested your application is and the number (and type) of parameters passed at each level. Just like the heap, the stack size is set in the System tab of the resource editor.
There are several ways of determining the right amount of stack usage for an application. The first method is to review your source code. Determine the functions that use a lot of stack space and where the deepest nesting occurs. From that point, you can calculate the maximum stack usage.
You can use the command lines provided with the compiler to get the stack usage on a per-function basis. For example, if you’re using GCC complier, you can add -fstack-usage commands to generate an extra file with a .su extension, that specifies the maximum amount of stack used by each function. For more information, see https://gcc.gnu.org/onlinedocs/gnat_ugn/Static-Stack-Usage-Analysis.html .
Add a little extra to your computed maximum so that you have space to add a small amount of code to the application without having to change the stack size.
The second method is more empirical. Use the debugger to monitor the memory used. First, you fill the stack with unusual data. An arbitrary number such as 0xFEEDBEEF works well because it sticks out visually, and the chance of your application writing a lot of that number on the stack is low. Then you simply run the application and check the Memory window to see how much of the stack has not been overwritten. It is important to exercise the application thoroughly to make sure all the paths have been followed and the maximum stack usage has occurred.
An alternative to this method is to place a read/write (access) breakpoint at the bottom of the stack and see if it is ever reached. If it is then you need more stack space. If not, simply move it up until it does hit and you have your peak usage.
Lastly, some third-party tools and IDEs offer built-in, stack-checking functions, which can be especially useful when you are using a real-time operating system (RTOS). In those environments, each task typically has its own dedicated stack. You want to be sure to optimize each one to minimize waste.