Skip to main content
Arduino

Return to Answer

replaced http://arduino.stackexchange.com/ with https://arduino.stackexchange.com/
Source Link

This compiles to 1018 bytes. Using both avr-nm and disassembly Using both avr-nm and disassembly, I broke down that size into individual functions. From largest to smallest:

This compiles to 1018 bytes. Using both avr-nm and disassembly, I broke down that size into individual functions. From largest to smallest:

This compiles to 1018 bytes. Using both avr-nm and disassembly, I broke down that size into individual functions. From largest to smallest:

Source Link
Edgar Bonet
  • 45.1k
  • 4
  • 42
  • 81

You already have some perfectly good answers. I am posting this only to share some stats I did one day I asked myself the same sort of questions: What is taking so much space on a minimal sketch? What is the minimum needed to achieve the same functionality?

Below are three versions of a minimal blinky program that toggles the LED on pin 13 every second. All three versions have been compiled for an Uno (no USB involved) using avr-gcc 4.8.2, avr-libc 1.8.0 and arduino-core 1.0.5 (I do not use the Arduino IDE).

First, the standard Arduino way:

const uint8_t ledPin = 13;
void setup() {
 pinMode(ledPin, OUTPUT);
}
void loop() {
 digitalWrite(ledPin, HIGH);
 delay(1000);
 digitalWrite(ledPin, LOW);
 delay(1000);
}

This compiles to 1018 bytes. Using both avr-nm and disassembly, I broke down that size into individual functions. From largest to smallest:

 148 A ISR(TIMER0_OVF_vect)
 118 A init
 114 A pinMode
 108 A digitalWrite
 104 C vector table
 82 A turnOffPWM
 76 A delay
 70 A micros
 40 U loop
 26 A main
 20 A digital_pin_to_timer_PGM
 20 A digital_pin_to_port_PGM
 20 A digital_pin_to_bit_mask_PGM
 16 C __do_clear_bss
 12 C __init
 10 A port_to_output_PGM
 10 A port_to_mode_PGM
 8 U setup
 8 C .init9 (call main, jmp exit)
 4 C __bad_interrupt
 4 C _exit
-----------------------------------
1018 TOTAL

In the list above, the first column is the size in bytes, and the second column tells whether the code comes from the Arduino core library (A, 822 bytes total), the C runtime (C, 148 bytes) or the user (U, 48 bytes).

As can be seen in this list, the largest function is the routine servicing the timer 0 overflow interrupt. This routine is responsible of tracking time, and is needed by millis(), micros() and delay(). The second largest function is init(), which sets the hardware timers for PWM, enables TIMER0_OVF interrupt and disconnects the USART (that was used by the bootloader). Both this and the previous function are defined in <Arduino directory>/hardware/arduino/cores/arduino/wiring.c.

Next is the C + avr-libc version:

#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
 DDRB |= _BV(PB5); /* set pin PB5 as output */
 for (;;) {
 PINB = _BV(PB5); /* toggle PB5 */
 _delay_ms(1000);
 }
}

The break-down of the individual sizes:

104 C vector table
 26 U main
 12 C __init
 8 C .init9 (call main, jmp exit)
 4 C __bad_interrupt
 4 C _exit
----------------------------------
158 TOTAL

This is 132 bytes for the C runtime and 26 bytes of user code, including the inlined function _delay_ms().

It could be noted that, since this program does not use interrupts, the interrupt vector table is not needed, and regular user code could be put in its place. The following assembly version does exactly that:

#include <avr/io.h>
#define io(reg) _SFR_IO_ADDR(reg)
 sbi io(DDRB), 5 ; set PB5 as output
loop:
 sbi io(PINB), 5 ; toggle PB5
 ldi r26, 49 ; delay for 49 * 2^16 * 5 cycles
delay:
 sbiw r24, 1
 sbci r26, 0
 brne delay
 rjmp loop

This is assembled (with avr-gcc -nostdlib) into only 14 bytes, most of which are used to delay the toggles so that the blink is visible. If you remove that delay loop, you end up with a 6-byte program that blinks too fast to be seen (at 2 MHz):

 sbi io(DDRB), 5 ; set PB5 as output
loop:
 sbi io(PINB), 5 ; toggle PB5
 rjmp loop
default

AltStyle によって変換されたページ (->オリジナル) /