คุณมีคำตอบที่ดีอย่างสมบูรณ์อยู่แล้ว ฉันโพสต์สิ่งนี้เพียงเพื่อแบ่งปันสถิติบางอย่างที่ฉันทำในวันหนึ่งฉันถามคำถามแบบเดียวกันกับตัวเองว่า: อะไรคือการใช้พื้นที่มากในการร่างแบบย่อ อะไรคือความต้องการขั้นต่ำในการบรรลุหน้าที่การทำงานเดียวกัน
ด้านล่างนี้เป็นโปรแกรมบั๊กเล็ก ๆ สามเวอร์ชันที่สลับ LED ที่ขา 13 ทุกวินาที ทั้งสามเวอร์ชั่นได้รับการคอมไพล์สำหรับ Uno (ไม่เกี่ยวข้องกับ USB) โดยใช้ avr-gcc 4.8.2, avr-libc 1.8.0 และ arduino-core 1.0.5 (ฉันไม่ได้ใช้ Arduino IDE)
ครั้งแรกที่วิธี Arduino มาตรฐาน:
const uint8_t ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
}
ซึ่งรวบรวมได้ถึง 1,018 ไบต์ เมื่อใช้ทั้งสองavr-nm
และถอดชิ้นส่วนฉันแบ่งขนาดนั้นออกเป็นฟังก์ชั่นแต่ละอย่าง จากมากไปน้อยที่สุด:
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
ในรายการด้านบนคอลัมน์แรกคือขนาดเป็นไบต์และคอลัมน์ที่สองบอกว่ารหัสมาจากห้องสมุดแกนหลัก Arduino (A, 822 ไบต์รวม), C runtime (C, 148 ไบต์) หรือผู้ใช้ (U , 48 ไบต์)
ดังที่เห็นได้ในรายการนี้ฟังก์ชั่นที่ใหญ่ที่สุดคือรูทีนการซ่อมบำรุงตัวจับเวลา 0 โอเวอร์โฟลว์อินเตอร์รัปต์ ประจำวันนี้เป็นผู้รับผิดชอบในการติดตามของเวลาและเป็นสิ่งจำเป็นโดยmillis()
, และmicros()
delay()
ฟังก์ชั่นที่ใหญ่เป็นอันดับสองคือinit()
ซึ่งตั้งค่าตัวจับเวลาฮาร์ดแวร์สำหรับ PWM เปิดใช้งาน TIMER0_OVF ขัดจังหวะและยกเลิกการเชื่อมต่อ USART (ซึ่งใช้โดย bootloader) <Arduino directory>/hardware/arduino/cores/arduino/wiring.c
ทั้งสองนี้และฟังก์ชั่นก่อนหน้านี้ที่กำหนดไว้ใน
ถัดไปเป็นเวอร์ชัน 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);
}
}
การแยกย่อยแต่ละขนาด:
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
นี่คือ 132 ไบต์สำหรับรันไทม์ C และ 26 _delay_ms()
ไบต์ของรหัสผู้ใช้รวมถึงฟังก์ชั่น
อาจสังเกตได้ว่าเนื่องจากโปรแกรมนี้ไม่ได้ใช้การขัดจังหวะจึงไม่จำเป็นต้องใช้ตารางเวกเตอร์ขัดจังหวะและสามารถใส่รหัสผู้ใช้ปกติแทน แอสเซมบลีรุ่นต่อไปนี้ไม่ว่า:
#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
นี่คือการประกอบ (กับavr-gcc -nostdlib
) เป็นเพียง 14 ไบต์ซึ่งส่วนใหญ่จะใช้ในการชะลอการสลับเพื่อให้การกะพริบตาสามารถมองเห็นได้ หากคุณลบลูปการหน่วงเวลานั้นคุณลงเอยด้วยโปรแกรม 6 ไบต์ที่กะพริบเร็วเกินกว่าจะมองเห็นได้ (ที่ 2 MHz):
sbi io(DDRB), 5 ; set PB5 as output
loop:
sbi io(PINB), 5 ; toggle PB5
rjmp loop