moved elf loading and debugging info to the mote type, rather than keeping a separate refence in each mote. this patch reduces both the memory usage of MSPSim-based motes, and the processing time to load them

This commit is contained in:
fros4943 2010-03-26 12:29:11 +00:00
parent bec1ccc57d
commit ce5d19fefd
4 changed files with 133 additions and 80 deletions

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: MspMote.java,v 1.44 2010/03/11 22:15:58 fros4943 Exp $
* $Id: MspMote.java,v 1.45 2010/03/26 12:29:11 fros4943 Exp $
*/
package se.sics.cooja.mspmote;
@ -35,10 +35,8 @@ import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Observable;
import org.apache.log4j.Logger;
@ -57,8 +55,8 @@ import se.sics.cooja.WatchpointMote;
import se.sics.cooja.interfaces.IPAddress;
import se.sics.cooja.motes.AbstractEmulatedMote;
import se.sics.cooja.mspmote.interfaces.MspSerial;
import se.sics.cooja.mspmote.plugins.MspBreakpointContainer;
import se.sics.cooja.mspmote.plugins.CodeVisualizerSkin;
import se.sics.cooja.mspmote.plugins.MspBreakpointContainer;
import se.sics.cooja.plugins.Visualizer;
import se.sics.mspsim.cli.CommandHandler;
import se.sics.mspsim.cli.LineListener;
@ -69,8 +67,6 @@ import se.sics.mspsim.platform.GenericNode;
import se.sics.mspsim.ui.JFrameWindowManager;
import se.sics.mspsim.util.ComponentRegistry;
import se.sics.mspsim.util.ConfigManager;
import se.sics.mspsim.util.DebugInfo;
import se.sics.mspsim.util.ELF;
import se.sics.mspsim.util.MapEntry;
import se.sics.mspsim.util.MapTable;
@ -93,7 +89,6 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
private MspMoteType myMoteType = null;
private MspMoteMemory myMemory = null;
private MoteInterfaceHandler myMoteInterfaceHandler = null;
private ELF myELFModule = null;
public ComponentRegistry registry = null;
/* Stack monitoring variables */
@ -132,7 +127,11 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
registry.registerComponent("windowManager", new JFrameWindowManager());
/* Create watchpoint container */
breakpointsContainer = new MspBreakpointContainer(this, getFirmwareDebugInfo(this));
try {
breakpointsContainer = new MspBreakpointContainer(this, ((MspMoteType)getType()).getFirmwareDebugInfo());
} catch (IOException e) {
throw (RuntimeException) new RuntimeException("Error: " + e.getMessage()).initCause(e);
}
}
}
@ -185,13 +184,6 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
myMemory = (MspMoteMemory) memory;
}
/**
* @return ELF module
*/
public ELF getELF() {
return myELFModule;
}
public Simulation getSimulation() {
return simulation;
}
@ -268,19 +260,15 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
this.myCpu.setTrace(0); /* TODO Enable */
int[] memory = myCpu.getMemory();
logger.info("Loading ELF from: " + fileELF.getAbsolutePath());
logger.info("Loading firmware from: " + fileELF.getAbsolutePath());
GUI.setProgressMessage("Loading " + fileELF.getName());
if (GUI.isVisualizedInApplet()) {
myELFModule = node.loadFirmware(new URL(GUI.getAppletCodeBase(), fileELF.getName()), memory);
} else {
myELFModule = node.loadFirmware(fileELF.getPath(), memory);
}
node.loadFirmware(((MspMoteType)getType()).getELF(), memory);
/* Throw exceptions at bad memory access */
/*myCpu.setThrowIfWarning(true);*/
/* Create mote address memory */
MapTable map = myELFModule.getMap();
MapTable map = ((MspMoteType)getType()).getELF().getMap();
MapEntry[] allEntries = map.getAllEntries();
myMemory = new MspMoteMemory(allEntries, myCpu);
@ -404,7 +392,11 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
myMoteInterfaceHandler = createMoteInterfaceHandler();
/* Create watchpoint container */
breakpointsContainer = new MspBreakpointContainer(this, getFirmwareDebugInfo(this));
try {
breakpointsContainer = new MspBreakpointContainer(this, ((MspMoteType)getType()).getFirmwareDebugInfo());
} catch (IOException e) {
throw (RuntimeException) new RuntimeException("Error: " + e.getMessage()).initCause(e);
}
for (Element element: configXML) {
String name = element.getName();
@ -492,44 +484,4 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
return breakpointsContainer;
}
private static Hashtable<File, Hashtable<Integer, Integer>> getFirmwareDebugInfo(MspMote mote) {
/* Fetch all executable addresses */
ArrayList<Integer> addresses = mote.getELF().getDebug().getExecutableAddresses();
Hashtable<File, Hashtable<Integer, Integer>> fileToLineHash =
new Hashtable<File, Hashtable<Integer, Integer>>();
for (int address: addresses) {
DebugInfo info = mote.getELF().getDebugInfo(address);
if (info != null && info.getPath() != null && info.getFile() != null && info.getLine() >= 0) {
/* Nasty Cygwin-Windows fix */
String path = info.getPath();
if (path.contains("/cygdrive/")) {
int index = path.indexOf("/cygdrive/");
char driveCharacter = path.charAt(index+10);
path = path.replace("/cygdrive/" + driveCharacter + "/", driveCharacter + ":/");
}
File file = new File(path, info.getFile());
try {
file = file.getCanonicalFile();
} catch (IOException e) {
}
Hashtable<Integer, Integer> lineToAddrHash = fileToLineHash.get(file);
if (lineToAddrHash == null) {
lineToAddrHash = new Hashtable<Integer, Integer>();
fileToLineHash.put(file, lineToAddrHash);
}
lineToAddrHash.put(info.getLine(), address);
}
}
return fileToLineHash;
}
}

