Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code Size Comparison Cortex M3: IAR ARM vs Keil µVision

I am currently developing a small project for an STM32F103 microcontroller which features a Cortex-M3 CPU. Due to CMSIS standard header files it is possible to use the exact same code with IAR and Keil µVision. Because of that, I found it interesting to compare both compilers regarding code size (which is the most critical for small microcontrollers).

Both compilers were set on max. optimization level (for size). Unfortunately, I am not quite sure how IAR and Keil measure code size.

For example, IAR gives me this output:

    868 bytes of readonly  code memory 
     28 bytes of readonly  data memory 
  2'056 bytes of readwrite data memory 

and Keil this:

Program Size: Code=676 RO-data=252 RW-data=0 ZI-data=1640

At a first glance I am not able to detect which amount of bytes relates to used flash size and which to used SRAM.

Of course I know, that flash is Read-only and that SRAM is read-write but then there is code memory and data memory on IAR's side, and ZI-data and Code on Keil's side.

Anyone here who has more in depth knowledge about this?

like image 352
binaryBigInt Avatar asked Nov 05 '25 03:11

binaryBigInt


1 Answers

Let's try to break this down in a systematic way. From a programmers point of view we want to differentiate between Code (Instructions) and Data.

Code is usually stored in some kind of non-volatile memory (ROM, FLASH, etc.) and is read and executed at runtime by the processor core. Modern MCU's usually read their instructions from FLASH but can also execute code from RAM. This is mainly useful in order to run the code faster (since FLASH is rather slow to access) or in order to implement some update functionality that can update the whole FLASH memory. Running code from RAM can also be used to construct self-modifying software, but that is a rather exotic use-case.

When talking about data we usually first think of variables, that are modified during run-time (read-write) and therefore need to be stored in random-access memory (RAM) that is usually volatile (values are lost at power-down). But there are more types to keep in mind:

  • Constants: Data values, that do not change during run-time, e.g. a peripheral register address or a hard-coded delay time. These values need to be placed into non-volatile memory, which can be read-only (e.g. FLASH).
  • Initialized variables: Most variables of a program need to have a defined initial value (e.g. the starting value of a loop count variable). This initial value is actually nothing else than a constant data value (see above), that is automatically copied to its associated variable at the beginning of its lifetime. Since a typical program requires quite a lot of those initialization values, modern compilers implement different optimization methods to reduce the memory footprint of this initializers. These includes clustering all variables that are initialized with the value zero (zero-initialization) and providing different data compression methods for non-zero initialized variables.

With these things in mind we can make an educated guess regarding the output of the IAR and Keil linker:

+---------------------+-----------------------+-------------------+
| Memory Object       | IAR term              | Keil term         |
+---------------------+-----------------------+-------------------+
| Code in ROM         | readonly code memory  | Code              |
| Code in RAM         | readwrite code memory | ?                 |
| Constants in ROM    | readonly data memory  | RO-Data           |
| Initializers in ROM | readonly data memory  | (RW-Data)         |
| Variables in RAM    | readwrite data memory | RW-Data + ZI-Data |
+---------------------+-----------------------+-------------------+

Calculating memory usage is pretty straight-forward with IAR:

  • ROM usage = (readonly code memory) + (readonly data memory)
  • RAM usage = (readwrite code memory) + (readwrite data memory)

For Keil it is a bit more complicated:

  • ROM usage = (Code) + (RO-data) + (RW-data)
  • RAM usage = (RW-data) + (ZI-data)
like image 104
Blue Avatar answered Nov 07 '25 13:11

Blue