Search code examples
arraysarduinoavravr-gccatmega

Arduino atmega2560 code size


I've been trying to run some code on an ATMEGA2560, and I've finally boiled everything down to this:

Works

#include "Arduino.h"
#include "HardwareSerial.h"

const char bob[7000] = "Hello\0";


void setup(void) {
  Serial.begin(9600);
  Serial.println("jshInit...");
  Serial.println(bob);
}

void loop(void) {
  Serial.println("foo...");
}

Doesn't do anything at all

#include "Arduino.h"
#include "HardwareSerial.h"

const char bob[8000] = "Hello\0";


void setup(void) {
  Serial.begin(9600);
  Serial.println("jshInit...");
  Serial.println(bob);
}

void loop(void) {
  Serial.println("foo...");
}

The only difference here is the size of bob. There are no compiler warnings or anything, even if bob is 20000, the Arduino just refuses to work if the bob array is too big.

Does anyone know what's wrong? I'm compiling with the Arduino IDE here, but for my main project I'm using avr-gcc (GCC) 4.5.3, and I tried 4.8.2 as well - same problem on all of them.

The atmega2560 has 256kb flash and 8kB RAM. It could be I'm using all the RAM (but it should tell me if so?), also there is the const keyword on bob which should mean it goes into flash?


Solution

  • Yes, you were indeed using up your SRAM.

    regarding your comment: You can not somehow use the const keyword to achieve the same thing as by using PROGMEM attribute.

    const is used to tell the compiler that the data is to be "read-only". const was intended for uses such as this, not as a means to identify where the data should be stored. If it were used as a means to define data storage, then it loses its correct meaning (changes its semantics) in other situations such as in the function parameter example.

    However, if you have lots of constant strings/data, you should indeed use PROGMEM to instruct the compiler to move the data into the flash memory.

    If you have data sets that require read/write access and have to be non-volatile you would use the EEPROM.

    There are tools like avr-size.exe (part of the GCC toolchain) to check your static SRAM usage at compile time. Keep in mind that you also have to make sure that the dynamic SRAM requirements (STACK) does not exceed the remaining memory during program execution.

    Its also possible to determine the SRAM usage at runtime by looking at the stack pointer. If only maximum SRAM usage is of interest, its also possible to write a dummy-pattern to the SRAM (all 0xAA for example), and check up to what address the pattern has been overwritten.