esb mote extends general msp mote
This commit is contained in:
parent
09345f05ae
commit
c18afffd36
5 changed files with 1666 additions and 0 deletions
115
tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/ESBMote.java
Normal file
115
tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/ESBMote.java
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* 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: ESBMote.java,v 1.1 2008/02/07 14:53:29 fros4943 Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
package se.sics.cooja.mspmote;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.*;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import se.sics.cooja.*;
|
||||||
|
import se.sics.cooja.interfaces.*;
|
||||||
|
import se.sics.cooja.mspmote.interfaces.*;
|
||||||
|
import se.sics.mspsim.platform.esb.ESBNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fredrik Osterlind
|
||||||
|
*/
|
||||||
|
public class ESBMote extends MspMote {
|
||||||
|
private static Logger logger = Logger.getLogger(ESBMote.class);
|
||||||
|
|
||||||
|
public ESBNode esbNode = null;
|
||||||
|
|
||||||
|
public ESBMote() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESBMote(MoteType moteType, Simulation sim) {
|
||||||
|
super((ESBMoteType) moteType, sim);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean initEmulator(File fileELF) {
|
||||||
|
try {
|
||||||
|
createCPUAndMemory(fileELF);
|
||||||
|
|
||||||
|
esbNode = new ESBNode(getCPU());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.fatal("Error when creating ESB mote: " + e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MoteInterfaceHandler createMoteInterfaceHandler() {
|
||||||
|
MoteInterfaceHandler moteInterfaceHandler = new MoteInterfaceHandler();
|
||||||
|
// Add position interface
|
||||||
|
Position motePosition = new Position(this);
|
||||||
|
Random random = new Random();
|
||||||
|
motePosition.setCoordinates(random.nextDouble()*100, random.nextDouble()*100, random.nextDouble()*100);
|
||||||
|
moteInterfaceHandler.addActiveInterface(motePosition);
|
||||||
|
|
||||||
|
// Add log interface
|
||||||
|
Log moteLog = new ESBLog(this);
|
||||||
|
moteInterfaceHandler.addActiveInterface(moteLog);
|
||||||
|
|
||||||
|
// Add time interface
|
||||||
|
Clock moteClock = new MspClock(this);
|
||||||
|
moteInterfaceHandler.addActiveInterface(moteClock);
|
||||||
|
|
||||||
|
// Add led interface
|
||||||
|
LED moteLed = new ESBLED(this);
|
||||||
|
moteInterfaceHandler.addActiveInterface(moteLed);
|
||||||
|
|
||||||
|
// Add button interface
|
||||||
|
Button moteButton = new ESBButton(this);
|
||||||
|
moteInterfaceHandler.addActiveInterface(moteButton);
|
||||||
|
|
||||||
|
// Add ID interface
|
||||||
|
MoteID moteID = new MspMoteID(this);
|
||||||
|
moteInterfaceHandler.addActiveInterface(moteID);
|
||||||
|
|
||||||
|
// Add radio interface
|
||||||
|
myRadio = new TR1001Radio(this);
|
||||||
|
moteInterfaceHandler.addActiveInterface(myRadio);
|
||||||
|
|
||||||
|
return moteInterfaceHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
if (getInterfaces().getMoteID() != null) {
|
||||||
|
return "ESB Mote, ID=" + getInterfaces().getMoteID().getMoteID();
|
||||||
|
} else {
|
||||||
|
return "ESB Mote, ID=null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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: ESBMoteType.java,v 1.1 2008/02/07 14:53:29 fros4943 Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
package se.sics.cooja.mspmote;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import se.sics.cooja.*;
|
||||||
|
|
||||||
|
@ClassDescription("ESB Mote Type")
|
||||||
|
@AbstractionLevelDescription("Emulated level")
|
||||||
|
public class ESBMoteType extends MspMoteType {
|
||||||
|
private static Logger logger = Logger.getLogger(ESBMoteType.class);
|
||||||
|
|
||||||
|
public static final String target = "esb";
|
||||||
|
public static final String targetNice = "ESB";
|
||||||
|
|
||||||
|
public ESBMoteType() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESBMoteType(String identifier) {
|
||||||
|
setIdentifier(identifier);
|
||||||
|
setDescription(targetNice + " Mote Type #" + identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mote generateMote(Simulation simulation) {
|
||||||
|
return new ESBMote(this, simulation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean configureAndInit(JFrame parentFrame, Simulation simulation,
|
||||||
|
boolean visAvailable) throws MoteTypeCreationException {
|
||||||
|
return configureAndInitMspType(parentFrame, simulation, visAvailable, target, targetNice);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
354
tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMote.java
Normal file
354
tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspMote.java
Normal file
|
@ -0,0 +1,354 @@
|
||||||
|
/*
|
||||||
|
* 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: MspMote.java,v 1.1 2008/02/07 14:53:29 fros4943 Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
package se.sics.cooja.mspmote;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.jdom.Element;
|
||||||
|
|
||||||
|
import se.sics.cooja.*;
|
||||||
|
import se.sics.cooja.mspmote.interfaces.TR1001Radio;
|
||||||
|
import se.sics.mspsim.core.MSP430;
|
||||||
|
import se.sics.mspsim.core.MapTable;
|
||||||
|
import se.sics.mspsim.util.ELF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fredrik Osterlind
|
||||||
|
*/
|
||||||
|
public abstract class MspMote implements Mote {
|
||||||
|
private static Logger logger = Logger.getLogger(MspMote.class);
|
||||||
|
|
||||||
|
/* 2.4 MHz */
|
||||||
|
public static int NR_CYCLES_PER_MSEC = 2365;
|
||||||
|
|
||||||
|
/* Cycle counter */
|
||||||
|
public long cycleCounter = 0;
|
||||||
|
|
||||||
|
private Simulation mySimulation = null;
|
||||||
|
private MSP430 myCpu = null;
|
||||||
|
private MspMoteType myMoteType = null;
|
||||||
|
private MspMoteMemory myMemory = null;
|
||||||
|
private MoteInterfaceHandler myMoteInterfaceHandler = null;
|
||||||
|
private ELF myELFModule = null;
|
||||||
|
|
||||||
|
protected TR1001Radio myRadio = null; /* TODO Only used by ESB (TR1001) */
|
||||||
|
|
||||||
|
/* Stack monitoring variables */
|
||||||
|
private boolean stopNextInstruction = false;
|
||||||
|
private boolean monitorStackUsage = false;
|
||||||
|
private int stackPointerLow = Integer.MAX_VALUE;
|
||||||
|
private int heapStartAddress;
|
||||||
|
private StackOverflowObservable stackOverflowObservable = new StackOverflowObservable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abort current tick immediately.
|
||||||
|
* May for example be called by a breakpoint handler.
|
||||||
|
*/
|
||||||
|
public void stopNextInstruction() {
|
||||||
|
stopNextInstruction = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MspMote() {
|
||||||
|
myMoteType = null;
|
||||||
|
mySimulation = null;
|
||||||
|
myCpu = null;
|
||||||
|
myMemory = null;
|
||||||
|
myMoteInterfaceHandler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MspMote(MspMoteType moteType, Simulation simulation) {
|
||||||
|
myMoteType = moteType;
|
||||||
|
mySimulation = simulation;
|
||||||
|
|
||||||
|
initEmulator(myMoteType.getELFFile());
|
||||||
|
|
||||||
|
myMoteInterfaceHandler = createMoteInterfaceHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return MSP430 CPU
|
||||||
|
*/
|
||||||
|
public MSP430 getCPU() {
|
||||||
|
return myCpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoteMemory getMemory() {
|
||||||
|
return myMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemory(MoteMemory memory) {
|
||||||
|
myMemory = (MspMoteMemory) memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Simulation getSimulation() {
|
||||||
|
return mySimulation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSimulation(Simulation simulation) {
|
||||||
|
mySimulation = simulation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stack monitoring variables */
|
||||||
|
public class StackOverflowObservable extends Observable {
|
||||||
|
public void signalStackOverflow() {
|
||||||
|
setChanged();
|
||||||
|
notifyObservers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable stack monitoring
|
||||||
|
*
|
||||||
|
* @param monitoring Monitoring enabled
|
||||||
|
*/
|
||||||
|
public void monitorStack(boolean monitoring) {
|
||||||
|
this.monitorStackUsage = monitoring;
|
||||||
|
resetLowestStackPointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Lowest SP since stack monitoring was enabled
|
||||||
|
*/
|
||||||
|
public int getLowestStackPointer() {
|
||||||
|
return stackPointerLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets lowest stack pointer variable
|
||||||
|
*/
|
||||||
|
public void resetLowestStackPointer() {
|
||||||
|
stackPointerLow = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Stack overflow observable
|
||||||
|
*/
|
||||||
|
public StackOverflowObservable getStackOverflowObservable() {
|
||||||
|
return stackOverflowObservable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates MSP430 CPU object and address memory for current object.
|
||||||
|
* This method should normally not be called from outside constructor.
|
||||||
|
*
|
||||||
|
* @param fileELF ELF file
|
||||||
|
* @throws IOException File loading failed
|
||||||
|
*/
|
||||||
|
protected void createCPUAndMemory(File fileELF) throws IOException {
|
||||||
|
myCpu = new MSP430(0);
|
||||||
|
myCpu.setMonitorExec(true);
|
||||||
|
|
||||||
|
int[] memory = myCpu.getMemory();
|
||||||
|
|
||||||
|
myELFModule = ELF.readELF(fileELF.getPath());
|
||||||
|
myELFModule.loadPrograms(memory);
|
||||||
|
MapTable map = myELFModule.getMap();
|
||||||
|
myCpu.getDisAsm().setMap(map);
|
||||||
|
myCpu.setMap(map);
|
||||||
|
|
||||||
|
/* TODO Need new memory type including size and type as well */
|
||||||
|
|
||||||
|
/* Create mote address memory */
|
||||||
|
Properties varAddresses = new Properties();
|
||||||
|
for (int i=0; i < map.functionNames.length; i++) {
|
||||||
|
if (map.functionNames[i] != null) {
|
||||||
|
varAddresses.put(map.functionNames[i], new Integer(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myMemory = new MspMoteMemory(varAddresses, myCpu);
|
||||||
|
|
||||||
|
myCpu.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(State newState) {
|
||||||
|
logger.warn("Msp motes can't change state");
|
||||||
|
}
|
||||||
|
|
||||||
|
public State getState() {
|
||||||
|
return Mote.State.ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoteType getType() {
|
||||||
|
return myMoteType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(MoteType type) {
|
||||||
|
myMoteType = (MspMoteType) type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addStateObserver(Observer newObserver) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteStateObserver(Observer newObserver) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoteInterfaceHandler getInterfaces() {
|
||||||
|
return myMoteInterfaceHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterfaces(MoteInterfaceHandler moteInterfaceHandler) {
|
||||||
|
myMoteInterfaceHandler = moteInterfaceHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an interface handler object and registers interfaces to it.
|
||||||
|
*
|
||||||
|
* @return Interface handler
|
||||||
|
*/
|
||||||
|
protected abstract MoteInterfaceHandler createMoteInterfaceHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes emulator by creating CPU, memory and node object.
|
||||||
|
*
|
||||||
|
* @param ELFFile ELF file
|
||||||
|
* @return True if successful
|
||||||
|
*/
|
||||||
|
protected abstract boolean initEmulator(File ELFFile);
|
||||||
|
|
||||||
|
public void tick(int simTime) {
|
||||||
|
// Let all interfaces act
|
||||||
|
myMoteInterfaceHandler.doPassiveActionsBeforeTick();
|
||||||
|
myMoteInterfaceHandler.doActiveActionsBeforeTick();
|
||||||
|
|
||||||
|
stopNextInstruction = false;
|
||||||
|
|
||||||
|
// Leave control to emulated CPU
|
||||||
|
MSP430 cpu = getCPU();
|
||||||
|
cycleCounter += NR_CYCLES_PER_MSEC;
|
||||||
|
|
||||||
|
if (monitorStackUsage) {
|
||||||
|
// CPU loop with stack observer
|
||||||
|
int newStack;
|
||||||
|
while (!stopNextInstruction && cpu.step() < cycleCounter) {
|
||||||
|
/* Check if radio has pending incoming bytes */
|
||||||
|
if (myRadio != null && myRadio.hasPendingBytes()) {
|
||||||
|
myRadio.tryDeliverNextByte(cpu.cycles);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { /* Fast CPU loop */
|
||||||
|
do {
|
||||||
|
/* Check if radio has pending incoming bytes */
|
||||||
|
if (myRadio != null && myRadio.hasPendingBytes()) {
|
||||||
|
myRadio.tryDeliverNextByte(cpu.cycles);
|
||||||
|
}
|
||||||
|
} while (!stopNextInstruction && (cpu.step() < cycleCounter) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset abort flag
|
||||||
|
stopNextInstruction = false;
|
||||||
|
|
||||||
|
// Let all interfaces act after tick
|
||||||
|
myMoteInterfaceHandler.doActiveActionsAfterTick();
|
||||||
|
myMoteInterfaceHandler.doPassiveActionsAfterTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setConfigXML(Simulation simulation, Collection<Element> configXML, boolean visAvailable) {
|
||||||
|
for (Element element: configXML) {
|
||||||
|
String name = element.getName();
|
||||||
|
|
||||||
|
if (name.equals("motetype_identifier")) {
|
||||||
|
|
||||||
|
setSimulation(simulation);
|
||||||
|
myMoteType = (MspMoteType) simulation.getMoteType(element.getText());
|
||||||
|
getType().setIdentifier(element.getText());
|
||||||
|
|
||||||
|
initEmulator(myMoteType.getELFFile());
|
||||||
|
myMoteInterfaceHandler = createMoteInterfaceHandler();
|
||||||
|
|
||||||
|
} else if (name.equals("interface_config")) {
|
||||||
|
Class<? extends MoteInterface> moteInterfaceClass = simulation.getGUI().tryLoadClass(
|
||||||
|
this, MoteInterface.class, element.getText().trim());
|
||||||
|
|
||||||
|
if (moteInterfaceClass == null) {
|
||||||
|
logger.fatal("Could not load mote interface class: " + element.getText().trim());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MoteInterface moteInterface = getInterfaces().getInterfaceOfType(moteInterfaceClass);
|
||||||
|
moteInterface.setConfigXML(element.getChildren(), visAvailable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Element> getConfigXML() {
|
||||||
|
Vector<Element> config = new Vector<Element>();
|
||||||
|
|
||||||
|
Element element;
|
||||||
|
|
||||||
|
// Mote type identifier
|
||||||
|
element = new Element("motetype_identifier");
|
||||||
|
element.setText(getType().getIdentifier());
|
||||||
|
config.add(element);
|
||||||
|
|
||||||
|
// Active interface configs (if any)
|
||||||
|
for (MoteInterface moteInterface: getInterfaces().getAllActiveInterfaces()) {
|
||||||
|
element = new Element("interface_config");
|
||||||
|
element.setText(moteInterface.getClass().getName());
|
||||||
|
|
||||||
|
Collection interfaceXML = moteInterface.getConfigXML();
|
||||||
|
if (interfaceXML != null) {
|
||||||
|
element.addContent(interfaceXML);
|
||||||
|
config.add(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passive interface configs (if any)
|
||||||
|
for (MoteInterface moteInterface: getInterfaces().getAllPassiveInterfaces()) {
|
||||||
|
element = new Element("interface_config");
|
||||||
|
element.setText(moteInterface.getClass().getName());
|
||||||
|
|
||||||
|
Collection interfaceXML = moteInterface.getConfigXML();
|
||||||
|
if (interfaceXML != null) {
|
||||||
|
element.addContent(interfaceXML);
|
||||||
|
config.add(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
/*
|
||||||
|
* 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: MspMoteMemory.java,v 1.1 2008/02/07 14:53:29 fros4943 Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
package se.sics.cooja.mspmote;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import se.sics.cooja.AddressMemory;
|
||||||
|
import se.sics.cooja.MoteMemory;
|
||||||
|
import se.sics.mspsim.core.MSP430;
|
||||||
|
|
||||||
|
public class MspMoteMemory implements MoteMemory, AddressMemory {
|
||||||
|
private static Logger logger = Logger.getLogger(MspMoteMemory.class);
|
||||||
|
private final Properties variableAddresses;
|
||||||
|
|
||||||
|
private int TEMP_MEM_START;
|
||||||
|
private MSP430 cpu;
|
||||||
|
|
||||||
|
public MspMoteMemory(Properties variableAddresses, MSP430 cpu) {
|
||||||
|
this.variableAddresses = variableAddresses;
|
||||||
|
|
||||||
|
this.cpu = cpu;
|
||||||
|
TEMP_MEM_START = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getVariableNames() {
|
||||||
|
String[] names = new String[variableAddresses.size()];
|
||||||
|
Enumeration nameEnum = variableAddresses.keys();
|
||||||
|
for (int i = 0; i < variableAddresses.size(); i++) {
|
||||||
|
names[i] = (String) nameEnum.nextElement();
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVariableAddress(String varName) {
|
||||||
|
if (!variableAddresses.containsKey(varName)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ((Integer) variableAddresses.get(varName)).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearMemory() {
|
||||||
|
logger.fatal("clearMemory() not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getMemorySegment(int address, int size) {
|
||||||
|
int[] ret = new int[size];
|
||||||
|
|
||||||
|
System.arraycopy(cpu.memory, address - TEMP_MEM_START, ret, 0, size);
|
||||||
|
|
||||||
|
// TODO XXX Slow method
|
||||||
|
byte[] ret2 = new byte[size];
|
||||||
|
for (int i=0; i < size; i++) {
|
||||||
|
ret2[i] = (byte) ret[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemorySegment(int address, byte[] data) {
|
||||||
|
// TODO XXX Slow method
|
||||||
|
int[] intArr = new int[data.length];
|
||||||
|
for (int i=0; i < data.length; i++) {
|
||||||
|
intArr[i] = data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
System.arraycopy(intArr, 0, cpu.memory, address - TEMP_MEM_START, data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalSize() {
|
||||||
|
return cpu.memory.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean variableExists(String varName) {
|
||||||
|
return variableAddresses.containsKey(varName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIntValueOf(String varName) {
|
||||||
|
// Get start address of variable
|
||||||
|
if (!variableAddresses.containsKey(varName)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int varAddr = ((Integer) variableAddresses.get(varName)).intValue();
|
||||||
|
|
||||||
|
byte[] varData = getMemorySegment(varAddr, 2);
|
||||||
|
|
||||||
|
int retVal = 0;
|
||||||
|
int pos = 0;
|
||||||
|
retVal += ((varData[pos++] & 0xFF)) << 8;
|
||||||
|
retVal += ((varData[pos++] & 0xFF)) << 0;
|
||||||
|
|
||||||
|
return Integer.reverseBytes(retVal) >> 16; // Crop two bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIntValueOf(String varName, int newVal) {
|
||||||
|
// Get start address of variable
|
||||||
|
if (!variableAddresses.containsKey(varName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int varAddr = ((Integer) variableAddresses.get(varName)).intValue();
|
||||||
|
|
||||||
|
// TODO Check if small/big-endian when coming from JNI?
|
||||||
|
int newValToSet = Integer.reverseBytes(newVal);
|
||||||
|
|
||||||
|
// Create byte array
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
byte[] varData = new byte[4];
|
||||||
|
varData[pos++] = (byte) ((newValToSet & 0xFF000000) >> 24);
|
||||||
|
varData[pos++] = (byte) ((newValToSet & 0xFF0000) >> 16);
|
||||||
|
varData[pos++] = (byte) ((newValToSet & 0xFF00) >> 8);
|
||||||
|
varData[pos++] = (byte) ((newValToSet & 0xFF) >> 0);
|
||||||
|
|
||||||
|
setMemorySegment(varAddr, varData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getByteValueOf(String varName) {
|
||||||
|
// Get start address of variable
|
||||||
|
if (!variableAddresses.containsKey(varName)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int varAddr = ((Integer) variableAddresses.get(varName)).intValue();
|
||||||
|
|
||||||
|
byte[] varData = getMemorySegment(varAddr, 1);
|
||||||
|
|
||||||
|
return varData[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByteValueOf(String varName, byte newVal) {
|
||||||
|
// Get start address of variable
|
||||||
|
if (!variableAddresses.containsKey(varName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int varAddr = ((Integer) variableAddresses.get(varName)).intValue();
|
||||||
|
|
||||||
|
byte[] varData = new byte[1];
|
||||||
|
|
||||||
|
varData[0] = newVal;
|
||||||
|
|
||||||
|
setMemorySegment(varAddr, varData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getByteArray(String varName, int length) {
|
||||||
|
// Get start address of variable
|
||||||
|
if (!variableAddresses.containsKey(varName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int varAddr = ((Integer) variableAddresses.get(varName)).intValue();
|
||||||
|
|
||||||
|
// TODO Check if small/big-endian when coming from JNI?
|
||||||
|
return getMemorySegment(varAddr, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByteArray(String varName, byte[] data) {
|
||||||
|
// Get start address of variable
|
||||||
|
if (!variableAddresses.containsKey(varName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int varAddr = ((Integer) variableAddresses.get(varName)).intValue();
|
||||||
|
|
||||||
|
// TODO Check if small/big-endian when coming from JNI?
|
||||||
|
setMemorySegment(varAddr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,942 @@
|
||||||
|
/*
|
||||||
|
* 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: MspMoteType.java,v 1.1 2008/02/07 14:53:29 fros4943 Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
package se.sics.cooja.mspmote;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.event.DocumentEvent;
|
||||||
|
import javax.swing.event.DocumentListener;
|
||||||
|
import javax.swing.filechooser.FileFilter;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.jdom.Element;
|
||||||
|
|
||||||
|
import se.sics.cooja.*;
|
||||||
|
import se.sics.cooja.dialogs.MessageList;
|
||||||
|
|
||||||
|
@ClassDescription("Msp Mote Type")
|
||||||
|
public abstract class MspMoteType implements MoteType {
|
||||||
|
private static Logger logger = Logger.getLogger(MspMoteType.class);
|
||||||
|
|
||||||
|
private static final String firmwareFileExtension = ".firmware";
|
||||||
|
|
||||||
|
/* Convenience: Preselecting last used directory */
|
||||||
|
protected static File lastParentDirectory = null;
|
||||||
|
|
||||||
|
private String identifier = null;
|
||||||
|
private String description = null;
|
||||||
|
|
||||||
|
/* If source file is defined, (re)compilation is performed */
|
||||||
|
private File fileELF = null;
|
||||||
|
private File fileSource = null;
|
||||||
|
private String compileCommand = null;
|
||||||
|
|
||||||
|
public String getIdentifier() {
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdentifier(String identifier) {
|
||||||
|
this.identifier = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set ELF file.
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* ELF file
|
||||||
|
*/
|
||||||
|
public void setELFFile(File file) {
|
||||||
|
this.fileELF = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set compile command.
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* Compile command
|
||||||
|
*/
|
||||||
|
public void setCompileCommand(String command) {
|
||||||
|
this.compileCommand = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ELF file
|
||||||
|
*/
|
||||||
|
public File getELFFile() {
|
||||||
|
return fileELF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Compile command
|
||||||
|
*/
|
||||||
|
public String getCompileCommand() {
|
||||||
|
return compileCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set source file
|
||||||
|
*
|
||||||
|
* @param file Source file
|
||||||
|
*/
|
||||||
|
public void setSourceFile(File file) {
|
||||||
|
fileSource = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Source file
|
||||||
|
*/
|
||||||
|
public File getSourceFile() {
|
||||||
|
return fileSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures and initialized Msp mote types.
|
||||||
|
*
|
||||||
|
* @param parentFrame Graphical parent frame
|
||||||
|
* @param simulation Current simulation
|
||||||
|
* @param visAvailable Enable graphical interfaces and user input
|
||||||
|
* @param target Contiki target platform name
|
||||||
|
* @param targetNice Nicer representation of target
|
||||||
|
* @return True is successful
|
||||||
|
* @throws MoteTypeCreationException Mote type creation failed
|
||||||
|
*/
|
||||||
|
protected boolean configureAndInitMspType(JFrame parentFrame, Simulation simulation,
|
||||||
|
boolean visAvailable, String target, String targetNice)
|
||||||
|
throws MoteTypeCreationException {
|
||||||
|
boolean compileFromSource = false;
|
||||||
|
|
||||||
|
if (getIdentifier() == null && !visAvailable) {
|
||||||
|
throw new MoteTypeCreationException("No identifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate unique identifier */
|
||||||
|
if (getIdentifier() == null) {
|
||||||
|
int counter = 0;
|
||||||
|
boolean identifierOK = false;
|
||||||
|
while (!identifierOK) {
|
||||||
|
counter++;
|
||||||
|
setIdentifier(target + counter);
|
||||||
|
identifierOK = true;
|
||||||
|
|
||||||
|
// Check if identifier is already used by some other type
|
||||||
|
for (MoteType existingMoteType : simulation.getMoteTypes()) {
|
||||||
|
if (existingMoteType != this
|
||||||
|
&& existingMoteType.getIdentifier().equals(getIdentifier())) {
|
||||||
|
identifierOK = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getDescription() == null) {
|
||||||
|
setDescription(targetNice + " Mote Type #" + counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let user choose whether to compile or load existing binaries */
|
||||||
|
Object[] options = { "Select", "Compile" };
|
||||||
|
|
||||||
|
String question = targetNice + " mote type depends on an ELF file.\n"
|
||||||
|
+ "If you want to use an already existing file, click 'Select'.\n\n"
|
||||||
|
+ "To compile this file from source, click 'Compile'";
|
||||||
|
String title = "Select or compile " + targetNice + " firmware";
|
||||||
|
int answer = JOptionPane.showOptionDialog(GUI.frame,
|
||||||
|
question, title, JOptionPane.YES_NO_OPTION,
|
||||||
|
JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
|
||||||
|
|
||||||
|
if (answer != JOptionPane.YES_OPTION && answer != JOptionPane.NO_OPTION) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
compileFromSource = answer != JOptionPane.YES_OPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Description */
|
||||||
|
if (getDescription() == null) {
|
||||||
|
setDescription(targetNice + " Mote Type #" + getIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getSourceFile() != null) {
|
||||||
|
compileFromSource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compileFromSource) {
|
||||||
|
MspELFCompiler compiler = new MspELFCompiler(target);
|
||||||
|
compiler.setCompileCommand(compileCommand);
|
||||||
|
|
||||||
|
if (visAvailable) {
|
||||||
|
boolean success = compiler.showDialog(GUI.frame, this);
|
||||||
|
if (success) {
|
||||||
|
setSourceFile(compiler.getSourceFile());
|
||||||
|
setELFFile(compiler.getOutputFile());
|
||||||
|
setCompileCommand(compiler.getLastCompileCommand());
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MessageList compilationOutput = new MessageList();
|
||||||
|
try {
|
||||||
|
compiler.compileFirmware(getSourceFile(), null, null, compilationOutput,
|
||||||
|
true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
MoteTypeCreationException newException = new MoteTypeCreationException(
|
||||||
|
"Mote type creation failed: " + e.getMessage());
|
||||||
|
newException = (MoteTypeCreationException) newException.initCause(e);
|
||||||
|
newException.setCompilationOutput(compilationOutput);
|
||||||
|
throw newException;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*File parentFile = getSourceFile().getParentFile();*/
|
||||||
|
/*final String filenameNoExtension = getSourceFile().getName().substring(0,
|
||||||
|
getSourceFile().getName().length() - 2);*/
|
||||||
|
/*setELFFile(new File(parentFile, filenameNoExtension + firmwareFileExtension));*/
|
||||||
|
|
||||||
|
setSourceFile(compiler.getSourceFile());
|
||||||
|
setELFFile(compiler.getOutputFile());
|
||||||
|
setCompileCommand(compiler.getLastCompileCommand());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check dependency files
|
||||||
|
if (getELFFile() == null || !getELFFile().exists()) {
|
||||||
|
if (visAvailable) {
|
||||||
|
JFileChooser fc = new JFileChooser();
|
||||||
|
|
||||||
|
// Select previous directory
|
||||||
|
if (lastParentDirectory != null) {
|
||||||
|
fc.setCurrentDirectory(lastParentDirectory);
|
||||||
|
} else {
|
||||||
|
fc.setCurrentDirectory(new java.io.File(GUI
|
||||||
|
.getExternalToolsSetting("PATH_CONTIKI")));
|
||||||
|
}
|
||||||
|
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||||
|
fc.addChoosableFileFilter(new FileFilter() {
|
||||||
|
public boolean accept(File f) {
|
||||||
|
if (f.isDirectory()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String filename = f.getName();
|
||||||
|
if (filename != null) {
|
||||||
|
if (filename.endsWith(firmwareFileExtension)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return "ELF file";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fc.setDialogTitle("Select ELF file");
|
||||||
|
|
||||||
|
if (fc.showOpenDialog(parentFrame) == JFileChooser.APPROVE_OPTION) {
|
||||||
|
lastParentDirectory = fc.getSelectedFile().getParentFile();
|
||||||
|
setELFFile(fc.getSelectedFile());
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new MoteTypeCreationException("No ELF file was created");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class MspELFCompiler {
|
||||||
|
private static int LABEL_WIDTH = 170;
|
||||||
|
|
||||||
|
private static int LABEL_HEIGHT = 15;
|
||||||
|
|
||||||
|
private JButton cancelButton = new JButton("Cancel");
|
||||||
|
|
||||||
|
private JButton compileButton = new JButton("Compile");
|
||||||
|
|
||||||
|
private JButton createButton = new JButton("Create");
|
||||||
|
|
||||||
|
private JTextField sourceTextField = new JTextField();
|
||||||
|
|
||||||
|
private JTextField compileCommandTextField = new JTextField();
|
||||||
|
|
||||||
|
// private JFormattedTextField nodeIDTextField;
|
||||||
|
// private NumberFormat integerFormat = NumberFormat.getIntegerInstance();
|
||||||
|
|
||||||
|
private String lastCompileCommand = null;
|
||||||
|
|
||||||
|
private File sourceFile = null;
|
||||||
|
|
||||||
|
private File ELFFile = null;
|
||||||
|
|
||||||
|
private String target;
|
||||||
|
|
||||||
|
private JDialog myDialog;
|
||||||
|
|
||||||
|
private String customizedCompileCommand = null;
|
||||||
|
|
||||||
|
static enum DialogState {
|
||||||
|
NO_SOURCE, SELECTED_SOURCE, IS_COMPILING, COMPILED_SOURCE
|
||||||
|
}
|
||||||
|
|
||||||
|
public MspELFCompiler(String target) {
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCompileCommand(String filename) {
|
||||||
|
if (customizedCompileCommand != null) {
|
||||||
|
return customizedCompileCommand;
|
||||||
|
}
|
||||||
|
return GUI.getExternalToolsSetting("PATH_MAKE") + " " + filename + firmwareFileExtension + " TARGET=" + target;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCompileCommand(String command) {
|
||||||
|
if (command == null || command.isEmpty()) {
|
||||||
|
customizedCompileCommand = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
customizedCompileCommand = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Compiler output
|
||||||
|
*/
|
||||||
|
public File getOutputFile() {
|
||||||
|
return ELFFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getSourceFile() {
|
||||||
|
return sourceFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastCompileCommand() {
|
||||||
|
return lastCompileCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDialog(DialogState dialogState) {
|
||||||
|
switch (dialogState) {
|
||||||
|
case NO_SOURCE:
|
||||||
|
compileButton.setEnabled(false);
|
||||||
|
createButton.setEnabled(false);
|
||||||
|
compileCommandTextField.setText("");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_COMPILING:
|
||||||
|
compileButton.setEnabled(false);
|
||||||
|
createButton.setEnabled(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SELECTED_SOURCE:
|
||||||
|
File sourceFile = new File(sourceTextField.getText());
|
||||||
|
if (!sourceFile.exists()) {
|
||||||
|
updateDialog(DialogState.NO_SOURCE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
File parentDirectory = sourceFile.getParentFile();
|
||||||
|
if (!parentDirectory.exists()) {
|
||||||
|
updateDialog(DialogState.NO_SOURCE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sourceFile.getName().endsWith(".c")) {
|
||||||
|
updateDialog(DialogState.NO_SOURCE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = sourceFile.getName().substring(0,
|
||||||
|
sourceFile.getName().length() - 2);
|
||||||
|
|
||||||
|
compileButton.setEnabled(true);
|
||||||
|
createButton.setEnabled(false);
|
||||||
|
compileCommandTextField.setText(getCompileCommand(name));
|
||||||
|
compileButton.requestFocusInWindow();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMPILED_SOURCE:
|
||||||
|
compileButton.setEnabled(true);
|
||||||
|
createButton.setEnabled(true);
|
||||||
|
|
||||||
|
createButton.requestFocusInWindow();
|
||||||
|
myDialog.getRootPane().setDefaultButton(createButton);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void compileFirmware(final File sourceFile,
|
||||||
|
final Action successAction, final Action failAction,
|
||||||
|
MessageList compilationOutput, boolean synchronous) throws Exception {
|
||||||
|
final File parentDirectory = sourceFile.getParentFile();
|
||||||
|
final String filenameNoExtension = sourceFile.getName().substring(0,
|
||||||
|
sourceFile.getName().length() - 2);
|
||||||
|
|
||||||
|
String command = getCompileCommand(filenameNoExtension);
|
||||||
|
logger.info("Compile command: " + command);
|
||||||
|
|
||||||
|
compilationOutput.clearMessages();
|
||||||
|
|
||||||
|
try {
|
||||||
|
String[] cmd = command.split(" ");
|
||||||
|
|
||||||
|
final Process compileProcess = Runtime.getRuntime().exec(cmd, null,
|
||||||
|
parentDirectory);
|
||||||
|
|
||||||
|
final BufferedReader processNormal = new BufferedReader(
|
||||||
|
new InputStreamReader(compileProcess.getInputStream()));
|
||||||
|
final BufferedReader processError = new BufferedReader(
|
||||||
|
new InputStreamReader(compileProcess.getErrorStream()));
|
||||||
|
|
||||||
|
final PrintStream listNormal = compilationOutput
|
||||||
|
.getInputStream(MessageList.NORMAL);
|
||||||
|
final PrintStream listError = compilationOutput
|
||||||
|
.getInputStream(MessageList.ERROR);
|
||||||
|
|
||||||
|
final File ELFFile = new File(parentDirectory, filenameNoExtension + firmwareFileExtension);
|
||||||
|
if (ELFFile.exists()) {
|
||||||
|
ELFFile.delete();
|
||||||
|
if (ELFFile.exists()) {
|
||||||
|
listError.println("Error when deleting old " + ELFFile.getName());
|
||||||
|
if (failAction != null) {
|
||||||
|
failAction.actionPerformed(null);
|
||||||
|
}
|
||||||
|
throw new MoteTypeCreationException("Error when deleting old "
|
||||||
|
+ ELFFile.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread readInput = new Thread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
String readLine;
|
||||||
|
try {
|
||||||
|
while ((readLine = processNormal.readLine()) != null) {
|
||||||
|
if (listNormal != null && readLine != null) {
|
||||||
|
listNormal.println(readLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.warn("Error while reading from process");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "read input stream thread");
|
||||||
|
|
||||||
|
Thread readError = new Thread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
String readLine;
|
||||||
|
try {
|
||||||
|
while ((readLine = processError.readLine()) != null) {
|
||||||
|
if (listError != null && readLine != null) {
|
||||||
|
listError.println(readLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.warn("Error while reading from process");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "read input stream thread");
|
||||||
|
|
||||||
|
final MoteTypeCreationException syncException = new MoteTypeCreationException(
|
||||||
|
"");
|
||||||
|
Thread handleCompilationResultThread = new Thread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
/* Wait for compilation to end */
|
||||||
|
try {
|
||||||
|
compileProcess.waitFor();
|
||||||
|
} catch (Exception e) {
|
||||||
|
syncException.setCompilationOutput(new MessageList());
|
||||||
|
syncException.fillInStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check return value */
|
||||||
|
if (compileProcess.exitValue() != 0) {
|
||||||
|
listError.println("Process returned error code "
|
||||||
|
+ compileProcess.exitValue());
|
||||||
|
if (failAction != null) {
|
||||||
|
failAction.actionPerformed(null);
|
||||||
|
}
|
||||||
|
syncException.setCompilationOutput(new MessageList());
|
||||||
|
syncException.fillInStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ELFFile.exists()) {
|
||||||
|
listError.println("Can't locate output file " + ELFFile);
|
||||||
|
if (failAction != null) {
|
||||||
|
failAction.actionPerformed(null);
|
||||||
|
}
|
||||||
|
syncException.setCompilationOutput(new MessageList());
|
||||||
|
syncException.fillInStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
listNormal.println("");
|
||||||
|
listNormal.println("Compilation succeded");
|
||||||
|
if (successAction != null) {
|
||||||
|
successAction.actionPerformed(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "enable create button thread");
|
||||||
|
|
||||||
|
readInput.start();
|
||||||
|
readError.start();
|
||||||
|
handleCompilationResultThread.start();
|
||||||
|
|
||||||
|
if (synchronous) {
|
||||||
|
try {
|
||||||
|
handleCompilationResultThread.join();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw (MoteTypeCreationException) new MoteTypeCreationException(
|
||||||
|
"Compilation error: " + e.getMessage()).initCause(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syncException.hasCompilationOutput()) {
|
||||||
|
throw (MoteTypeCreationException) new MoteTypeCreationException(
|
||||||
|
"Compilation error").initCause(syncException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
if (failAction != null) {
|
||||||
|
failAction.actionPerformed(null);
|
||||||
|
}
|
||||||
|
throw (MoteTypeCreationException) new MoteTypeCreationException(
|
||||||
|
"Compilation error: " + ex.getMessage()).initCause(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean showDialog(Frame parentFrame, final MspMoteType moteType) {
|
||||||
|
myDialog = new JDialog(parentFrame, "Compile ELF file", true);
|
||||||
|
final MessageList taskOutput = new MessageList();
|
||||||
|
|
||||||
|
// BOTTOM BUTTON PART
|
||||||
|
Box buttonBox = Box.createHorizontalBox();
|
||||||
|
buttonBox.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
|
||||||
|
|
||||||
|
buttonBox.add(Box.createHorizontalGlue());
|
||||||
|
|
||||||
|
cancelButton.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
sourceFile = null;
|
||||||
|
ELFFile = null;
|
||||||
|
|
||||||
|
myDialog.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
compileButton.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
final File selectedSourceFile = new File(sourceTextField.getText());
|
||||||
|
|
||||||
|
/* Strip .c file extension */
|
||||||
|
final String filenameNoExtension = selectedSourceFile.getName()
|
||||||
|
.substring(0, selectedSourceFile.getName().length() - 2);
|
||||||
|
|
||||||
|
Action successAction = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
updateDialog(DialogState.COMPILED_SOURCE);
|
||||||
|
File parentFile = selectedSourceFile.getParentFile();
|
||||||
|
|
||||||
|
lastCompileCommand = getCompileCommand(filenameNoExtension);
|
||||||
|
sourceFile = selectedSourceFile;
|
||||||
|
ELFFile = new File(parentFile, filenameNoExtension + firmwareFileExtension);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Action failAction = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
updateDialog(DialogState.SELECTED_SOURCE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateDialog(DialogState.IS_COMPILING);
|
||||||
|
try {
|
||||||
|
compileFirmware(new File(sourceTextField.getText()), successAction,
|
||||||
|
failAction, taskOutput, false);
|
||||||
|
} catch (Exception e2) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
createButton.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
myDialog.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
buttonBox.add(cancelButton);
|
||||||
|
buttonBox.add(Box.createHorizontalStrut(5));
|
||||||
|
buttonBox.add(compileButton);
|
||||||
|
buttonBox.add(Box.createHorizontalStrut(5));
|
||||||
|
buttonBox.add(createButton);
|
||||||
|
|
||||||
|
// MAIN DIALOG CONTENTS
|
||||||
|
Box horizBox;
|
||||||
|
JLabel label;
|
||||||
|
Box vertBox = Box.createVerticalBox();
|
||||||
|
|
||||||
|
// Source
|
||||||
|
horizBox = Box.createHorizontalBox();
|
||||||
|
horizBox.setMaximumSize(new Dimension(Integer.MAX_VALUE, LABEL_HEIGHT));
|
||||||
|
horizBox.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
|
label = new JLabel("Contiki process sourcefile");
|
||||||
|
label.setPreferredSize(new Dimension(LABEL_WIDTH, LABEL_HEIGHT));
|
||||||
|
|
||||||
|
sourceTextField.setText("");
|
||||||
|
if (moteType.getSourceFile() != null) {
|
||||||
|
sourceTextField.setText(moteType.getSourceFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
sourceTextField.setColumns(25);
|
||||||
|
|
||||||
|
sourceTextField.getDocument().addDocumentListener(new DocumentListener() {
|
||||||
|
public void insertUpdate(DocumentEvent e) {
|
||||||
|
updateDialog(DialogState.SELECTED_SOURCE);
|
||||||
|
}
|
||||||
|
public void changedUpdate(DocumentEvent e) {
|
||||||
|
updateDialog(DialogState.SELECTED_SOURCE);
|
||||||
|
}
|
||||||
|
public void removeUpdate(DocumentEvent e) {
|
||||||
|
updateDialog(DialogState.SELECTED_SOURCE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JButton browseButton = new JButton("Browse");
|
||||||
|
browseButton.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
updateDialog(DialogState.NO_SOURCE);
|
||||||
|
|
||||||
|
JFileChooser fc = new JFileChooser();
|
||||||
|
if (lastParentDirectory != null) {
|
||||||
|
fc.setCurrentDirectory(lastParentDirectory);
|
||||||
|
} else {
|
||||||
|
fc.setCurrentDirectory(new java.io.File(GUI
|
||||||
|
.getExternalToolsSetting("PATH_CONTIKI")));
|
||||||
|
}
|
||||||
|
|
||||||
|
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||||
|
fc.addChoosableFileFilter(new FileFilter() {
|
||||||
|
public boolean accept(File f) {
|
||||||
|
if (f.isDirectory()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String filename = f.getName();
|
||||||
|
if (filename != null) {
|
||||||
|
if (filename.endsWith(".c")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return "Contiki process source";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fc.setDialogTitle("Select Contiki process source");
|
||||||
|
|
||||||
|
if (fc.showOpenDialog(myDialog) == JFileChooser.APPROVE_OPTION) {
|
||||||
|
lastParentDirectory = null;
|
||||||
|
sourceTextField.setText("");
|
||||||
|
|
||||||
|
File selectedFile = fc.getSelectedFile();
|
||||||
|
if (!selectedFile.exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectedFile.getName().endsWith(".c")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastParentDirectory = fc.getSelectedFile().getParentFile();
|
||||||
|
sourceTextField.setText(fc.getSelectedFile().getAbsolutePath());
|
||||||
|
updateDialog(DialogState.SELECTED_SOURCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
horizBox.add(label);
|
||||||
|
horizBox.add(Box.createHorizontalStrut(10));
|
||||||
|
horizBox.add(sourceTextField);
|
||||||
|
horizBox.add(browseButton);
|
||||||
|
|
||||||
|
vertBox.add(horizBox);
|
||||||
|
vertBox.add(Box.createRigidArea(new Dimension(0, 5)));
|
||||||
|
|
||||||
|
// Node ID
|
||||||
|
/*
|
||||||
|
* horizBox = Box.createHorizontalBox(); horizBox.setMaximumSize(new
|
||||||
|
* Dimension(Integer.MAX_VALUE,LABEL_HEIGHT));
|
||||||
|
* horizBox.setAlignmentX(Component.LEFT_ALIGNMENT); label = new
|
||||||
|
* JLabel("Node ID (0=EEPROM)"); label.setPreferredSize(new
|
||||||
|
* Dimension(LABEL_WIDTH,LABEL_HEIGHT));
|
||||||
|
*
|
||||||
|
* nodeIDTextField = new JFormattedTextField(integerFormat);
|
||||||
|
* nodeIDTextField.setValue(new Integer(0));
|
||||||
|
* nodeIDTextField.setColumns(25);
|
||||||
|
* nodeIDTextField.addPropertyChangeListener("value", new
|
||||||
|
* PropertyChangeListener() { public void
|
||||||
|
* propertyChange(PropertyChangeEvent e) {
|
||||||
|
* updateDialog(DialogState.SELECTED_SOURCE); } });
|
||||||
|
*
|
||||||
|
* horizBox.add(label); horizBox.add(Box.createHorizontalStrut(150));
|
||||||
|
* horizBox.add(nodeIDTextField);
|
||||||
|
*
|
||||||
|
* vertBox.add(horizBox); vertBox.add(Box.createRigidArea(new
|
||||||
|
* Dimension(0,5)));
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Compile command
|
||||||
|
horizBox = Box.createHorizontalBox();
|
||||||
|
horizBox.setMaximumSize(new Dimension(Integer.MAX_VALUE, LABEL_HEIGHT));
|
||||||
|
horizBox.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
|
label = new JLabel("Compile command");
|
||||||
|
label.setPreferredSize(new Dimension(LABEL_WIDTH, LABEL_HEIGHT));
|
||||||
|
|
||||||
|
compileCommandTextField.setText("");
|
||||||
|
compileCommandTextField.setColumns(25);
|
||||||
|
compileCommandTextField.setEditable(true);
|
||||||
|
|
||||||
|
compileCommandTextField.getDocument().addDocumentListener(new DocumentListener() {
|
||||||
|
public void insertUpdate(DocumentEvent e) {
|
||||||
|
setCompileCommand(compileCommandTextField.getText());
|
||||||
|
}
|
||||||
|
public void changedUpdate(DocumentEvent e) {
|
||||||
|
setCompileCommand(compileCommandTextField.getText());
|
||||||
|
}
|
||||||
|
public void removeUpdate(DocumentEvent e) {
|
||||||
|
setCompileCommand(compileCommandTextField.getText());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
horizBox.add(label);
|
||||||
|
horizBox.add(Box.createHorizontalStrut(10));
|
||||||
|
horizBox.add(compileCommandTextField);
|
||||||
|
|
||||||
|
vertBox.add(horizBox);
|
||||||
|
vertBox.add(Box.createRigidArea(new Dimension(0, 5)));
|
||||||
|
|
||||||
|
vertBox.add(Box.createRigidArea(new Dimension(0, 5)));
|
||||||
|
vertBox.add(new JLabel("Compilation output:"));
|
||||||
|
vertBox.add(Box.createRigidArea(new Dimension(0, 5)));
|
||||||
|
|
||||||
|
vertBox.add(new JScrollPane(taskOutput));
|
||||||
|
vertBox.add(Box.createRigidArea(new Dimension(0, 5)));
|
||||||
|
|
||||||
|
vertBox.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||||
|
Container contentPane = myDialog.getContentPane();
|
||||||
|
contentPane.add(vertBox, BorderLayout.CENTER);
|
||||||
|
contentPane.add(buttonBox, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
myDialog.pack();
|
||||||
|
myDialog.setLocationRelativeTo(parentFrame);
|
||||||
|
myDialog.getRootPane().setDefaultButton(compileButton);
|
||||||
|
|
||||||
|
// Dispose on escape key
|
||||||
|
InputMap inputMap = myDialog.getRootPane().getInputMap(
|
||||||
|
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||||
|
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false),
|
||||||
|
"dispose");
|
||||||
|
AbstractAction cancelAction = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
cancelButton.doClick();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
myDialog.getRootPane().getActionMap().put("dispose", cancelAction);
|
||||||
|
|
||||||
|
myDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
|
||||||
|
myDialog.addWindowListener(new WindowListener() {
|
||||||
|
public void windowDeactivated(WindowEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void windowIconified(WindowEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void windowDeiconified(WindowEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void windowOpened(WindowEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void windowClosed(WindowEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void windowActivated(WindowEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
cancelButton.doClick();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
updateDialog(DialogState.NO_SOURCE);
|
||||||
|
if (moteType.getSourceFile() != null) {
|
||||||
|
updateDialog(DialogState.SELECTED_SOURCE);
|
||||||
|
if (customizedCompileCommand != null && !customizedCompileCommand.equals("")) {
|
||||||
|
compileCommandTextField.setText(customizedCompileCommand);
|
||||||
|
}
|
||||||
|
compileButton.requestFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
myDialog.setVisible(true);
|
||||||
|
|
||||||
|
return sourceFile != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public JPanel getTypeVisualizer() {
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
JLabel label = new JLabel();
|
||||||
|
JPanel smallPane;
|
||||||
|
|
||||||
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
||||||
|
|
||||||
|
// Identifier
|
||||||
|
smallPane = new JPanel(new BorderLayout());
|
||||||
|
label = new JLabel("Identifier");
|
||||||
|
smallPane.add(BorderLayout.WEST, label);
|
||||||
|
label = new JLabel(getIdentifier());
|
||||||
|
smallPane.add(BorderLayout.EAST, label);
|
||||||
|
panel.add(smallPane);
|
||||||
|
|
||||||
|
// Description
|
||||||
|
smallPane = new JPanel(new BorderLayout());
|
||||||
|
label = new JLabel("Description");
|
||||||
|
smallPane.add(BorderLayout.WEST, label);
|
||||||
|
label = new JLabel(getDescription());
|
||||||
|
smallPane.add(BorderLayout.EAST, label);
|
||||||
|
panel.add(smallPane);
|
||||||
|
|
||||||
|
// ELF Hex file
|
||||||
|
smallPane = new JPanel(new BorderLayout());
|
||||||
|
label = new JLabel("ELF file");
|
||||||
|
smallPane.add(BorderLayout.WEST, label);
|
||||||
|
label = new JLabel(getELFFile().getName());
|
||||||
|
label.setToolTipText(getELFFile().getPath());
|
||||||
|
smallPane.add(BorderLayout.EAST, label);
|
||||||
|
panel.add(smallPane);
|
||||||
|
|
||||||
|
// Source file
|
||||||
|
smallPane = new JPanel(new BorderLayout());
|
||||||
|
label = new JLabel("Source file");
|
||||||
|
smallPane.add(BorderLayout.WEST, label);
|
||||||
|
if (getSourceFile() != null) {
|
||||||
|
label = new JLabel(getSourceFile().getName());
|
||||||
|
label.setToolTipText(getSourceFile().getPath());
|
||||||
|
} else {
|
||||||
|
label = new JLabel("[not specified]");
|
||||||
|
}
|
||||||
|
smallPane.add(BorderLayout.EAST, label);
|
||||||
|
panel.add(smallPane);
|
||||||
|
|
||||||
|
panel.add(Box.createRigidArea(new Dimension(0, 5)));
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectConfig getConfig() {
|
||||||
|
logger.warn("Msp mote type project config not implemented");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Element> getConfigXML() {
|
||||||
|
Vector<Element> config = new Vector<Element>();
|
||||||
|
|
||||||
|
Element element;
|
||||||
|
|
||||||
|
// Identifier
|
||||||
|
element = new Element("identifier");
|
||||||
|
element.setText(getIdentifier());
|
||||||
|
config.add(element);
|
||||||
|
|
||||||
|
// Description
|
||||||
|
element = new Element("description");
|
||||||
|
element.setText(getDescription());
|
||||||
|
config.add(element);
|
||||||
|
|
||||||
|
// Source file
|
||||||
|
if (fileSource != null) {
|
||||||
|
element = new Element("source");
|
||||||
|
element.setText(fileSource.getPath());
|
||||||
|
config.add(element);
|
||||||
|
element = new Element("command");
|
||||||
|
element.setText(compileCommand);
|
||||||
|
config.add(element);
|
||||||
|
} else {
|
||||||
|
// ELF file
|
||||||
|
element = new Element("elf");
|
||||||
|
element.setText(fileELF.getPath());
|
||||||
|
config.add(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setConfigXML(Simulation simulation,
|
||||||
|
Collection<Element> configXML, boolean visAvailable)
|
||||||
|
throws MoteTypeCreationException {
|
||||||
|
for (Element element : configXML) {
|
||||||
|
String name = element.getName();
|
||||||
|
|
||||||
|
if (name.equals("identifier")) {
|
||||||
|
identifier = element.getText();
|
||||||
|
} else if (name.equals("description")) {
|
||||||
|
description = element.getText();
|
||||||
|
} else if (name.equals("source")) {
|
||||||
|
fileSource = new File(element.getText());
|
||||||
|
} else if (name.equals("command")) {
|
||||||
|
compileCommand = element.getText();
|
||||||
|
} else if (name.equals("elf")) {
|
||||||
|
fileELF = new File(element.getText());
|
||||||
|
} else {
|
||||||
|
logger.fatal("Unrecognized entry in loaded configuration: " + name);
|
||||||
|
throw new MoteTypeCreationException(
|
||||||
|
"Unrecognized entry in loaded configuration: " + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return configureAndInit(GUI.frame, simulation, visAvailable);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue