예제 #1
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;
  }