[Tinyos-2-commits] CVS: tinyos-2.x-contrib/tunit/tests/tinyos-2.x/tos/chips/general_radio_tests/TestMac Makefile, NONE, 1.1 TestMacC.nc, NONE, 1.1 TestMacP.nc, NONE, 1.1 suite.properties, NONE, 1.1

David Moss mossmoss at users.sourceforge.net
Fri Nov 9 09:16:01 PST 2007


Update of /cvsroot/tinyos/tinyos-2.x-contrib/tunit/tests/tinyos-2.x/tos/chips/general_radio_tests/TestMac
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv18666

Added Files:
	Makefile TestMacC.nc TestMacP.nc suite.properties 
Log Message:
Creation - from Miklos

--- NEW FILE: Makefile ---
COMPONENT=TestMacC
include $(MAKERULES)

--- NEW FILE: TestMacC.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
 */

configuration TestMacC
{
}

implementation
{
	components TestMacP, ActiveMessageC, new TestCaseC(), new TimerMilliC();

	TestMacP.SetUpOneTime -> TestCaseC.SetUpOneTime;
	TestMacP.TestCase -> TestCaseC.TestCase;
	TestMacP.TearDownOneTime -> TestCaseC.TearDownOneTime;

	components new StatisticsC() as RxThroughputC;
	TestMacP.RxThroughput -> RxThroughputC;
	components new StatisticsC() as RxCountC;
	TestMacP.RxCount -> RxCountC;
	components new StatisticsC() as RxMissingC;
	TestMacP.RxMissing -> RxMissingC;
	components new StatisticsC() as RxDuplicatesC;
	TestMacP.RxDuplicates -> RxDuplicatesC;
	components new StatisticsC() as TxThroughputC;
	TestMacP.TxThroughput -> TxThroughputC;
	components new StatisticsC() as TxCountC;
	TestMacP.TxCount -> TxCountC;
	components new StatisticsC() as TxNotAckedC;
	TestMacP.TxNotAcked -> TxNotAckedC;
	components new StatisticsC() as TxFailedC;
	TestMacP.TxFailed -> TxFailedC;

	TestMacP.SplitControl -> ActiveMessageC;
	TestMacP.AMSend -> ActiveMessageC.AMSend[0x17];
	TestMacP.Receive -> ActiveMessageC.Receive[0x17];
	TestMacP.Snoop -> ActiveMessageC.Snoop[0x17];
	TestMacP.PacketAcknowledgements -> ActiveMessageC;
	TestMacP.Timer -> TimerMilliC;
}

--- NEW FILE: TestMacP.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 <Timer.h>
#include "TestCase.h"

module TestMacP
{
	uses
	{
		interface TestControl as SetUpOneTime;
		interface TestCase;
		interface TestControl as TearDownOneTime;

		interface Statistics as RxThroughput;
		interface Statistics as RxCount;
		interface Statistics as RxMissing;
		interface Statistics as RxDuplicates;
		interface Statistics as TxThroughput;
		interface Statistics as TxCount;
		interface Statistics as TxNotAcked;
		interface Statistics as TxFailed;

		interface SplitControl;
		interface AMSend;
		interface Receive;
		interface Receive as Snoop;
		interface PacketAcknowledgements;
		interface Timer<TMilli>;
	}
}

implementation
{
/* ----- message ----- */

	typedef struct test_msg_t
	{
		uint8_t source;		// in the range [0, MAX_SOURCE-1]
		uint32_t sequence;	// in the range [1, expected]
		uint8_t stuff[23];
	} test_msg_t;

	enum
	{
		STATE_READY = 0,
		STATE_RUNNING = 1,
		STATE_STOPPED = 2,
	};
	uint8_t state;

	void realStart();

/* ----- receive ----- */

	enum { MAX_SOURCE = 10 };

	typedef struct rx_stat_t
	{
		uint32_t expected;		// the number of messages we expect
		uint32_t sequence;		// the last sequence number we saw, starts from 1
		uint32_t missing;		// the number of missing packets
		uint32_t duplicates;	// the number of duplicate packets
		uint32_t errors;		// backward jumps in the sequence numbers
		uint32_t firstTime;		// when was the first message received
		uint32_t lastTime;		// when was the last message received
	} rx_stat_t;

	rx_stat_t rxStats[MAX_SOURCE];

	void receive(message_t* msg)
	{
		uint8_t source = ((test_msg_t*)(msg->data))->source;
		uint32_t seq = ((test_msg_t*)(msg->data))->sequence;

		// start up the slave nodes
		if( state == STATE_READY )
		{
			if( TOS_NODE_ID == 0 )
				assertFail("unexpected test message before startup");
			else
				realStart();
		}
		else if( state != STATE_RUNNING )
			return;

		if( source < MAX_SOURCE && 0 < seq && seq <= rxStats[source].expected )
		{
			if( rxStats[source].sequence == seq )
				rxStats[source].duplicates += 1;
			else if( rxStats[source].sequence > seq )
				rxStats[source].errors += 1;
			else 
				rxStats[source].missing += seq - rxStats[source].sequence - 1;

			rxStats[source].lastTime = call Timer.getNow();
			if( rxStats[source].sequence == 0 )
				rxStats[source].firstTime = rxStats[source].lastTime;

			rxStats[source].sequence = seq;
		}
		else
			assertFail("unexpected test message received");
	}

	event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len)
	{
		receive(msg);
		return msg;
	}
	
	event message_t* Snoop.receive(message_t* msg, void* payload, uint8_t len)
	{
		receive(msg);
		return msg;
	}
	
	void rxReport(uint8_t id)
	{
		call RxThroughput.log("pkts/sec", (1000.0 * (rxStats[id].sequence - rxStats[id].missing - 1)) / (float)(rxStats[id].lastTime - rxStats[id].firstTime));
		call RxCount.log("pkts", rxStats[id].sequence - rxStats[id].missing);
		call RxMissing.log("1/1000 pkts", (rxStats[id].missing + rxStats[id].expected - rxStats[id].sequence) * 1000.0 / rxStats[id].expected);
		call RxDuplicates.log("1/1000 pkts", rxStats[id].duplicates * 1000.0 / rxStats[id].expected);

		assertEquals("rx sequence number error", 0, rxStats[id].errors);
	}

/* ----- transmit ----- */

	message_t txMsg;
	uint32_t txSequence;
	uint32_t txBusy;
	uint32_t txUnacked;
	uint32_t txCount;
	uint32_t txFirstTime;
	uint32_t txLastTime;

	uint8_t sendSource;
	uint8_t sendTarget;

	task void sendTask()
	{
		test_msg_t* data;
		
		if( state != STATE_RUNNING )
			return;

		if( txSequence == 0 )
			txFirstTime = call Timer.getNow();

		data = (test_msg_t*)(txMsg.data);
		data->source = sendSource;
		data->sequence = txSequence + 1;

		call PacketAcknowledgements.requestAck(&txMsg);
		if( call AMSend.send(sendTarget, &txMsg, sizeof(test_msg_t)) != SUCCESS )
		{
			++txBusy;
			post sendTask();
		}
	}

	event void AMSend.sendDone(message_t* msg, error_t error)
	{
		txLastTime = call Timer.getNow();

		if( error != SUCCESS )
		{
			++txBusy;
			post sendTask();
		}
		else
		{
			if( ! call PacketAcknowledgements.wasAcked(msg) )
				++txUnacked;

			if( ++txSequence < txCount )
				post sendTask();
		}
	}

	void txReport()
	{
		call TxThroughput.log("pkts/sec", 1000.0 * txSequence / (txLastTime - txFirstTime));
		call TxCount.log("pkts", txSequence);
		call TxNotAcked.log("1/1000 pkts", txUnacked * 1000.0 / txSequence);
		call TxFailed.log("1/1000 pkts", txBusy * 1000.0 / txSequence);
	}

/* ----- real test ----- */

	enum { TEST_DURATION = 15000 };

	// called once for each node
	void realStart()
	{
		if( state != STATE_READY )
			assertFail("unexpected real start");

		state = STATE_RUNNING;

		txCount = 1000;
		sendSource = TOS_NODE_ID;
		sendTarget = (TOS_NODE_ID + 1) % 2;

		rxStats[sendTarget].expected = 1000;
		rxStats[sendTarget].sequence = -1;

		call Timer.startOneShot(TEST_DURATION);
		post sendTask();
	}

	event void Timer.fired()
	{
		if( state == STATE_RUNNING )
		{
			state = STATE_STOPPED;

			txReport();
			rxReport(sendTarget);

			if( TOS_NODE_ID == 0 )
				call Timer.startOneShot(2000);	// settle down
		}
		else if( state == STATE_STOPPED )
			call TestCase.done();
	}

/* ----- startup / shutdown ----- */
	
	task void splitStart()
	{
		if( call SplitControl.start() != SUCCESS )
			post splitStart();
	}

	event void SetUpOneTime.run()
	{
		post splitStart();
	}

	event void SplitControl.startDone(error_t error)
	{
		if( error != SUCCESS )
			post splitStart();
		else
			call SetUpOneTime.done();
	}

	task void splitStop()
	{
		if( call SplitControl.stop() != SUCCESS )
			post splitStop();
	}

	event void TearDownOneTime.run()
	{
		post splitStop();
	}

	event void SplitControl.stopDone(error_t error)
	{
		if( error != SUCCESS )
			post splitStop();
		else
			call TearDownOneTime.done();
	}

	event void TestCase.run()
	{
		if( TOS_NODE_ID != 0 )
			assertFail("unexpected testcase run");
		else
			realStart();
	}
}

--- NEW FILE: suite.properties ---
/**
 * Valid keywords are:
 *  @author <optional author(s)>  (multiple)
 *  @testname <optional testname>  (once)
 *  @description <optional, multiline description>  (once)
 *  @extra <any build/install extras> (multiple)
 *  @ignore <single target>  (multiple)
 *  @only <single target> (multiple)
 *  @minnodes <# nodes>  (once)
 *  @maxnodes <# nodes>  (once)
 *  @exactnodes <# of exact nodes>  (once)
 *  @mintargets <# of minimum targets for heterogeneous network testing>  (once)
 *  @timeout <timeout duration of the test in minutes, default is 1 min.>
 *  @skip  (once)
 */

@testname MAC 0<->1 with acks
@author Miklos Maroti
@timeout 1
@exactnodes 2
@description Tests the performance of the MAC layer when two nodes are sending 
full packets to each other as fast as they can with acknowledgements enabled.

@extra CFLAGS+=-DCC2420_DEF_CHANNEL=11
@extra CFLAGS+=-DCC2420_NO_ADDRESS_RECOGNITION
@extra CFLAGS+=-DRF230_DEF_CHANNEL=11
@extra CFLAGS+=-DTASKLET_IS_TASK




More information about the Tinyos-2-commits mailing list