]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Merge commit 'release/2.1.1-4.4' into debian/2.1.1
authorR. Steve McKown <rsmckown@gmail.com>
Wed, 3 Nov 2010 20:35:46 +0000 (14:35 -0600)
committerR. Steve McKown <rsmckown@gmail.com>
Wed, 3 Nov 2010 20:35:46 +0000 (14:35 -0600)
17 files changed:
support/make/Makerules
tos/chips/msp430/adc12/Msp430Adc12.h
tos/chips/msp430/usci/Msp430UartP.nc
tos/chips/msp430/usci/Msp430Usci.h
tos/interfaces/ReadRefNow.nc [new file with mode: 0644]
tos/interfaces/Write.nc [new file with mode: 0644]
tos/interfaces/WriteNow.nc [new file with mode: 0644]
tos/platforms/olimexp169/PlatformSerialC.nc
tos/platforms/olimexp169/PlatformSerialP.nc [deleted file]
tos/platforms/olimexp169/PlatformUartC.nc [new file with mode: 0644]
tos/platforms/tmicore/MoteClockP.nc
tos/platforms/tmicore/PlatformSerialC.nc
tos/platforms/tmicore/PlatformUartC.nc [new file with mode: 0644]
tos/system/SharedArbiterC.nc [new file with mode: 0644]
tos/system/SharedArbiterP.nc [new file with mode: 0644]
tos/system/SharedSplitControlC.nc [new file with mode: 0644]
tos/system/SharedSplitControlP.nc [new file with mode: 0644]

index 6850fb1376b36c179da878bc4452a0f29c4eab1b..6c48f9a0522bdfc1c972d011912e5a3ffcb55a86 100644 (file)
@@ -49,9 +49,7 @@ TINYOS_MAKELOCAL ?= $(TINYOS_MAKE_PATH)/Makelocal
 TINYOS_MAKEDEFAULTS ?= $(TINYOS_MAKE_PATH)/Makedefaults
 
 #  Allow users to specify additional directories to find TOSMake files.
-TOSMAKE_TEMP_PATH := $(TOSMAKE_PATH)
-TOSMAKE_PATH = $(TINYOS_MAKE_PATH) 
-TOSMAKE_PATH += $(TOSMAKE_TEMP_PATH)
+TOSMAKE_PATH += $(TINYOS_MAKE_PATH)
 
 #  Save makecmdgoals (a read only var) to goals so that we can modify it.
 GOALS += $(MAKECMDGOALS)
index 6e6854e8850ef04fb08f747a0243c6b900d7e80a..6cbce0175d4ca765e5d182e682a62070178f6b06 100644 (file)
@@ -164,15 +164,19 @@ enum sampcon_id_enum
 // The unique string for accessing HAL2 via ReadStream
 #define ADCC_READ_STREAM_SERVICE "AdcC.ReadStream.Client"
 
-/* Test for GCC bug (bitfield access) - only version 3.2.3 is known to be stable */
+/* Test for GCC bug (bitfield access) - versions 3.2.3 and 4.4.3 are known to
+ * be stable
+ */
 // TODO: check whether this is still relevant...
 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__)
 #if GCC_VERSION == 332
 #error "The msp430-gcc version (3.3.2) contains a bug which results in false accessing \
 of bitfields in structs and makes MSP430ADC12M.nc fail ! Use version 3.2.3 instead."
 #elif GCC_VERSION != 323
+#if GCC_VERSION < 443
 #warning "This version of msp430-gcc might contain a bug which results in false accessing \
 of bitfields in structs (MSP430ADC12M.nc would fail). Use version 3.2.3 instead."
+#endif
 #endif  
 
 #ifndef __msp430_have_adc12
index 72df1df0c1827f63ef14f7836a5927aaa43b3828..605c426960f5d926d10670ec8582a70dc76383f6 100644 (file)
@@ -55,7 +55,7 @@ generic module Msp430UartP() {
 implementation {
   enum {
     /* Bit positions in m_pins */
-    PINS_RXD = 1,
+    PINS_RXD = 0,
     PINS_TXD
   };
 
@@ -104,12 +104,20 @@ implementation {
        call TXD.selectModuleFunc();
       }
 
+      /* Reset important state variables */
+      m_robuf = 0;
+      m_sobuf = 0;
+
       /* Clear interrupts; we'll add them as needed */
       call Registers.clrIeRx();
       call Registers.clrIeTx();
 
       /* Enable the device */
       call Registers.clrCtl1(UCSWRST);
+
+      /* TOS convention is for receive interrupts on by default. */
+      call Registers.clrIfgRx();
+      call Registers.setIeRx();
     }
   }
 
@@ -124,10 +132,14 @@ implementation {
       call Registers.clrIeTx();
       call Registers.clrIfgRx();
 
+      /* Reset important state variables */
+      m_robuf = 0;
+      m_sobuf = 0;
+
       /* Restore pins to their pre-configure state */
-      if (m_pins & PINS_RXD)
+      if (m_pins & (1 << PINS_RXD))
        call RXD.selectIOFunc();
-      if (m_pins & PINS_TXD)
+      if (m_pins & (1 << PINS_TXD))
        call TXD.selectIOFunc();
     }
   }
@@ -158,16 +170,18 @@ implementation {
     /* FIXME: this can cause an arbitrarily long ISR, if m_slen is large.
      * But depending on timing, we may always only write 1 byte.
      */
-    while (!call Registers.getIfgTx()); /* in case interleaved UB.send */
-    while (m_slen && call Registers.getIfgTx()) {
-      call Registers.setTxbuf(*m_sbuf);
-      if (--m_slen)
-       m_sbuf++;
-    }
-    if (m_slen == 0) {
-      call Registers.clrIeTx();
-      m_sobuf = 0;
-      signal UartStream.sendDone(m_sobuf, m_solen, SUCCESS);
+    if (m_sobuf) {
+      while (!call Registers.getIfgTx()); /* in case interleaved UB.send */
+      while (m_slen && call Registers.getIfgTx()) {
+       call Registers.setTxbuf(*m_sbuf);
+       if (--m_slen)
+         m_sbuf++;
+      }
+      if (m_slen == 0) {
+       call Registers.clrIeTx();
+       m_sobuf = 0;
+       signal UartStream.sendDone(m_sobuf, m_solen, SUCCESS);
+      }
     }
   }
 
index 88e4c90198b48e7470c6ea56f09d2cc6d503dfdb..31ba96ae37ece6023b3c55bd7208a5d9077d5904 100644 (file)
@@ -101,8 +101,9 @@ typedef enum {
   UBRX_1MHZ_19200=54, UMCTL_1MHZ_19200=(0 << 4) + (5 << 1) + 0,
   UBRX_1MHZ_38400=27, UMCTL_1MHZ_38400=(0 << 4) + (2 << 1) + 0,
   UBRX_1MHZ_115200=9, UMCTL_1MHZ_115200=(0 << 4) + (1 << 1) + 0,
-  UBRX_1E6MHZ_9600=104, UMCTL_1E6MHZ_9600=(0 << 4) + (1 << 1) + 0,
-  UBRX_1E6MHZ_115200=8, UMCTL_1E6MHZ_115200=(0 << 4) + (6 << 1) + 0,
+  UBRX_1E6HZ_9600=104, UMCTL_1E6HZ_9600=(0 << 4) + (1 << 1) + 0,
+  UBRX_1E6HZ_19200=52, UMCTL_1E6HZ_19200=(0 << 4) + (0 << 1) + 0,
+  UBRX_1E6HZ_115200=8, UMCTL_1E6HZ_115200=(0 << 4) + (6 << 1) + 0,
 } msp430_usci_uart_rate_t;
 
 typedef struct {
diff --git a/tos/interfaces/ReadRefNow.nc b/tos/interfaces/ReadRefNow.nc
new file mode 100644 (file)
index 0000000..75215ed
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2005 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - 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.
+ * - Neither the name of the Arch Rock Corporation 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 COPYRIGHT HOLDERS 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
+ * ARCHED ROCK OR ITS 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
+ *
+ */
+
+/**
+ * The ReadRef interface is intended for split-phase low-rate or
+ * high-latency reading of large values. The type of the value is
+ * given as a template argument. When a value is too large to be
+ * comfortably passed on the stack, the caller should allocate space
+ * for the value and pass the pointer to read(). When the readDone()
+ * comes back, the space will be filled with the new value.
+ *
+ * <p>
+ * This interface has the same calling semantics as the Read interface
+ * described in TEP 114, except that it is async.
+ * 
+ * See TEP114 - SIDs: Source and Sink Independent Drivers for details.
+ * 
+ * @param val_t the type of the object that will be returned
+ *
+ * @author Gilman Tolle <gtolle@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+interface ReadRefNow<val_t> {
+  /**
+   * Initiates a read of the value.
+   * 
+   * @param 'val_t* ONE val' a pointer to space that will be filled by the value
+   *
+   * @return SUCCESS if a readDone() event will eventually come back.
+   */
+  async command error_t read( val_t* val );
+  
+  /**
+   * Signals the completion of the read(). The returned pointer will
+   * be the same as the original pointer passed to read().
+   *
+   * @param result SUCCESS if the read() was successful
+   * @param 'val_t* ONE val' a pointer to the value that has been read
+   */
+  async event void readDone( error_t result, val_t* val );
+}
diff --git a/tos/interfaces/Write.nc b/tos/interfaces/Write.nc
new file mode 100644 (file)
index 0000000..d46948e
--- /dev/null
@@ -0,0 +1,39 @@
+/* Copyright (c) 2006-2010 by Sporian Microsystems, Inc.
+ * All Rights Reserved.
+ *
+ * This document is the proprietary and confidential property of Sporian
+ * Microsystems, Inc.  All use, distribution, reproduction or re-distribution
+ * is disallowed without the prior express written consent of Sporian
+ * Microsystems, Inc.
+ */
+
+/**
+ * The Write interface is intended for split-phase low-rate or
+ * high-latency writing of small values. The type of the value is
+ * given as a template argument. Because this interface is
+ * split-phase, these values may be backed by hardware, or a
+ * long-running computation.  This interface is the output analog
+ * of the standard Read interface.
+ *
+ * @param val_t the type of the object that will be written
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+
+interface Write<val_t> {
+  /**
+   * Initiate a write of the provided value.
+   *
+   * @param val The value to write.
+   * @return SUCCESS if <code>writeDone()</code> will later be signalled,
+   * EBUSY if a write is already in progress, or FAIL for other errors.
+   */
+  command error_t write(val_t val);
+
+  /**
+   * Signalled upon completion of the write operation initiated by the previous
+   * <code>write()</code> command.
+   */
+  event void writeDone(error_t error);
+}
diff --git a/tos/interfaces/WriteNow.nc b/tos/interfaces/WriteNow.nc
new file mode 100644 (file)
index 0000000..caaadff
--- /dev/null
@@ -0,0 +1,42 @@
+/* Copyright (c) 2006-2010 by Sporian Microsystems, Inc.
+ * All Rights Reserved.
+ *
+ * This document is the proprietary and confidential property of Sporian
+ * Microsystems, Inc.  All use, distribution, reproduction or re-distribution
+ * is disallowed without the prior express written consent of Sporian
+ * Microsystems, Inc.
+ */
+
+/**
+ * The Write interface is intended for split-phase low-rate or
+ * high-latency writing of small values. The type of the value is
+ * given as a template argument. Because this interface is
+ * split-phase, these values may be backed by hardware, or a
+ * long-running computation.  This interface is the output analog
+ * of the standard Read interface.
+ *
+ * This interface is equivalent to the Write interface, except that its
+ * operations are defined async.
+ *
+ * @param val_t the type of the object that will be written
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+
+interface WriteNow<val_t> {
+  /**
+   * Initiate a write of the provided value.
+   *
+   * @param val The value to write.
+   * @return SUCCESS if <code>writeDone()</code> will later be signalled,
+   * EBUSY if a write is already in progress, or FAIL for other errors.
+   */
+  async command error_t write(val_t val);
+
+  /**
+   * Signalled upon completion of the write operation initiated by the previous
+   * <code>write()</code> command.
+   */
+  async event void writeDone(error_t error);
+}
index 58d28330083586e2ac7d263667ce1c91807d8fd2..1acf9fac9bccb2d62c83e91414dadca96be92562 100644 (file)
@@ -9,13 +9,11 @@ configuration PlatformSerialC {
 
 implementation {
 
-  components new Msp430Uart0C() as UartC;
+  components PlatformUartC as UartC;
   UartStream = UartC;
   UartByte = UartC;
 
   components TelosSerialP;
   StdControl = TelosSerialP;
-  TelosSerialP.Msp430UartConfigure <- UartC.Msp430UartConfigure;
-  TelosSerialP.Resource -> UartC.Resource;
 
 }
diff --git a/tos/platforms/olimexp169/PlatformSerialP.nc b/tos/platforms/olimexp169/PlatformSerialP.nc
deleted file mode 100644 (file)
index 034547d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2008, Titanium Mirror, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- *   this list of conditions and the following disclaimer.
- * - 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.
- * - Neither the name of the Technische Universität Berlin 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 COPYRIGHT HOLDERS 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 COPYRIGHT
- * OWNER 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.
- */
-
- /**
- * @author R. Steve McKown <rsmckown@gmail.com>
- */
-
-module PlatformSerialP {
-  provides interface StdControl;
-  uses interface Resource;
-}
-implementation {
-  command error_t StdControl.start()
-  {
-    return call Resource.immediateRequest();
-  }
-
-  command error_t StdControl.stop()
-  {
-    call Resource.release();
-    return SUCCESS;
-  }
-
-  event void Resource.granted() {}
-}
diff --git a/tos/platforms/olimexp169/PlatformUartC.nc b/tos/platforms/olimexp169/PlatformUartC.nc
new file mode 100644 (file)
index 0000000..bc06f1f
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2008-2010, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - 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.
+ * - Neither the name of the Technische Universität Berlin 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ */
+
+ /**
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+configuration PlatformUartC {
+  provides {
+    interface Resource;
+    interface UartStream;
+    interface UartByte;
+  }
+}
+implementation {
+  components new Msp430Uart0C() as UartC;
+  Resource = UartC;
+  UartStream = UartC;
+  UartByte = UartC;
+
+  components TelosSerialP;
+  TelosSerialP.Msp430UartConfigure <- UartC.Msp430UartConfigure;
+  TelosSerialP.Resource -> UartC.Resource;
+
+}
index ca169f2758f1ec079134cef2b355f1377dd0c402..a9a976845eedbcf3838f14c2b3d5d9023d6a3f98 100644 (file)
@@ -41,7 +41,7 @@ module MoteClockP {
 implementation {
   command error_t Init.init()
   {
-    uint16_t i;
+    volatile uint16_t i;
 
 #if defined (CALDCO_8MHZ_) && !defined(__DisableCalData)
     if (CALBC1_8MHZ != 0xff || CALDCO_8MHZ != 0xff) {
index 28f4354ed1c17757958ed94c222b22a6bbd38567..a32ffa043c1c5957b74b39f2e8a7a6e1389eb49e 100644 (file)
@@ -37,16 +37,11 @@ configuration PlatformSerialC {
   provides interface UartByte;
 }
 implementation {
-  components new Msp430UartA1C() as UartC;
+  components PlatformUartC as UartC;
   UartStream = UartC;
   UartByte = UartC;
 
   components PlatformSerialP;
   StdControl = PlatformSerialP;
   PlatformSerialP.Resource -> UartC;
-
-#if 0 /* If you want to change the configuration... */
-  components SomeConfigurationComponentC as ConfigC;
-  UartC.AsyncConfigure -> ConfigC;
-#endif
 }
