001 起動後フリーズする(RAM不足)
Arduinoは組み込み向けのCPUなので、RAMやROMの容量が非常に少ないです。
色々と凝ったことをやらせようとすると、たちまちメモリ不足に陥ります。
ROMの容量は32KBが制限値で、スケッチをコンパイルするたび下記のように、トータルサイズが出力されます。
しかし、RAM不足は、コンパイルでは発見できない上、書き込んで、動作させてみると、、、
「不安定」
「固まる」
など、プログラムのバグなのか、RAM不足なのかが良く分からない状態となります。
ちょっと面倒ではありますが、RAMの使用量を調べる方法が有るので、その方法を説明します
1.まず、ArduinoIDEの「環境設定」で、以下のチェックをONにします
2.設定が終わったら、スケッチをビルドします
3.コンパイルメッセージがいつもより多く表示されるので、「*.elf」というファイルが出力されている事を確認します
この「elf」ファイルを後で使います
4.ArduinoIDEをインストールしたフォルダに移動し、「avr-objdump.exe」という実行ファイルを探します
IDEの実行ファイルがあるフォルダの「hardware\tools\avr\bin\avr-objdump.exe」に有ります
例)C:\Arduino\arduino-1.0.5-r2-windows\arduino-1.0.5-r2\hardware\tools\avr\bin\
avr-objdump.exe
5.コマンドプロンプトを起動し、以下のコマンドを実行します
avr-objdump.exe -h xxxxxx.cpp.elf
(実際は、実行ファイルも、elfファイルもフルパスで指定すればよいです)
6.すると、以下のようなダンプ結果が出力されます
ここで注目するのは「.data」と「.bss」のサイズになります
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 00000152 00800100 00004410 000044a4 2**0
CONTENTS, ALLOC, LOAD, DATA
1 .text 00004410 00000000 00000000 00000094 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .bss 0000039f 00800252 00800252 000045f6 2**0
ALLOC
3 .debug_aranges 00000ae8 00000000 00000000 000045f6 2**0
CONTENTS, READONLY, DEBUGGING
4 .debug_pubnames 00001cb3 00000000 00000000 000050de 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_info 00015ceb 00000000 00000000 00006d91 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_abbrev 00003b6f 00000000 00000000 0001ca7c 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_line 0000893e 00000000 00000000 000205eb 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_frame 000012f0 00000000 00000000 00028f2c 2**2
CONTENTS, READONLY, DEBUGGING
9 .debug_str 0000496d 00000000 00000000 0002a21c 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_loc 000072ac 00000000 00000000 0002eb89 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_ranges 00000b80 00000000 00000000 00035e35 2**0
CONTENTS, READONLY, DEBUGGING
上記の例で「00000152」と「0000039f」がRAMのサイズになります
Arduino UNO のRAMサイズは以下4つの合計が0x800(2048byte)以下である必要があります
・初期化済みデータ:(.data)
・非初期化済みデータ:(.bss)
・スタックメモリ・・・関数などをコールした時などに使うメモリ
・ヒープメモリ・・・一時変数の領域
上のダンプの例ですと、0x4f1(1265byte)のRAMを使っており、ヒープ&スタック用のメモリが783byte残された状態という事が解ります。
ちなみに、ヒープ&スタックは、プログラムの関数内で変数を宣言した時や、関数コールした時等必要なRAM領域となります。
この領域が枯渇すると、固まったり、意図しない動作をしたりします。
と、駆け足で説明を書いたので、わかりにくい所も多々あるかと思いますが、みなさんRAM不足には気を付けましょう(^^)/