From: mmaroti Date: Tue, 22 Apr 2008 10:55:20 +0000 (+0000) Subject: low power listening: better state machine X-Git-Tag: release_tinyos_2_1_0_0~460 X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=commitdiff_plain;h=7f15d5823adb5954801e7adef825a29542127605;p=tinyos-2.x.git low power listening: better state machine --- diff --git a/tos/chips/rf230/DefaultMacC.nc b/tos/chips/rf230/DefaultMacC.nc index 382b8b89..cb9e3b11 100644 --- a/tos/chips/rf230/DefaultMacC.nc +++ b/tos/chips/rf230/DefaultMacC.nc @@ -94,6 +94,9 @@ implementation LowPowerListeningLayerC.SubControl -> MessageBufferLayerC; LowPowerListeningLayerC.SubSend -> MessageBufferLayerC; LowPowerListeningLayerC.SubReceive -> MessageBufferLayerC; + LowPowerListeningLayerC.PacketSleepInterval -> DefaultPacketC; + LowPowerListeningLayerC.IEEE154Packet -> IEEE154PacketC; + LowPowerListeningLayerC.PacketAcknowledgements -> DefaultPacketC; MessageBufferLayerC.Packet -> DefaultPacketC; MessageBufferLayerC.RadioSend -> TrafficMonitorLayerC; @@ -116,8 +119,8 @@ implementation SoftwareAckLayerC.SubReceive -> RF230LayerC; CsmaLayerC.Config -> DefaultMacP; - CsmaLayerC.SubSend -> RF230LayerC; - CsmaLayerC.SubCCA -> RF230LayerC; + CsmaLayerC -> RF230LayerC.RadioSend; + CsmaLayerC -> RF230LayerC.RadioCCA; RF230LayerC.RF230Config -> DefaultMacP; RF230LayerC.PacketLinkQuality -> DefaultPacketC.PacketLinkQuality; diff --git a/tos/chips/rf230/DummyLayerC.nc b/tos/chips/rf230/DummyLayerC.nc index 5aebc90d..f1f6f699 100644 --- a/tos/chips/rf230/DummyLayerC.nc +++ b/tos/chips/rf230/DummyLayerC.nc @@ -25,30 +25,55 @@ generic configuration DummyLayerC() { provides { + interface SplitControl; + interface Send; + interface Receive; + interface LowPowerListening; + interface RadioState; interface RadioSend; interface RadioReceive; interface RadioCCA; interface DummyConfig as UnconnectedConfig; + interface PacketField as UnconnectedPacketSleepInterval; + interface IEEE154Packet as UnconnectedIEEE154Packet; + interface PacketAcknowledgements as UnconnectedPacketAcknowledgments; } uses { interface RadioState as SubState; - interface RadioSend as SubSend; - interface RadioReceive as SubReceive; - interface RadioCCA as SubCCA; + interface RadioSend as SubRadioSend; + interface RadioReceive as SubRadioReceive; + interface RadioCCA as SubRadioCCA; + interface SplitControl as SubControl; + interface Send as SubSend; + interface Receive as SubReceive; interface DummyConfig as Config; + interface PacketField as PacketSleepInterval; + interface IEEE154Packet; + interface PacketAcknowledgements; + + interface LowPowerListening as UnconnectedLowPowerListening; } } implementation { RadioState = SubState; - RadioSend = SubSend; - RadioReceive = SubReceive; - RadioCCA = SubCCA; + RadioSend = SubRadioSend; + RadioReceive = SubRadioReceive; + RadioCCA = SubRadioCCA; + + SplitControl = SubControl; + Send = SubSend; + Receive = SubReceive; + Config = UnconnectedConfig; + PacketSleepInterval = UnconnectedPacketSleepInterval; + IEEE154Packet = UnconnectedIEEE154Packet; + PacketAcknowledgements = UnconnectedPacketAcknowledgments; + LowPowerListening = UnconnectedLowPowerListening; } diff --git a/tos/chips/rf230/LowPowerListeningLayerC.nc b/tos/chips/rf230/LowPowerListeningLayerC.nc index f8605585..a60ff739 100644 --- a/tos/chips/rf230/LowPowerListeningLayerC.nc +++ b/tos/chips/rf230/LowPowerListeningLayerC.nc @@ -38,6 +38,8 @@ configuration LowPowerListeningLayerC interface Receive as SubReceive; interface PacketField as PacketSleepInterval; + interface IEEE154Packet; + interface PacketAcknowledgements; } } @@ -45,14 +47,17 @@ implementation { components LowPowerListeningLayerP, new TimerMilliC(); - LowPowerListening = LowPowerListeningLayerP; - PacketSleepInterval = LowPowerListeningLayerP; SplitControl = LowPowerListeningLayerP; - SubControl = LowPowerListeningLayerP; Send = LowPowerListeningLayerP; - SubSend = LowPowerListeningLayerP; Receive = LowPowerListeningLayerP; + LowPowerListening = LowPowerListeningLayerP; + + SubControl = LowPowerListeningLayerP; + SubSend = LowPowerListeningLayerP; SubReceive = LowPowerListeningLayerP; + PacketSleepInterval = LowPowerListeningLayerP; + IEEE154Packet = LowPowerListeningLayerP; + PacketAcknowledgements = LowPowerListeningLayerP; LowPowerListeningLayerP.Timer -> TimerMilliC; } diff --git a/tos/chips/rf230/LowPowerListeningLayerP.nc b/tos/chips/rf230/LowPowerListeningLayerP.nc index 53252843..8b4876da 100644 --- a/tos/chips/rf230/LowPowerListeningLayerP.nc +++ b/tos/chips/rf230/LowPowerListeningLayerP.nc @@ -41,6 +41,8 @@ module LowPowerListeningLayerP interface Receive as SubReceive; interface PacketField as PacketSleepInterval; + interface IEEE154Packet; + interface PacketAcknowledgements; interface Timer; } } @@ -63,96 +65,139 @@ implementation MIN_DUTY = 2, // the minimum duty cycle }; - uint16_t rxSleepInterval; + uint16_t sleepInterval; + + message_t* txMsg; + uint8_t txLen; + error_t txError; /*----------------- state machine -----------------*/ enum { - STATE_OFF = 0, // timer off, radio off - STATE_SLEEP = 1, // timer on, radio off - STATE_LISTEN = 2, // timer on/off, radio on - STATE_SEND = 3, // timer on/off, radio on - - STATE_OFF_TO_LISTEN = 10, - STATE_SLEEP_TO_LISTEN = 11, - STATE_SLEEP_TO_SEND = 12, - STATE_SLEEP_TO_OFF = 13, - STATE_LISTEN_TO_SLEEP_1 = 14, // we go back to listen if a message arrives in this state - STATE_LISTEN_TO_SLEEP_2 = 15, - STATE_LISTEN_TO_OFF = 16, - STATE_SEND_DONE = 17, + OFF = 0, + OFF_SUBSTOP = 1, // must have consecutive indices + OFF_SUBSTOP_DONE = 2, // must have consecutive indices + OFF_STOP_END = 3, // must have consecutive indices + OFF_START_END = 4, + + LISTEN_SUBSTART = 5, // must have consecutive indices + LISTEN_SUBSTART_DONE = 6, // must have consecutive indices + LISTEN_TIMER = 7, // must have consecutive indices + LISTEN = 8, // must have consecutive indices + + SLEEP_SUBSTOP = 9, // must have consecutive indices + SLEEP_SUBSTOP_DONE = 10, // must have consecutive indices + SLEEP_TIMER = 11, // must have consecutive indices + SLEEP = 12, // must have consecutive indices + + SEND_SUBSTART = 13, // must have consecutive indices + SEND_SUBSTART_DONE = 14, // must have consecutive indices + SEND_TIMER = 15, // must have consecutive indices + SEND_SUBSEND= 16, + SEND_SUBSEND_DONE = 17, + SEND_SUBSEND_DONE_LAST = 18, + SEND_DONE = 19, }; uint8_t state; - message_t* txMsg; - uint8_t txLen; - task void transition() { error_t error; + uint16_t transmitInterval; - if( state == STATE_OFF_TO_LISTEN || state == STATE_SLEEP_TO_LISTEN || state == STATE_SLEEP_TO_SEND ) + if( state == LISTEN_SUBSTART || state == SEND_SUBSTART ) { error = call SubControl.start(); ASSERT( error == SUCCESS || error == EBUSY ); - if( error != SUCCESS ) + if( error == SUCCESS ) + ++state; + else post transition(); } - else if( state == STATE_LISTEN_TO_OFF || state == STATE_LISTEN_TO_SLEEP_1 ) + else if( state == SLEEP_SUBSTOP || state == OFF_SUBSTOP ) { error = call SubControl.stop(); ASSERT( error == SUCCESS || error == EBUSY ); - if( error != SUCCESS ) + if( error == SUCCESS ) + ++state; + else post transition(); - else if( state == STATE_LISTEN_TO_SLEEP_1 ) - state = STATE_LISTEN_TO_SLEEP_2; } - else if( state == STATE_SLEEP_TO_OFF ) + else if( state == OFF_START_END ) + { + state = LISTEN_SUBSTART; + post transition(); + + signal SplitControl.startDone(SUCCESS); + } + else if( state == OFF_STOP_END ) { - state = STATE_OFF; + state = OFF; signal SplitControl.stopDone(SUCCESS); } - else if( state == STATE_SEND ) + else if( state == LISTEN_TIMER ) { - error = call SubSend.send(txMsg, txLen); - if( error == SUCCESS ) - state = STATE_SEND_DONE; + state = LISTEN; + if( sleepInterval > 0 ) + call Timer.startOneShot(LISTEN_WAKEUP); + } + else if( state == SLEEP_TIMER ) + { + if( sleepInterval > 0 ) + { + state = SLEEP; + call Timer.startOneShot(sleepInterval); + } else { - state = STATE_LISTEN; - if( rxSleepInterval > 0 ) - call Timer.startOneShot(AFTER_TRANSMIT); - - signal Send.sendDone(txMsg, error); + state = LISTEN_SUBSTART; + post transition(); } } - else if( state == STATE_LISTEN ) + else if( state == SEND_TIMER ) { - if( rxSleepInterval > 0 ) - call Timer.startOneShot(LISTEN_WAKEUP); + transmitInterval = call LowPowerListening.getRxSleepInterval(txMsg); + + if( transmitInterval > 0 ) + call Timer.startOneShot(transmitInterval); + + state = SEND_SUBSEND; + post transition(); } - else if( state == STATE_SLEEP ) + else if( state == SEND_SUBSEND) { - if( rxSleepInterval > 0 ) - call Timer.startOneShot(rxSleepInterval); + txError = call SubSend.send(txMsg, txLen); + + if( txError == SUCCESS ) + state = SEND_SUBSEND_DONE; else { - state = STATE_SLEEP_TO_LISTEN; + state = SEND_DONE; post transition(); } } + else if( state == SEND_DONE ) + { + state = LISTEN; + if( sleepInterval > 0 ) + call Timer.startOneShot(AFTER_TRANSMIT); + + signal Send.sendDone(txMsg, txError); + } } command error_t SplitControl.start() { - if( state != STATE_OFF ) + if( state == OFF_START_END ) + return EBUSY; + else if( state != OFF ) return EALREADY; - state = STATE_OFF_TO_LISTEN; + state = OFF_START_END; post transition(); return SUCCESS; @@ -161,35 +206,34 @@ implementation event void SubControl.startDone(error_t error) { ASSERT( error == SUCCESS || error == EBUSY ); - ASSERT( state == STATE_OFF_TO_LISTEN || state == STATE_SLEEP_TO_LISTEN || state == STATE_SLEEP_TO_SEND ); + ASSERT( state == LISTEN_SUBSTART_DONE || state == SEND_SUBSTART_DONE ); if( error == SUCCESS ) - { - if( state == STATE_OFF_TO_LISTEN ) - signal SplitControl.startDone(SUCCESS); - else if( state == STATE_SLEEP_TO_SEND ) - state = STATE_SEND; - else - state = STATE_LISTEN; - } + ++state; + else + --state; post transition(); } command error_t SplitControl.stop() { - if( state == STATE_OFF ) - return EALREADY; - else if( state != STATE_LISTEN || state != STATE_SLEEP ) - return EBUSY; + if( state == SLEEP || state == LISTEN ) + { + call Timer.stop(); + post transition(); + } - call Timer.stop(); - if( state == STATE_SLEEP ) - state = STATE_SLEEP_TO_OFF; + if( state == LISTEN_TIMER || state == LISTEN || state == SLEEP_SUBSTOP ) + state = OFF_SUBSTOP; + else if( state == SLEEP_SUBSTOP_DONE ) + state = OFF_SUBSTOP_DONE; + else if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP ) + state = OFF_STOP_END; + else if( state == OFF ) + return EALREADY; else - state = STATE_LISTEN_TO_OFF; - - post transition(); + return EBUSY; return SUCCESS; } @@ -197,49 +241,48 @@ implementation event void SubControl.stopDone(error_t error) { ASSERT( error == SUCCESS || error == EBUSY ); - ASSERT( state == STATE_LISTEN_TO_SLEEP_2 || state == STATE_LISTEN_TO_OFF ); + ASSERT( state == SLEEP_SUBSTOP_DONE || state == OFF_SUBSTOP_DONE ); if( error == SUCCESS ) - { - if( state == STATE_LISTEN_TO_OFF ) - state = STATE_SLEEP_TO_OFF; - else - state = STATE_SLEEP; - } + ++state; + else + --state; post transition(); } event void Timer.fired() { - ASSERT( state == STATE_LISTEN || state == STATE_SLEEP ); + ASSERT( state == LISTEN || state == SLEEP || state == SEND_SUBSEND|| state == SEND_SUBSEND_DONE ); - if( state == STATE_LISTEN ) - state = STATE_LISTEN_TO_SLEEP_1; - else - state = STATE_SLEEP_TO_LISTEN; + if( state == LISTEN ) + state = SLEEP_SUBSTOP; + else if( state == SLEEP ) + state = LISTEN_SUBSTART; + else if( state == SEND_SUBSEND_DONE ) + state = SEND_SUBSEND_DONE_LAST; + else if( state == SEND_SUBSEND) + state = SEND_DONE; post transition(); } - void rxSleepIntervalChanged() + void sleepIntervalChanged() { - if( rxSleepInterval == 0 ) + if( (state == LISTEN && sleepInterval == 0) || state == SLEEP ) { call Timer.stop(); - if( state == STATE_SLEEP ) - state = STATE_SLEEP_TO_LISTEN; + --state; + post transition(); } - - post transition(); } event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) { - if( state == STATE_LISTEN_TO_SLEEP_1 ) - state = STATE_LISTEN; + if( state == SLEEP_SUBSTOP ) + state = LISTEN; - if( state == STATE_LISTEN && rxSleepInterval > 0 ) + if( state == LISTEN && sleepInterval > 0 ) call Timer.startOneShot(AFTER_RECEIVE); return signal Receive.receive(msg, payload, len); @@ -247,42 +290,61 @@ implementation command error_t Send.send(message_t* msg, uint8_t len) { - if( state == STATE_LISTEN || state == STATE_SLEEP ) - call Timer.stop(); - - if( state == STATE_LISTEN || state == STATE_LISTEN_TO_SLEEP_1 ) + if( state == LISTEN || state == SLEEP ) { - state = STATE_SEND; - post transition(); - } - else if( state == STATE_SLEEP ) - { - state = STATE_SLEEP_TO_SEND; + call Timer.stop(); post transition(); } - else if( state == STATE_SLEEP_TO_LISTEN ) - state = STATE_SLEEP_TO_SEND; + + if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == LISTEN ) + state = SEND_SUBSTART; + else if( state == LISTEN_SUBSTART_DONE ) + state = SEND_SUBSTART_DONE; + else if( state == LISTEN_TIMER || state == SLEEP_SUBSTOP|| state == LISTEN ) + state = SEND_TIMER; else return EBUSY; txMsg = msg; txLen = len; + txError = FAIL; } command error_t Send.cancel(message_t* msg) { - return call SubSend.cancel(msg); + if( state == SEND_SUBSEND ) + { + call Timer.stop(); + state = LISTEN_TIMER; + post transition(); + + // TODO: ask if sendDone should be called after a succesfull cancel + return SUCCESS; + } + else + return FAIL; } event void SubSend.sendDone(message_t* msg, error_t error) { - ASSERT( state == STATE_SEND_DONE ); + ASSERT( state == SEND_SUBSEND_DONE || state == SEND_SUBSEND_DONE_LAST ); + ASSERT( msg == txMsg ); - state = STATE_LISTEN; - if( rxSleepInterval > 0 ) - call Timer.startOneShot(AFTER_TRANSMIT); + txError = error; - signal Send.sendDone(msg, error); + // TODO: extend the PacketAcknowledgements interface with getAckRequired + if( error != SUCCESS + || call LowPowerListening.getRxSleepInterval(msg) == 0 + || state == SEND_SUBSEND_DONE_LAST + || (call IEEE154Packet.getAckRequired(msg) && call PacketAcknowledgements.wasAcked(msg)) ) + { + call Timer.stop(); + state = SEND_DONE; + } + else + state = SEND_SUBSEND; + + post transition(); } command uint8_t Send.maxPayloadLength() @@ -307,30 +369,30 @@ implementation return ((10000 * LISTEN_WAKEUP) / dutyCycle) - LISTEN_WAKEUP; } - command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t sleepInterval) + command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t interval) { - if( sleepInterval < MIN_SLEEP ) + if( interval < MIN_SLEEP ) return 10000; - else if( sleepInterval >= MAX_SLEEP ) + else if( interval >= MAX_SLEEP ) return MIN_DUTY; - return (10000 * LISTEN_WAKEUP) / (LISTEN_WAKEUP + sleepInterval); + return (10000 * LISTEN_WAKEUP) / (LISTEN_WAKEUP + interval); } - command void LowPowerListening.setLocalSleepInterval(uint16_t sleepInterval) + command void LowPowerListening.setLocalSleepInterval(uint16_t interval) { - if( sleepInterval < MIN_SLEEP ) - sleepInterval = 0; - else if( sleepInterval > MAX_SLEEP ) - sleepInterval = MAX_SLEEP; + if( interval < MIN_SLEEP ) + interval = 0; + else if( interval > MAX_SLEEP ) + interval = MAX_SLEEP; - rxSleepInterval = sleepInterval; - rxSleepIntervalChanged(); + sleepInterval = interval; + sleepIntervalChanged(); } command uint16_t LowPowerListening.getLocalSleepInterval() { - return rxSleepInterval; + return sleepInterval; } command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) @@ -341,17 +403,17 @@ implementation command uint16_t LowPowerListening.getLocalDutyCycle() { - return call LowPowerListening.sleepIntervalToDutyCycle(rxSleepInterval); + return call LowPowerListening.sleepIntervalToDutyCycle(sleepInterval); } - command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepInterval) + command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t interval) { - if( sleepInterval < MIN_SLEEP ) - sleepInterval = 0; - else if( sleepInterval > MAX_SLEEP ) - sleepInterval = MAX_SLEEP; + if( interval < MIN_SLEEP ) + interval = 0; + else if( interval > MAX_SLEEP ) + interval = MAX_SLEEP; - call PacketSleepInterval.set(msg, sleepInterval); + call PacketSleepInterval.set(msg, interval); } command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg)