added some basic functionality for cooja motes like save/load support, compile dialog, and configurable mote interfaces. some parts are still missing (memory r/w access and mote IDs)

+
code restructuring preparing for a generic emulated mote type layer in cooja (made avrora-based motes look more like mspsim-based motes)
This commit is contained in:
fros4943 2009-09-17 10:45:13 +00:00
parent edae45a101
commit 969154c6f0
8 changed files with 750 additions and 1279 deletions

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 2009, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: MicaZCompileDialog.java,v 1.1 2009/09/17 10:45:14 fros4943 Exp $
*/
package se.sics.cooja.avrmote;
import java.awt.Container;
import java.io.File;
import org.apache.log4j.Logger;
import se.sics.cooja.GUI;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteType;
import se.sics.cooja.Simulation;
import se.sics.cooja.dialogs.AbstractCompileDialog;
public class MicaZCompileDialog extends AbstractCompileDialog {
private static Logger logger = Logger.getLogger(MicaZCompileDialog.class);
public static boolean showDialog(
Container parent,
Simulation simulation,
MoteType moteType) {
final AbstractCompileDialog dialog = new MicaZCompileDialog(parent, simulation, moteType);
/* Show dialog and wait for user */
dialog.setVisible(true); /* BLOCKS */
if (!dialog.createdOK()) {
return false;
}
/* Assume that if a firmware exists, compilation was ok */
return true;
}
private MicaZCompileDialog(Container parent, Simulation simulation, MoteType moteType) {
super(parent, simulation, moteType);
/* Add all available MicaZ mote interfaces
* Selected by default unless interfaces already configured */
boolean selected = true;
if (moteIntfBox.getComponentCount() > 0) {
selected = false;
}
for (Class<? extends MoteInterface> intfClass: ((MicaZMoteType)moteType).getAllMoteInterfaceClasses()) {
addMoteInterface(intfClass, selected);
}
}
public boolean canLoadFirmware(File file) {
if (file.getName().endsWith(".elf")) {
return true;
}
return false;
}
public String getDefaultCompileCommands(File source) {
/* TODO Split into String[] */
return
/*"make clean TARGET=micaz\n" + */
GUI.getExternalToolsSetting("PATH_MAKE") + " " + getExpectedFirmwareFile(source).getName() + " TARGET=micaz";
}
public File getExpectedFirmwareFile(File source) {
return ((MicaZMoteType)moteType).getExpectedFirmwareFile(source);
}
public void writeSettingsToMoteType() {
/* Nothing to do */
}
}

View file

