LoginSignup
6
2

More than 5 years have passed since last update.

Arduino SRAMメモリオーバーを判定して見ました。

Last updated at Posted at 2019-01-30

概要

Arduino UNOを使用したセンサーに改良を加えていると、ある時から正常に動作しなくなり原因を調べたところ、SRAMメモリ不足が原因ということが分かりました。
丁度いい機会なので、SRAMメモリについて調べ、今後、同様の問題を早期に発見できるように対策を考えたいと思います。

先に結論を伝えると、空きメモリ容量が残っていても文字が追加できなくなることが分かりましたので、文字列が加算できなくなったタイミングでオーバーフロー判定とすることにしました。

環境

・Arduino UNO

仕様より:https://www.switch-science.com/catalog/789/
image.png

→SRAM:2KB(2048Byte)あることが分かります。

・書き込み時のメッセージと仕様が一致していることを確認します。
image.png

実行中の空きメモリ容量を調査

下記のサイトのfreeRamメソッドを使用し、空きメモリを調査します。
参考:https://playground.arduino.cc/Code/AvailableMemory

<メソッドを追加した時の書き込みメッセージと空きメモリ出力結果>
image.png

memory.ino
#define SERIAL_BAUD 9600

void setup() {
  Serial.begin(SERIAL_BAUD);

  dispMemory();
}

void loop() {

}

void dispMemory(){
  Serial.print(F("Free memory=")); 
  Serial.print(freeRam(), DEC);
  Serial.println(F("[bytes]"));
}

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

メモリオーバー時の動作を確認

メンバ変数に文字を結合していき、メモリオーバーしたときの動作を確認します。

memory2.ino
#define SERIAL_BAUD 9600

String m_buf = "a";

void setup() {
  Serial.begin(SERIAL_BAUD);

  dispMemory();
}

void loop() {
  m_buf.concat(F("a"));
  Serial.print(F("String Length=")); 
  Serial.println(m_buf.length()); 

  dispMemory();
}

void dispMemory(){
  Serial.print(F("Free memory=")); 
  Serial.print(freeRam(), DEC);
  Serial.println(F("[bytes]"));
}

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

・書き込み時のメッセージ:
image.png

・実行開始時の出力結果:
image.png

・メモリオーバーフロー後の出力結果: ※同じ出力結果が続きます。
image.png

文字数が1687バイトを超えたところで、文字列の増加が止まっています。
そして特にエラーにはならず、問題なく動作し続けています。

空きメモリは、140バイトは残っている状態で、文字が追加できなくなっているので、freeRamの結果だけを見て処理が継続できるかの判断はできなさそうです。

調査用メソッド作成

freeRamの結果を元に、オーバーフローを判定することは難しいようなので、今回は文字を加算した値が文字数として反映されているかどうかをチェックし、メモリオーバーフローが発生しているか確認するメソッドを作成しました。

bool isMemory(){
  String s = F("");
  s.concat(F("a"));
  if(s.length() == 1){
    return true;
  }
  return false;
}

<実行結果>
image.png

文字が1669文字で文字追加が出来なくなっており、その結果(false:0)が表示されています。

まとめ

ArduinoMegaを使った開発が多かったため、ArduinoUnoでSRAMメモリ不足という問題になかなか気づくことが出来ず、時間を使ってしまいました。
今後は同様の問題が発生した場合も上記のコードを使えば素早く判断することが出来ると思います。

6
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2