cmicrocontrolleravravr-gccwinavr

Big hex file from small AVR program


I am now teaching my friend how to program AVR microcontrollers. We've written this small program, which sends simple morse-like code.

The problem is that, after compilling it both with AVR-GCC and WinAVR the a.out file is almost 30KB and the hex file is 11KB, so that it doesn't fit the attiny2313 flash.

WinAVR CMD: avr-gcc -mmcu=attiny2313 -Os -g main.c

Avr-objcopy: avr-objcopy -O ihex a.out a.hex

Here is the code:

#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>

void light_led(int ms)
{
 PORTD |= (1 << 4);
 _delay_ms(ms);
 PORTD &= ~(1 << 4);
 _delay_ms(1000);
}

void send_char(int c)
{
 int i;
 for(i = 1; i < 8+1; i++)
 {
  if(c & i) light_led(1000);
  else light_led(500); 
 }
}

int main(void)
{
 DDRD |= (1 << 4);
 //char text[] = {'t', 'e', 's', 't'};
 int i;
 for(i = 0; i < 1; i++) send_char(100);//text[i]);
 return 0;
}

Solution

  • The size of the hex file is misleading. It takes 43 bytes to represent 16, so your executable is actually only 4 K.

    That said, passing the parameter to the _delay_ms() function really blows up the code. I tried this instead, always calling the delay function with a constant, and the executable was less than 190 bytes.

    #define F_CPU 8000000L
    #include <avr/io.h>
    #include <util/delay.h>
    
    void light_led(int longer)
    {
     PORTD |= (1 << 4);
     if(longer) _delay_ms(1000);
     else  _delay_ms(500);
     PORTD &= ~(1 << 4);
     _delay_ms(1000);
    }
    
    void send_char(int c)
    {
     int i;
     for(i = 1; i < 8+1; i++)
     {
      if(c & i) light_led(1);
      else light_led(0); 
     }
    }
    
    int main(void)
    {
     DDRD |= (1 << 4);
     //char text[] = {'t', 'e', 's', 't'};
     int i;
     for(i = 0; i < 1; i++) send_char(100);//text[i]);
     return 0;
    }