आपके पास पहले से ही कुछ अच्छे उत्तर हैं। मैं यह केवल कुछ आँकड़े साझा करने के लिए पोस्ट कर रहा हूं, मैंने एक दिन खुद से एक ही तरह के सवाल पूछे: न्यूनतम स्केच पर इतनी जगह क्या ले रही है? समान कार्यक्षमता प्राप्त करने के लिए न्यूनतम क्या आवश्यक है?
नीचे एक न्यूनतम ब्लिंक प्रोग्राम के तीन संस्करण दिए गए हैं, जो हर सेकंड पिन 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);
}
यह 1018 बाइट्स के लिए संकलित है। दोनों avr-nm
और disassembly का उपयोग करके , मैंने उस आकार को अलग-अलग कार्यों में तोड़ दिया। सबसे बड़े से लेकर सबसे छोटे:
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 कोर लाइब्रेरी (ए, 822 बाइट्स कुल) से आता है, सी रनटाइम (सी, 148 बाइट्स) या उपयोगकर्ता (यू , 48 बाइट्स)।
जैसा कि इस सूची में देखा जा सकता है, सबसे बड़ा कार्य टाइमर 0 ओवरफ़्लो रुकावट को नियंत्रित करने वाला रूटीन है। यह दिनचर्या ट्रैकिंग समय के लिए जिम्मेदार है, और इसकी आवश्यकता है millis()
, micros()
और delay()
। दूसरा सबसे बड़ा कार्य है init()
, जो PWM के लिए हार्डवेयर टाइमर सेट करता है , TIMER0_OVF को बाधित करता है और USART (जो बूटलोडर द्वारा उपयोग किया जाता है) को डिस्कनेक्ट करता है। यह और पिछले फ़ंक्शन दोनों को परिभाषित किया गया है
<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 बाइट्स और उपयोगकर्ता कोड के 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 मेगाहर्ट्ज पर):
sbi io(DDRB), 5 ; set PB5 as output
loop:
sbi io(PINB), 5 ; toggle PB5
rjmp loop