When developing firmware for an embedded project, it is important to know how much flash and SRAM the program is using. This allows you to make the best decision on whether the chosen MCU has sufficient resources for your needs.
By default, GCC does not give any information regarding program size. However, GCC does include a utility that can help, sensibly it is called “size.exe” (or “arm-none-eabi-size.exe” for the embedded GCC version). If you run the program as follows:
c:\iccv9cortex\gnuarm\bin\arm-none-eabi-size -A -x bin\Debug\Test.elf
The /path/to/ is as installed by ImageCraft’s JumpStart C++ program, but any embedded GCC installation will have this program. The last argument is the input file (in default ELF format). “-A” means to output in SysV format (Berkeley format is the other option), and “-x” is to use hexadecimal output. The above produces something as follows:
bin\Debug\TestDriver.elf :
section size addr
.text 0x6720 0x8000000
.ARM.extab 0x258 0x8006720
.ARM.exidx 0x2f0 0x8006978
.ARM.attributes 0x2a 0x8006c68
.data 0x804 0x20000000
.bss 0x9c0 0x20000804
._user_heap_stack 0x2804 0x200011c4
.debug_line 0x405a 0x0
.debug_info 0x24c75 0x0
...
.debug_ranges 0x60 0x0
.comment 0x75 0x0
.debug_frame 0x2dd4 0x0
.stab 0x9c 0x0
.stabstr 0x14f 0x0
Total 0x3d8f3
Each line represents a “region” in the output file. If a region has an address of 0x0, it means that it is not using any space in the target MCU and most likely only contains debug information, and will be used for debugging only. The regions’ names and allocations are controlled by the linker script used so your output may look slightly different.
The entries of interest are: .text this is the size of your program, i.e. flash usage. In this example, 0x6720 or 26400 bytes of flash is used, plenty left over from the 512K STM32F411RE that I am using.
.data and .bss are the static SRAM usage. .data has the global/static variables that have initialization, and .bss has the global/static variables that have no initialization (but are initialized to zero per C/C++ definition). In this case, 4548 bytes are needed, also significantly less than the 128K bytes of SRAM available on the F411RE.
Finally, ._user_heap_stack is the area reserved for memory allocated at runtime, heap is for memory used by malloc/free, and C++’s “new” etc., and stack is used for mainly for local variables and function context. As the runtime memory size changes as your program is run, this is only the minimum amount set in the linker script. Your program controls how much dynamic memory it uses. Stack usage depends on the call patterns in your program and how much stack space (e.g. local variables) a function uses. A future blog post will describe one way to determine stack usage of a program.
You can write a simple utility program to process the “size” output to give a simple summary, which is what we have done with the JumpStart C++ tools. A typical post-build message looks like this:
ELF file output size
Code size: 26400 bytes starting at 0x08000000
SRAM data: 4548 bytes starting at 0x20000000
Heap and Stack: 10244 bytes heap starts 0x200011C4 stack starts 0x200039C8
With size.exe and some processing, it is simple to see your program’s flash and SRAM requirements.