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:
parent
bec1ccc57d
commit
ce5d19fefd
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue