Arduinoメールチェッカー(その3)
メールチェッカーの不安定要因であたメモリーリーク問題が解決したため、最新版のコードをアップします。
「MailChecker_pub20090609.zip」をダウンロード
対策は、Arduino TexitStringライブラリのメモリーリークに示したTextStringライブラリコードの変更になります。変更箇所のみを以下に再掲します。
Stringライブラリのコードに、以下のデストラクタを追加します。
<WString.hへの追加>
public:
~String(); ←追加
<WString.cppへの追加>
String::~String()
{
free(_array);
}
あわせて、メールチェッカーのコードも若干見直しを行いました。
- メールサーバーに送信するpop3コマンド文字列を保持するバッファ量を拡大
- String.indexOf()メンバー関数の引数(検索する文字の指定)を、" "から' 'に変更。
" "を指定するとStringオブジェクトを引数として渡します。
' 'の場合は、charのスペース(0x20)を引数として渡します。
→ " "を引数にした場合のメモリーリークは解決したのですが、処理が重いオブジェクトを使用するまでもないため、charデータ型に変更しました
メールチェッカーのメモリー使用量
メールチェッカーのコードがスタック・ヒープをどの程度使っているのかを調べてみました。yagihiroさんのblogを参考にしました。
IDEと一緒にインストールされる「avr-objdump, avr-nm」を使用してヒープの割当を調べると以下の通りでした。elfファイルは、スケッチを保存したフォルダーのapplet配下に生成されます。
C:>avr-objdump -h MailChecker23.elf
MailChecker23.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 000001f8 00800100 00003c26 00003cba 2**0
CONTENTS, ALLOC, LOAD, DATA
1 .text 00003c26 00000000 00000000 00000094 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .bss 0000026b 008002f8 008002f8 00003eb2 2**0
ALLOC
.data + .bssセクションが 0x463 = 1123byte確保されています。この領域は、グローバルないしは静的に宣言している変数・インスタンス・定数などを格納しているようです。私は、SRAM 2KBのATmega328を使用しているため、SRAMの約半分をこの領域で使用していることになりす。
avr-nmコマンドにて、シンボル毎のメモリ割付を確認することができます。
C:>avr-nm -n -C MailChecker23.elf
00800100 D __data_start
008002f8 B __bss_start
~中略~
008002f8 D __data_end
008002f8 D _edata
~中略~
00800563 B __bss_end
00800563 N __heap_start
ヒープが0x0563から始まることが分かります。
Arduino TexitStringライブラリのメモリーリークに示した、heap pointerを出力するコードを入れて、pop3サーバーアクセス開始時のheap pointerを調べると以下でした。
Heap ptr :6C3
Stack ptr:8D6
プログラム開始時に確保するヒープ領域が0x160 = 352byte程度あることを示します。
Stack Endが0x08FF(2KBのSRAM空間の終わり)だとすると、Stack pointerが0x8D6のため、スタックを0x29 = 41byte使っていることになります。
Stack pointer - Heap pointerが空きメモリーということになるため、0x213 = 531byteが空きメモリーということになります。DateTime, NTPなどのライブラリも取り込んだため、残りメモリーが少なくなってきました。
上記から分かったメモリーマップのイメージを図にすると以下となります。
グローバル変数を多用して汚いコードになっている部分を、関数への引数渡しに書き替えてデーターの流れをすっきり見るようにしようかとも思ったのですが、スタックの使用量増加がよく分からないため(その分.data + .bssは減るのですが)当面は現状のままで行こうと思います。
| 固定リンク
「Arduino」カテゴリの記事
- ArduinoでXMLを解析する(2009.08.25)
- Arduino RSSリーダー(2009.09.06)
- Arduino 0017(2009.08.14)
- SPIデバイスの混在とSS信号の初期状態(2009.08.31)
- Arduino Nano 3.0 Get(2009.08.12)

コメント
ああ、なるほど、Arduinoと言うかAvr-Gccのメモリ割付状況はこうやって調べるのですか。早速ネタに使わせてもらおう。
メモリ割付状況なんて、「気にする人は気にする。気にならない人は全く無視するか、そんな物がある事すら知らない。」と言うのが今のArduinoだと思うんですけれど、ならappletなんて中間ファイルを吐き出すフォルダーは気にする人位しか見ないのだから標準でMAP出力してくれれば良いのに!と思ってしまう。
cores以下にあるmakefileをいじれば良いのかな。
投稿: hamayan | 2009年6月10日 (水) 10時05分
どうぞネタにしてやって下さい。私が発見したテクではありませんが、、
coreにあるmakefineを眺めてみたのですが、冒頭のコメントに、「This makefile allows you to build sketches from the command line without the Arduino environment (or Java).」なんてことが書いてあります。CLI make用ですか!
以下の定義があるためSymbol table/mapを生成するのではと期待したのですが、エラーが発生してうまくmakeできませんでした(Windows環境ではダメで、Linux環境ならうまくいくのかしら)。
--- makefileの抜粋 ----
OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump
NM = $(AVR_TOOLS_PATH)/avr-nm
# Create extended listing file from ELF output file.
.elf.lss:
$(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file.
.elf.sym:
$(NM) -n $< > $@
投稿: todotani | 2009年6月10日 (水) 22時37分