Skip to content

Update to Arduino IDE 1.5.x to support detecting and reporting out of RAM conditions #1377

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 3, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 33 additions & 7 deletions app/src/processing/app/Sketch.java
Original file line number Diff line number Diff line change
Expand Up @@ -1613,25 +1613,51 @@ public void setCompilingProgress(int percent) {


protected void size(PreferencesMap prefs) throws RunnerException {
long size = 0;
String maxsizeString = prefs.get("upload.maximum_size");
if (maxsizeString == null)
long textSize = 0;
long dataSize = 0;
String maxTextSizeString = prefs.get("upload.maximum_size");
String maxDataSizeString = prefs.get("upload.maximum_data_size");
if (maxTextSizeString == null)
return;
long maxsize = Integer.parseInt(maxsizeString);
long maxTextSize = Integer.parseInt(maxTextSizeString);
long maxDataSize = -1;
if(maxDataSizeString != null)
maxDataSize = Integer.parseInt(maxDataSizeString);
Sizer sizer = new Sizer(prefs);
try {
size = sizer.computeSize();
long[] sizes = sizer.computeSize();
textSize = sizes[0];
dataSize = sizes[1];
System.out.println(I18n
.format(_("Binary sketch size: {0} bytes (of a {1} byte maximum) - {2}% used"),
size, maxsize, size * 100 / maxsize));
textSize, maxTextSize, textSize * 100 / maxTextSize));
if(dataSize >= 0) {
if(maxDataSize > 0) {
System.out.println(I18n
.format(_("Minimum Memory usage: {0} bytes (of a {1} byte maximum) - {2}% used"),
dataSize, maxDataSize, dataSize * 100 / maxDataSize));
} else {
System.out.println(I18n
.format(_("Minimum Memory usage: {0} bytes"),
dataSize));
}
}
} catch (RunnerException e) {
System.err.println(I18n.format(_("Couldn't determine program size: {0}"),
e.getMessage()));
}

if (size > maxsize)
if (textSize > maxTextSize)
throw new RunnerException(
_("Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it."));

if (maxDataSize > 0 && dataSize > maxDataSize)
throw new RunnerException(
_("Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint."));

int warnDataPercentage = Integer.parseInt(prefs.get("build.warn_data_percentage"));
if (maxDataSize > 0 && dataSize > maxDataSize*warnDataPercentage/100)
System.out.println(_("Low memory available, stability problems may occur"));
}

protected String upload(String buildPath, String suggestedClassName, boolean usingProgrammer)
Expand Down
55 changes: 44 additions & 11 deletions app/src/processing/app/debug/Sizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,40 @@
import processing.app.helpers.StringReplacer;

