Ketika saya menyusun sketsa ini untuk Yún:
int led = 7;
void setup() {
pinMode(led, OUTPUT);
}
void loop() {
digitalWrite(led, HIGH);
}
Saya mendapat:
Sketsa menggunakan 5.098 byte (17%) dari ruang penyimpanan program.
Maksimal adalah 28.672 byte. Variabel global menggunakan 153 byte (5%) dari memori dinamis, meninggalkan 2.407 byte untuk variabel lokal. Maksimal 2,560 byte.
Bahkan ketika saya mengkompilasi sketsa BareMinimum:
void setup() {
// setup
}
void loop() {
// loop
}
Saya mendapat:
Sketsa menggunakan 4.548 byte (15%) dari ruang penyimpanan program.
Maksimal adalah 28.672 byte. Variabel global menggunakan 151 byte (5%) dari memori dinamis, meninggalkan 2.409 byte untuk variabel lokal. Maksimal 2,560 byte.
Mengapa sketsa minimum kosong menghabiskan 15% dari ruang penyimpanan program yang dialokasikan? Dan mengapa sketsa yang sangat sederhana memakan 17% ruang penyimpanan program? Menurut situs web Arduino :
Sangat mudah untuk menggunakan semuanya dengan memiliki banyak string dalam program Anda. Misalnya, deklarasi seperti:
char message[] = "I support the Cape Wind project.";
menempatkan 33 byte ke SRAM (setiap karakter mengambil byte, plus terminator '\ 0').
Namun, tidak ada string yang dinyatakan dalam salah satu sketsa ini.
Sepertinya mereka mungkin mengimpor atau menggunakan perpustakaan / kelas lain yang tidak saya tentukan. Mungkin mengimpor perpustakaan sistem default? Atau itu sesuatu yang lain?
sumber
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:
Ini mengkompilasi hingga 1018 byte. Menggunakan keduanya
avr-nm
dan pembongkaran , saya membagi ukuran itu menjadi fungsi individu. Dari terbesar ke terkecil: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()
dandelay()
. Fungsi terbesar kedua adalahinit()
, 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:
Rincian ukuran individu:
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:
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):sumber
Saya menulis posting tentang Mengapa perlu 1.000 byte untuk berkedip satu LED? .
Jawaban singkatnya adalah: "Tidak perlu 2000 byte untuk berkedip dua LED!"
Jawaban yang lebih panjang adalah bahwa pustaka Arduino standar (yang tidak harus Anda gunakan jika tidak mau) memiliki beberapa fungsionalitas yang bagus untuk menyederhanakan hidup Anda. Misalnya, Anda dapat mengatasi pin dengan angka saat runtime, di mana perpustakaan mengkonversi (katakanlah) pin 8 ke port yang benar dan nomor bit yang benar. Jika Anda mengakses port hard-code, Anda bisa menghemat overhead itu.
Bahkan jika Anda tidak menggunakannya, pustaka standar menyertakan kode untuk menghitung "ticks" sehingga Anda dapat mengetahui "waktu" saat ini (dengan menelepon
millis()
). Untuk melakukan ini harus menambahkan overhead dari beberapa rutinitas layanan interupsi.Jika Anda menyederhanakan (pada Arduino Uno) untuk sketsa ini, Anda mendapatkan penggunaan memori program hingga 178 byte (pada IDE 1.0.6):
OK, 178 byte tidak terlalu banyak, dan 104 byte pertama adalah vektor interupsi perangkat keras (masing-masing 4 byte, untuk 26 vektor).
Jadi bisa dibilang, hanya ada 74 byte yang diperlukan untuk berkedip LED. Dan dari 74 byte itu kebanyakan adalah kode yang dibuat oleh kompiler untuk menginisialisasi memori global. Jika Anda menambahkan kode yang cukup untuk berkedip dua LED:
Kemudian ukuran kode meningkat menjadi 186 byte. Jadi karena itu Anda bisa berpendapat bahwa hanya perlu
186 - 178 = 8
byte untuk berkedip LED.Jadi, 8 byte untuk berkedip LED. Kedengarannya cukup efisien bagi saya.
Jika Anda tergoda untuk mencoba ini di rumah, saya harus menunjukkan bahwa sementara kode yang diposting di atas berkedip dua LED, itu memang sangat cepat. Bahkan, mereka berkedip pada 2 MHz - lihat tangkapan layar. Saluran 1 (kuning) adalah pin 12, saluran 2 (cyan) adalah pin 13.
Seperti yang Anda lihat, pin output memiliki gelombang persegi dengan frekuensi 2 MHz. Pin 13 mengubah status 62,5 ns (satu siklus clock) sebelum pin 12, karena urutan toggling pin dalam kode.
Jadi, kecuali jika Anda memiliki mata yang jauh lebih baik daripada mata saya, Anda tidak akan benar-benar melihat efek berkedip.
Sebagai tambahan yang lucu, Anda sebenarnya dapat mengaktifkan dua pin dalam jumlah ruang program yang sama dengan mengganti satu pin.
Itu mengkompilasi menjadi 178 byte.
Ini memberi Anda frekuensi yang lebih tinggi:
Sekarang kita mencapai 2,66 MHz.
sumber
init()
(seperti biasanyamain()
) maka file wiring.c (yang adainit
di dalamnya) tidak ditautkan. Akibatnya, pemrosesan untuk penangan interupsi (untukmillis()
,micros()
dll.) Dihilangkan. Mungkin tidak terlalu praktis untuk menghilangkannya, kecuali Anda tidak perlu mengatur waktu, tetapi faktanya sketsa itu tumbuh dalam ukuran tergantung pada apa yang Anda masukkan ke dalamnya. Misalnya, jika Anda menggunakan Serial, memori program dan RAM terpukul.