Anda sudah memiliki jawaban yang sangat bagus. Saya memposting ini hanya untuk membagikan beberapa statistik yang saya lakukan suatu hari saya bertanya pada diri sendiri pertanyaan yang sama: Apa yang mengambil begitu banyak ruang pada sketsa minimal? Berapa minimum yang dibutuhkan untuk mencapai fungsi yang sama?
Di bawah ini adalah tiga versi program blinky minimal yang mengaktifkan LED pada pin 13 setiap detik. Ketiga versi telah dikompilasi untuk Uno (tidak ada USB yang terlibat) menggunakan avr-gcc 4.8.2, avr-libc 1.8.0 dan arduino-core 1.0.5 (Saya tidak menggunakan Arduino IDE).
Pertama, cara Arduino standar:
const uint8_t ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
}
Ini mengkompilasi hingga 1018 byte. Menggunakan keduanya avr-nm
dan pembongkaran , saya membagi ukuran itu menjadi fungsi individu. Dari terbesar ke terkecil:
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
Dalam daftar di atas, kolom pertama adalah ukuran dalam byte, dan kolom kedua memberitahu apakah kode tersebut berasal dari perpustakaan inti Arduino (A, total 822 byte), runtime C (C, 148 byte) atau pengguna (U , 48 byte).
Seperti yang dapat dilihat dalam daftar ini, fungsi terbesar adalah servis rutin timer 0 overflow interrupt. Rutin ini bertanggung jawab untuk melacak waktu, dan dibutuhkan oleh millis()
, micros()
dan delay()
. Fungsi terbesar kedua adalah init()
, yang mengatur timer perangkat keras untuk PWM, memungkinkan TIMER0_OVF mengganggu dan memutus USART (yang digunakan oleh bootloader). Baik ini dan fungsi sebelumnya didefinisikan dalam
<Arduino directory>/hardware/arduino/cores/arduino/wiring.c
.
Berikutnya adalah versi C + avr-libc:
#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);
}
}
Rincian ukuran individu:
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
Ini adalah 132 byte untuk runtime C dan 26 byte kode pengguna, termasuk fungsi sebaris _delay_ms()
.
Dapat dicatat bahwa, karena program ini tidak menggunakan interupsi, tabel vektor interupsi tidak diperlukan, dan kode pengguna reguler dapat diletakkan di tempatnya. Versi perakitan berikut melakukan hal itu:
#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
Ini dirakit (dengan avr-gcc -nostdlib
) menjadi hanya 14 byte, yang sebagian besar digunakan untuk menunda matikan sehingga kedipan terlihat. Jika Anda menghapus loop penundaan itu, Anda berakhir dengan program 6-byte yang berkedip terlalu cepat untuk dilihat (pada 2 MHz):
sbi io(DDRB), 5 ; set PB5 as output
loop:
sbi io(PINB), 5 ; toggle PB5
rjmp loop