improved mspsim-connected regarding command handlers and context, implemented stack track method

This commit is contained in:
Fredrik Osterlind 2012-03-01 15:24:32 +01:00
parent 681fe65c04
commit 268608f7e3

View File

@ -59,6 +59,7 @@ import se.sics.cooja.mspmote.plugins.CodeVisualizerSkin;
import se.sics.cooja.mspmote.plugins.MspBreakpointContainer; import se.sics.cooja.mspmote.plugins.MspBreakpointContainer;
import se.sics.cooja.plugins.BufferListener.BufferAccess; import se.sics.cooja.plugins.BufferListener.BufferAccess;
import se.sics.cooja.plugins.Visualizer; import se.sics.cooja.plugins.Visualizer;
import se.sics.mspsim.cli.CommandContext;
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;
@ -74,6 +75,7 @@ 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;
import se.sics.mspsim.util.SimpleProfiler;
/** /**
* @author Fredrik Osterlind * @author Fredrik Osterlind
@ -88,7 +90,6 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
} }
private CommandHandler commandHandler; private CommandHandler commandHandler;
private ArrayList<LineListener> commandListeners = new ArrayList<LineListener>();
private MSP430 myCpu = null; private MSP430 myCpu = null;
private MspMoteType myMoteType = null; private MspMoteType myMoteType = null;
private MspMoteMemory myMemory = null; private MspMoteMemory myMemory = null;
@ -150,24 +151,6 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
return new MoteInterfaceHandler(this, getType().getMoteInterfaceClasses()); return new MoteInterfaceHandler(this, getType().getMoteInterfaceClasses());
} }
public void sendCLICommand(String line) {
if (commandHandler != null) {
commandHandler.lineRead(line);
}
}
public boolean hasCLIListener() {
return !commandListeners.isEmpty();
}
public void addCLIListener(LineListener listener) {
commandListeners.add(listener);
}
public void removeCLIListener(LineListener listener) {
commandListeners.remove(listener);
}
/** /**
* @return MSP430 CPU * @return MSP430 CPU
*/ */
@ -234,17 +217,7 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
* @throws IOException Preparing mote failed * @throws IOException Preparing mote failed
*/ */
protected void prepareMote(File fileELF, GenericNode node) throws IOException { protected void prepareMote(File fileELF, GenericNode node) throws IOException {
LineOutputStream lout = new LineOutputStream(new LineListener() { this.commandHandler = new CommandHandler(System.out, System.err);
public void lineRead(String line) {
for (LineListener l: commandListeners.toArray(new LineListener[0])) {
if (l == null) {
continue;
}
l.lineRead(line);
}
}});
PrintStream out = new PrintStream(lout);
this.commandHandler = new CommandHandler(out, out);
node.setCommandHandler(commandHandler); node.setCommandHandler(commandHandler);
ConfigManager config = new ConfigManager(); ConfigManager config = new ConfigManager();
@ -271,6 +244,10 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
myCpu.reset(); myCpu.reset();
} }
public CommandHandler getCLICommandHandler() {
return commandHandler;
}
/* called when moteID is updated */ /* called when moteID is updated */
public void idUpdated(int newID) { public void idUpdated(int newID) {
} }
@ -344,13 +321,9 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
myCpu.stepMicros(t - lastExecute, duration); myCpu.stepMicros(t - lastExecute, duration);
lastExecute = t; lastExecute = t;
} catch (EmulationException e) { } catch (EmulationException e) {
String stackTraceOutput = sendCLICommandAndPrint("stacktrace"); String trace = e.getMessage() + "\n\n" + getStackTrace();
if (stackTraceOutput == null) {
stackTraceOutput = "";
}
stackTraceOutput = e.getMessage() + "\n\n" + stackTraceOutput;
throw (ContikiError) throw (ContikiError)
new ContikiError(stackTraceOutput).initCause(e); new ContikiError(trace).initCause(e);
} }
/* Schedule wakeup */ /* Schedule wakeup */
@ -377,22 +350,29 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
}*/ }*/
} }
public String sendCLICommandAndPrint(String cmd) { public String getStackTrace() {
String response = executeCLICommand(cmd); return executeCLICommand("stacktrace");
logger.fatal(response); }
return response;
public int executeCLICommand(String cmd, CommandContext context) {
return commandHandler.executeCommand(cmd, context);
} }
public String executeCLICommand(String cmd) { public String executeCLICommand(String cmd) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
LineListener tmp = new LineListener() { LineListener ll = new LineListener() {
public void lineRead(String line) { public void lineRead(String line) {
sb.append(line + "\n"); sb.append(line).append("\n");
} }
}; };
commandListeners.add(tmp); PrintStream po = new PrintStream(new LineOutputStream(ll));
sendCLICommand(cmd); CommandContext c = new CommandContext(commandHandler, null, "", new String[0], 1, null);
commandListeners.remove(tmp); c.out = po;
c.err = po;
if (0 != executeCLICommand(cmd, c)) {
sb.append("\nWarning: command failed");
}
return sb.toString(); return sb.toString();
} }
@ -507,7 +487,7 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
} }
public String getPCString() { public String getPCString() {
int pc = myCpu.reg[MSP430Constants.PC]; int pc = myCpu.getPC();
ELF elf = (ELF)myCpu.getRegistry().getComponent(ELF.class); ELF elf = (ELF)myCpu.getRegistry().getComponent(ELF.class);
DebugInfo di = elf.getDebugInfo(pc); DebugInfo di = elf.getDebugInfo(pc);
@ -517,6 +497,17 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
} }
if (di == null) { if (di == null) {
/* Return PC value */ /* Return PC value */
MapEntry mapEntry = ((SimpleProfiler)myCpu.getProfiler()).getCallMapEntry(0);
if (mapEntry != null) {
String file = mapEntry.getFile();
if (file != null) {
if (file.indexOf('/') >= 0) {
file = file.substring(file.lastIndexOf('/')+1);
}
}
String name = mapEntry.getName();
return file + ":?:" + name;
}
return String.format("*%02x", myCpu.reg[MSP430Constants.PC]); return String.format("*%02x", myCpu.reg[MSP430Constants.PC]);
} }
@ -527,15 +518,19 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
/* strip path */ /* strip path */
file = file.substring(file.lastIndexOf('/')+1, file.length()); file = file.substring(file.lastIndexOf('/')+1, file.length());
} }
String function = di.getFunction(); String function = di.getFunction();
function = function==null?"?":function; function = function==null?"":function;
if (function.contains(":")) { if (function.contains(":")) {
/* strip arguments */ /* strip arguments */
function = function.substring(0, function.lastIndexOf(':')); function = function.substring(0, function.lastIndexOf(':'));
} }
return file + ":" + function + ":" + lineNo; if (function.equals("* not available")) {
function = "?";
}
return file + ":" + lineNo + ":" + function;
/*return executeCLICommand("line " + myCpu.reg[MSP430Constants.PC]);*/ /*return executeCLICommand("line " + myCpu.getPC());*/
} }
public MemoryMonitor createMemoryMonitor(final MemoryEventHandler meh) { public MemoryMonitor createMemoryMonitor(final MemoryEventHandler meh) {