public class Sizer implements MessageConsumer {
private long size;
private long textSize;
private long dataSize;
private long eepromSize;
private RunnerException exception;
private PreferencesMap prefs;
private String firstLine;
private Pattern pattern;
private Pattern textPattern;
private Pattern dataPattern;
private Pattern eepromPattern;

public Sizer(PreferencesMap _prefs) {
prefs = _prefs;
pattern = Pattern.compile(prefs.get("recipe.size.regex"));
textPattern = Pattern.compile(prefs.get("recipe.size.regex"));
dataPattern = null;
String pref = prefs.get("recipe.size.regex.data");
if(pref != null)
dataPattern = Pattern.compile(pref);
eepromPattern = null;
pref = prefs.get("recipe.size.regex.eeprom");
if(pref != null)
eepromPattern = Pattern.compile(pref);
}

public long computeSize() throws RunnerException {
public long[] computeSize() throws RunnerException {

int r = 0;
try {
String pattern = prefs.get("recipe.size.pattern");
String cmd[] = StringReplacer.formatAndSplit(pattern, prefs, true);

exception = null;
size = -1;
textSize = -1;
dataSize = -1;
eepromSize = -1;
Process process = Runtime.getRuntime().exec(cmd);
MessageSiphon in = new MessageSiphon(process.getInputStream(), this);
MessageSiphon err = new MessageSiphon(process.getErrorStream(), this);
Expand All @@ -77,17 +91,36 @@ public long computeSize() throws RunnerException {
if (exception != null)
throw exception;

if (size == -1)
if (textSize == -1)
throw new RunnerException(firstLine);

return size;
return new long[] { textSize, dataSize, eepromSize };
}

public void message(String s) {
if (firstLine == null)
firstLine = s;
Matcher matcher = pattern.matcher(s.trim());
if (matcher.matches())
size = Long.parseLong(matcher.group(1));
Matcher textMatcher = textPattern.matcher(s.trim());
if (textMatcher.matches()) {
if (textSize < 0)
textSize = 0;
textSize += Long.parseLong(textMatcher.group(1));
}
if(dataPattern != null) {
Matcher dataMatcher = dataPattern.matcher(s.trim());
if (dataMatcher.matches()) {
if (dataSize < 0)
dataSize = 0;
dataSize += Long.parseLong(dataMatcher.group(1));
}
}
if(eepromPattern != null) {
Matcher eepromMatcher = eepromPattern.matcher(s.trim());
if (eepromMatcher.matches()) {
if (eepromSize < 0)
eepromSize = 0;
eepromSize += Long.parseLong(eepromMatcher.group(1));
}
}
}
}
}
2 changes: 2 additions & 0 deletions build/shared/lib/preferences.txt
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ target_package = arduino
target_platform = avr
board = uno
software=ARDUINO
# Warn when data segment uses greater than this percentage
build.warn_data_percentage = 75

programmer = arduino:avrispmkii

Expand Down
22 changes: 22 additions & 0 deletions hardware/arduino/avr/boards.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ uno.name=Arduino Uno
uno.upload.tool=avrdude
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.maximum_data_size=2048
uno.upload.speed=115200

uno.bootloader.tool=avrdude
Expand Down Expand Up @@ -46,6 +47,7 @@ atmega328diecimila.build.variant=standard
atmega328diecimila.menu.cpu.atmega328=ATmega328

atmega328diecimila.menu.cpu.atmega328.upload.maximum_size=30720
atmega328diecimila.menu.cpu.atmega328.upload.maximum_data_size=2048
atmega328diecimila.menu.cpu.atmega328.upload.speed=57600

atmega328diecimila.menu.cpu.atmega328.bootloader.high_fuses=0xDA
Expand All @@ -59,6 +61,7 @@ atmega328diecimila.menu.cpu.atmega328.build.mcu=atmega328p
atmega328diecimila.menu.cpu.atmega168=ATmega168

atmega328diecimila.menu.cpu.atmega168.upload.maximum_size=14336
atmega328diecimila.menu.cpu.atmega168.upload.maximum_data_size=1024
atmega328diecimila.menu.cpu.atmega168.upload.speed=19200

atmega328diecimila.menu.cpu.atmega168.bootloader.high_fuses=0xdd
Expand Down Expand Up @@ -88,6 +91,7 @@ nano.build.variant=eightanaloginputs
nano.menu.cpu.atmega328=ATmega328

nano.menu.cpu.atmega328.upload.maximum_size=30720
nano.menu.cpu.atmega328.upload.maximum_data_size=2048
nano.menu.cpu.atmega328.upload.speed=57600

nano.menu.cpu.atmega328.bootloader.low_fuses=0xFF
Expand All @@ -102,6 +106,7 @@ menu.cpu.nano.atmega328.build.mcu=atmega328p
nano.menu.cpu.atmega168=ATmega168

nano.menu.cpu.atmega168.upload.maximum_size=14336
nano.menu.cpu.atmega168.upload.maximum_data_size=1024
nano.menu.cpu.atmega168.upload.speed=19200

nano.menu.cpu.atmega168.bootloader.low_fuses=0xff
Expand Down Expand Up @@ -165,6 +170,7 @@ leonardo.name=Arduino Leonardo
leonardo.upload.tool=avrdude
leonardo.upload.protocol=avr109
leonardo.upload.maximum_size=28672
leonardo.upload.maximum_data_size=2560
leonardo.upload.speed=57600
leonardo.upload.disable_flushing=true
leonardo.upload.use_1200bps_touch=true
Expand Down Expand Up @@ -193,6 +199,7 @@ micro.name=Arduino Micro
micro.upload.tool=avrdude
micro.upload.protocol=avr109
micro.upload.maximum_size=28672
micro.upload.maximum_data_size=2560
micro.upload.speed=57600
micro.upload.disable_flushing=true
micro.upload.use_1200bps_touch=true
Expand Down Expand Up @@ -221,6 +228,7 @@ esplora.name=Arduino Esplora
esplora.upload.tool=avrdude
esplora.upload.protocol=avr109
esplora.upload.maximum_size=28672
esplora.upload.maximum_data_size=2560
esplora.upload.speed=57600
esplora.upload.disable_flushing=true
esplora.upload.use_1200bps_touch=true
Expand Down Expand Up @@ -265,6 +273,7 @@ mini.build.variant=eightanaloginputs
mini.menu.cpu.atmega328=ATmega328

mini.menu.cpu.atmega328.upload.maximum_size=28672
mini.menu.cpu.atmega328.upload.maximum_data_size=2048
mini.menu.cpu.atmega328.upload.speed=115200

mini.menu.cpu.atmega328.bootloader.high_fuses=0xd8
Expand All @@ -278,6 +287,7 @@ mini.menu.cpu.atmega328.build.mcu=atmega328p
mini.menu.cpu.atmega168=ATmega168

mini.menu.cpu.atmega168.upload.maximum_size=14336
mini.menu.cpu.atmega168.upload.maximum_data_size=1024
mini.menu.cpu.atmega168.upload.speed=19200

mini.menu.cpu.atmega168.bootloader.high_fuses=0xdd
Expand All @@ -293,6 +303,7 @@ ethernet.name=Arduino Ethernet
ethernet.upload.tool=avrdude
ethernet.upload.protocol=arduino
ethernet.upload.maximum_size=32256
ethernet.upload.maximum_data_size=2048
ethernet.upload.speed=115200

ethernet.bootloader.tool=avrdude
Expand All @@ -316,6 +327,7 @@ fio.name=Arduino Fio
fio.upload.tool=avrdude
fio.upload.protocol=arduino
fio.upload.maximum_size=30720
fio.upload.maximum_data_size=2048
fio.upload.speed=57600

fio.bootloader.tool=avrdude
Expand Down Expand Up @@ -355,6 +367,7 @@ bt.build.variant=eightanaloginputs
## -----------------------
bt.menu.cpu.atmega328=ATmega328
bt.menu.cpu.atmega328.upload.maximum_size=28672
bt.menu.cpu.atmega328.upload.maximum_data_size=2048

bt.menu.cpu.atmega328.bootloader.high_fuses=0xd8
bt.menu.cpu.atmega328.bootloader.extended_fuses=0x05
Expand All @@ -366,6 +379,7 @@ bt.menu.cpu.atmega328.build.mcu=atmega328p
## -----------------------
bt.menu.cpu.atmega168=ATmega168
bt.menu.cpu.atmega168.upload.maximum_size=14336
bt.menu.cpu.atmega168.upload.maximum_data_size=1024

bt.menu.cpu.atmega168.bootloader.high_fuses=0xdd
bt.menu.cpu.atmega168.bootloader.extended_fuses=0x00
Expand All @@ -380,6 +394,7 @@ LilyPadUSB.name=LilyPad Arduino USB
LilyPadUSB.upload.tool=avrdude
LilyPadUSB.upload.protocol=avr109
LilyPadUSB.upload.maximum_size=28672
LilyPadUSB.upload.maximum_data_size=2560
LilyPadUSB.upload.speed=57600
LilyPadUSB.upload.disable_flushing=true
LilyPadUSB.upload.use_1200bps_touch=true
Expand Down Expand Up @@ -423,6 +438,7 @@ lilypad.build.variant=standard
lilypad.menu.cpu.atmega328=ATmega328

lilypad.menu.cpu.atmega328.upload.maximum_size=30720
lilypad.menu.cpu.atmega328.upload.maximum_data_size=2048
lilypad.menu.cpu.atmega328.upload.speed=57600

lilypad.menu.cpu.atmega328.bootloader.low_fuses=0xFF
Expand All @@ -437,6 +453,7 @@ lilypad.menu.cpu.atmega328.build.mcu=atmega328p
lilypad.menu.cpu.atmega168=ATmega168

lilypad.menu.cpu.atmega168.upload.maximum_size=14336
lilypad.menu.cpu.atmega168.upload.maximum_data_size=1024
lilypad.menu.cpu.atmega168.upload.speed=19200

lilypad.menu.cpu.atmega168.bootloader.low_fuses=0xe2
Expand Down Expand Up @@ -466,6 +483,7 @@ pro.build.variant=standard
pro.menu.cpu.16MHzatmega328=ATmega328 (5V, 16 MHz)

pro.menu.cpu.16MHzatmega328.upload.maximum_size=30720
pro.menu.cpu.16MHzatmega328.upload.maximum_data_size=2048
pro.menu.cpu.16MHzatmega328.upload.speed=57600

pro.menu.cpu.16MHzatmega328.bootloader.low_fuses=0xFF
Expand All @@ -481,6 +499,7 @@ pro.menu.cpu.16MHzatmega328.build.f_cpu=16000000L
pro.menu.cpu.8MHzatmega328=ATmega328 (3.3V, 8 MHz)

pro.menu.cpu.8MHzatmega328.upload.maximum_size=30720
pro.menu.cpu.8MHzatmega328.upload.maximum_data_size=2048
pro.menu.cpu.8MHzatmega328.upload.speed=57600

pro.menu.cpu.8MHzatmega328.bootloader.low_fuses=0xFF
Expand All @@ -496,6 +515,7 @@ pro.menu.cpu.8MHzatmega328.build.f_cpu=8000000L
pro.menu.cpu.16MHzatmega168=ATmega168 (5V, 16 MHz)

pro.menu.cpu.16MHzatmega168.upload.maximum_size=14336
pro.menu.cpu.16MHzatmega168.upload.maximum_data_size=1024
pro.menu.cpu.16MHzatmega168.upload.speed=19200

pro.menu.cpu.16MHzatmega168.bootloader.low_fuses=0xff
Expand All @@ -511,6 +531,7 @@ pro.menu.cpu.16MHzatmega168.build.f_cpu=16000000L
pro.menu.cpu.8MHzatmega168=ATmega168 (3.3V, 8 MHz)

pro.menu.cpu.8MHzatmega168.upload.maximum_size=14336
pro.menu.cpu.8MHzatmega168.upload.maximum_data_size=1024
pro.menu.cpu.8MHzatmega168.upload.speed=19200

pro.menu.cpu.8MHzatmega168.bootloader.low_fuses=0xc6
Expand Down Expand Up @@ -544,6 +565,7 @@ atmegang.build.variant=standard
atmegang.menu.cpu.atmega168=ATmega168

atmegang.menu.cpu.atmega168.upload.maximum_size=14336
atmegang.menu.cpu.atmega168.upload.maximum_data_size=1024

atmegang.menu.cpu.atmega168.bootloader.low_fuses=0xff
atmegang.menu.cpu.atmega168.bootloader.high_fuses=0xdd
Expand Down
6 changes: 4 additions & 2 deletions hardware/arduino/avr/platform.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.obj
recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"

## Compute size
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.hex"
recipe.size.regex=Total\s+([0-9]+).*
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).*
recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).*
recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).*


# AVR Uploader/Programmers tools
Expand Down