Pages: [1] 2   Go Down
Author Topic: SRAM size compile time check/report.  (Read 9271 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
God Member
*****
Karma: 1
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley

here is the replacement size function I'm using in Sketch.java:
Code:
 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
Code:
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.
« Last Edit: August 02, 2013, 02:57:49 pm by Coding Badly » Logged

Austin, TX USA
Offline Offline
God Member
*****
Karma: 4
Posts: 997
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cool, Dave.  Nice work.

Mikal
Logged

0
Offline Offline
God Member
*****
Karma: 1
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Mikal smiley

As an afterthought, I'm thinking it should direct users to here instead:
http://www.arduino.cc/en/Tutorial/Memory
Logged

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Awesome.  I've added an item to my todo list to integrate this code.
Logged

0
Offline Offline
God Member
*****
Karma: 1
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cool smiley  Thx David!
« Last Edit: October 23, 2008, 08:41:00 pm by dcb » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 30
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I'm pretty new to tinkering with this sort of thing, but it would definitely be a help to me to incorporate this feature in my IDE. Can anyone post or direct to a step-by-step method of incorporating this capability into my current Arduino IDE?

I'm developing in Mac OSX 10.5.5 using Arduino 0011

Thanks
Logged

Colorado
Offline Offline
Full Member
***
Karma: 2
Posts: 220
Arduino 0022 and Ubuntu 11.10 64bit.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Very Nice, I just updated to version 0013 and your patch worked very well. Thanks  You smiley

Now to finish a door lock using an APSX RW-210 and a boarduino  smiley
« Last Edit: January 23, 2009, 10:38:41 am by mrtaylor » Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 153
veroboaring is the new XGame - Extreme Veroboarder
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi David, where those .java files goes?
I want to implement that info because i have some RAM problems with my arduino, it's use LCD, I2C and a 20keys keyboard, i do not why i'm out of memory!!

And i forget....I2C as master!

Thanks!
Frank
« Last Edit: February 14, 2009, 07:53:28 pm by FrankRadio » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 97
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Could someone please expound on how to implement these patches? A search of my computer and google has been no help. I'm not sure which files to change.

Thanks,
Matt
Logged

0
Offline Offline
God Member
*****
Karma: 1
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It is a little involved.  You have to know how to compile java and where to put the compiled files (and how to change the classpath) so they will override the existing classes in the jar files.  

Then remember that you did that so when something breaks in the next release you undo any changes before reporting an issue.

« Last Edit: February 19, 2009, 04:36:48 pm by dcb » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 97
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sounds above my pay grade. Too bad though, sounds like a nice feature. I'm working on a project now with ver0013 that showed symptoms of SRAM problems.
Logged

0
Offline Offline
God Member
*****
Karma: 1
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

All the program is doing is running:
hardware/tools/avr/bin/avr-objdump -h  [sketchName].elf

You could run avr-objdump from the command line if you know where to find the elf file for your script (same place as the hex file that gets uploaded).
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 97
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I ran avr-objdump as per your instructions. Attached is a screen shot of the output. After looking at your code in the first post, I'm thinking .data, .text and .bss are the important lines. I'm also assuming that the "Size" column is in HEX. So .data=542, .text=8380 and .bss=426. The Arduino-0013 compiler outputs a sketch size of 8946 bytes. So I'm thinking .text is part of the sketch size but beyond that I'm not clear on which numbers are included in my sketch size and which are SRAM.



Thanks for your help so far,
Matt
Logged

0
Offline Offline
God Member
*****
Karma: 1
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

yup, text = flash size, data + bss = the static ram usage (not uncluding any dynamic allocations, call stacks, etc.

You have used up 968 bytes of sram statically, out of 1024 bytes.  you might need to introduce your program to PROGMEM.

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 18
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Copied from J Luciani's post in http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1236113624/11#11, you might find

Code:
avr-size YOUR-PROGRAM-NAME.elf
is a bit simpler to just check the headlines.

This gives you a size summary of three elements of memory:

text = code (flash) memory
data = initialised data (in RAM - includes strings etc)
bss = non-initialised data (actually normally set to 0x00) also in RAM.

So total RAM usage = (data + bss), but this does not include dynamic memory allocated from the heap at run time...

All of these values are in DECIMAL.  Then the total is given in decimal and hex.
Logged

Pages: [1] 2   Go Up
Jump to: