From 643ce5adfee8ab16efde3813917a76e7f180face Mon Sep 17 00:00:00 2001 From: fros4943 Date: Fri, 18 May 2007 13:45:19 +0000 Subject: [PATCH] added support for several contiki comm stacks (uip + rime) --- platform/cooja/dev/cooja-radio.c | 238 ++++++++++++++++++ platform/cooja/dev/cooja-radio.h | 111 ++++++++ tools/cooja/java/se/sics/cooja/GUI.java | 9 +- .../cooja/contikimote/ContikiMoteType.java | 54 +++- .../contikimote/ContikiMoteTypeDialog.java | 45 +++- 5 files changed, 446 insertions(+), 11 deletions(-) create mode 100644 platform/cooja/dev/cooja-radio.c create mode 100644 platform/cooja/dev/cooja-radio.h diff --git a/platform/cooja/dev/cooja-radio.c b/platform/cooja/dev/cooja-radio.c new file mode 100644 index 000000000..3d6225049 --- /dev/null +++ b/platform/cooja/dev/cooja-radio.c @@ -0,0 +1,238 @@ +/* + * 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: cooja-radio.c,v 1.1 2007/05/18 13:48:16 fros4943 Exp $ + */ + +#include +#include "contiki.h" + +#include "dev/radio.h" +#include "dev/cooja-radio.h" +#include "lib/simEnvChange.h" +#include "sys/cooja_mt.h" + +#define MAX_RETRIES 100 +#define SS_INTERFERENCE -70 + +const struct simInterface radio_interface; + +// COOJA variables +char simTransmitting; +char simReceiving; + +char simInDataBuffer[COOJA_RADIO_BUFSIZE]; +int simInSize; +char simInPolled; +char simOutDataBuffer[COOJA_RADIO_BUFSIZE]; +int simOutSize; + +char simRadioHWOn = 1; +int simSignalStrength = -200; +char simPower = 100; +int simRadioChannel = 1; +int inSendFunction = 0; + +static void (* receiver_callback)(const struct radio_driver *); + +const struct radio_driver cooja_driver = + { + radio_send, + radio_read, + radio_set_receiver, + radio_on, + radio_off, + }; + +/*-----------------------------------------------------------------------------------*/ +void +radio_set_receiver(void (* recv)(const struct radio_driver *)) +{ + receiver_callback = recv; +} +/*-----------------------------------------------------------------------------------*/ +int +radio_on(void) +{ + simRadioHWOn = 1; + return 1; +} +/*-----------------------------------------------------------------------------------*/ +int +radio_off(void) +{ + simRadioHWOn = 0; + return 1; +} +/*---------------------------------------------------------------------------*/ +void +radio_set_channel(int channel) +{ + simRadioChannel = channel; +} +/*-----------------------------------------------------------------------------------*/ +int +radio_sstrength(void) +{ + return simSignalStrength; +} +/*-----------------------------------------------------------------------------------*/ +void +radio_set_txpower(unsigned char power) +{ + /* 1 - 100: Number indicating output power */ + simPower = power; +} +/*-----------------------------------------------------------------------------------*/ +static void +doInterfaceActionsBeforeTick(void) +{ + // If radio is turned off, do nothing + if (!simRadioHWOn) { + simInSize = 0; + simInPolled = 0; + return; + } + + // Don't fall asleep while receiving (in main file) + if (simReceiving) { + simDontFallAsleep = 1; + return; + } + + // If no incoming radio data, do nothing + if (simInSize == 0) { + simInPolled = 0; + return; + } + + // Check size of received packet + if (simInSize > COOJA_RADIO_BUFSIZE) { + // Drop packet by not delivering + return; + } + + // ** Good place to add explicit manchester/gcr-encoding + + if(receiver_callback != NULL && !simInPolled) { + receiver_callback(&cooja_driver); + simInPolled = 1; + } +} +/*---------------------------------------------------------------------------*/ +u16_t +radio_read(u8_t *buf, u16_t bufsize) +{ + int tmpInSize = simInSize; + if(simInSize > 0) { + + memcpy(buf, simInDataBuffer, simInSize); + simInSize = 0; + return tmpInSize; + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +static void +doInterfaceActionsAfterTick(void) +{ + // Make sure we are awake during radio activity + if (simReceiving || simTransmitting) { + simDontFallAsleep = 1; + return; + } +} +/*-----------------------------------------------------------------------------------*/ +int +radio_send(const u8_t *payload, u16_t payload_len) +{ + /* If radio already actively transmitting, drop packet*/ + if(inSendFunction) { + return COOJA_RADIO_DROPPED; + } + + inSendFunction = 1; + + /* If radio is turned off, do nothing */ + if(!simRadioHWOn) { + inSendFunction = 0; + return COOJA_RADIO_DROPPED; + } + + /* Drop packet if data size too large */ + if(payload_len > COOJA_RADIO_BUFSIZE) { + inSendFunction = 0; + return COOJA_RADIO_TOOLARGE; + } + + /* Drop packet if no data length */ + if(payload_len <= 0) { + inSendFunction = 0; + return COOJA_RADIO_ZEROLEN; + } + + /* ** Good place to add explicit manchester/gcr-decoding */ + + /* Copy packet data to temporary storage */ + memcpy(simOutDataBuffer, payload, payload_len); + simOutSize = payload_len; + + /* Busy-wait until both radio HW and ether is ready */ + { + int retries = 0; + while(retries < MAX_RETRIES && !simNoYield && + (simSignalStrength > SS_INTERFERENCE || simReceiving)) { + retries++; + cooja_mt_yield(); + if(!(simSignalStrength > SS_INTERFERENCE || simReceiving)) { + /* Wait one extra tick before transmission starts */ + cooja_mt_yield(); + } + } + } + + if(simSignalStrength > SS_INTERFERENCE || simReceiving) { + inSendFunction = 0; + return COOJA_RADIO_DROPPED; + } + + // - Initiate transmission - + simTransmitting = 1; + + // Busy-wait while transmitting + while(simTransmitting && !simNoYield) { + cooja_mt_yield(); + } + + inSendFunction = 0; + return COOJA_RADIO_OK; +} +/*-----------------------------------------------------------------------------------*/ +SIM_INTERFACE(radio_interface, + doInterfaceActionsBeforeTick, + doInterfaceActionsAfterTick); diff --git a/platform/cooja/dev/cooja-radio.h b/platform/cooja/dev/cooja-radio.h new file mode 100644 index 000000000..7e9d2268e --- /dev/null +++ b/platform/cooja/dev/cooja-radio.h @@ -0,0 +1,111 @@ +/* + * 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. + * + * This file is part of the Contiki operating system. + * + * $Id: cooja-radio.h,v 1.1 2007/05/18 13:48:30 fros4943 Exp $ + */ + +#ifndef __COOJA_RADIO_H__ +#define __COOJA_RADIO_H__ + +#include "contiki.h" +#include "contiki-conf.h" + +#include "dev/radio.h" + +#include "net/uip.h" +#include "net/uip-fw.h" + +#define COOJA_RADIO_BUFSIZE UIP_BUFSIZE +#define COOJA_RADIO_DROPPED UIP_FW_DROPPED +#define COOJA_RADIO_TOOLARGE UIP_FW_TOOLARGE +#define COOJA_RADIO_ZEROLEN UIP_FW_ZEROLEN +#define COOJA_RADIO_OK UIP_FW_OK + +extern const struct radio_driver cooja_driver; + +/** + * Turn radio hardware on. + */ +int +radio_on(void); + +/** + * Turn radio hardware off. + */ +int +radio_off(void); + +/** + * Set radio receiver. + */ +void +radio_set_receiver(void (* recv)(const struct radio_driver *)); + +/** + * Set radio channel. + */ +void +radio_set_channel(int channel); + +/** + * Set transmission power of transceiver. + * + * \param p The power of the tranceiver, between 1 (lowest) and 100 + * (highest). + */ +void +radio_set_txpower(unsigned char p); + +/** + * Send a packet from the given buffer with the given length. + */ +int +radio_send(const u8_t *payload, u16_t payload_len); + +/** + * Check if an incoming packet has been received. + * + * This function checks the receive buffer to see if an entire packet + * has been received. + * + * \return The length of the received packet, or 0 if no packet has + * been received. + */ +u16_t +radio_read(u8_t *buf, u16_t bufsize); + +/** + * This function returns the recevied signal strength of the last + * received packet. This function typically is called when a packet + * has been received. + */ +int radio_sstrength(void); + +#endif /* __COOJA_RADIO_H__ */ diff --git a/tools/cooja/java/se/sics/cooja/GUI.java b/tools/cooja/java/se/sics/cooja/GUI.java index f4a5429ca..fc4e7478c 100644 --- a/tools/cooja/java/se/sics/cooja/GUI.java +++ b/tools/cooja/java/se/sics/cooja/GUI.java @@ -24,7 +24,7 @@ * (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: GUI.java,v 1.46 2007/05/14 12:13:08 fros4943 Exp $ + * $Id: GUI.java,v 1.47 2007/05/18 13:45:19 fros4943 Exp $ */ package se.sics.cooja; @@ -896,9 +896,12 @@ public class GUI { } // Compile library - logger.info("> Compiling library"); + logger.info("> Compiling library (uIP comm stack)"); + // TODO Warning, assuming uIP communication stack boolean compilationSucceded = ContikiMoteTypeDialog.compileLibrary( - moteTypeID, contikiBaseDir, filesToCompile, false, null, System.err); + moteTypeID, contikiBaseDir, filesToCompile, false, + ContikiMoteType.CommunicationStack.UIP, + null, System.err); if (!libFile.exists() || !depFile.exists() || !mapFile.exists()) compilationSucceded = false; diff --git a/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteType.java b/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteType.java index 756418cf8..d4210cb46 100644 --- a/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteType.java +++ b/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteType.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ContikiMoteType.java,v 1.13 2007/05/11 10:55:26 fros4943 Exp $ + * $Id: ContikiMoteType.java,v 1.14 2007/05/18 13:46:31 fros4943 Exp $ */ package se.sics.cooja.contikimote; @@ -88,6 +88,32 @@ public class ContikiMoteType implements MoteType { */ final static public File tempOutputDirectory = new File("obj_cooja"); + /** + * Communication stacks in Contiki. + */ + public enum CommunicationStack { + UIP, + RIME; + + public String toString() { + if (this == UIP) + return "uIP"; + if (this == RIME) + return "Rime"; + return "[unknown]"; + } + + public static CommunicationStack parse(String name) { + if (name.equals("uIP") || name.equals("UIP")) + return UIP; + if (name.equals("Rime") || name.equals("RIME")) + return RIME; + + logger.warn("Can't parse communication stack name: " + name); + return UIP; + } + } + // Regular expressions for parsing the map file final static private String bssSectionAddrRegExp = "^.bss[ \t]*0x([0-9A-Fa-f]*)[ \t]*0x[0-9A-Fa-f]*[ \t]*$"; final static private String bssSectionSizeRegExp = "^.bss[ \t]*0x[0-9A-Fa-f]*[ \t]*0x([0-9A-Fa-f]*)[ \t]*$"; @@ -114,7 +140,8 @@ public class ContikiMoteType implements MoteType { private Vector coreInterfaces = null; private Vector> moteInterfaces = null; private boolean hasSystemSymbols = false; - + private CommunicationStack commStack = CommunicationStack.UIP; + // Simulation holding this mote type private Simulation mySimulation = null; @@ -206,7 +233,8 @@ public class ContikiMoteType implements MoteType { identifier, new File(contikiBaseDir), compilationFiles, - hasSystemSymbols, + hasSystemSymbols, + commStack, taskOutput.getInputStream(MessageList.NORMAL), taskOutput.getInputStream(MessageList.ERROR)); if (!libFile.exists() || !depFile.exists() || !mapFile.exists()) @@ -459,7 +487,20 @@ public class ContikiMoteType implements MoteType { public boolean hasSystemSymbols() { return hasSystemSymbols; } + + /** + * @param commStack Communication stack + */ + public void setCommunicationStack(CommunicationStack commStack) { + this.commStack = commStack; + } + /** + * @return Contiki communication stack + */ + public CommunicationStack getCommunicationStack() { + return commStack; + } /** * @return Contiki mote type's library class name @@ -1140,6 +1181,11 @@ public class ContikiMoteType implements MoteType { element.setText(new Boolean(hasSystemSymbols).toString()); config.add(element); + // Communication stack + element = new Element("commstack"); + element.setText(commStack.toString()); + config.add(element); + return config; } @@ -1174,6 +1220,8 @@ public class ContikiMoteType implements MoteType { sensors.add(element.getText()); } else if (name.equals("symbols")) { hasSystemSymbols = Boolean.parseBoolean(element.getText()); + } else if (name.equals("commstack")) { + commStack = CommunicationStack.parse(element.getText()); } else if (name.equals("coreinterface")) { coreInterfaces.add(element.getText()); } else if (name.equals("moteinterface")) { diff --git a/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteTypeDialog.java b/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteTypeDialog.java index f37cad367..073f0469c 100644 --- a/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteTypeDialog.java +++ b/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteTypeDialog.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ContikiMoteTypeDialog.java,v 1.28 2007/05/11 10:55:26 fros4943 Exp $ + * $Id: ContikiMoteTypeDialog.java,v 1.29 2007/05/18 13:47:13 fros4943 Exp $ */ package se.sics.cooja.contikimote; @@ -83,7 +83,8 @@ public class ContikiMoteTypeDialog extends JDialog { textCoreDir, textProjectDirs; private JButton createButton, testButton, rescanButton; private JCheckBox symbolsCheckBox; - + private JComboBox commStackComboBox; + private JPanel processPanel; // Holds process checkboxes private JPanel sensorPanel; // Holds sensor checkboxes private JPanel moteInterfacePanel; // Holds mote interface checkboxes @@ -228,6 +229,9 @@ public class ContikiMoteTypeDialog extends JDialog { myDialog.symbolsCheckBox.setSelected(true); } + // Set preset communication stack + myDialog.commStackComboBox.setSelectedItem(moteTypeToConfigure.getCommunicationStack()); + // Scan directories for processes, sensors and core interfaces // TODO Really do this without starting a separate thread? myDialog.updateVisualFields(); @@ -686,6 +690,25 @@ public class ContikiMoteTypeDialog extends JDialog { mainPane.add(new JSeparator()); mainPane.add(Box.createRigidArea(new Dimension(0, 5))); + // Communication stack + smallPane = new JPanel(); + smallPane.setAlignmentX(Component.LEFT_ALIGNMENT); + smallPane.setLayout(new BoxLayout(smallPane, BoxLayout.X_AXIS)); + label = new JLabel("Communication stack"); + + commStackComboBox = new JComboBox(new Object[] { + ContikiMoteType.CommunicationStack.UIP, + ContikiMoteType.CommunicationStack.RIME}); + commStackComboBox.setSelectedIndex(0); + + smallPane.add(label); + smallPane.add(Box.createHorizontalStrut(10)); + smallPane.add(Box.createHorizontalGlue()); + smallPane.add(commStackComboBox); + mainPane.add(smallPane); + + mainPane.add(Box.createRigidArea(new Dimension(0, 5))); + // Processes smallPane = new JPanel(); smallPane.setAlignmentX(Component.LEFT_ALIGNMENT); @@ -1113,6 +1136,7 @@ public class ContikiMoteTypeDialog extends JDialog { compilationSucceded = ContikiMoteTypeDialog.compileLibrary(identifier, contikiDir, compilationFiles, symbolsCheckBox.isSelected(), + (ContikiMoteType.CommunicationStack) commStackComboBox.getSelectedItem(), taskOutput.getInputStream(MessageList.NORMAL), taskOutput.getInputStream(MessageList.ERROR)); } @@ -1332,9 +1356,9 @@ public class ContikiMoteTypeDialog extends JDialog { * @return True if compilation succeded, false otherwise */ public static boolean compileLibrary(String identifier, File contikiDir, - Vector sourceFiles, boolean includeSymbols, final PrintStream outputStream, - final PrintStream errorStream) { - + Vector sourceFiles, boolean includeSymbols, + ContikiMoteType.CommunicationStack commStack, + final PrintStream outputStream, final PrintStream errorStream) { File libFile = new File(ContikiMoteType.tempOutputDirectory, identifier + ContikiMoteType.librarySuffix); File mapFile = new File(ContikiMoteType.tempOutputDirectory, @@ -1418,6 +1442,13 @@ public class ContikiMoteTypeDialog extends JDialog { } } + // Add communication stack source files + if (commStack == ContikiMoteType.CommunicationStack.UIP) { + sourceFileNames += " cooja-radio.c radio-uip.c init-net-uip.c"; + } else if (commStack == ContikiMoteType.CommunicationStack.RIME) { + sourceFileNames += " cooja-radio.c radio-rime.c init-net-rime.c"; + } + logger.info("-- Compiling --"); logger.info("Project dirs: " + sourceDirs); logger.info("Project sources: " + sourceFileNames); @@ -2116,6 +2147,10 @@ public class ContikiMoteTypeDialog extends JDialog { // Set "using symbols" myMoteType.setHasSystemSymbols(symbolsCheckBox.isSelected()); + // Set communication stack + myMoteType.setCommunicationStack( + (ContikiMoteType.CommunicationStack) commStackComboBox.getSelectedItem()); + dispose(); } else if (e.getActionCommand().equals("testsettings")) { testButton.requestFocus();