From 3188988ea201dff64052bce372c6cc5032fdb823 Mon Sep 17 00:00:00 2001 From: razvanm Date: Wed, 16 Sep 2009 00:51:50 +0000 Subject: [PATCH] Big commit of the default lpl. These changes deprecate TEP105. --- apps/tests/TestNetwork/TestNetworkAppC.nc | 4 +- apps/tests/TestNetwork/TestNetworkC.nc | 10 +- tos/chips/cc2420/CC2420.h | 11 ++ tos/chips/cc2420/lpl/DefaultLplC.nc | 3 +- tos/chips/cc2420/lpl/DefaultLplP.nc | 141 +++--------------- tos/chips/cc2420/lpl/DummyLplP.nc | 32 +--- tos/chips/cc2420/lpl/PowerCycleC.nc | 1 - tos/chips/cc2420/lpl/PowerCycleP.nc | 3 +- .../rf2xx/layers/LowPowerListeningDummyP.nc | 20 +-- .../rf2xx/layers/LowPowerListeningLayerC.nc | 2 + .../rf2xx/layers/LowPowerListeningLayerP.nc | 68 ++------- tos/interfaces/LowPowerListening.nc | 96 +++--------- tos/interfaces/SystemLowPowerListening.nc | 8 + tos/platforms/micaz/ActiveMessageC.nc | 8 +- tos/platforms/telosa/ActiveMessageC.nc | 2 + tos/system/AMSenderC.nc | 19 +-- tos/system/DirectAMSenderC.nc | 59 ++++++++ tos/system/LplAMSenderC.nc | 28 ++++ tos/system/LplAMSenderP.nc | 23 +++ tos/system/SystemLowPowerListeningC.nc | 10 ++ tos/system/SystemLowPowerListeningP.nc | 16 ++ 21 files changed, 239 insertions(+), 325 deletions(-) create mode 100644 tos/interfaces/SystemLowPowerListening.nc create mode 100644 tos/system/DirectAMSenderC.nc create mode 100644 tos/system/LplAMSenderC.nc create mode 100644 tos/system/LplAMSenderP.nc create mode 100644 tos/system/SystemLowPowerListeningC.nc create mode 100644 tos/system/SystemLowPowerListeningP.nc diff --git a/apps/tests/TestNetwork/TestNetworkAppC.nc b/apps/tests/TestNetwork/TestNetworkAppC.nc index b64adf2d..337b8d2e 100644 --- a/apps/tests/TestNetwork/TestNetworkAppC.nc +++ b/apps/tests/TestNetwork/TestNetworkAppC.nc @@ -17,7 +17,7 @@ configuration TestNetworkAppC {} implementation { components TestNetworkC, MainC, LedsC, ActiveMessageC; components DisseminationC; - components new DisseminatorC(uint16_t, SAMPLE_RATE_KEY) as Object16C; + components new DisseminatorC(uint32_t, SAMPLE_RATE_KEY) as Object32C; components CollectionC as Collector; components new CollectionSenderC(CL_TEST); components new TimerMilliC(); @@ -39,7 +39,7 @@ implementation { TestNetworkC.DisseminationControl -> DisseminationC; TestNetworkC.Leds -> LedsC; TestNetworkC.Timer -> TimerMilliC; - TestNetworkC.DisseminationPeriod -> Object16C; + TestNetworkC.DisseminationPeriod -> Object32C; TestNetworkC.Send -> CollectionSenderC; TestNetworkC.ReadSensor -> DemoSensorC; TestNetworkC.RootControl -> Collector; diff --git a/apps/tests/TestNetwork/TestNetworkC.nc b/apps/tests/TestNetwork/TestNetworkC.nc index 28e248f0..7e727824 100644 --- a/apps/tests/TestNetwork/TestNetworkC.nc +++ b/apps/tests/TestNetwork/TestNetworkC.nc @@ -20,7 +20,7 @@ module TestNetworkC { uses interface SplitControl as SerialControl; uses interface StdControl as RoutingControl; uses interface StdControl as DisseminationControl; - uses interface DisseminationValue as DisseminationPeriod; + uses interface DisseminationValue as DisseminationPeriod; uses interface Send; uses interface Leds; uses interface Read as ReadSensor; @@ -87,7 +87,7 @@ implementation { void sendMessage() { TestNetworkMsg* msg = (TestNetworkMsg*)call Send.getPayload(&packet, sizeof(TestNetworkMsg)); uint16_t metric; - am_addr_t parent; + am_addr_t parent = 0; call CtpInfo.getParent(&parent); call CtpInfo.getEtx(&metric); @@ -113,10 +113,10 @@ implementation { event void Timer.fired() { - uint16_t nextInt; + uint32_t nextInt; call Leds.led0Toggle(); dbg("TestNetworkC", "TestNetworkC: Timer fired.\n"); - nextInt = call Random.rand16() % SEND_INTERVAL; + nextInt = call Random.rand32() % SEND_INTERVAL; nextInt += SEND_INTERVAL >> 1; call Timer.startOneShot(nextInt); if (!sendBusy) @@ -132,7 +132,7 @@ implementation { } event void DisseminationPeriod.changed() { - const uint16_t* newVal = call DisseminationPeriod.get(); + const uint32_t* newVal = call DisseminationPeriod.get(); call Timer.stop(); call Timer.startPeriodic(*newVal); } diff --git a/tos/chips/cc2420/CC2420.h b/tos/chips/cc2420/CC2420.h index 91138798..a350b5b6 100644 --- a/tos/chips/cc2420/CC2420.h +++ b/tos/chips/cc2420/CC2420.h @@ -183,6 +183,17 @@ typedef nx_struct cc2420_packet_t { #define TINYOS_6LOWPAN_NETWORK_ID 0x3f #endif +/** + * The LPL defaults to stay-on. + */ +#ifndef LPL_DEF_LOCAL_WAKEUP +#define LPL_DEF_LOCAL_WAKEUP 0 +#endif + +#ifndef LPL_DEF_REMOTE_WAKEUP +#define LPL_DEF_REMOTE_WAKEUP 0 +#endif + enum { // size of the header not including the length byte MAC_HEADER_SIZE = sizeof( cc2420_header_t ) - 1, diff --git a/tos/chips/cc2420/lpl/DefaultLplC.nc b/tos/chips/cc2420/lpl/DefaultLplC.nc index 2d80b9f3..b18b08a5 100644 --- a/tos/chips/cc2420/lpl/DefaultLplC.nc +++ b/tos/chips/cc2420/lpl/DefaultLplC.nc @@ -66,6 +66,7 @@ implementation { new StateC() as SendStateC, new TimerMilliC() as OffTimerC, new TimerMilliC() as SendDoneTimerC, + SystemLowPowerListeningC, LedsC; LowPowerListening = DefaultLplP; @@ -94,5 +95,5 @@ implementation { DefaultLplP.RadioBackoff -> CC2420CsmaC; DefaultLplP.Random -> RandomC; DefaultLplP.Leds -> LedsC; - + DefaultLplP.SystemLowPowerListening -> SystemLowPowerListeningC; } diff --git a/tos/chips/cc2420/lpl/DefaultLplP.nc b/tos/chips/cc2420/lpl/DefaultLplP.nc index a1cf07cf..7398f3c9 100644 --- a/tos/chips/cc2420/lpl/DefaultLplP.nc +++ b/tos/chips/cc2420/lpl/DefaultLplP.nc @@ -67,6 +67,7 @@ module DefaultLplP { interface Timer as SendDoneTimer; interface Random; interface Leds; + interface SystemLowPowerListening; } } @@ -111,7 +112,6 @@ implementation { void initializeSend(); void startOffTimer(); - uint16_t getActualDutyCycle(uint16_t dutyCycle); /***************** Init Commands ***************/ command error_t Init.init() { @@ -121,134 +121,42 @@ implementation { /***************** LowPowerListening Commands ***************/ /** - * Set this this node's radio sleep interval, in milliseconds. + * Set this this node's radio wakeup interval, in milliseconds. * Once every interval, the node will sleep and perform an Rx check - * on the radio. Setting the sleep interval to 0 will keep the radio + * on the radio. Setting the wakeup interval to 0 will keep the radio * always on. * - * This is the equivalent of setting the local duty cycle rate. - * - * @param sleepIntervalMs the length of this node's Rx check interval, in [ms] + * @param intervalMs the length of this node's wakeup interval, in [ms] */ - command void LowPowerListening.setLocalSleepInterval( - uint16_t sleepIntervalMs) { - call PowerCycle.setSleepInterval(sleepIntervalMs); + command void LowPowerListening.setLocalWakeupInterval(uint16_t intervalMs) { + call PowerCycle.setSleepInterval(intervalMs); } /** - * @return the local node's sleep interval, in [ms] + * @return the local node's wakeup interval, in [ms] */ - command uint16_t LowPowerListening.getLocalSleepInterval() { + command uint16_t LowPowerListening.getLocalWakeupInterval() { return call PowerCycle.getSleepInterval(); } - /** - * Set this node's radio duty cycle rate, in units of [percentage*100]. - * For example, to get a 0.05% duty cycle, - * - * call LowPowerListening.setDutyCycle(5); - * - * - * For a 100% duty cycle (always on), - * - * call LowPowerListening.setDutyCycle(10000); - * - * - * This is the equivalent of setting the local sleep interval explicitly. - * - * @param dutyCycle The duty cycle percentage, in units of [percentage*100] - */ - command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) { - call PowerCycle.setSleepInterval( - call LowPowerListening.dutyCycleToSleepInterval(dutyCycle)); - } - - /** - * @return this node's radio duty cycle rate, in units of [percentage*100] - */ - command uint16_t LowPowerListening.getLocalDutyCycle() { - return call LowPowerListening.sleepIntervalToDutyCycle( - call PowerCycle.getSleepInterval()); - } - - /** * Configure this outgoing message so it can be transmitted to a neighbor mote - * with the specified Rx sleep interval. + * with the specified wakeup interval. * @param msg Pointer to the message that will be sent - * @param sleepInterval The receiving node's sleep interval, in [ms] + * @param intervalMs The receiving node's wakeup interval, in [ms] */ - command void LowPowerListening.setRxSleepInterval(message_t *msg, - uint16_t sleepIntervalMs) { - (call CC2420PacketBody.getMetadata(msg))->rxInterval = sleepIntervalMs; + command void LowPowerListening.setRemoteWakeupInterval(message_t *msg, + uint16_t intervalMs) { + (call CC2420PacketBody.getMetadata(msg))->rxInterval = intervalMs; } /** - * @return the destination node's sleep interval configured in this message + * @return the destination node's wakeup interval configured in this message */ - command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) { + command uint16_t LowPowerListening.getRemoteWakeupInterval(message_t *msg) { return (call CC2420PacketBody.getMetadata(msg))->rxInterval; } - /** - * Configure this outgoing message so it can be transmitted to a neighbor mote - * with the specified Rx duty cycle rate. - * Duty cycle is in units of [percentage*100], i.e. 0.25% duty cycle = 25. - * - * @param msg Pointer to the message that will be sent - * @param dutyCycle The duty cycle of the receiving mote, in units of - * [percentage*100] - */ - command void LowPowerListening.setRxDutyCycle(message_t *msg, - uint16_t dutyCycle) { - (call CC2420PacketBody.getMetadata(msg))->rxInterval = - call LowPowerListening.dutyCycleToSleepInterval(dutyCycle); - } - - - /** - * @return the destination node's duty cycle configured in this message - * in units of [percentage*100] - */ - command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) { - return call LowPowerListening.sleepIntervalToDutyCycle( - (call CC2420PacketBody.getMetadata(msg))->rxInterval); - } - - /** - * Convert a duty cycle, in units of [percentage*100], to - * the sleep interval of the mote in milliseconds - * @param dutyCycle The duty cycle in units of [percentage*100] - * @return The equivalent sleep interval, in units of [ms] - */ - command uint16_t LowPowerListening.dutyCycleToSleepInterval( - uint16_t dutyCycle) { - dutyCycle = getActualDutyCycle(dutyCycle); - - if(dutyCycle == 10000) { - return 0; - } - - return ((uint32_t)DUTY_ON_TIME * (10000 - dutyCycle)) / dutyCycle; - } - - /** - * Convert a sleep interval, in units of [ms], to a duty cycle - * in units of [percentage*100] - * @param sleepInterval The sleep interval in units of [ms] - * @return The duty cycle in units of [percentage*100] - */ - command uint16_t LowPowerListening.sleepIntervalToDutyCycle( - uint16_t sleepInterval) { - if(sleepInterval == 0) { - return 10000; - } - - return getActualDutyCycle(((uint32_t)DUTY_ON_TIME * 10000) - / (sleepInterval + DUTY_ON_TIME)); - } - - /***************** Send Commands ***************/ /** * Each call to this send command gives the message a single @@ -480,7 +388,7 @@ implementation { /***************** Functions ***************/ void initializeSend() { - if(call LowPowerListening.getRxSleepInterval(currentSendMsg) + if(call LowPowerListening.getRemoteWakeupInterval(currentSendMsg) > ONE_MESSAGE) { if((call CC2420PacketBody.getHeader(currentSendMsg))->dest == IEEE154_BROADCAST_ADDR) { @@ -491,7 +399,7 @@ implementation { } call SendDoneTimer.startOneShot( - call LowPowerListening.getRxSleepInterval(currentSendMsg) + 20); + call LowPowerListening.getRemoteWakeupInterval(currentSendMsg) + 20); } post send(); @@ -499,21 +407,8 @@ implementation { void startOffTimer() { - call OffTimer.startOneShot(DELAY_AFTER_RECEIVE); + call OffTimer.startOneShot(call SystemLowPowerListening.getDelayAfterReceive()); } - /** - * Check the bounds on a given duty cycle - * We're never over 100%, and we're never at 0% - */ - uint16_t getActualDutyCycle(uint16_t dutyCycle) { - if(dutyCycle > 10000) { - return 10000; - } else if(dutyCycle == 0) { - return 1; - } - - return dutyCycle; - } } diff --git a/tos/chips/cc2420/lpl/DummyLplP.nc b/tos/chips/cc2420/lpl/DummyLplP.nc index dbc6bb53..36a79ffa 100644 --- a/tos/chips/cc2420/lpl/DummyLplP.nc +++ b/tos/chips/cc2420/lpl/DummyLplP.nc @@ -32,7 +32,7 @@ /** * Dummy low power listening interface used when LowPowerListening is not * compiled in with the application. - * Sleep interval is always 0, and duty cycle is always 100% + * Wakeup interval is always 0 (always on) * @author David Moss */ @@ -44,41 +44,19 @@ module DummyLplP { implementation { - command void LowPowerListening.setLocalSleepInterval(uint16_t sleepIntervalMs) { + command void LowPowerListening.setLocalWakeupInterval(uint16_t intervalMs) { } - command uint16_t LowPowerListening.getLocalSleepInterval() { + command uint16_t LowPowerListening.getLocalWakeupInterval() { return 0; } - command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) { + command void LowPowerListening.setRemoteWakeupInterval(message_t *msg, uint16_t intervalMs) { } - command uint16_t LowPowerListening.getLocalDutyCycle() { - return 10000; - } - - command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) { - } - - command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) { + command uint16_t LowPowerListening.getRemoteWakeupInterval(message_t *msg) { return 0; } - command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) { - } - - command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) { - return 10000; - } - - command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) { - return 0; - } - - command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t sleepInterval) { - return 10000; - } - } diff --git a/tos/chips/cc2420/lpl/PowerCycleC.nc b/tos/chips/cc2420/lpl/PowerCycleC.nc index 41dca278..971cf15a 100644 --- a/tos/chips/cc2420/lpl/PowerCycleC.nc +++ b/tos/chips/cc2420/lpl/PowerCycleC.nc @@ -76,7 +76,6 @@ implementation { PowerCycleP.SplitControlState -> SplitControlStateC; PowerCycleP.OnTimer -> OnTimerC; PowerCycleP.Leds -> LedsC; - } diff --git a/tos/chips/cc2420/lpl/PowerCycleP.nc b/tos/chips/cc2420/lpl/PowerCycleP.nc index 34099244..741224ce 100644 --- a/tos/chips/cc2420/lpl/PowerCycleP.nc +++ b/tos/chips/cc2420/lpl/PowerCycleP.nc @@ -75,7 +75,7 @@ module PowerCycleP { implementation { /** The current period of the duty cycle, equivalent of wakeup interval */ - uint16_t sleepInterval = 0; + uint16_t sleepInterval = LPL_DEF_LOCAL_WAKEUP; /** The number of times the CCA has been sampled in this wakeup period */ uint16_t ccaChecks; @@ -99,7 +99,6 @@ implementation { bool finishSplitControlRequests(); bool isDutyCycling(); - /***************** PowerCycle Commands ****************/ /** * Set the sleep interval, in binary milliseconds diff --git a/tos/chips/rf2xx/layers/LowPowerListeningDummyP.nc b/tos/chips/rf2xx/layers/LowPowerListeningDummyP.nc index 953fc280..a0294c28 100644 --- a/tos/chips/rf2xx/layers/LowPowerListeningDummyP.nc +++ b/tos/chips/rf2xx/layers/LowPowerListeningDummyP.nc @@ -28,23 +28,11 @@ module LowPowerListeningDummyP implementation { - command void LowPowerListening.setLocalSleepInterval(uint16_t sleepIntervalMs) { } + command void LowPowerListening.setLocalWakeupInterval(uint16_t intervalMs) { } - command uint16_t LowPowerListening.getLocalSleepInterval() { return 0; } + command uint16_t LowPowerListening.getLocalWakeupInterval() { return 0; } - command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) { } + command void LowPowerListening.setRemoteWakeupInterval(message_t *msg, uint16_t intervalMs) { } - command uint16_t LowPowerListening.getLocalDutyCycle() { return 10000; } - - command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) { } - - command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) { return 0; } - - command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) { } - - command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) { return 10000; } - - command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) { return 0; } - - command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t sleepInterval) { return 10000; } + command uint16_t LowPowerListening.getRemoteWakeupInterval(message_t *msg) { return 0; } } diff --git a/tos/chips/rf2xx/layers/LowPowerListeningLayerC.nc b/tos/chips/rf2xx/layers/LowPowerListeningLayerC.nc index 76f0a9a2..75d07154 100644 --- a/tos/chips/rf2xx/layers/LowPowerListeningLayerC.nc +++ b/tos/chips/rf2xx/layers/LowPowerListeningLayerC.nc @@ -47,6 +47,7 @@ configuration LowPowerListeningLayerC implementation { components LowPowerListeningLayerP, new TimerMilliC(); + components SystemLowPowerListeningC; SplitControl = LowPowerListeningLayerP; Send = LowPowerListeningLayerP; @@ -62,4 +63,5 @@ implementation PacketAcknowledgements = LowPowerListeningLayerP; LowPowerListeningLayerP.Timer -> TimerMilliC; + LowPowerListeningLayerP.SystemLowPowerListening -> SystemLowPowerListeningC; } diff --git a/tos/chips/rf2xx/layers/LowPowerListeningLayerP.nc b/tos/chips/rf2xx/layers/LowPowerListeningLayerP.nc index 5a78dcce..12fd1cfe 100644 --- a/tos/chips/rf2xx/layers/LowPowerListeningLayerP.nc +++ b/tos/chips/rf2xx/layers/LowPowerListeningLayerP.nc @@ -46,6 +46,7 @@ module LowPowerListeningLayerP interface PacketAcknowledgements; interface LowPowerListeningConfig as Config; interface Timer; + interface SystemLowPowerListening; } } @@ -56,18 +57,12 @@ implementation // minimum wakeup time to catch a transmission in milliseconds LISTEN_WAKEUP = 6U, // use xxxL if LISTEN_WAKEUP * 10000 > 65535 - // extra wakeup time after receiving a message in milliseconds - AFTER_RECEIVE = 10U, - - // extra wakeup time after transmitting a message in milliseconds - AFTER_TRANSMIT = 10U, - MIN_SLEEP = 2, // the minimum sleep interval in milliseconds MAX_SLEEP = 30000, // the maximum sleep interval in milliseconds MIN_DUTY = 2, // the minimum duty cycle }; - uint16_t sleepInterval; + uint16_t sleepInterval = LPL_DEF_LOCAL_WAKEUP; message_t* txMsg; error_t txError; @@ -161,7 +156,7 @@ implementation } else if( state == SEND_TIMER ) { - transmitInterval = call LowPowerListening.getRxSleepInterval(txMsg); + transmitInterval = call LowPowerListening.getRemoteWakeupInterval(txMsg); if( transmitInterval > 0 ) call Timer.startOneShot(transmitInterval); @@ -185,7 +180,7 @@ implementation { state = LISTEN; if( sleepInterval > 0 ) - call Timer.startOneShot(AFTER_TRANSMIT); + call Timer.startOneShot(call SystemLowPowerListening.getDelayAfterReceive()); signal Send.sendDone(txMsg, txError); } @@ -274,7 +269,7 @@ implementation state = LISTEN; if( state == LISTEN && sleepInterval > 0 ) - call Timer.startOneShot(AFTER_RECEIVE); + call Timer.startOneShot(call SystemLowPowerListening.getDelayAfterReceive()); return signal Receive.receive(msg); } @@ -333,7 +328,7 @@ implementation // TODO: extend the PacketAcknowledgements interface with getAckRequired if( error != SUCCESS - || call LowPowerListening.getRxSleepInterval(msg) == 0 + || call LowPowerListening.getRemoteWakeupInterval(msg) == 0 || state == SEND_SUBSEND_DONE_LAST || (call Config.getAckRequired(msg) && call PacketAcknowledgements.wasAcked(msg)) ) { @@ -353,27 +348,7 @@ implementation return ((void*)msg) + sizeof(message_t) - call RadioPacket.metadataLength(msg); } - command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) - { - if( dutyCycle >= 10000 ) - return 0; - else if( dutyCycle <= MIN_DUTY ) - return MAX_SLEEP; - - return ((10000U * LISTEN_WAKEUP) / dutyCycle) - LISTEN_WAKEUP; - } - - command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t interval) - { - if( interval < MIN_SLEEP ) - return 10000; - else if( interval >= MAX_SLEEP ) - return MIN_DUTY; - - return (10000U * LISTEN_WAKEUP) / (LISTEN_WAKEUP + interval); - } - - command void LowPowerListening.setLocalSleepInterval(uint16_t interval) + command void LowPowerListening.setLocalWakeupInterval(uint16_t interval) { if( interval < MIN_SLEEP ) interval = 0; @@ -390,23 +365,12 @@ implementation } } - command uint16_t LowPowerListening.getLocalSleepInterval() + command uint16_t LowPowerListening.getLocalWakeupInterval() { return sleepInterval; } - command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) - { - call LowPowerListening.setLocalSleepInterval( - call LowPowerListening.dutyCycleToSleepInterval(dutyCycle)); - } - - command uint16_t LowPowerListening.getLocalDutyCycle() - { - return call LowPowerListening.sleepIntervalToDutyCycle(sleepInterval); - } - - command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t interval) + command void LowPowerListening.setRemoteWakeupInterval(message_t *msg, uint16_t interval) { if( interval < MIN_SLEEP ) interval = 0; @@ -416,23 +380,11 @@ implementation getMeta(msg)->sleepint = interval; } - command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) + command uint16_t LowPowerListening.getRemoteWakeupInterval(message_t *msg) { return getMeta(msg)->sleepint; } - command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) - { - call LowPowerListening.setRxSleepInterval(msg, - call LowPowerListening.dutyCycleToSleepInterval(dutyCycle)); - } - - command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) - { - return call LowPowerListening.sleepIntervalToDutyCycle( - call LowPowerListening.getRxSleepInterval(msg)); - } - /*----------------- RadioPacket -----------------*/ async command uint8_t RadioPacket.headerLength(message_t* msg) diff --git a/tos/interfaces/LowPowerListening.nc b/tos/interfaces/LowPowerListening.nc index b5225c4f..68d9cc4a 100644 --- a/tos/interfaces/LowPowerListening.nc +++ b/tos/interfaces/LowPowerListening.nc @@ -35,98 +35,38 @@ * @author Jonathan Hui * @author David Moss */ - + #include "message.h" - -interface LowPowerListening { +interface LowPowerListening { /** - * Set this this node's radio sleep interval, in milliseconds. - * Once every interval, the node will sleep and perform an Rx check - * on the radio. Setting the sleep interval to 0 will keep the radio - * always on. - * - * This is the equivalent of setting the local duty cycle rate. - * - * @param sleepIntervalMs the length of this node's Rx check interval, in [ms] - */ - command void setLocalSleepInterval(uint16_t sleepIntervalMs); - - /** - * @return the local node's sleep interval, in [ms] - */ - command uint16_t getLocalSleepInterval(); - - /** - * Set this node's radio duty cycle rate, in units of [percentage*100]. - * For example, to get a 0.05% duty cycle, - * - * call LowPowerListening.setDutyCycle(5); - * + * Set this this node's radio wakeup interval, in milliseconds. After + * each interval, the node will wakeup and check for radio activity. * - * For a 100% duty cycle (always on), - * - * call LowPowerListening.setDutyCycle(10000); - * + * Note: The wakeup interval can be set to 0 to indicate that the radio + * should stay on all the time but in order to get a startDone this + * should only be done when the duty-cycling is off (after a stopDone). * - * This is the equivalent of setting the local sleep interval explicitly. - * - * @param dutyCycle The duty cycle percentage, in units of [percentage*100] - */ - command void setLocalDutyCycle(uint16_t dutyCycle); - - /** - * @return this node's radio duty cycle rate, in units of [percentage*100] - */ - command uint16_t getLocalDutyCycle(); - - - /** - * Configure this outgoing message so it can be transmitted to a neighbor mote - * with the specified Rx sleep interval. - * @param 'message_t* ONE msg' Pointer to the message that will be sent - * @param sleepInterval The receiving node's sleep interval, in [ms] + * @param intervalMs the length of this node's Rx check interval, in [ms] */ - command void setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs); + command void setLocalWakeupInterval(uint16_t intervalMs); /** - * @param 'message_t* ONE msg' - * @return the destination node's sleep interval configured in this message + * @return the local node's wakeup interval, in [ms] */ - command uint16_t getRxSleepInterval(message_t *msg); - + command uint16_t getLocalWakeupInterval(); + /** * Configure this outgoing message so it can be transmitted to a neighbor mote - * with the specified Rx duty cycle rate. - * Duty cycle is in units of [percentage*100], i.e. 0.25% duty cycle = 25. - * + * with the specified wakeup interval. * @param 'message_t* ONE msg' Pointer to the message that will be sent - * @param dutyCycle The duty cycle of the receiving mote, in units of - * [percentage*100] + * @param intervalMs The receiving node's wakeup interval, in [ms] */ - command void setRxDutyCycle(message_t *msg, uint16_t dutyCycle); - + command void setRemoteWakeupInterval(message_t *msg, uint16_t intervalMs); + /** * @param 'message_t* ONE msg' - * @return the destination node's duty cycle configured in this message - * in units of [percentage*100] - */ - command uint16_t getRxDutyCycle(message_t *msg); - - /** - * Convert a duty cycle, in units of [percentage*100], to - * the sleep interval of the mote in milliseconds - * @param dutyCycle The duty cycle in units of [percentage*100] - * @return The equivalent sleep interval, in units of [ms] + * @return the destination node's wakeup interval configured in this message */ - command uint16_t dutyCycleToSleepInterval(uint16_t dutyCycle); - - /** - * Convert a sleep interval, in units of [ms], to a duty cycle - * in units of [percentage*100] - * @param sleepInterval The sleep interval in units of [ms] - * @return The duty cycle in units of [percentage*100] - */ - command uint16_t sleepIntervalToDutyCycle(uint16_t sleepInterval); - + command uint16_t getRemoteWakeupInterval(message_t *msg); } diff --git a/tos/interfaces/SystemLowPowerListening.nc b/tos/interfaces/SystemLowPowerListening.nc new file mode 100644 index 00000000..d64bcca2 --- /dev/null +++ b/tos/interfaces/SystemLowPowerListening.nc @@ -0,0 +1,8 @@ +interface SystemLowPowerListening +{ + command void setDefaultRemoteWakeupInterval(uint16_t intervalMs); + command void setDelayAfterReceive(uint16_t intervalMs); + + command uint16_t getDefaultRemoteWakeupInterval(); + command uint16_t getDelayAfterReceive(); +} diff --git a/tos/platforms/micaz/ActiveMessageC.nc b/tos/platforms/micaz/ActiveMessageC.nc index b5d90c5a..aaf2bfff 100644 --- a/tos/platforms/micaz/ActiveMessageC.nc +++ b/tos/platforms/micaz/ActiveMessageC.nc @@ -37,11 +37,11 @@ /** * - * The Active Message layer on the micaZ platform. This is a naming wrapper + * The Active Message layer on the Telos platform. This is a naming wrapper * around the CC2420 Active Message layer. * * @author Philip Levis - * @date June 19 2005 + * @version $Revision$ $Date$ */ #include "Timer.h" @@ -58,11 +58,12 @@ configuration ActiveMessageC { interface PacketAcknowledgements; interface PacketTimeStamp as PacketTimeStamp32khz; interface PacketTimeStamp as PacketTimeStampMilli; + interface LowPowerListening; } } implementation { components CC2420ActiveMessageC as AM; - + SplitControl = AM; AMSend = AM; @@ -71,6 +72,7 @@ implementation { Packet = AM; AMPacket = AM; PacketAcknowledgements = AM; + LowPowerListening = AM; components CC2420PacketC; PacketTimeStamp32khz = CC2420PacketC; diff --git a/tos/platforms/telosa/ActiveMessageC.nc b/tos/platforms/telosa/ActiveMessageC.nc index 0e651491..aaf2bfff 100644 --- a/tos/platforms/telosa/ActiveMessageC.nc +++ b/tos/platforms/telosa/ActiveMessageC.nc @@ -58,6 +58,7 @@ configuration ActiveMessageC { interface PacketAcknowledgements; interface PacketTimeStamp as PacketTimeStamp32khz; interface PacketTimeStamp as PacketTimeStampMilli; + interface LowPowerListening; } } implementation { @@ -71,6 +72,7 @@ implementation { Packet = AM; AMPacket = AM; PacketAcknowledgements = AM; + LowPowerListening = AM; components CC2420PacketC; PacketTimeStamp32khz = CC2420PacketC; diff --git a/tos/system/AMSenderC.nc b/tos/system/AMSenderC.nc index eba17537..7d293a31 100644 --- a/tos/system/AMSenderC.nc +++ b/tos/system/AMSenderC.nc @@ -46,14 +46,15 @@ generic configuration AMSenderC(am_id_t AMId) { } implementation { - components new AMQueueEntryP(AMId) as AMQueueEntryP; - components AMQueueP, ActiveMessageC; - AMQueueEntryP.Send -> AMQueueP.Send[unique(UQ_AMQUEUE_SEND)]; - AMQueueEntryP.AMPacket -> ActiveMessageC; - - AMSend = AMQueueEntryP; - Packet = ActiveMessageC; - AMPacket = ActiveMessageC; - Acks = ActiveMessageC; +#if defined(LOW_POWER_LISTENING) + components new LplAMSenderC(AMId) as SenderC; +#else + components new DirectAMSenderC(AMId) as SenderC; +#endif + + AMSend = SenderC; + Packet = SenderC; + AMPacket = SenderC; + Acks = SenderC; } diff --git a/tos/system/DirectAMSenderC.nc b/tos/system/DirectAMSenderC.nc new file mode 100644 index 00000000..cb4fe07a --- /dev/null +++ b/tos/system/DirectAMSenderC.nc @@ -0,0 +1,59 @@ +// $Id$ +/* + * "Copyright (c) 2006 Stanford University. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose, without fee, and without written + * agreement is hereby granted, provided that the above copyright + * notice, the following two paragraphs and the author appear in all + * copies of this software. + * + * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE + * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY + * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + * ENHANCEMENTS, OR MODIFICATIONS." + */ + +/** + * The virtualized active message send abstraction. Each instantiation + * of AMSenderC has its own queue of depth one. Therefore, it does not + * have to contend with other AMSenderC instantiations for queue space. + * The underlying implementation schedules the packets in these queues + * using some form of fair-share queueing. + * + * @author Philip Levis + * @date Jan 16 2006 + * @see TEP 116: Packet Protocols + */ + +#include "AM.h" + +generic configuration DirectAMSenderC(am_id_t AMId) { + provides { + interface AMSend; + interface Packet; + interface AMPacket; + interface PacketAcknowledgements as Acks; + } +} + +implementation { + components new AMQueueEntryP(AMId) as AMQueueEntryP; + components AMQueueP, ActiveMessageC; + + AMQueueEntryP.Send -> AMQueueP.Send[unique(UQ_AMQUEUE_SEND)]; + AMQueueEntryP.AMPacket -> ActiveMessageC; + + AMSend = AMQueueEntryP; + Packet = ActiveMessageC; + AMPacket = ActiveMessageC; + Acks = ActiveMessageC; +} diff --git a/tos/system/LplAMSenderC.nc b/tos/system/LplAMSenderC.nc new file mode 100644 index 00000000..ec5d5618 --- /dev/null +++ b/tos/system/LplAMSenderC.nc @@ -0,0 +1,28 @@ +#include "AM.h" + +generic configuration LplAMSenderC(am_id_t AMId) +{ + provides { + interface AMSend; + interface Packet; + interface AMPacket; + interface PacketAcknowledgements as Acks; + } +} + +implementation +{ + components new DirectAMSenderC(AMId); + components new LplAMSenderP(); + components ActiveMessageC; + components SystemLowPowerListeningC; + + AMSend = LplAMSenderP; + Packet = DirectAMSenderC; + AMPacket = DirectAMSenderC; + Acks = DirectAMSenderC; + + LplAMSenderP.SubAMSend -> DirectAMSenderC; + LplAMSenderP.Lpl -> ActiveMessageC; + LplAMSenderP.SystemLowPowerListening -> SystemLowPowerListeningC; +} diff --git a/tos/system/LplAMSenderP.nc b/tos/system/LplAMSenderP.nc new file mode 100644 index 00000000..59f1bd9b --- /dev/null +++ b/tos/system/LplAMSenderP.nc @@ -0,0 +1,23 @@ +generic module LplAMSenderP() +{ + provides interface AMSend; + uses { + interface AMSend as SubAMSend; + interface LowPowerListening as Lpl; + interface SystemLowPowerListening; + } +} + +implementation +{ + event void SubAMSend.sendDone(message_t* msg, error_t error) + { + call Lpl.setRemoteWakeupInterval(msg, call SystemLowPowerListening.getDefaultRemoteWakeupInterval()); + signal AMSend.sendDone(msg, error); + } + + command error_t AMSend.send(am_addr_t addr, message_t* msg, uint8_t len) { return call SubAMSend.send(addr, msg, len); } + command error_t AMSend.cancel(message_t* msg) { return call SubAMSend.cancel(msg); } + command uint8_t AMSend.maxPayloadLength() { return call SubAMSend.maxPayloadLength(); } + command void* AMSend.getPayload(message_t* msg, uint8_t len) { return call SubAMSend.getPayload(msg, len); } +} diff --git a/tos/system/SystemLowPowerListeningC.nc b/tos/system/SystemLowPowerListeningC.nc new file mode 100644 index 00000000..2aa909cb --- /dev/null +++ b/tos/system/SystemLowPowerListeningC.nc @@ -0,0 +1,10 @@ +configuration SystemLowPowerListeningC +{ + provides interface SystemLowPowerListening; +} + +implementation +{ + components SystemLowPowerListeningP; + SystemLowPowerListening = SystemLowPowerListeningP; +} diff --git a/tos/system/SystemLowPowerListeningP.nc b/tos/system/SystemLowPowerListeningP.nc new file mode 100644 index 00000000..db91cbf2 --- /dev/null +++ b/tos/system/SystemLowPowerListeningP.nc @@ -0,0 +1,16 @@ +module SystemLowPowerListeningP +{ + provides interface SystemLowPowerListening; +} + +implementation +{ + uint16_t remoteWakeup = LPL_DEF_REMOTE_WAKEUP; + uint16_t delayAfterReceive = DELAY_AFTER_RECEIVE; + + command void SystemLowPowerListening.setDefaultRemoteWakeupInterval(uint16_t intervalMs) { remoteWakeup = intervalMs; } + command void SystemLowPowerListening.setDelayAfterReceive(uint16_t intervalMs) { delayAfterReceive = intervalMs; } + + command uint16_t SystemLowPowerListening.getDefaultRemoteWakeupInterval() { return remoteWakeup; } + command uint16_t SystemLowPowerListening.getDelayAfterReceive() { return delayAfterReceive; } +} -- 2.39.2