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();
        }
      }
    }*/
  }
Beispiel #2
0
  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;
  }