public void execute(long t, int duration) { /* Wait until mote boots */ if (myMoteInterfaceHandler.getClock().getTime() < 0) { scheduleNextWakeup(t - myMoteInterfaceHandler.getClock().getTime()); return; } if (stopNextInstruction) { stopNextInstruction = false; /*sendCLICommandAndPrint("trace 1000");*/ /* TODO Enable */ scheduleNextWakeup(t); throw new RuntimeException("MSPSim requested simulation stop"); } if (lastExecute < 0) { /* Always execute one microsecond the first time */ lastExecute = t; } if (t < lastExecute) { throw new RuntimeException("Bad event ordering: " + lastExecute + " < " + t); } /* Execute MSPSim-based mote */ /* TODO Try-catch overhead */ try { nextExecute = t + duration + myCpu.stepMicros(t - lastExecute, duration); lastExecute = t; } catch (EmulationException e) { String stackTraceOutput = sendCLICommandAndPrint("stacktrace"); throw (ContikiError) new ContikiError(stackTraceOutput).initCause(e); } /* Schedule wakeup */ if (nextExecute < t) { throw new RuntimeException(t + ": MSPSim requested early wakeup: " + nextExecute); } /*logger.debug(t + ": Schedule next wakeup at " + nextExecute);*/ scheduleNextWakeup(nextExecute); /* XXX TODO Reimplement stack monitoring using MSPSim internals */ /*if (monitorStackUsage) { int newStack = cpu.reg[MSP430.SP]; if (newStack < stackPointerLow && newStack > 0) { stackPointerLow = cpu.reg[MSP430.SP]; // Check if stack is writing in memory if (stackPointerLow < heapStartAddress) { stackOverflowObservable.signalStackOverflow(); stopNextInstruction = true; getSimulation().stopSimulation(); } } }*/ }
/** * Prepares CPU, memory and ELF module. * * @param fileELF ELF file * @param cpu MSP430 cpu * @throws IOException Preparing mote failed */ protected void prepareMote(File fileELF, GenericNode node) throws IOException { LineOutputStream lout = new LineOutputStream( new LineListener() { 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); ConfigManager config = new ConfigManager(); node.setup(config); this.myCpu = node.getCPU(); this.myCpu.setMonitorExec(true); this.myCpu.setTrace(0); /* TODO Enable */ int[] memory = myCpu.getMemory(); logger.info("Loading firmware from: " + fileELF.getAbsolutePath()); GUI.setProgressMessage("Loading " + fileELF.getName()); node.loadFirmware(((MspMoteType) getType()).getELF(), memory); /* Throw exceptions at bad memory access */ /*myCpu.setThrowIfWarning(true);*/ /* Create mote address memory */ MapTable map = ((MspMoteType) getType()).getELF().getMap(); MapEntry[] allEntries = map.getAllEntries(); myMemory = new MspMoteMemory(allEntries, myCpu); heapStartAddress = map.heapStartAddress; myCpu.reset(); }
/** * Prepares CPU, memory and ELF module. * * @param fileELF ELF file * @param cpu MSP430 cpu * @throws IOException Preparing mote failed */ protected void prepareMote(File fileELF, GenericNode node) throws IOException { LineOutputStream lout = new LineOutputStream( new LineListener() { @Override public void lineRead(String line) { LineListener listener = commandListener; if (listener != null) { listener.lineRead(line); } } }); PrintStream out = new PrintStream(lout); this.commandHandler = new CommandHandler(out, out); node.setCommandHandler(commandHandler); ConfigManager config = new ConfigManager(); node.setup(config); this.myCpu = node.getCPU(); this.myCpu.setMonitorExec(true); int[] memory = myCpu.getMemory(); if (GUI.isVisualizedInApplet()) { myELFModule = node.loadFirmware(new URL(GUI.getAppletCodeBase(), fileELF.getName()), memory); } else { myELFModule = node.loadFirmware(fileELF.getPath(), memory); } /* Throw exceptions at bad memory access */ /*myCpu.setThrowIfWarning(true);*/ /* Create mote address memory */ MapTable map = myELFModule.getMap(); MapEntry[] allEntries = map.getAllEntries(); myMemory = new MspMoteMemory(allEntries, myCpu); heapStartAddress = map.heapStartAddress; myCpu.reset(); }
public int getCPUFrequency() { return myCpu.getDCOFrequency(); }
public boolean tick(long simTime) { if (stopNextInstruction) { stopNextInstruction = false; throw new RuntimeException("MSPSim requested simulation stop"); } /* Nodes may be added in an ongoing simulation: * Update cycle drift to current simulation time */ if (firstTick) { firstTick = false; cycleDrift += (-NR_CYCLES_PER_MSEC * simTime); } long maxSimTimeCycles = NR_CYCLES_PER_MSEC * (simTime + 1) + cycleDrift; if (maxSimTimeCycles <= cycleCounter) { return false; } // Leave control to emulated CPU cycleCounter += 1; MSP430 cpu = getCPU(); if (cpu.cycles > cycleCounter) { /* CPU already ticked too far - just wait it out */ return true; } myMoteInterfaceHandler.doActiveActionsBeforeTick(); /* Experimental program counter history */ for (int i = pcHistory.length - 1; i > 0; i--) { pcHistory[i] = pcHistory[i - 1]; } pcHistory[0] = cpu.reg[MSP430.PC]; try { cpu.step(cycleCounter); } catch (EmulationException e) { if (e.getMessage().startsWith("Bad operation")) { /* Experimental: print program counter history */ LineListener oldListener = commandListener; LineListener tmpListener = new LineListener() { public void lineRead(String line) { logger.fatal(line); } }; setCLIListener(tmpListener); logger.fatal("Bad operation detected. Program counter history:"); for (int element : pcHistory) { sendCLICommand("line " + element); } setCLIListener(oldListener); } throw (RuntimeException) new RuntimeException("Emulated exception: " + e.getMessage()).initCause(e); } /* Check if radio has pending incoming bytes */ if (myRadio != null && myRadio.hasPendingBytes()) { myRadio.tryDeliverNextByte(cpu.cycles); } if (monitorStackUsage) { int newStack = cpu.reg[MSP430.SP]; if (newStack < stackPointerLow && newStack > 0) { stackPointerLow = cpu.reg[MSP430.SP]; // Check if stack is writing in memory if (stackPointerLow < heapStartAddress) { stackOverflowObservable.signalStackOverflow(); stopNextInstruction = true; getSimulation().stopSimulation(); } } } return true; }