Application Note: Tips and Tricks to Optimize Your C Code for 8-bit AVR Microcontrollers

In contrast to software development where there are relatively plenty of memory space and CPU power, every byte in hardware development counts, and you must follow strict optimization instructions to save the memory space and have faster firmware.

ATMEL has a set of 11 tips in an application note that worth sharing. The AN starts with introducing the reader with the hardware details of AVR CPU architecture and the AVR GCC compiler which has 5 optimization levels (-O0, -O1, -O2, -O3 and -Os).

Tips and Tricks to Reduce Code Size

The development platform used for writing this AN consists of :

  • IDE: Atmel AVR Studio 5.
  • Toolchain: AVR_8_bit_GNU_Toolchain_3.2.1_292.
  • Hardware: Atmel ATmega88PA.

Keep in mind that: In GCC compilation results, we have three memory sections: “text” for everything stored in FLASH memory, “data” used for initialized global data and “bss” contains all uninitialized global data. Data and bss are stored in SRAM memory. For more details, read the MCUoneclipse’s article.

Use The Right Data Type—Don’t Waste Spaces

optimize c code: Use right variable length

This is a glaring example of wasting memory spaces when allocating a variable with length more than needed (the ADCH is an 8-bit-long register).

[the_ad id=”2268″]

Global vs. Local Variables

optimize c code: global vs local variables

A global variable has a dedicated address in the SRAM while local variables would be assigned to a register or allocated to stack when they are declared, and once the function ends execution the function’s local variables can be removed. That’s why using global variables consumes SRAM while using local variables doesn’t.

An extra code will be executed to initialize the global variable each startup (after reset).

Store Constants in Program Space

Optimize C code: Contants in program space

Having many variables with non-zero value means consuming more SRAM: These non-zero values will be stored in SRAM to initialize each non-zero variable with the corresponding value. Another case: Serial.print(“Hello World\n”). The “Hello World\n” will be stored in the SRAM, and having too much of these variables and functions with constant arguments will definitely make you run out of SRAM. One of the tips here is to store these values in the program space.

More tips that worth reading about in the application note.


Yahya Tawil

Embedded Hardware Engineer interested in open hardware and was born in the same year as Linux. Yahya is the editor-in-chief of Atadiat and believes in the importance of sharing free, practical, spam-free and high quality written content with others. His experience with Embedded Systems includes developing firmware with bare-metal C and Arduino, designing PCB&schematic and content creation.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back to top button