1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-30 16:24:09 +03:00

Detect RAM usage and stop if full

This resolves issue #1356 and add the ability for the Arduino IDE to
detect the amount of RAM allocated to a sketch and compare that to the
available RAM on each board. If RAM is more than 90% full, it will fail
on building since there is not enough free RAM for the heap and stack to
use.
This commit is contained in:
Loren M. Lang
2013-04-22 17:48:22 -07:00
parent 443d0e1f26
commit 7c87db3532
4 changed files with 95 additions and 20 deletions

View File

@ -1613,23 +1613,41 @@ public class Sketch {
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(maxDataSize > 0) {
System.out.println(I18n
.format(_("Memory usage: {0} bytes (of a {1} byte maximum) - {2}% used"),
dataSize, maxDataSize, dataSize * 100 / maxDataSize));
} else {
System.out.println(I18n
.format(_("Memory usage: {0} bytes"),
dataSize));
}
} catch (RunnerException e) {
System.err.println(I18n.format(_("Couldn't determine program size: {0}"),
e.getMessage()));
}
if (size > maxsize)
/* At least 10% of RAM should be reserved for stack/heap usage */
if (textSize > maxTextSize ||
(maxDataSize > 0 && dataSize > maxDataSize*9/10))
throw new RunnerException(
_("Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it."));
}

View File

@ -33,18 +33,30 @@ import processing.app.helpers.PreferencesMap;
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 {
@ -52,7 +64,9 @@ public class Sizer implements MessageConsumer {
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);
@ -77,17 +91,36 @@ public class Sizer implements MessageConsumer {
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));
}
}
}
}
}