이미 완벽하게 좋은 답변이 있습니다. 나는 언젠가 나에게 같은 종류의 질문을 한 통계를 공유하기 위해 이것을 게시하고있다. 최소한의 스케치에서 너무 많은 공간을 차지하는 것은 무엇입니까? 동일한 기능을 달성하기 위해 필요한 최소량은 얼마입니까?
아래는 매번 핀 13의 LED를 토글하는 최소한의 깜박임 프로그램의 세 가지 버전입니다. 세 가지 버전 모두 avr-gcc 4.8.2, avr-libc 1.8.0 및 arduino-core 1.0.5 (Arduino IDE를 사용하지 않음)를 사용하여 Uno (USB 포함 안 됨) 용으로 컴파일되었습니다.
먼저 표준 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
와 분해를 사용하여 해당 크기를 개별 기능으로 분류했습니다. 가장 큰 것에서 가장 작은 것까지 :
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 바이트), C 런타임 (C, 148 바이트) 또는 사용자 (U , 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
C 런타임의 경우 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 바이트 프로그램 (2MHz)으로 끝납니다.
sbi io(DDRB), 5 ; set PB5 as output
loop:
sbi io(PINB), 5 ; toggle PB5
rjmp loop