あなたはすでにいくつかの完全に良い答えを持っています。これを投稿するのは、ある日自分がやった統計を共有するためだけです。私は同じような質問を自問しました。同じ機能を実現するために最低限必要なものは何ですか?
以下は、ピン13のLEDを1秒ごとに切り替える最小点滅プログラムの3つのバージョンです。3つのバージョンはすべて、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
上記のリストの最初の列はバイト単位のサイズで、2番目の列はコードがArduinoコアライブラリ(A、合計822バイト)、Cランタイム(C、148バイト)、またはユーザー(U 、48バイト)。
このリストからわかるように、最大の機能はタイマー0オーバーフロー割り込みを処理するルーチンです。このルーチンは、時間を追跡する責任がある、とによって必要とされmillis()
、micros()
そしてdelay()
。2番目に大きい関数は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バイトのプログラムが点滅して速すぎて見られなくなります(2 MHzで)。
sbi io(DDRB), 5 ; set PB5 as output
loop:
sbi io(PINB), 5 ; toggle PB5
rjmp loop