diff --git a/tos/platforms/tmicore/PlatformUartC.nc b/tos/platforms/tmicore/PlatformUartC.nc
new file mode 100644 (file)
index 0000000..10a7cec
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2008-2010, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - 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.
+ * - Neither the name of the Technische Universität Berlin 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ */
+
+ /**
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+configuration PlatformUartC {
+  provides {
+    interface Resource;
+    interface UartStream;
+    interface UartByte;
+  }
+}
+implementation {
+  components new Msp430UartA1C() as UartC;
+  Resource = UartC;
+  UartStream = UartC;
+  UartByte = UartC;
+
+#if 0 /* If you want to change the Uart's configuration... */
+  components SomeConfigurationComponentC as ConfigC;
+  UartC.AsyncConfigure -> ConfigC;
+#endif
+}
diff --git a/tos/system/SharedArbiterC.nc b/tos/system/SharedArbiterC.nc
new file mode 100644 (file)
index 0000000..1949978
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - 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.
+ * - Neither the name of the Technische Universität Berlin 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ */
+
+/**
+ * A shared arbiter that allows 1...N clients to acquire the resource
+ * simultaneously, with the intention of returning control to the default
+ * owner upon release by all clients.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+generic configuration SharedArbiterC(char resourceName[]) {
+  provides {
+    interface Resource[uint8_t id];
+    interface ResourceDefaultOwner;
+    interface ArbiterInfo;
+  }
+}
+implementation {
+  enum { CLIENTS = uniqueCount(resourceName) };
+
+  components new SharedArbiterP();
+  Resource = SharedArbiterP;
+  ResourceDefaultOwner = SharedArbiterP;
+  ArbiterInfo = SharedArbiterP;
+
+  components new BitVectorC(CLIENTS) as GrantedVectorC;
+  SharedArbiterP.GrantedVector -> GrantedVectorC;
+
+  components new BitVectorC(CLIENTS) as RequestingVectorC;
+  SharedArbiterP.RequestingVector -> RequestingVectorC;
+
+  components new StateC();
+  SharedArbiterP.State -> StateC;
+}
diff --git a/tos/system/SharedArbiterP.nc b/tos/system/SharedArbiterP.nc
new file mode 100644 (file)
index 0000000..b912fa1
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2010, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - 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.
+ * - Neither the name of the Technische Universität Berlin 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ */
+
+/**
+ * A shared arbiter that allows 1...N clients to acquire the resource
+ * simultaneously.  The purpose of this arbiter to allow access to a shared,
+ * switched subsystem.  For example, a communications bus that can handle IO
+ * for multiple clients simultaneously, but is powered down when not in use.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+generic module SharedArbiterP() {
+  provides {
+    interface Resource[uint8_t id];
+    interface ResourceDefaultOwner;
+    interface ArbiterInfo;
+  }
+  uses {
+    interface BitVector as GrantedVector;
+    interface BitVector as RequestingVector;
+    interface State;
+  }
+}
+implementation {
+  enum {
+    S_IDLE = 0,                /* Resource is not in use; owned by default owner */
+    S_REQUESTING,      /* Requesting the resource from the default owner */
+    S_IMMREQUESTING,   /* Immediate resource request from the default owner */
+    S_GRANTED,         /* One or more clients have been granted the resource */
+
+    NO_CLIENT = 0xff,
+  };
+
+  uint8_t m_granted;   /* Count of clients granted the resource */
+  uint8_t m_requesting;        /* Count of clients requesting the resource */
+
+  uint8_t addRequesting(uint8_t id)
+  {
+    atomic {
+      call RequestingVector.set(id);
+      return ++m_requesting;
+    }
+  }
+
+  uint8_t rmRequesting(uint8_t id)
+  {
+    atomic {
+      call RequestingVector.clear(id);
+      return --m_requesting;
+    }
+  }
+
+  uint8_t addGranted(uint8_t id)
+  {
+    atomic {
+      call GrantedVector.set(id);
+      return ++m_granted;
+    }
+  }
+
+  uint8_t rmGranted(uint8_t id)
+  {
+    atomic {
+      call GrantedVector.clear(id);
+      return --m_granted;
+    }
+  }
+
+  task void grantedTask()
+  {
+    unsigned id;
+
+    atomic {
+      if (m_requesting == 0)
+       return;
+    }
+
+    for (id = 0; id < call RequestingVector.size(); id++) {
+      bool grant = FALSE;
+
+      atomic {
+       if (call RequestingVector.get(id)) {
+         rmRequesting(id);
+         addGranted(id);
+         grant = TRUE;
+       }
+      }
+      if (grant)
+       signal Resource.granted[id]();
+    }
+  }
+
+  async command error_t Resource.request[uint8_t id]()
+  {
+    /* The Resource docs do not say what happens when a user calls
+     * Resource.request() after the resource has already been granted.  We
+     * elect to call EBUSY, as if the request was still in process.
+     */
+    if (call RequestingVector.get(id) || call GrantedVector.get(id))
+      return EBUSY;
+
+    addRequesting(id);
+    if (call State.requestState(S_REQUESTING) == SUCCESS)
+      signal ResourceDefaultOwner.requested();
+    else if (call State.isState(S_GRANTED))
+      post grantedTask();
+    return SUCCESS;
+  }
+
+  async command error_t Resource.immediateRequest[uint8_t id]()
+  {
+    /* The Resource docs do not say what happens when a user calls
+     * Resource.request() after the resource has already been granted.  We
+     * elect to call EBUSY, as if the request was still in process.
+     */
+    if (call RequestingVector.get(id) || call GrantedVector.get(id))
+      return EBUSY;
+
+    if (call State.requestState(S_IMMREQUESTING) == SUCCESS) {
+      signal ResourceDefaultOwner.immediateRequested();
+      if (call State.isState(S_IMMREQUESTING))
+       call State.toIdle();
+    }
+    if (call State.isState(S_GRANTED)) {
+      addGranted(id);
+      return SUCCESS;
+    }
+    return FAIL;
+  }
+
+  async command error_t Resource.release[uint8_t id]()
+  {
+    if (!call GrantedVector.get(id))
+      return FAIL;
+
+    if (rmGranted(id) == 0) {
+      call State.toIdle();
+      signal ResourceDefaultOwner.granted();
+    }
+    return SUCCESS;
+  }
+
+  async command error_t ResourceDefaultOwner.release()
+  {
+    if (call State.isState(S_REQUESTING)) {
+      call State.forceState(S_GRANTED);
+      post grantedTask();
+      return SUCCESS;
+    } else if (call State.isState(S_IMMREQUESTING)) {
+      call State.forceState(S_GRANTED);
+      return SUCCESS;
+    } else
+      return FAIL;
+  }
+
+  async command bool ArbiterInfo.inUse()
+  {
+    atomic {
+      if (m_granted)
+        return TRUE;
+    }
+    return FALSE;
+  }
+
+  /* The ArbiterInfo interface doesn't work so well for a shared resource, as
+   * 1+ users may hold the resource at any time.
+   */
+  async command uint8_t ArbiterInfo.userId()
+  {
+    atomic {
+      if (m_granted)
+        return 1;
+    }
+    return NO_CLIENT;
+  }
+
+  async command uint8_t Resource.isOwner[uint8_t id]()
+  {
+    atomic return call GrantedVector.get(id);
+  }
+
+  async command uint8_t ResourceDefaultOwner.isOwner()
+  {
+    atomic return !(call State.isState(S_GRANTED));
+  }
+
+  default event void Resource.granted[uint8_t id]() {}
+  default async event void ResourceDefaultOwner.granted() {}
+  default async event void ResourceDefaultOwner.requested()
+  {
+    call ResourceDefaultOwner.release();
+  }
+  default async event void ResourceDefaultOwner.immediateRequested()
+  {
+    call ResourceDefaultOwner.release();
+  }
+}
diff --git a/tos/system/SharedSplitControlC.nc b/tos/system/SharedSplitControlC.nc
new file mode 100644 (file)
index 0000000..a525476
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - 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.
+ * - Neither the name of the Technische Universität Berlin 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ */
+
+/**
+ * Allows multiple clients, who all need to have some underlying component
+ * started, to share the control of a SplitControl (MasterControl) interface.
+ * Any client successfully starting with SplitControl.start() / startDone()
+ * means the MasterControl state is on/started.  That state is retained until
+ * the last client successfully completes SplitControl.stop() / stopDone(),
+ * at which time the MasterControl state will be off/stopped.
+ *
+ * @param p_deferStopTime is the number of mibbiseconds the implementation
+ * waits after all clients have completed stop operations before the device
+ * wired to MasterControl is actually stopped.  Ths allows implementations to
+ * control 'flapping' of the state of the underlying device.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+generic configuration SharedSplitControlC(char resourceName[],
+    uint16_t p_deferStopTime) {
+  provides interface SplitControl[uint8_t id];
+  uses interface SplitControl as MasterControl;
+}
+implementation {
+  enum { CLIENTS = uniqueCount(resourceName) };
+
+  components new SharedSplitControlP(CLIENTS, p_deferStopTime);
+  SplitControl = SharedSplitControlP;
+  MasterControl = SharedSplitControlP;
+
+  components MainC;
+  MainC.SoftwareInit -> SharedSplitControlP;
+
+  components new TimerMilliC();
+  SharedSplitControlP.Timer -> TimerMilliC;
+
+  components new StateC();
+  SharedSplitControlP.State -> StateC;
+}
diff --git a/tos/system/SharedSplitControlP.nc b/tos/system/SharedSplitControlP.nc
new file mode 100644 (file)
index 0000000..a4cc7ce
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2010, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - 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.
+ * - Neither the name of the Technische Universität Berlin 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ */
+
+/**
+ * Allows multiple clients, who all need to have some underlying component
+ * started, to share the control of a SplitControl (MasterControl) interface.
+ * Any client successfully starting with SplitControl.start() / startDone()
+ * means the MasterControl state is on/started.  That state is retained until
+ * the last client successfully completes SplitControl.stop() / stopDone(),
+ * at which time the MasterControl state will be off/stopped.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+generic module SharedSplitControlP(uint8_t p_clients,
+    uint16_t p_deferStopTime) {
+  provides {
+    interface Init;
+    interface SplitControl[uint8_t id];
+  }
+  uses {
+    interface SplitControl as MasterControl;
+    interface Timer<TMilli>;
+    interface State;
+  }
+}
+implementation {
+  enum {
+    /* MasterControl states */
+    S_IDLE = 0,
+    S_START,
+    S_ON,
+    S_STOPWAIT,
+    S_STOP,
+
+    /* S_STOPWAIT is special, for the master only.  After all clients have
+     * stopped, the master could be stopped.  But, we leave it on in the
+     * S_STOPWAIT state for a little bit before actually stopping it, so that
+     * we can reduce start/stop thrashing in our application.  This behavior
+     * is controlled by the p_deferStopTime parameter.
+     */
+  };
+
+  uint8_t m_state[p_clients];
+
+  command error_t Init.init()
+  {
+    return SUCCESS;
+  }
+
+  task void signalStarts()
+  {
+    unsigned id;
+
+    for (id = 0; id < p_clients; id++) {
+      if (m_state[id] == S_START) {
+       m_state[id] = S_ON;
+       signal SplitControl.startDone[id](SUCCESS);
+      }
+    }
+  }
+
+  command error_t SplitControl.start[uint8_t id]()
+  {
+    error_t error;
+
+    if (id >= p_clients)
+      return FAIL;
+
+    switch (m_state[id]) {
+      case S_IDLE:
+       switch (call State.getState()) {
+         case S_IDLE:
+           error = call MasterControl.start();
+           if (error == SUCCESS) {
+             call State.forceState(S_START);
+             m_state[id] = S_START;
+           }
+           return error;
+           break;
+         case S_START:
+           m_state[id] = S_START;
+           return SUCCESS;
+           break;
+         case S_STOPWAIT:
+           call Timer.stop();
+           call State.forceState(S_ON);
+           /* fall through */
+         case S_ON:
+           m_state[id] = S_START;
+           post signalStarts();
+           return SUCCESS;
+           break;
+         case S_STOP:
+           /* Master will restart as soon as its stop is done */
+           m_state[id] = S_START;
+           return SUCCESS;
+           break;
+         default:
+           /* Should never get here */
+           return FAIL;
+       }
+       break;
+      case S_START:
+       return SUCCESS;
+       break;
+      case S_ON:
+       return EALREADY;
+       break;
+      case S_STOP:
+      default:
+       return EBUSY;
+       break;
+    }
+  }
+
+  event void MasterControl.startDone(error_t error)
+  {
+    unsigned id;
+    unsigned newState = (error == SUCCESS) ? S_ON : S_IDLE;
+
+    /* Master is starting, implying >= 1 client starting and all others are off.
+     * Master and all starting clients transition to the on state if the start
+     * was successful, or fall back to the idle (off) state if not.
+     */
+    call State.forceState(newState);
+    for (id = 0; id < p_clients; id++) {
+      if (m_state[id] == S_START) {
+       m_state[id] = newState;
+       signal SplitControl.startDone[id](error);
+      }
+    }
+  }
+
+  task void signalStops()
+  {
+    unsigned id;
+    bool allOff = TRUE;
+
+    for (id = 0; id < p_clients; id++) {
+      if (m_state[id] == S_STOP) {
+       m_state[id] = S_IDLE;
+       signal SplitControl.stopDone[id](SUCCESS);
+      } else if (m_state[id] != S_IDLE)
+       allOff = FALSE;
+    }
+    if (allOff) {
+      /* All clients are off.  We can stop the master, but we might wait a bit
+       * before stopping the master.
+       */
+      if (p_deferStopTime) {
+       call State.forceState(S_STOPWAIT);
+       call Timer.startOneShot(p_deferStopTime);
+      } else {
+       if (call MasterControl.stop() == SUCCESS)
+         call State.forceState(S_STOP);
+      }
+    }
+  }
+
+  command error_t SplitControl.stop[uint8_t id]()
+  {
+    if (id >= p_clients)
+      return FAIL;
+
+    switch (m_state[id]) {
+      case S_IDLE:
+       return EALREADY;
+       break;
+      case S_ON:
+       switch (call State.getState()) {
+         case S_ON:
+           /* fall through */
+         case S_STOPWAIT:
+         case S_IDLE:
+           /* Invalid condition.  If the master is off, then all clients
+            * should also be off.  Go ahead signal the client to stop.
+            */
+           m_state[id] = S_STOP;
+           post signalStops();
+           return SUCCESS;
+           break;
+         case S_START:
+         case S_STOP:
+         default:
+           /* Invalid condition.  For the master to be starting, all clients
+            * must either be off or starting.  For the master to be stopping,
+            * no client can be on.  We can generally correct this invalid
+            * condition by setting the client to S_STOP and dealing with it
+            * in MasterControl.startDone() or stopDone() (respectively).
+            */
+           m_state[id] = S_STOP;
+           return SUCCESS;
+           break;
+       }
+       break;
+      case S_STOP:
+       return SUCCESS;
+       break;
+      case S_START:
+      default:
+       return EBUSY;
+       break;
+    }
+    /* If we get here, we had an invalid state combination */
+  }
+
+  event void Timer.fired()
+  {
+    error_t error = call MasterControl.stop();
+
+    if (error == SUCCESS)
+      call State.forceState(S_STOP);
+    else {
+      unsigned id;
+
+      /* If we failed to start, we need to signal any starting clients */
+      for (id = 0; id < p_clients; id++) {
+       if (m_state[id] == S_START) {
+         m_state[id] = S_ON;
+         signal SplitControl.startDone[id](SUCCESS);
+       }
+      }
+    }
+  }
+
+  event void MasterControl.stopDone(error_t error)
+  {
+    unsigned id;
+    unsigned newState = (error == SUCCESS) ? S_IDLE : S_ON;
+    bool starts = FALSE;
+
+    /* Master is stopping, implying >= 1 client stopping.  Other clients may
+     * be in any other state.  Master and all stopping clients transition to
+     * the off state if the start was successful, or fall back to the on state
+     * if not.
+     */
+    call State.forceState(newState);
+    for (id = 0; id < p_clients; id++) {
+      if (m_state[id] == S_STOP) {
+       m_state[id] = newState;
+       signal SplitControl.stopDone[id](error);
+      } else if (m_state[id] == S_START)
+       starts = TRUE;
+    }
+
+    /* While the master was stopping, some clients that were off may have
+     * issued a start.  It is possible that we need to start the master again.
+     * If the master start() fails, all clients in start get kicked back to
+     * off, in error.
+     */
+    if (starts) {
+      error = call MasterControl.start();
+
+      if (error == SUCCESS)
+       call State.forceState(S_START);
+      else {
+       for (id = 0; id < p_clients; id++) {
+         if (m_state[id] == S_START) {
+           m_state[id] = S_IDLE;
+           signal SplitControl.startDone[id](error);
+         }
+       }
+      }
+    }
+  }
+
+  default event void SplitControl.startDone[uint8_t id](error_t error) {}
+  default event void SplitControl.stopDone[uint8_t id](error_t error) {}
+}