Here is a fix I'm using, it uses avr-objdump to determine the sram usage (limited to 1024 bytes) and sketch size, it prints out the size of the statically allocated ram after the sketch size and prints a warning if it exceeds a certain threshold, and throws an error if max ram is exceeded. Handy for quickly reminding users using too much data in ram (easy to do) to consider using PROGMEM.
Enjoy
here is the replacement size function I'm using in Sketch.java:
protected void size(String buildPath, String suggestedClassName)
throws RunnerException {
long size = 0;
long maxsize = Preferences.getInteger("boards." + Preferences.get("board") + ".upload.maximum_size");
String s = Preferences.get("boards." + Preferences.get("board") + ".upload.maximum_ram_size");
long maxram = s==null?1024:Integer.parseInt(s);
s = Preferences.get("boards." + Preferences.get("board") + ".upload.warning_ram_size");
long warningram = s==null?maxram/2:Integer.parseInt(s);
Sizer sizer = new Sizer(buildPath, suggestedClassName);
try {
size = sizer.computeSize();
System.out.println("Binary sketch size: " + size + " bytes (of a " +
maxsize + " byte maximum)");
System.out.println("Chip memory sram: " + sizer.data +
" bytes (of a " +maxram+ " byte maximum)");
} catch (RunnerException e) {
System.err.println("Couldn't determine program size: " + e.getMessage());
}
if (sizer.data > maxram)
throw new RunnerException(
"Allowable chip memory exceeded; see http://www.arduino.cc/en/Reference/PROGMEM to reduce ram size");
if (sizer.data > warningram)
System.err.println("Warning Large amount of chip memory used. Consider using PROGMEM, http://www.arduino.cc/en/Reference/PROGMEM, to reduce ram size ");
if (size > maxsize)
throw new RunnerException(
"Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.");
}
And here is the replacement Sizer.java
package processing.app;
import java.io.*;
import java.util.*;
public class Sizer implements MessageConsumer {
private String buildPath, sketchName;
private String firstLine;
private long size;
private RunnerException exception;
public Sizer(String buildPath, String sketchName) {
this.buildPath = buildPath;
this.sketchName = sketchName;
}
public long computeSize() throws RunnerException {
String userdir = System.getProperty("user.dir") + File.separator;
String avrBasePath;
if(Base.isMacOS()) {
avrBasePath = new String("hardware/tools/avr/bin/");
}
else if(Base.isLinux()) {
avrBasePath = new String("");
}
else {
avrBasePath = new String(userdir + "hardware/tools/avr/bin/");
}
String commandSize[] = new String[] {
avrBasePath + "avr-objdump",
"-h",
""
};
commandSize[2] = buildPath + File.separator + sketchName + ".elf";
try {
exception = null;
size = -1;
firstLine = null;
Process process = Runtime.getRuntime().exec(commandSize);
new MessageSiphon(process.getInputStream(), this);
new MessageSiphon(process.getErrorStream(), this);
boolean running = true;
while(running) {
try {
process.waitFor();
running = false;
} catch (InterruptedException intExc) { }
}
} catch (Exception e) {
// The default Throwable.toString() never returns null, but apparently
// some sub-class has overridden it to do so, thus we need to check for
// it. See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1166589459
exception = new RunnerException(
(e.toString() == null) ? e.getClass().getName() : e.toString());
}
if (exception != null)
throw exception;
if (size == -1)
throw new RunnerException(firstLine);
return size+1;
}
public int data = 0;
public void message(String s) {
if (firstLine == null)
firstLine = s;
else {
size+=checkTag(s," .text ");
data+=checkTag(s," .data ");
data+=checkTag(s," .bss ");
// exception = new RunnerException(e.toString());
}
}
private int checkTag(String s, String tag){
int size=0;
int p = s.indexOf(tag);
if(p != -1){
s=s.substring(p+6).trim();
p=s.indexOf(" ");
if(p != -1)
size = Integer.parseInt(s.substring(0,p).trim(),16);
}
return size;
}
}
Note: the original Sizer used avr-size, but it did not display any sram info on my XP machine.
Dave.