A reader of my monthly Firmware Update newsletter recently sent an e-mail to ask:
I am a firmware engineer. I read your recent blog post regarding the C stack, about which I have two questions: First, how can I increment or decrement the size of the stack in my code? Second, what size should I choose?
Here’s what I told him:
The size of the stack is set either in the linker command file or in the C or C++ startup code. You should be able to learn more about how to change the stack size from your specific compiler vendor’s manual or customer support.
Identifying the minimum stack size required for your specific application is made challenging by these stubborn facts:
– MEASURING the maximum stack growth during testing may not be sufficient. If you test for half a year, the product is sure to be run for a year or longer in the field. Have you really tested all possible cases? What about all possible series of interrupt service routines on top of that worst case use by main()?
– TOP DOWN ANALYSIS of the compiled code can be done to determine the number of function calls and interrupt service routines at maximum depth; their individual parameter and local variable use, etc. Unfortunately, these things may keep changing whenever you change the code and recompile.
The best approach is usually to perform a conservative top down analysis of the source code; when in doubt, always round up. Don’t forget about nested interrupt service routines. Double that conservative to set your initial stack budget. Then measure actual stack utilization during testing, preferably with code coverage analysis tools running–to ensure that you’ve tested all possible paths (except interrupts, which may run at different times in the field).
Then if you need to reclaim memory to ship the product, start shrinking the stack. But also put into place a high water mark system (e.g., 0xDEADBEEF) complete with supervisor code to put the product into a failsafe state if more than, for example, 80% of the stack is ever used.