View file

@ -26,22 +26,44 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: MspMoteType.java,v 1.34 2010/03/19 15:04:05 fros4943 Exp $
* $Id: MspMoteType.java,v 1.35 2010/03/26 12:29:11 fros4943 Exp $
*/
package se.sics.cooja.mspmote;
import java.awt.*;
import java.io.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.*;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import org.apache.log4j.Logger;
import org.jdom.Element;
import se.sics.cooja.*;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.GUI;
import se.sics.cooja.Mote;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteType;
import se.sics.cooja.ProjectConfig;
import se.sics.cooja.Simulation;
import se.sics.cooja.interfaces.IPAddress;
import se.sics.cooja.mspmote.interfaces.MspSerial;
import se.sics.cooja.util.ArrayUtils;
import se.sics.mspsim.util.DebugInfo;
import se.sics.mspsim.util.ELF;
/**
* MSP430-based mote types emulated in MSPSim.
@ -336,4 +358,75 @@ public abstract class MspMoteType implements MoteType {
public abstract Class<? extends MoteInterface>[] getAllMoteInterfaceClasses();
public abstract File getExpectedFirmwareFile(File source);
private static ELF loadELF(URL url) throws Exception {
byte[] data = ArrayUtils.readFromStream(url.openStream());
ELF elf = new ELF(data);
elf.readAll();
return elf;
}
private static ELF loadELF(String filepath) throws IOException {
return ELF.readELF(filepath);
}
private ELF elf; /* cached */
public ELF getELF() throws IOException {
if (elf == null) {
if (GUI.isVisualizedInApplet()) {
logger.warn("ELF loading in applet not implemented");
}
elf = loadELF(getContikiFirmwareFile().getPath());
}
return elf;
}
private Hashtable<File, Hashtable<Integer, Integer>> debuggingInfo = null; /* cached */
public Hashtable<File, Hashtable<Integer, Integer>> getFirmwareDebugInfo()
throws IOException {
if (debuggingInfo == null) {
debuggingInfo = getFirmwareDebugInfo(getELF());
}
return debuggingInfo;
}
public static Hashtable<File, Hashtable<Integer, Integer>> getFirmwareDebugInfo(ELF elf) {
/* Fetch all executable addresses */
ArrayList<Integer> addresses = elf.getDebug().getExecutableAddresses();
Hashtable<File, Hashtable<Integer, Integer>> fileToLineHash =
new Hashtable<File, Hashtable<Integer, Integer>>();
for (int address: addresses) {
DebugInfo info = elf.getDebugInfo(address);
if (info != null && info.getPath() != null && info.getFile() != null && info.getLine() >= 0) {
/* Nasty Cygwin-Windows fix */
String path = info.getPath();
if (path.contains("/cygdrive/")) {
int index = path.indexOf("/cygdrive/");
char driveCharacter = path.charAt(index+10);
path = path.replace("/cygdrive/" + driveCharacter + "/", driveCharacter + ":/");
}
File file = new File(path, info.getFile());
try {
file = file.getCanonicalFile();
} catch (IOException e) {
}
Hashtable<Integer, Integer> lineToAddrHash = fileToLineHash.get(file);
if (lineToAddrHash == null) {
lineToAddrHash = new Hashtable<Integer, Integer>();
fileToLineHash.put(file, lineToAddrHash);
}
lineToAddrHash.put(info.getLine(), address);
}
}
return fileToLineHash;
}
}

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: CodeVisualizerSkin.java,v 1.1 2010/03/11 22:15:58 fros4943 Exp $
* $Id: CodeVisualizerSkin.java,v 1.2 2010/03/26 12:29:11 fros4943 Exp $
*/
package se.sics.cooja.mspmote.plugins;
@ -47,6 +47,7 @@ import se.sics.cooja.Mote;
import se.sics.cooja.Simulation;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.mspmote.MspMote;
import se.sics.cooja.mspmote.MspMoteType;
import se.sics.cooja.plugins.Visualizer;
import se.sics.cooja.plugins.VisualizerSkin;
import se.sics.mspsim.core.MSP430;
@ -103,7 +104,7 @@ public class CodeVisualizerSkin implements VisualizerSkin {
}
try {
DebugInfo debugInfo =
((MspMote)mote).getELF().getDebugInfo(((MspMote)mote).getCPU().reg[MSP430.PC]);
((MspMoteType)mote.getType()).getELF().getDebugInfo(((MspMote)mote).getCPU().reg[MSP430.PC]);
if (debugInfo == null) {
return null;
}

View file

@ -26,24 +26,20 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: MspCodeWatcher.java,v 1.22 2010/01/15 10:55:03 fros4943 Exp $
* $Id: MspCodeWatcher.java,v 1.23 2010/03/26 12:29:11 fros4943 Exp $
*/
package se.sics.cooja.mspmote.plugins;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Observable;
import java.util.Observer;
@ -52,7 +48,6 @@ import java.util.Vector;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
@ -80,10 +75,10 @@ import se.sics.cooja.Simulation;
import se.sics.cooja.VisPlugin;
import se.sics.cooja.GUI.RunnableInEDT;
import se.sics.cooja.mspmote.MspMote;
import se.sics.cooja.mspmote.MspMoteType;
import se.sics.cooja.util.StringUtils;
import se.sics.mspsim.core.EmulationException;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.MSP430Core;
import se.sics.mspsim.ui.DebugUI;
import se.sics.mspsim.util.DebugInfo;
@ -289,7 +284,7 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin {
currentCodeFile = null;
try {
DebugInfo debugInfo = mspMote.getELF().getDebugInfo(mspMote.getCPU().reg[MSP430.PC]);
DebugInfo debugInfo = ((MspMoteType)mspMote.getType()).getELF().getDebugInfo(mspMote.getCPU().reg[MSP430.PC]);
if (debugInfo == null) {
return;
}
@ -324,7 +319,13 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin {
}
private void tryMapDebugInfo() {
final String[] debugFiles = mspMote.getELF().getDebug().getSourceFiles();
final String[] debugFiles;
try {
debugFiles = ((MspMoteType)mspMote.getType()).getELF().getDebug().getSourceFiles();
} catch (IOException e1) {
logger.fatal("Error: " + e1.getMessage(), e1);
return;
}
debugInfoMap = new RunnableInEDT<String[]>() {
public String[] work() {
/* Select which source file to use */
@ -435,7 +436,13 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin {
}
private static File[] getSourceFiles(MspMote mote, String[] map) {
final String[] sourceFiles = mote.getELF().getDebug().getSourceFiles();
final String[] sourceFiles;
try {
sourceFiles = ((MspMoteType)mote.getType()).getELF().getDebug().getSourceFiles();
} catch (IOException e1) {
logger.fatal("Error: " + e1.getMessage(), e1);
return null;
}
File contikiSource = mote.getType().getContikiSourceFile();
if (contikiSource != null) {
try {