mspmote is now a watchpoint mote + mspmote is responsible for parsing and providing firmware debugging info

This commit is contained in:
fros4943 2009-06-11 10:08:12 +00:00
parent a8aa75fa8d
commit 12ee67171b

View file

@ -26,15 +26,18 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: MspMote.java,v 1.29 2009/05/26 14:34:30 fros4943 Exp $ * $Id: MspMote.java,v 1.30 2009/06/11 10:08:12 fros4943 Exp $
*/ */
package se.sics.cooja.mspmote; package se.sics.cooja.mspmote;
import java.awt.event.ActionListener;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.net.URL; import java.net.URL;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Hashtable;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import java.util.Vector; import java.util.Vector;
@ -46,9 +49,12 @@ import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteInterfaceHandler; import se.sics.cooja.MoteInterfaceHandler;
import se.sics.cooja.MoteMemory; import se.sics.cooja.MoteMemory;
import se.sics.cooja.MoteType; import se.sics.cooja.MoteType;
import se.sics.cooja.Watchpoint;
import se.sics.cooja.Simulation; import se.sics.cooja.Simulation;
import se.sics.cooja.WatchpointMote;
import se.sics.cooja.interfaces.IPAddress; import se.sics.cooja.interfaces.IPAddress;
import se.sics.cooja.mspmote.interfaces.TR1001Radio; import se.sics.cooja.mspmote.interfaces.TR1001Radio;
import se.sics.cooja.mspmote.plugins.MspBreakpointContainer;
import se.sics.mspsim.cli.CommandHandler; import se.sics.mspsim.cli.CommandHandler;
import se.sics.mspsim.cli.LineListener; import se.sics.mspsim.cli.LineListener;
import se.sics.mspsim.cli.LineOutputStream; import se.sics.mspsim.cli.LineOutputStream;
@ -56,6 +62,7 @@ import se.sics.mspsim.core.EmulationException;
import se.sics.mspsim.core.MSP430; import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.platform.GenericNode; import se.sics.mspsim.platform.GenericNode;
import se.sics.mspsim.util.ConfigManager; import se.sics.mspsim.util.ConfigManager;
import se.sics.mspsim.util.DebugInfo;
import se.sics.mspsim.util.ELF; import se.sics.mspsim.util.ELF;
import se.sics.mspsim.util.MapEntry; import se.sics.mspsim.util.MapEntry;
import se.sics.mspsim.util.MapTable; import se.sics.mspsim.util.MapTable;
@ -63,7 +70,7 @@ import se.sics.mspsim.util.MapTable;
/** /**
* @author Fredrik Osterlind * @author Fredrik Osterlind
*/ */
public abstract class MspMote implements Mote { public abstract class MspMote implements Mote, WatchpointMote {
private static Logger logger = Logger.getLogger(MspMote.class); private static Logger logger = Logger.getLogger(MspMote.class);
/* 3.900 MHz according to Contiki's speed sync loop*/ /* 3.900 MHz according to Contiki's speed sync loop*/
@ -91,6 +98,8 @@ public abstract class MspMote implements Mote {
private int heapStartAddress; private int heapStartAddress;
private StackOverflowObservable stackOverflowObservable = new StackOverflowObservable(); private StackOverflowObservable stackOverflowObservable = new StackOverflowObservable();
private MspBreakpointContainer breakpointsContainer;
/** /**
* Abort current tick immediately. * Abort current tick immediately.
* May for example be called by a breakpoint handler. * May for example be called by a breakpoint handler.
@ -116,6 +125,9 @@ public abstract class MspMote implements Mote {
if (myMoteType != null) { if (myMoteType != null) {
initEmulator(myMoteType.getContikiFirmwareFile()); initEmulator(myMoteType.getContikiFirmwareFile());
myMoteInterfaceHandler = createMoteInterfaceHandler(); myMoteInterfaceHandler = createMoteInterfaceHandler();
/* Create watchpoint container */
breakpointsContainer = new MspBreakpointContainer(this, getFirmwareDebugInfo(this));
} }
} }
@ -384,6 +396,9 @@ public abstract class MspMote implements Mote {
initEmulator(myMoteType.getContikiFirmwareFile()); initEmulator(myMoteType.getContikiFirmwareFile());
myMoteInterfaceHandler = createMoteInterfaceHandler(); myMoteInterfaceHandler = createMoteInterfaceHandler();
/* Create watchpoint container */
breakpointsContainer = new MspBreakpointContainer(this, getFirmwareDebugInfo(this));
} else if (name.equals("interface_config")) { } else if (name.equals("interface_config")) {
String intfClass = element.getText().trim(); String intfClass = element.getText().trim();
if (intfClass.equals("se.sics.cooja.mspmote.interfaces.MspIPAddress")) { if (intfClass.equals("se.sics.cooja.mspmote.interfaces.MspIPAddress")) {
@ -430,4 +445,70 @@ public abstract class MspMote implements Mote {
return config; return config;
} }
/* Watchpoints: Forward to breakpoint container */
public void addWatchpointListener(ActionListener listener) {
breakpointsContainer.addWatchpointListener(listener);
}
public Watchpoint getLastWatchpoint() {
return breakpointsContainer.getLastWatchpoint();
}
public Mote getMote() {
return breakpointsContainer.getMote();
}
public ActionListener[] getWatchpointListeners() {
return breakpointsContainer.getWatchpointListeners();
}
public void removeWatchpointListener(ActionListener listener) {
breakpointsContainer.removeWatchpointListener(listener);
}
public MspBreakpointContainer getBreakpointsContainer() {
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;
}
} }