@ -26,16 +26,19 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: MicaZMote.java,v 1.6 2009/03/19 18:58:19 joxe Exp $
* $Id: MicaZMote.java,v 1.7 2009/09/17 10:45:14 fros4943 Exp $
*/
package se.sics.cooja.avrmote;
import java.io.File;
import java.util.Collection;
import java.util.Observer;
import java.util.Random;
import java.util.Vector;
import org.apache.log4j.Logger;
import org.jdom.Element;
import se.sics.cooja.Mote;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteInterfaceHandler;
@ -46,15 +49,18 @@ import se.sics.cooja.avrmote.interfaces.MicaClock;
import se.sics.cooja.avrmote.interfaces.MicaSerial;
import se.sics.cooja.avrmote.interfaces.MicaZLED;
import se.sics.cooja.avrmote.interfaces.MicaZRadio;
import se.sics.cooja.interfaces.MoteID;
import se.sics.cooja.interfaces.Position;
import avrora.sim.*;
import avrora.sim.platform.*;
import avrora.sim.mcu.*;
import avrora.core.*;
import avrora.core.LoadableProgram;
import avrora.sim.Interpreter;
import avrora.sim.Simulator;
import avrora.sim.State;
import avrora.sim.mcu.Microcontroller;
import avrora.sim.platform.MicaZ;
import avrora.sim.platform.PlatformFactory;
/**
* @author Joakim Eriksson
* @author Joakim Eriksson, Fredrik Osterlind
*/
public class MicaZMote implements Mote {
private static Logger logger = Logger.getLogger(MicaZMote.class);
@ -64,9 +70,10 @@ public class MicaZMote implements Mote {
/* Cycle counter */
public long cycleCounter = 0;
public long cycleDrift = 0;
public long usDrift = 0; /* us */
private Simulation mySimulation = null;
private MoteInterfaceHandler myMoteInterfaceHandler;
private Microcontroller myCpu = null;
private MicaZ micaZ = null;
private LoadableProgram program = null;
@ -77,7 +84,29 @@ public class MicaZMote implements Mote {
/* Stack monitoring variables */
private boolean stopNextInstruction = false;
private MoteInterfaceHandler myMoteInterfaceHandler;
public MicaZMote() {
myMoteType = null;
mySimulation = null;
myCpu = null;
/* TODO myMemory = null; */
myMoteInterfaceHandler = null;
}
public MicaZMote(Simulation simulation, MicaZMoteType type) {
mySimulation = simulation;
myMoteType = type;
}
protected boolean initEmulator(File fileELF) {
try {
prepareMote(fileELF);
} catch (Exception e) {
logger.fatal("Error when creating MicaZ mote: ", e);
return false;
}
return true;
}
/**
* Abort current tick immediately.
@ -87,40 +116,21 @@ public class MicaZMote implements Mote {
stopNextInstruction = true;
}
private MoteInterfaceHandler createMoteInterfaceHandler() {
return new MoteInterfaceHandler(this, getType().getMoteInterfaceClasses());
}
public MicaZ getMicaZ() {
return micaZ;
}
public MicaZMote() {
mySimulation = null;
myCpu = null;
myMoteInterfaceHandler = null;
}
public MicaZMote(Simulation simulation, MicaZMoteType type) {
mySimulation = simulation;
myMoteType = type;
}
protected void initMote() {
if (myMoteType != null) {
initEmulator(myMoteType.getContikiFirmwareFile().getAbsolutePath());
initEmulator(myMoteType.getContikiFirmwareFile());
myMoteInterfaceHandler = createMoteInterfaceHandler();
}
}
protected boolean initEmulator(String fileELF) {
//System.out.println("Loading elf file: " + fileELF);
try {
prepareMote(fileELF);
} catch (Exception e) {
logger.fatal("Error when creating MicaZ mote:", e);
return false;
}
return true;
}
public Simulation getSimulation() {
return mySimulation;
}
@ -136,7 +146,7 @@ public class MicaZMote implements Mote {
* @param cpu MSP430 cpu
* @throws Exception
*/
protected void prepareMote(String file) throws Exception {
protected void prepareMote(File file) throws Exception {
program = new LoadableProgram(file);
program.load();
PlatformFactory factory = new MicaZ.Factory();
@ -151,8 +161,8 @@ public class MicaZMote implements Mote {
logger.warn("MicaZ motes can't change state");
}
public State getState() {
return Mote.State.ACTIVE;
public int getID() {
return getInterfaces().getMoteID().getMoteID();
}
/* called when moteID is updated */
@ -164,13 +174,6 @@ public class MicaZMote implements Mote {
}
public void setType(MoteType type) {
//myMoteType = (MspMoteType) type;
}
public void addStateObserver(Observer newObserver) {
}
public void deleteStateObserver(Observer newObserver) {
}
public MoteInterfaceHandler getInterfaces() {
@ -182,24 +185,18 @@ public class MicaZMote implements Mote {
}
/* return false when done - e.g. true means more work to do before finished with this tick */
private boolean firstTick = true;
private long cyclesExecuted = 0;
public boolean tick(long simTime) {
if (stopNextInstruction) {
stopNextInstruction = false;
throw new RuntimeException("MSPSim requested simulation stop");
throw new RuntimeException("Avrora 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);
if (simTime + usDrift < 0) {
return false;
}
long maxSimTimeCycles = NR_CYCLES_PER_MSEC * (simTime + 1) + cycleDrift;
long maxSimTimeCycles = (long)(NR_CYCLES_PER_MSEC * ((simTime+usDrift+Simulation.MILLISECOND)/(double)Simulation.MILLISECOND));
if (maxSimTimeCycles <= cycleCounter) {
return false;
}
@ -211,17 +208,10 @@ public class MicaZMote implements Mote {
/* CPU already ticked too far - just wait it out */
return true;
}
// myMoteInterfaceHandler.doActiveActionsBeforeTick();
myMoteInterfaceHandler.doActiveActionsBeforeTick();
cyclesExecuted += interpreter.step();
//cpu.step(cycleCounter);
/* Check if radio has pending incoming bytes */
// if (myRadio != null && myRadio.hasPendingBytes()) {
// myRadio.tryDeliverNextByte(cpu.cycles);
// }
return true;
}
@ -235,12 +225,7 @@ public class MicaZMote implements Mote {
myMoteType = (MicaZMoteType) simulation.getMoteType(element.getText());
getType().setIdentifier(element.getText());
try {
prepareMote(myMoteType.getContikiFirmwareFile().getAbsolutePath());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
initEmulator(myMoteType.getContikiFirmwareFile());
myMoteInterfaceHandler = createMoteInterfaceHandler();
} else if (name.equals("interface_config")) {
@ -260,29 +245,6 @@ public class MicaZMote implements Mote {
return true;
}
private MoteInterfaceHandler createMoteInterfaceHandler() {
System.out.println("Creating mote interface handler....");
MoteInterfaceHandler moteInterfaceHandler = new MoteInterfaceHandler();
// Add position interface
Position motePosition = new Position(this);
Random random = new Random(); /* Do not use main random generator for positioning */
motePosition.setCoordinates(random.nextDouble()*100, random.nextDouble()*100, random.nextDouble()*100);
moteInterfaceHandler.addInterface(motePosition);
// Add LED interface
moteInterfaceHandler.addInterface(new MicaZLED(micaZ));
// Add Radio interface
moteInterfaceHandler.addInterface(new MicaZRadio(this));
// Add Clock interface
moteInterfaceHandler.addInterface(new MicaClock(this));
// Add Serial interface
moteInterfaceHandler.addInterface(new MicaSerial(this));
return moteInterfaceHandler;
}
public Collection<Element> getConfigXML() {
Vector<Element> config = new Vector<Element>();
@ -309,10 +271,21 @@ public class MicaZMote implements Mote {
}
public MoteMemory getMemory() {
/* TODO Implement */
return null;
}
public void setMemory(MoteMemory memory) {
/* TODO Implement */
}
public String toString() {
MoteID moteID = getInterfaces() != null ? getInterfaces().getMoteID() : null;
if (moteID != null) {
return "MicaZ Mote, ID=" + moteID.getMoteID();
} else {
return "MicaZ Mote, ID=null";
}
}
}

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: MicaClock.java,v 1.3 2009/05/26 14:35:52 fros4943 Exp $
* $Id: MicaClock.java,v 1.4 2009/09/17 10:45:13 fros4943 Exp $
*/
package se.sics.cooja.avrmote.interfaces;
@ -39,6 +39,7 @@ import org.jdom.Element;
import se.sics.cooja.*;
import se.sics.cooja.avrmote.MicaZMote;
import se.sics.cooja.interfaces.Clock;
import se.sics.cooja.mspmote.MspMote;
/**
@ -50,8 +51,8 @@ public class MicaClock extends Clock {
private MicaZMote myMote;
public MicaClock(MicaZMote mote) {
myMote = mote;
public MicaClock(Mote mote) {
myMote = (MicaZMote) mote;
}
public void setTime(long newTime) {
@ -59,16 +60,16 @@ public class MicaClock extends Clock {
}
public long getTime() {
int time = (int) ((myMote.cycleCounter) / MicaZMote.NR_CYCLES_PER_MSEC);
long time = (long) ((double)myMote.cycleCounter * Simulation.MILLISECOND / MspMote.NR_CYCLES_PER_MSEC);
return time > 0 ? time : 0;
}
public void setDrift(long drift) {
myMote.cycleDrift = Simulation.MILLISECOND * MicaZMote.NR_CYCLES_PER_MSEC * drift;
myMote.usDrift = drift;
}
public long getDrift() {
return (long) ((double)myMote.cycleDrift / MicaZMote.NR_CYCLES_PER_MSEC / Simulation.MILLISECOND);
return myMote.usDrift;
}
public JPanel getInterfaceVisualizer() {

View file

@ -8,11 +8,11 @@ import se.sics.cooja.dialogs.SerialUI;
public class MicaSerial extends SerialUI {
Mote mote;
MicaZMote mote;
public MicaSerial(MicaZMote micaZMote) {
mote = micaZMote;
MicaZ micaZ = micaZMote.getMicaZ();
public MicaSerial(Mote micaZMote) {
mote = (MicaZMote) micaZMote;
MicaZ micaZ = mote.getMicaZ();
/* this should go into some other piece of code for serial data */
AtmelMicrocontroller mcu = (AtmelMicrocontroller) micaZ.getMicrocontroller();
avrora.sim.mcu.USART usart = (avrora.sim.mcu.USART) mcu.getDevice("usart0");

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: MicaZID.java,v 1.1 2009/09/17 10:45:13 fros4943 Exp $
*/
package se.sics.cooja.avrmote.interfaces;
import java.util.Collection;
import java.util.Vector;
import javax.swing.JPanel;
import org.apache.log4j.Logger;
import org.jdom.Element;
import se.sics.cooja.Mote;
import se.sics.cooja.interfaces.MoteID;
public class MicaZID extends MoteID {
private static Logger logger = Logger.getLogger(MicaZID.class);
private int moteID = -1; /* TODO Implement */
public MicaZID(Mote mote) {
}
public int getMoteID() {
return moteID;
}
public void setMoteID(int newID) {
moteID = newID;
}
public JPanel getInterfaceVisualizer() {
return null;
}
public void releaseInterfaceVisualizer(JPanel panel) {
}
public double energyConsumption() {
return 0;
}
public Collection<Element> getConfigXML() {
Vector<Element> config = new Vector<Element>();
Element element;
// Infinite boolean
element = new Element("id");
element.setText(Integer.toString(getMoteID()));
config.add(element);
return config;
}
public void setConfigXML(Collection<Element> configXML, boolean visAvailable) {
for (Element element : configXML) {
if (element.getName().equals("id")) {
setMoteID(Integer.parseInt(element.getText()));
}
}
}
}

View file

@ -26,22 +26,29 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: MicaZLED.java,v 1.3 2009/03/19 18:58:19 joxe Exp $
* $Id: MicaZLED.java,v 1.4 2009/09/17 10:45:13 fros4943 Exp $
*/
package se.sics.cooja.avrmote.interfaces;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Collection;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JPanel;
import org.apache.log4j.Logger;
import org.jdom.Element;
import avrora.sim.FiniteStateMachine;
import avrora.sim.mcu.AtmelMicrocontroller;
import avrora.sim.platform.MicaZ;
import se.sics.cooja.*;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote;
import se.sics.cooja.avrmote.MicaZMote;
import se.sics.cooja.interfaces.LED;
import avrora.sim.FiniteStateMachine;
import avrora.sim.platform.MicaZ;
/**
* @author Joakim Eriksson
@ -61,7 +68,9 @@ public class MicaZLED extends LED {
private static final Color GREEN = new Color(0, 255, 0);
private static final Color RED = new Color(255, 0, 0);
public MicaZLED(MicaZ micaZ) {
public MicaZLED(Mote mote) {
MicaZ micaZ = ((MicaZMote) mote).getMicaZ();
avrora.sim.platform.LED.LEDGroup leds =
(avrora.sim.platform.LED.LEDGroup) micaZ.getDevice("leds");

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: MicaZRadio.java,v 1.3 2009/04/16 14:28:12 fros4943 Exp $
* $Id: MicaZRadio.java,v 1.4 2009/09/17 10:45:13 fros4943 Exp $
*/
package se.sics.cooja.avrmote.interfaces;
@ -89,9 +89,9 @@ public class MicaZRadio extends Radio implements CustomDataRadio {
Medium.Transmitter trans;
CC2420Radio.Receiver recv;
public MicaZRadio(MicaZMote mote) {
this.mote = mote;
micaz = mote.getMicaZ();
public MicaZRadio(Mote mote) {
this.mote = (MicaZMote) mote;
micaz = this.mote.getMicaZ();
cc2420 = (CC2420Radio) micaz.getDevice("radio");
trans = cc2420.getTransmitter();
recv = (CC2420Radio.Receiver) cc2420.getReceiver();