Recently I dug out my USBasp tool and a few AVR microcontrollers, for enjoying programming the C language again. Unexpectedly, the old ATTINY2313V and ATmega88V couldn’t work with my USBasp tool (maybe they have already been fused with an external crystal but I don’t have one at hand). The only two pieces that could work are ATmega16A and ATmega16L. At least I could still have some fun with it.

My waterfall-light built from ATmega16A

The code for playing the ATmega16A is at https://github.com/RobinDong/atmega16a.

Later when glancing over the documents of Atmel’s new ATTINY series, I found out that the ATTINY13A only have 1KB space to store program. My example of waterfall light was compiled out to a 2KB hex file. Does that mean I couldn’t put my program into the ATTINY13A? How could I get the real occupation size of flash for the hex file?

Here is one solution by using avr-size

$ avr-size main.hex
   text	   data	    bss	    dec	    hex	filename
      0	    756	      0	    756	    2f4	main.hex

Only 756 bytes (text + data) will be used in flash, so the ATTINY13A should be okay.

Another command for this is more human-readable

$ avr-size --format=avr --mcu=atmega16 main.elf
AVR Memory Usage
----------------
Device: atmega16
Program:     756 bytes (4.6% Full)
(.text + .data + .bootloader)
Data:          6 bytes (0.6% Full)
(.data + .bss + .noinit)

Now, what should I do if I want to reduce the size of the binary file compiled from my code? Here is the guide from Atmel.

First, I change the type of the variable “mode” from “unsigned int” to “unsigned char”, this leads the binary file to 726 bytes. Then change all inner functions to “static” (I guess this removed some unused symbol for external linking), reduce the binary size to 668 bytes.

—— 2021.07.13 ——

Furthermore, when I use “-mrelax” option in gcc-avr for linker relaxation, the binary size shrink to 656 bytes.