contiki mote schedules their next wakeup based on Contiki etimers + removed notion of active vs LPM state (optimization no longer needed)

This commit is contained in:
fros4943 2009-05-26 14:21:20 +00:00
parent a327180762
commit fba3701a86
1 changed files with 49 additions and 98 deletions

View File

@ -26,7 +26,7 @@
* 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: ContikiMote.java,v 1.11 2009/03/09 16:08:17 fros4943 Exp $ * $Id: ContikiMote.java,v 1.12 2009/05/26 14:21:20 fros4943 Exp $
*/ */
package se.sics.cooja.contikimote; package se.sics.cooja.contikimote;
@ -61,21 +61,6 @@ public class ContikiMote implements Mote {
private MoteInterfaceHandler myInterfaceHandler = null; private MoteInterfaceHandler myInterfaceHandler = null;
private Simulation mySim = null; private Simulation mySim = null;
// Time to wake up if sleeping
private int wakeUpTime = 0;
private State myState = State.ACTIVE;
// State observable
private class StateObservable extends Observable {
private void stateChanged() {
setChanged();
notifyObservers();
}
}
private StateObservable stateObservable = new StateObservable();
/** /**
* Creates a new uninitialized Contiki mote. * Creates a new uninitialized Contiki mote.
* *
@ -99,39 +84,21 @@ public class ContikiMote implements Mote {
this.myMemory = moteType.createInitialMemory(); this.myMemory = moteType.createInitialMemory();
this.myInterfaceHandler = new MoteInterfaceHandler(this, moteType.getMoteInterfaceClasses()); this.myInterfaceHandler = new MoteInterfaceHandler(this, moteType.getMoteInterfaceClasses());
myState = State.ACTIVE; scheduleNextWakeup(mySim.getSimulationTime());
} }
public void setState(State newState) { public void setState(State newState) {
if (myState == State.DEAD) { logger.warn("setState() not implemented");
return; }
}
if (myState == State.ACTIVE && newState != State.ACTIVE) {
myState = newState;
stateObservable.stateChanged();
}
if (myState == State.LPM && newState != State.LPM) {
myState = newState;
stateObservable.stateChanged();
}
if (myState == State.DEAD) {
mySim.getRadioMedium().unregisterMote(this, mySim);
}
}
public State getState() { public State getState() {
return myState; return State.ACTIVE;
} }
public void addStateObserver(Observer newObserver) { public void addStateObserver(Observer newObserver) {
stateObservable.addObserver(newObserver);
} }
public void deleteStateObserver(Observer newObserver) { public void deleteStateObserver(Observer newObserver) {
stateObservable.deleteObserver(newObserver);
} }
public MoteInterfaceHandler getInterfaces() { public MoteInterfaceHandler getInterfaces() {
@ -167,81 +134,40 @@ public class ContikiMote implements Mote {
} }
/** /**
* Ticks this mote once. This is done by first polling all interfaces * Ticks mote once. This is done by first polling all interfaces
* and letting them act on the stored memory before the memory is set. Then * and letting them act on the stored memory before the memory is set. Then
* the mote is ticked, and the new memory is received. * the mote is ticked, and the new memory is received.
* Finally all interfaces are allowing to act on the new memory in order to * Finally all interfaces are allowing to act on the new memory in order to
* discover relevant changes. This method also checks if mote should go to sleep * discover relevant changes. This method also schedules the next mote tick time
* depending on Contiki specifics; pending timers and polled processes. * depending on Contiki specifics; pending timers and polled processes.
* *
* @param simTime Current simulation time * @param simTime Current simulation time
*/ */
public boolean tick(long simTime) { public boolean tick(long simTime) {
State currentState = getState();
// If mote is dead, do nothing at all /* Poll mote interfaces */
if (currentState == State.DEAD) { myInterfaceHandler.doActiveActionsBeforeTick();
myInterfaceHandler.doPassiveActionsBeforeTick();
/* Check if pre-boot time */
if (myInterfaceHandler.getClock().getTime() < 0) {
scheduleNextWakeup(simTime + -myInterfaceHandler.getClock().getTime());
return false; return false;
} }
// If mote is sleeping and has a wake up time, should it wake up now? /* Copy mote memory to Contiki */
if (currentState == State.LPM && wakeUpTime > 0 && wakeUpTime <= simTime) { myType.setCoreMemory(myMemory);
setState(State.ACTIVE);
currentState = getState();
wakeUpTime = 0;
}
// If mote is active.. /* Handle a single Contiki events */
if (currentState == State.ACTIVE) { myType.tick();
// Let all active interfaces act before tick
// Observe that each interface may put the mote to sleep at this point
myInterfaceHandler.doActiveActionsBeforeTick();
}
// And let passive interfaces act even if mote is sleeping /* Copy mote memory from Contiki */
myInterfaceHandler.doPassiveActionsBeforeTick(); myType.getCoreMemory(myMemory);
/* Poll mote interfaces */
// If mote is still active, complete this tick myInterfaceHandler.doActiveActionsAfterTick();
currentState = getState();
if (currentState == State.ACTIVE) {
// Copy mote memory to core
myType.setCoreMemory(myMemory);
// Tick node
myType.tick();
// Fetch new updated memory from core
myType.getCoreMemory(myMemory);
// Let all active interfaces act again after tick
myInterfaceHandler.doActiveActionsAfterTick();
}
// Finally let all passive interfaces act
myInterfaceHandler.doPassiveActionsAfterTick(); myInterfaceHandler.doPassiveActionsAfterTick();
// If mote is awake, should it go to sleep?
if (currentState == State.ACTIVE) {
// Check if this mote should sleep (no more pending timers or processes to poll)
int processRunValue = myMemory.getIntValueOf("simProcessRunValue");
int etimersPending = myMemory.getIntValueOf("simEtimerPending");
int nextExpirationTime = myMemory.getIntValueOf("simNextExpirationTime");
if (processRunValue == 0 && etimersPending == 0) {
setState(State.LPM);
wakeUpTime = 0;
}
if (processRunValue == 0 && etimersPending == 1 && nextExpirationTime > 0) {
setState(State.LPM);
wakeUpTime = nextExpirationTime;
}
}
return false; return false;
} }
@ -278,7 +204,6 @@ public class ContikiMote implements Mote {
public boolean setConfigXML(Simulation simulation, Collection<Element> configXML, boolean visAvailable) { public boolean setConfigXML(Simulation simulation, Collection<Element> configXML, boolean visAvailable) {
mySim = simulation; mySim = simulation;
myState = State.ACTIVE;
for (Element element: configXML) { for (Element element: configXML) {
String name = element.getName(); String name = element.getName();
@ -306,6 +231,7 @@ public class ContikiMote implements Mote {
} }
} }
scheduleNextWakeup(mySim.getSimulationTime());
return true; return true;
} }
@ -319,4 +245,29 @@ public class ContikiMote implements Mote {
return "Contiki Mote, ID=" + getInterfaces().getMoteID().getMoteID(); return "Contiki Mote, ID=" + getInterfaces().getMoteID().getMoteID();
} }
private TimeEvent tickMoteEvent = new MoteTimeEvent(this, 0) {
public void execute(long t) {
/* Tick Contiki mote */
tick(mySim.getSimulationTime());
}
public String toString() {
return "CONTIKI TICK " + ContikiMote.this;
}
};
public void scheduleImmediateWakeup() {
scheduleNextWakeup(mySim.getSimulationTime());
}
public void scheduleNextWakeup(long time) {
if (tickMoteEvent.isScheduled() &&
tickMoteEvent.getTime() <= time) {
/* Native tick events already scheduled */
return;
}
/* Reschedule native mote event */
/*logger.info("Rescheduled tick from " + tickMoteEvent.time + " to " + time);*/
mySim.scheduleEventUnsafe(tickMoteEvent, time);
}
} }