From ce5d19fefdd3bc9df044ddff343aa35523f0ae20 Mon Sep 17 00:00:00 2001 From: fros4943 Date: Fri, 26 Mar 2010 12:29:11 +0000 Subject: [PATCH] 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 --- .../src/se/sics/cooja/mspmote/MspMote.java | 78 +++---------- .../se/sics/cooja/mspmote/MspMoteType.java | 103 +++++++++++++++++- .../mspmote/plugins/CodeVisualizerSkin.java | 5 +- .../cooja/mspmote/plugins/MspCodeWatcher.java | 27 +++-- 4 files changed, 133 insertions(+), 80 deletions(-) diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMote.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMote.java index 8602096c1..a2bc9f0a8 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMote.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMote.java @@ -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> getFirmwareDebugInfo(MspMote mote) { - /* Fetch all executable addresses */ - ArrayList addresses = mote.getELF().getDebug().getExecutableAddresses(); - - Hashtable> fileToLineHash = - new Hashtable>(); - - 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 lineToAddrHash = fileToLineHash.get(file); - if (lineToAddrHash == null) { - lineToAddrHash = new Hashtable(); - fileToLineHash.put(file, lineToAddrHash); - } - - lineToAddrHash.put(info.getLine(), address); - } - } - - return fileToLineHash; - } - } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteType.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteType.java index 083893b80..54cd7c233 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteType.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMoteType.java @@ -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[] 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> debuggingInfo = null; /* cached */ + public Hashtable> getFirmwareDebugInfo() + throws IOException { + if (debuggingInfo == null) { + debuggingInfo = getFirmwareDebugInfo(getELF()); + } + return debuggingInfo; + } + + public static Hashtable> getFirmwareDebugInfo(ELF elf) { + /* Fetch all executable addresses */ + ArrayList addresses = elf.getDebug().getExecutableAddresses(); + + Hashtable> fileToLineHash = + new Hashtable>(); + + 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 lineToAddrHash = fileToLineHash.get(file); + if (lineToAddrHash == null) { + lineToAddrHash = new Hashtable(); + fileToLineHash.put(file, lineToAddrHash); + } + + lineToAddrHash.put(info.getLine(), address); + } + } + + return fileToLineHash; + } + } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeVisualizerSkin.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeVisualizerSkin.java index f67e387a8..466b8d51c 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeVisualizerSkin.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/CodeVisualizerSkin.java @@ -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; } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java index 2ece2f094..cf88a22cd 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java @@ -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() { 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 {