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

📄 slottedcollisionlayerp.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 <Tasklet.h>#include <RadioAssert.h>module SlottedCollisionLayerP{	provides	{		interface RadioSend;		interface RadioReceive;		interface Init;	}	uses	{		interface RadioSend as SubSend;		interface RadioReceive as SubReceive;		interface RadioAlarm;		interface Random;		interface SlottedCollisionConfig as Config;#ifdef RF230_DEBUG		interface DiagMsg;#endif	}}implementation{/* ----- random ----- */	uint16_t nextRandom;	task void calcNextRandom()	{		uint16_t a = call Random.rand16();		atomic nextRandom = a;	}	uint16_t getNextRandom()	{		uint16_t a;		atomic		{			a = nextRandom;			nextRandom += 273;		}		post calcNextRandom();		return a;	}/* ----- schedule selection ----- */	tasklet_async event bool SubReceive.header(message_t* msg)	{		return signal RadioReceive.header(msg);	}	// WARNING!!! Do not change these values, the error values can overflow	enum	{		ERROR_DECAY = 3,		ERROR_SWITCH = 30,		// should be a multiple of (1 << decay)		ERROR_COLLISION = 20,	// must be less than (255 - switch) >> decay		ERROR_BUSY = 1,			// must be less than collision		ERROR_INITIAL = 80,		// must be less than giveup		ERROR_GIVEUP = 120,		// must be less than collision * (1 << decay)		ERROR_REPRESS = 40,		// must be more than switch		ERROR_MAX = 255,	};	/**	 * Returns TRUE if time is between start and start + window 	 * modulo the schedule size of (1 << exponent)	 */	inline bool isBetween(uint8_t exponent, uint16_t time, uint16_t start, uint16_t length)	{		return (uint16_t)((time - start) & ((1 << exponent) - 1)) < length;	}	tasklet_norace uint16_t schedule1;	tasklet_norace uint16_t schedule2;	tasklet_norace uint8_t error1;	tasklet_norace uint8_t error2;	tasklet_async event message_t* SubReceive.receive(message_t* msg)	{		uint8_t exponent = call Config.getScheduleExponent();		uint16_t start = call Config.getCollisionWindowStart(msg);		uint16_t length = call Config.getCollisionWindowLength(msg);		error1 -= error1 >> ERROR_DECAY;		if( isBetween(exponent, schedule1, start, length) )			error1 += ERROR_COLLISION; 		error2 -= error2 >> ERROR_DECAY;		if( isBetween(exponent, schedule2, start, length) )			error2 += ERROR_COLLISION;		if( error2 + ERROR_SWITCH <= error1 )		{			error1 = error2;			schedule1 = schedule2;			error2 = ERROR_GIVEUP;		}		if( error2 >= ERROR_GIVEUP )		{			error2 = ERROR_INITIAL;			schedule2 = getNextRandom();		}		return signal RadioReceive.receive(msg);	}	void printStats();	tasklet_async event void Config.timerTick()	{		if( error1 >= (1 << ERROR_DECAY) )			error1 -= error1 >> ERROR_DECAY;		else if( error1 > 0 )			--error1;		if( error2 >= (1 << ERROR_DECAY) )			error2 -= error2 >> ERROR_DECAY;		else if( error2 > 0 )			--error2;		printStats();	}/* ------ transmit ------ */	tasklet_norace uint8_t state;	enum	{		STATE_READY = 0,		STATE_PENDING = 1,		STATE_SENDING = 2,	};	enum { DELAY_DECAY = 2 };	tasklet_norace message_t *txMsg;	tasklet_norace uint16_t txDelay;	// the averaged delay between schedule and timestamp	tasklet_norace uint16_t txTime;		// the schedule time of transmission	tasklet_async event void SubSend.ready()	{		if( state == STATE_READY && call RadioAlarm.isFree() )			signal RadioSend.ready();	}	tasklet_async command error_t RadioSend.send(message_t* msg)	{		uint16_t backoff;		uint16_t time;		// TODO: we could supress transmission while error is large		if( state != STATE_READY || ! call RadioAlarm.isFree() || error1 >= ERROR_REPRESS )			return EBUSY;		txMsg = msg;		state = STATE_PENDING;		time = call RadioAlarm.getNow();		backoff = 1 + ((schedule1 - time - (txDelay >> DELAY_DECAY))			& ((1 << call Config.getScheduleExponent()) - 1));		backoff += getNextRandom() & (3 << call Config.getScheduleExponent());		call RadioAlarm.wait(backoff);		txTime = time + backoff;		return SUCCESS;	}	tasklet_async event void RadioAlarm.fired()	{		error_t error;		ASSERT( state == STATE_PENDING );		error = call SubSend.send(txMsg);		if( error == SUCCESS )			state = STATE_SENDING;		else		{			if( error2 + ERROR_SWITCH <= error1 )			{				error1 = error2;				schedule1 = schedule2;				error2 = ERROR_INITIAL;				schedule2 = getNextRandom();			}			else if( error1 < ERROR_MAX - ERROR_BUSY )				error1 = error1 + ERROR_BUSY;			state = STATE_READY;			signal RadioSend.sendDone(error);		}	}	tasklet_async event void SubSend.sendDone(error_t error)	{		ASSERT( state == STATE_SENDING );		if( error == SUCCESS )		{			txDelay += (call Config.getTransmitTime(txMsg) - txTime) - (txDelay >> DELAY_DECAY);			ASSERT( (txDelay >> DELAY_DECAY) < (1 << call Config.getScheduleExponent()) );		}		state = STATE_READY;		signal RadioSend.sendDone(error);	}/* ------ init  ------ */	command error_t Init.init()	{		// do not use Random here because it might not be initialized		schedule1 = (uint16_t)(TOS_NODE_ID * 1973);		schedule2 = schedule1 + 0117;		txDelay = call Config.getInitialDelay() << DELAY_DECAY;		return SUCCESS;	}#ifdef RF230_DEBUG	tasklet_norace uint8_t count;	void printStats()	{		if( ++count > 10 && call DiagMsg.record() )		{			count = 0;			call DiagMsg.str("slotted");			call DiagMsg.uint16(txDelay >> DELAY_DECAY);			call DiagMsg.uint16(schedule1);			call DiagMsg.uint8(error1);			call DiagMsg.uint16(schedule2);			call DiagMsg.uint8(error2);			call DiagMsg.send();		}	}#else	void printStats() { }#endif}

⌨️ 快捷键说明

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