⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lowpowerlisteninglayerp.nc

📁 tinyos2.0版本驱动
💻 NC
字号:
/* * Copyright (c) 2007, Vanderbilt 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 THE VANDERBILT 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 THE VANDERBILT * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *  * THE VANDERBILT 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 THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * Author: Miklos Maroti */#include <RadioAssert.h>module LowPowerListeningLayerP{provides	{interface SplitControl;interface Send;interface Receive;interface LowPowerListening;	}uses	{interface SplitControl as SubControl;interface Send as SubSend;interface Receive as SubReceive;interface PacketField<uint16_t> as PacketSleepInterval;interface IEEE154Packet;interface PacketAcknowledgements;interface Timer<TMilli>;	}}implementation{enum	{		// 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;message_t* txMsg;uint8_t txLen;error_t txError;/*----------------- state machine -----------------*/enum	{		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;task void transition(){error_t error;uint16_t transmitInterval;if( state == LISTEN_SUBSTART || state == SEND_SUBSTART ){  error = call SubControl.start();  ASSERT( error == SUCCESS || error == EBUSY );  if( error == SUCCESS )	++state;  else    post transition();}else if( state == SLEEP_SUBSTOP || state == OFF_SUBSTOP ){  error = call SubControl.stop();  ASSERT( error == SUCCESS || error == EBUSY );  if( error == SUCCESS )    ++state;  else    post transition();}else if( state == OFF_START_END ){  state = LISTEN_SUBSTART;  post transition();  signal SplitControl.startDone(SUCCESS);}		else if( state == OFF_STOP_END )		{			state = OFF;			signal SplitControl.stopDone(SUCCESS);		}		else if( state == LISTEN_TIMER )		{			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 = LISTEN_SUBSTART;				post transition();			}		}		else if( state == SEND_TIMER )		{			transmitInterval = call LowPowerListening.getRxSleepInterval(txMsg);			if( transmitInterval > 0 )				call Timer.startOneShot(transmitInterval);			state = SEND_SUBSEND;			post transition();		}		else if( state == SEND_SUBSEND)		{			txError = call SubSend.send(txMsg, txLen);			if( txError == SUCCESS )				state = SEND_SUBSEND_DONE;			else			{				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 == OFF_START_END )			return EBUSY;		else if( state != OFF )			return EALREADY;		state = OFF_START_END;		post transition();		return SUCCESS;	}	event void SubControl.startDone(error_t error)	{		ASSERT( error == SUCCESS || error == EBUSY );		ASSERT( state == LISTEN_SUBSTART_DONE || state == SEND_SUBSTART_DONE );		if( error == SUCCESS )			++state;		else			--state;		post transition();	}	command error_t SplitControl.stop()	{		if( state == SLEEP || state == LISTEN )		{			call Timer.stop();			post transition();		}		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			return EBUSY;		return SUCCESS;	}	event void SubControl.stopDone(error_t error)	{		ASSERT( error == SUCCESS || error == EBUSY );		ASSERT( state == SLEEP_SUBSTOP_DONE || state == OFF_SUBSTOP_DONE );		if( error == SUCCESS )			++state;		else			--state;		post transition();	}	event void Timer.fired()	{		ASSERT( state == LISTEN || state == SLEEP || state == SEND_SUBSEND || state == SEND_SUBSEND_DONE );		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();	}	event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len)	{		if( state == SLEEP_SUBSTOP )			state = LISTEN;		if( state == LISTEN && sleepInterval > 0 )			call Timer.startOneShot(AFTER_RECEIVE);		return signal Receive.receive(msg, payload, len);	}	command error_t Send.send(message_t* msg, uint8_t len)	{		if( state == LISTEN || state == SLEEP )		{			call Timer.stop();			post transition();		}		if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP )			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;		return SUCCESS;	}	command error_t Send.cancel(message_t* msg)	{		if( state == SEND_SUBSEND )		{			call Timer.stop();			state = SEND_DONE;			txError = ECANCEL;			post transition();			return SUCCESS;		}		else if( state == SEND_SUBSEND_DONE )		{			// we stop sending the message even if SubSend.cancel was not succesfull			state = SEND_SUBSEND_DONE_LAST;			return call SubSend.cancel(txMsg);		}		else			return FAIL;	}	event void SubSend.sendDone(message_t* msg, error_t error)	{		ASSERT( state == SEND_SUBSEND_DONE || state == SEND_SUBSEND_DONE_LAST );		ASSERT( msg == txMsg );		txError = 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()	{		return call SubSend.maxPayloadLength();	}	command void* Send.getPayload(message_t* msg, uint8_t len)	{		return call SubSend.getPayload(msg, len);	}/*----------------- LowPowerListening -----------------*/	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)    {		if( interval < MIN_SLEEP )			interval = 0;		else if( interval > MAX_SLEEP )			interval = MAX_SLEEP;		sleepInterval = interval;		if( (state == LISTEN && sleepInterval == 0) || state == SLEEP )		{			call Timer.stop();			--state;			post transition();		}	}	command uint16_t LowPowerListening.getLocalSleepInterval()    {			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)	{		if( interval < MIN_SLEEP )			interval = 0;		else if( interval > MAX_SLEEP )			interval = MAX_SLEEP;		call PacketSleepInterval.set(msg, interval);	}	command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg)    {      if( ! call PacketSleepInterval.isSet(msg) )        return sleepInterval;      return call PacketSleepInterval.get(msg);	}	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));	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -