[Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/imote2/tos/lib/TimeSync
GlobalTime.nc, NONE, 1.1 SysTimeStampingC.nc, NONE,
1.1 SysTimeStampingM.nc, NONE, 1.1 TimeStamping.nc, NONE,
1.1 TimeSync.txt, NONE, 1.1 TimeSyncC.nc, NONE,
1.1 TimeSyncInfo.nc, NONE, 1.1 TimeSyncM.nc, NONE,
1.1 TimeSyncMode.nc, NONE, 1.1 TimeSyncMsg.h, NONE,
1.1 TimeSyncNotify.nc, NONE, 1.1
Lama Nachman
lnachman at users.sourceforge.net
Tue Oct 10 17:10:24 PDT 2006
- Previous message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/imote2/tos/lib/TimeSync - New directory
- Next message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/imote2/tos/lib/FlashLogger
BlockStorage.h, NONE, 1.1 FileMount.nc, NONE, 1.1 FileRead.nc,
NONE, 1.1 FileStorage.nc, NONE, 1.1 FileWrite.nc, NONE,
1.1 FlashLoggerC.nc, NONE, 1.1 FlashLoggerM.nc, NONE,
1.1 Storage.h, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-1.x/contrib/imote2/tos/lib/TimeSync
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv29096
Added Files:
GlobalTime.nc SysTimeStampingC.nc SysTimeStampingM.nc
TimeStamping.nc TimeSync.txt TimeSyncC.nc TimeSyncInfo.nc
TimeSyncM.nc TimeSyncMode.nc TimeSyncMsg.h TimeSyncNotify.nc
Log Message:
Pushed out new release, OCT 2006
--- NEW FILE: GlobalTime.nc ---
/*
* Copyright (c) 2002-2003, 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, Brano Kusy
* Date last modified: Oct/04
* - moved getOffset, getSkew, and getSyncPt to TimeSyncInfo interface
*
*/
interface GlobalTime
{
/**
* Returns the current local time of this mote. The local time can
* either be the SysTime as returned by SysTimeC (if the
* TIMESYNC_SYSTIME macro is defined) or the ClockTime as returned
* by the LocalTime interface of the ClockC component (if the
* TIMESYNC_SYSTIME is not defined).
*/
async command result_t getLocalTime(uint32_t *timeLow, uint32_t *timeHigh);
/**
* Reads the current global time. This method is a combination
* of <code>getLocalTime</code> and <code>local2Global</code>.
* @return SUCCESS if this mote is synchronized, FAIL otherwise.
*/
async command result_t getGlobalTime(uint32_t *timeLow, uint32_t *timeHigh);
/**
* Converts the local time given in <code>time</code> into the
* corresponding global time and stores this again in
* <code>time</code>. The following equation is used to compute the
* conversion:
*
* globalTime = localTime + offset + skew * (localTime - syncPoint)
*
* The skew is normalized to 0.0 (1.0 is subtracted) to increase the
* machine precision. The syncPoint value is periodically updated to
* increase the machine precision of the floating point arithmetic and
* also to allow time wrap.
*
* @return SUCCESS if this mote is synchronized, FAIL otherwise.
*/
async command result_t local2Global(uint32_t *time, uint32_t *timeHigh);
/**
* Converts the global time given in <code>time</code> into the
* correspoding local time and stores this again in
* <code>time</code>. This method performs the inverse of the
* <code>local2Global</clode> transformation.
*
* @return SUCCESS if this mote is synchronized, FAIL otherwise.
*/
async command result_t global2Local(uint32_t *time, uint32_t *timeHigh);
}
--- NEW FILE: SysTimeStampingC.nc ---
/*
* @author: Brano Kusy, kusy at isis.vanderbilt.edu
* Date last modified: jan05
*
* provides timestamping on transmitting/receiving SFD interrupt,uses
* SysTime (Timer3) to get local time
*
*/
configuration SysTimeStampingC
{
provides
{
interface TimeStamping;
}
}
implementation
{
components SysTimeStampingM, CC2420RadioM, SysTimeC, LedsC, HPLCC2420M;
TimeStamping = SysTimeStampingM;
SysTimeStampingM.RadioSendCoordinator -> CC2420RadioM.RadioSendCoordinator;
SysTimeStampingM.RadioReceiveCoordinator -> CC2420RadioM.RadioReceiveCoordinator;
SysTimeStampingM.SysTime64 -> SysTimeC;
SysTimeStampingM.Leds -> LedsC;
SysTimeStampingM.HPLCC2420RAM -> HPLCC2420M;
}
--- NEW FILE: SysTimeStampingM.nc ---
/*
* @author: Brano Kusy, kusy at isis.vanderbilt.edu
* Date last modified: jan05
*
* provides timestamping on transmitting/receiving SFD interrupt,uses
* SysTime (Timer3) to get local time
*/
#include "AM.h"
module SysTimeStampingM
{
provides
{
interface TimeStamping;
}
uses
{
interface RadioCoordinator as RadioSendCoordinator;
interface RadioCoordinator as RadioReceiveCoordinator;
interface SysTime64;
interface Leds;
interface HPLCC2420RAM;
}
}
implementation
{
// the offset of the time-stamp field in the message,
// or -1 if no stamp is necessariy.
norace int8_t sendStampOffset = -1;
norace int8_t sendStampOffsetHigh = -1;
uint32_t rcv_time, send_time, rcv_timeHigh, send_timeHigh;
norace TOS_MsgPtr ptosMsg;
enum{
TX_FIFO_MSG_START = 10,
SEND_TIME_CORRECTION = -2300,
};
async event void RadioSendCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff)
{
int32_t temp;
uint8_t i, *ptr, *srcPtr, *dstPtr;
if (ptosMsg != 0 && ptosMsg != msgBuff)
return;
//atomic send_time = call SysTime.getTime32() - SEND_TIME_CORRECTION;
atomic call SysTime64.getTime64(&send_time, &send_timeHigh);
//temp = *(int32_t*)((void*)msgBuff->data+sendStampOffset);
ptr = &msgBuff->data;
//trace(DBG_USR1,"sendOff=%d sendOffHi=%d\r\n",sendStampOffset,sendStampOffsetHigh);
memcpy(&temp,ptr+sendStampOffset,4);
send_time += temp;
//temp = *(int32_t*)((void*)msgBuff->data+sendStampOffsetHigh);
ptr = &msgBuff->data;
memcpy(&temp,ptr+sendStampOffsetHigh,4);
send_timeHigh += temp;
//call Leds.redToggle();
if( sendStampOffset < 0 )
return;
/* *(uint32_t*)((void*)msgBuff->data + sendStampOffset) += send_time;
*(uint32_t*)((void*)msgBuff->data + sendStampOffsetHigh) += send_timeHigh;
send_time = *(uint32_t*)((void*)msgBuff->data + sendStampOffset);
send_timeHigh = *(uint32_t*)((void*)msgBuff->data + sendStampOffsetHigh);*/
//call HPLCC2420RAM.write(TX_FIFO_MSG_START + sendStampOffset, 8, (void*)msgBuff->data + sendStampOffset);
call HPLCC2420RAM.write(TX_FIFO_MSG_START + sendStampOffset, 4, &send_time);
call HPLCC2420RAM.write(TX_FIFO_MSG_START + sendStampOffsetHigh, 4, &send_timeHigh);
sendStampOffset = -1;
//trace (DBG_USR1,"send_time: %x\r\n",send_time);
}
task void postPrintRcvTime(){
trace (DBG_USR1,"rcv_time: %x\r\n",rcv_time);
}
async event void RadioReceiveCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff)
{
atomic {
call SysTime64.getTime64(&rcv_time, &rcv_timeHigh);
}
//call Leds.greenToggle();
//post postPrintRcvTime();
}
command result_t TimeStamping.getStamp(uint32_t *tLow, uint32_t *tHigh)
{
atomic {
*tLow=rcv_time;
*tHigh=rcv_timeHigh;
}
return SUCCESS;
}
/*
command uint32_t TimeStamping.getSendTime() {
uint32_t tmp;
atomic tmp=send_time;
return tmp;
}
*/
//this needs to be called right after SendMsg.send() returned success, so
//the code in addStamp() method runs before a task in the radio stack is
//posted that writes to fifo -> which triggers coordinator event
//if a msg is already being served by the radio, (sendStampOffset is
//defined), timestamping returns fail
/*
command result_t TimeStamping.addStamp(int8_t offset)
{
if(sendStampOffset<0 && 0 <= offset && offset <= TOSH_DATA_LENGTH-4 ){
atomic sendStampOffset = offset;
ptosMsg = 0;
return SUCCESS;
}
else
sendStampOffset = -1;
return FAIL;
}
*/
command result_t TimeStamping.addStamp2(TOS_MsgPtr msg, int8_t offset, int8_t offsetHigh)
{
if(sendStampOffset<0 && 0 <= offset && offset <= TOSH_DATA_LENGTH-4 ){
atomic {
sendStampOffset = offset;
sendStampOffsetHigh = offsetHigh;
}
ptosMsg = msg;
return SUCCESS;
}
else
sendStampOffset = -1;
return FAIL;
}
async event result_t HPLCC2420RAM.readDone(uint16_t addr, uint8_t length, uint8_t* buffer){
return SUCCESS;
}
async event result_t HPLCC2420RAM.writeDone(uint16_t addr, uint8_t length, uint8_t* buffer){
return SUCCESS;
}
async event void RadioSendCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
async event void RadioSendCoordinator.blockTimer() { }
async event void RadioReceiveCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
async event void RadioReceiveCoordinator.blockTimer() { }
async event result_t SysTime64.alarmFired(uint32_t val) { }
}
--- NEW FILE: TimeStamping.nc ---
/*
* Copyright (c) 2002, 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, Brano Kusy (kusy at isis.vanderbilt.edu)
* Date last modified: 10/11/05
*
* addStamp() is now depricated, see below for more info
*
*/
interface TimeStamping
{
/**
* Returns the time stamp of the last received message. This
* method should be called when the ReceiveMsg.receive() is fired.
* The returned value contains the 32-bit local time when the message
* was received.
*/
command result_t getStamp(uint32_t *tLow, uint32_t *tHigh);
/**
* Adds a time stamp to the next message sent by the radio. This
* method must be called immediatelly after SendMsg.send() returns
* SUCCESS. The message must include space for the 32-bit time stamp.
* The offset parameter is the offset of the time stamp field
* in the TOS_Msg.data payload. It must be a value between 0 and 25,
* although implementations can require a smaller range (e.g. [2,25]).
* It is advisable to put the time stamp field at the end of the message.
* The local time will be ADDED to this time stamp field in the message
* at the time of transmission. Therefore, if the time stamp field
* is initialized to 0 when SendMsg.send() is invoked, the receiver
* will receive the local time of the sender when it actually sent the
* message. On the other hand, if the time stamp field in the message
* is initialized with the negative of the local time of some event,
* then the receiver will receive the elapsed time since that event.
* @return SUCCESS if the offset is in the valid range, or FALSE
* if the message will not be time stamped.
*
* use:
* if( call SendMsg.send(ADDR, MSG_LEN, &msg) )
* call TimeStamping.addStamp(offsetof(struct MsgData, timeStampField));
*
* DEPRICATED - see addStamp2() !!!!!!!!!!!!!
*/
//command result_t addStamp(int8_t offset);
/**
* The same as addStamp(), getStamp() commands, we just remembers pointer to the
* timestamped TOS msg to avoid timestamping different TOS packets.
* Pointers to the message can be easily obtained from the SendMsg.send() command resp
* RcvMsg.receive() event handlers (which are anyways the places where you need to
* query for the message timestamp).
*/
command result_t addStamp2(TOS_MsgPtr msg, int8_t offset, int8_t offsetHigh);
}
--- NEW FILE: TimeSync.txt ---
authors/contact:
brano kusy, kusy at isis.vanderbilt.edu
miklos maroti
directory shortcuts: $cvs = tinyos-1.x directory of std tinyos release
$vu = $cvs/contrib/vu
further information:
- algorithm/evaluation: our sensys'04 paper
- timestamping: doc files for $cvs/tos/platform/mica2/SysTimeStamping, or
$vu/system/ClockTimeStamping
- how to deploy: $vu/apps/TestTimeSync docs
supported platforms: mica2, mica2dot,
telso(only 32kHz clock available),
micaz(only 1MHz clock available),
mica(used to work, not supported any longer)
description:
------------
TimeSyncC component provides continuous global time service:
(1)global time is local time of the elected leader of the network - the root and
other nodes synchronize to this global time.
(2)this is flooding algorihtm: each node bcasts timesync msgs once per 30 secs;
(3)algorithm compensates for the clock drift wrt clock crystal of the root: each
node keeps a certain number of msgs in regression table and (re)calculates skew
of its local time vs global time when a new timesync msg comes.
(4)two different clock sources can be used with TimeSyncC component: CPU
crystal(7.37MHz) or external crystal(32kHz), this is allowed by separation of
timestamping mechanism from timesync
interfaces:
-----------
StdControl: interface to start/stop time-sync, init() needs to be called
GlobalTime: provides methods to obtain global time in network, and means to
transform global time to local time and vice versa
TimeSyncInfo: provides accessors to internal time-sync information
TimeSyncMode: user/timer based sending of time-sync msgs
TimeSyncNotify: coordinator interfaces, provide hooks to time-sync module
testing:
--------
***see contribu/vu/apps/testtimesync directory for more details.***
parameters:
-----------
settable in Makefile:
TIMESYNC_RATE - period (seconds) in which each node broadcasts time sync msg
TIMESYNC_SYSTIME - specify wether external crystal or CPU is used for timing
TIMESYNC_DEBUG - multihop is simulated in software, see ReceiveMsg.receive()
event in TimeSyncM and TestTimeSync application
sample use in Makefile:
PFLAGS := $(PFLAGS) -DTIMESYNC_SYSTIME -DTIMESYNC_RATE=20 -DTIMESYNC_DEBUG
wiring:
-------
TimeSyncC must be initialized via StdControl. once inited, use GlobalTime
interface to obtain the global time in the network. TimeSync is using
GenericComm and Timer, so the upmost app has to initialize these two components.
your code should look like:
Main.StdControl -> TimerC;
Main.StdControl -> GenericComm;
Main.StdControl -> TimesyncC;
required system files:
----------------------
1) you will need the following files from the $vu/tos directory in order to use
the TimeSync component with CPU clock (TIMESYNC_SYSTIME is defined):
lib/TimeSync
lib/platform/mica2
2) if using external clock (TIMESYNC_SYSTIME is NOT defined) you need the
following files from $vu/tos directory:
lib/TimeSync/*
platform/avrmote/*
system/ClockTimeStamping*
!warning - Clock.nc interface divereged from the original quite a bit -> u may
experience compatibility issues, we're looking into solving this
3) for telos and micaz you need to include $vu/tos/lib/CC2420 directory
Makefile:
--------
if you have a full copy of the tinyos-1.x cvs tree, Makefile of your app should
look like:
1) CPU timing:
COMPONENT=xxxxxxxx
VUDIR=%T/../contrib/vu/tos
PFLAGS += -I$(VUDIR)/lib/TimeSync -I$(VUDIR)/platform/mica2
PFLAGS += -DTIMESYNC_SYSTIME -DTIMESYNC_RATE=60
include ../Makerules
2) for external crystal:
COMPONENT=xxxxxxxx
VUDIR=%T/../contrib/vu/tos
PFLAGS += -I$(VUDIR)/lib/TimeSync -I$(VUDIR)/platform/avrmote -I$(VUDIR)/mica2
PFLAGS += -DTIMESYNC_RATE=60
include ../Makerules
3)telos/micaz:
add PFLAGS += -I$(VUDIR)/lib/CC2420 before all other includes described in 1) or 2)
(see vu/apps/TestTimeSync how to resolve conflicts between mica2 and micaz/telos
files)
--- NEW FILE: TimeSyncC.nc ---
/*
* Copyright (c) 2002, 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, Brano Kusy
* Date last modified: 3/17/03
*/
includes TimeSyncMsg;
configuration TimeSyncC
{
provides interface StdControl;
provides interface GlobalTime;
//interfaces for extra fcionality: need not to be wired
provides interface TimeSyncInfo;
provides interface TimeSyncMode;
provides interface TimeSyncNotify;
}
implementation
{
components TimeSyncM, TimerC, GenericComm, CommModuleC, LedsC, Main, BluSHC,
#if defined(PLATFORM_MICA2) || defined(PLATFORM_MICA2DOT)
#ifdef TIMESYNC_SYSTIME
SysTimeC, SysTimeStampingC as TimeStampingC;
#else
ClockC, ClockTimeStampingC as TimeStampingC;
#endif
#elif PLATFORM_MICAZ
#ifdef TIMESYNC_SYSTIME
SysTimeC, SysTimeStampingC as TimeStampingC;
#else
#not_supported!
//implementation of CC2420 on micaZ uses Timer0 which conflicts with
//Vanderbilt Clock* and Timer* components. as there is no component that
//would provide 4 byte local time driven by 32kHz external crystal on
//micaz, we support only CPU clock.
#endif
#elif PLATFORM_IMOTE2
#ifdef TIMESYNC_SYSTIME
SysTimeC, SysTimeStampingC as TimeStampingC;
#else
//#not_supported!
//implementation of CC2420 on micaZ uses Timer0 which conflicts with
//Vanderbilt Clock* and Timer* components. as there is no component that
//would provide 4 byte local time driven by 32kHz external crystal on
//micaz, we support only CPU clock.
#endif
#elif PLATFORM_TELOS
TimeStampingC
#ifdef TIMESYNC_SYSTIME
,LocalTimeMicroC;
#else
;
#endif
#endif
GlobalTime = TimeSyncM;
StdControl = TimeSyncM;
TimeSyncInfo = TimeSyncM;
TimeSyncMode = TimeSyncM;
TimeSyncNotify = TimeSyncM;
Main.StdControl -> TimerC;
// Main.StdControl -> GenericComm;
Main.StdControl -> CommModuleC;
Main.StdControl -> SysTimeC;
//TimeSyncM.SendMsg -> GenericComm.SendMsg[AM_TIMESYNCMSG];
//TimeSyncM.ReceiveMsg -> GenericComm.ReceiveMsg[AM_TIMESYNCMSG];
TimeSyncM.SendMsg -> CommModuleC.SendMsg[AM_TIMESYNCMSG];
TimeSyncM.ReceiveMsg -> CommModuleC.ReceiveMsg[AM_TIMESYNCMSG];
TimeSyncM.Timer -> TimerC.Timer[unique("Timer")];
TimeSyncM.Leds -> LedsC;
TimeSyncM.TimeStamping -> TimeStampingC;
TimeSyncM.ComputeByteOffset -> CommModuleC.ComputeByteOffset;
#if TIMESYNC_SYSTIME
#ifdef PLATFORM_TELOS
TimeSyncM.LocalTime -> LocalTimeMicroC;
#else
TimeSyncM.SysTime64 -> SysTimeC;
#endif
#else
#ifdef PLATFORM_TELOS
TimeSyncM.LocalTime -> TimerC;
#else
TimeSyncM.LocalTime -> ClockC;
#endif
#endif
BluSHC.BluSH_AppI[unique("BluSH")] -> TimeSyncM.tbl;
}
--- NEW FILE: TimeSyncInfo.nc ---
/*
* Copyright (c) 2002-2003, 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, Brano Kusy
* Date last modified: Oct/04
*/
interface TimeSyncInfo
{
/**
* Returns current offset of the local time wrt global time.
*/
async command uint32_t getOffset();
/**
* Returns current skew of the local time wrt global time.
* This value is normalized to 0.0 (1.0 is subtracted) to get maximum
* representation precision.
*/
async command float getSkew();
/**
* Returns the local time of the last synchronization point. This
* value is close to the current local time and updated when a new
* time synchronization message arrives.
*/
async command uint32_t getSyncPoint();
/**
* Returns the current root to which this node is synchronized.
*/
async command uint16_t getRootID();
/**
* Returns the latest seq number seen from the current root.
*/
async command uint8_t getSeqNum();
/**
* Returns the number of entries stored currently in the
* regerssion table.
*/
async command uint8_t getNumEntries();
/**
* Returns the value of heartBeats variable.
*/
async command uint8_t getHeartBeats();
async command uint16_t getSyncPeriod();
}
--- NEW FILE: TimeSyncM.nc ---
/*
* Copyright (c) 2002, 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, Brano Kusy (kusy at isis.vanderbilt.edu)
* Date last modified: jan05
*
* suggestions, contributions: Barbara Hohlt
* Janos Sallai
*/
includes Timer;
includes TimeSyncMsg;
includes trace;
module TimeSyncM
{
provides
{
interface StdControl;
interface GlobalTime;
//interfaces for extra fcionality: need not to be wired
interface TimeSyncInfo;
interface TimeSyncMode;
interface TimeSyncNotify;
interface BluSH_AppI as tbl;
}
uses
{
interface SendMsg;
interface ReceiveMsg;
interface Timer;
interface Leds;
interface TimeStamping;
interface SysTime64;
command result_t ComputeByteOffset(uint8_t* lo, uint8_t* hi);
}
}
implementation
{
enum {
MAX_ENTRIES = 8, // number of entries in the table
BEACON_RATE = TIMESYNC_RATE, // how often send the beacon msg (in seconds)
ROOT_TIMEOUT = 10, //time to declare itself the root if no msg was received (in sync periods)
IGNORE_ROOT_MSG = 4, // after becoming the root ignore other roots messages (in send period)
ENTRY_VALID_LIMIT = 8, // number of entries to become synchronized
ENTRY_SEND_LIMIT = 3, // number of entries to send sync messages
ENTRY_THROWOUT_LIMIT = 200
};
typedef struct TableItem {
uint32_t localLow;
uint32_t localHigh;
uint32_t globalLow;
uint32_t globalHigh;
} TableItem;
TableItem table[MAX_ENTRIES];
uint8_t tableEntries;
enum {
STATE_IDLE = 0x00,
STATE_PROCESSING = 0x01,
STATE_SENDING = 0x02,
STATE_INIT = 0x04,
};
uint8_t state, mode;
uint8_t lastSeqNumSent;
float calculatedPropagationTime;
int16_t compensationPropagationTime;
uint16_t syncPeriod, slowSyncPeriod, fastSyncPeriod;
uint8_t syncCounter, syncCounter2, Nburst;
#define ROOT_ID 0xbb
/*
We do linear regression from localTime to timeOffset (globalTime - localTime).
This way we can keep the slope close to zero (ideally) and represent it
as a float with high precision.
timeOffset - offsetAverage = skew * (localTime - localAverage)
timeOffset = offsetAverage + skew * (localTime - localAverage)
globalTime = localTime + offsetAverage + skew * (localTime - localAverage)
*/
double skew;
uint32_t localAverage;
int32_t offsetAverage;
uint8_t numEntries; // the number of full entries in the table
TOS_Msg processedMsgBuffer;
TOS_MsgPtr processedMsg;
TOS_Msg outgoingMsgBuffer;
#define outgoingMsg ((TimeSyncMsg*)outgoingMsgBuffer.data)
uint8_t heartBeats; // the number of sucessfully sent messages
// since adding a new entry with lower beacon id than ours
command BluSH_result_t tbl.getName(char *buff, uint8_t len){
const char name[] = "tb";
strcpy(buff,name);
return BLUSH_SUCCESS_DONE;
}
command BluSH_result_t tbl.callApp(char *cmdBuff, uint8_t cmdLen,
char *resBuff, uint8_t resLen){
int i;
uint32_t timeLow0, timeHigh0, timeLow1, timeHigh1;
for (i=0; i<numEntries; i++) {
trace(DBG_USR1,"%u\t%u\r\n",table[i].localLow,table[i].globalLow);
}
trace(DBG_USR1,"ROOT_ID=%x TOS_LOCAL_ADDRESS=%x\r\n",ROOT_ID,TOS_LOCAL_ADDRESS);
trace(DBG_USR1,"skew=%1.20e\r\n",skew);
atomic {
call GlobalTime.getLocalTime(&timeLow0,&timeHigh0);
timeLow1=timeLow0; timeHigh1=timeHigh0;
call GlobalTime.local2Global(&timeLow1,&timeHigh1);
call GlobalTime.global2Local(&timeLow1,&timeHigh1);
}
trace(DBG_USR1,"TL0=%u TH0=%u TL1=%u TH1=%u\r\n",
timeLow0,timeHigh0,timeLow1,timeHigh1);
timeLow0 = call SysTime64.getTime32();
call GlobalTime.local2Global(&timeLow1,&timeHigh1);
timeHigh0 = call SysTime64.getTime32();
trace(DBG_USR1,"local2Global takes %d cycles\r\n",timeHigh0-timeLow0);
timeLow0 = call SysTime64.getTime32();
call GlobalTime.global2Local(&timeLow1,&timeHigh1);
timeHigh0 = call SysTime64.getTime32();
trace(DBG_USR1,"global2Local takes %d cycles\r\n",timeHigh0-timeLow0);
timeLow0 = call SysTime64.getTime32();
call SysTime64.setAlarm(timeLow0+10000000);
trace(DBG_USR1,"match register set @ time %u mr=%u\r\n",timeLow0,OSMR2);
trace(DBG_USR1,"OIER = %x OIER_E1=%x OIER_E2=%x\r\n",OIER,OIER_E1,OIER_E2);
return BLUSH_SUCCESS_DONE;
}
async event result_t SysTime64.alarmFired(uint32_t val) {
uint32_t currentTime;
currentTime = call SysTime64.getTime32();
//call Leds.redToggle();
trace(DBG_USR1, "match register interrupt @ time %u, oscr0=%u \r\n",currentTime,val);
}
async command result_t GlobalTime.getLocalTime(uint32_t *timeLow, uint32_t *timeHigh)
{
return call SysTime64.getTime64(timeLow, timeHigh);
}
async command result_t GlobalTime.getGlobalTime(uint32_t *timeLow, uint32_t *timeHigh)
{
call GlobalTime.getLocalTime(timeLow, timeHigh);
return call GlobalTime.local2Global(timeLow, timeHigh);
}
result_t is_synced()
{
return numEntries>=ENTRY_VALID_LIMIT || outgoingMsg->rootID==TOS_LOCAL_ADDRESS;
}
void calcSkew(double *skewptr, TableItem* tb, uint8_t n) {
uint16_t numAdd;
int32_t temp1, temp2;
uint8_t i, j, weight;
double beta;
numAdd=0; beta=0;
for (j=0; j<n; j++)
for (i=j+1; i<n; i++) {
weight = (i-j)*(i-j);
temp1 = (int32_t)tb[i].globalLow-(int32_t)tb[j].globalLow;
temp2 = (int32_t)tb[i].localLow-(int32_t)tb[j].localLow;
beta += ((double) temp1/temp2 - 1)*weight;
numAdd += weight;
}
*skewptr = beta/numAdd;
}
void l2g(uint32_t *timeLow, uint32_t *timeHigh, TableItem* tb, uint8_t n, double beta) {
#define WRAP_FACTOR 4294967296.0
uint32_t count=0;
double d, gwrap, lwrap, gt, ltd, timeOffset;
gwrap=tb[n-1].globalHigh*WRAP_FACTOR;
lwrap=tb[n-1].localHigh*WRAP_FACTOR;
timeOffset = (double)tb[n-1].globalLow - (double)tb[n-1].localLow +
gwrap - lwrap;
d = timeOffset-((double)tb[n-1].localLow*beta+lwrap*beta);
ltd=(double)(*timeLow) + (*timeHigh)*WRAP_FACTOR;
gt = (ltd + beta*ltd + d + 0.5);
while(gt>WRAP_FACTOR) {
gt-=WRAP_FACTOR;
count++;
}
*timeLow = (uint32_t) gt;
*timeHigh = count;
}
void l2g_correct(uint32_t *timeLow, uint32_t *timeHigh, TableItem* tb, uint8_t n,
double beta, int32_t delay) {
uint32_t count=0;
double d, gwrap, lwrap, gt, ltd, timeOffset;
gwrap=tb[n-1].globalHigh*WRAP_FACTOR;
lwrap=tb[n-1].localHigh*WRAP_FACTOR;
timeOffset = (double)tb[n-1].globalLow - (double)tb[n-1].localLow +
gwrap - lwrap;
d = timeOffset-((double)tb[n-1].localLow*beta+lwrap*beta);
ltd=(double)(*timeLow) + (*timeHigh)*WRAP_FACTOR + (double)delay;
gt = (ltd + beta*ltd + d + 0.5);
while(gt>WRAP_FACTOR) {
gt-=WRAP_FACTOR;
count++;
}
*timeLow = (uint32_t) gt;
*timeHigh = count;
}
void g2l_correct(uint32_t *timeLow, uint32_t *timeHigh, TableItem* tb, uint8_t n,
double beta, int32_t delay) {
uint32_t count=0;
double d, gwrap, lwrap, lt, gtd, timeOffset;
gwrap=tb[n-1].globalHigh*WRAP_FACTOR;
lwrap=tb[n-1].localHigh*WRAP_FACTOR;
timeOffset = (double)tb[n-1].globalLow - (double)tb[n-1].localLow +
gwrap - lwrap;
d = timeOffset-((double)tb[n-1].localLow*beta+lwrap*beta);
gtd=(double)(*timeLow) + (*timeHigh)*WRAP_FACTOR - (double)delay;
lt = (gtd - d )/(1.0+beta) + 0.5;
while(lt>WRAP_FACTOR) {
lt-=WRAP_FACTOR;
count++;
}
*timeLow = (uint32_t) lt;
*timeHigh = count;
}
void local2GlobalND(uint32_t *timeLow, uint32_t *timeHigh)
{
if (outgoingMsg->rootID != TOS_LOCAL_ADDRESS) {
l2g(timeLow, timeHigh, table, numEntries, skew);
}
}
async command result_t GlobalTime.local2Global(uint32_t *timeLow, uint32_t *timeHigh)
{
if (outgoingMsg->rootID != TOS_LOCAL_ADDRESS) {
l2g_correct(timeLow, timeHigh, table, numEntries, skew, compensationPropagationTime);
}
return is_synced();
}
async command result_t GlobalTime.global2Local(uint32_t *timeLow, uint32_t *timeHigh)
{
if (outgoingMsg->rootID != TOS_LOCAL_ADDRESS) {
g2l_correct(timeLow, timeHigh, table, numEntries, skew, compensationPropagationTime);
}
return is_synced();
}
void clearTable()
{
atomic numEntries = 0;
//trace(DBG_USR1,"clearTable() called\r\n");
}
void addNewEntry(TimeSyncMsg *msg)
{
int8_t i;
//uint32_t age, oldestTime = 0;
int32_t timeErrorLow, timeErrorHigh;
// clear table if the received entry is inconsistent
timeErrorLow = msg->arrivalTime;
timeErrorHigh = msg->arrivalTimeHigh;
local2GlobalND(&timeErrorLow, &timeErrorHigh);
timeErrorLow -= msg->sendingTime;
if( is_synced() &&
(timeErrorLow > ENTRY_THROWOUT_LIMIT || timeErrorLow < -ENTRY_THROWOUT_LIMIT))
clearTable();
if (numEntries<MAX_ENTRIES) {
//atomic {
table[numEntries].localLow = msg->arrivalTime;
table[numEntries].globalLow = msg->sendingTime;
table[numEntries].localHigh = msg->arrivalTimeHigh;
table[numEntries].globalHigh = msg->sendingTimeHigh;
numEntries++;
//}
} else {
//atomic {
for (i=0; i<MAX_ENTRIES-1; i++) {
table[i].localLow = table[i+1].localLow;
table[i].globalLow = table[i+1].globalLow;
table[i].localHigh = table[i+1].localHigh;
table[i].globalHigh = table[i+1].globalHigh;
}
table[MAX_ENTRIES-1].localLow = msg->arrivalTime;
table[MAX_ENTRIES-1].globalLow = msg->sendingTime;
table[MAX_ENTRIES-1].localHigh = msg->arrivalTimeHigh;
table[MAX_ENTRIES-1].globalHigh = msg->sendingTimeHigh;
//}
}
}
void task processMsg()
{
uint32_t receiveTime, receiveTimeHigh;
float temp, dif;
uint8_t *ptr, i;
TimeSyncMsg* msg = (TimeSyncMsg*)processedMsg->data;
#define ALPHA 0.2
#define THRESHOLD_PROPAGATION_ERROR 1000
/* trace (DBG_USR1,"processMsg msg->seqNum=%d outg->seqNum=%d\r\n",
msg->seqNum, outgoingMsg->seqNum);
trace (DBG_USR1,"%x %x %d %d\r\n",msg->rootID,msg->nodeID,msg->seqNum,msg->isSynced);*/
/*trace(DBG_USR1, "seqNum=%d lastSeqNum=%d lastparent=%x TOSLA=%x\r\n",
msg->seqNum,lastSeqNumSent,msg->lastParent,TOS_LOCAL_ADDRESS);*/
if (msg->seqNum==lastSeqNumSent && msg->lastParent==TOS_LOCAL_ADDRESS) {
receiveTime = msg->arrivalTime; receiveTimeHigh = msg->arrivalTimeHigh;
call GlobalTime.local2Global(&receiveTime, &receiveTimeHigh);
temp = (receiveTime-(msg->sendingTime-msg->propagationTimeThisPacket))/2.0;
//trace(DBG_USR1,"receiveTime=%d sendingTime=%d propThisPac=%d temp=%f\r\n",receiveTime,
//msg->sendingTime,msg->propagationTimeThisPacket,temp);
dif = calculatedPropagationTime-temp;
if (dif<0)
dif = -dif;
if (dif>THRESHOLD_PROPAGATION_ERROR)
calculatedPropagationTime=temp;
else
calculatedPropagationTime=(calculatedPropagationTime*(1-ALPHA)+temp*ALPHA);
outgoingMsg->propagationTime=(int16_t)calculatedPropagationTime;
//trace(DBG_USR1,"temp=%f dif=%f calcPropTime=%f\r\n",temp,dif,calculatedPropagationTime);
}
if (msg->isSynced==0) {
syncCounter++;
if (syncPeriod==slowSyncPeriod) {
atomic syncPeriod = fastSyncPeriod;
call Timer.stop();
call Timer.start(TIMER_ONE_SHOT, (uint32_t)1000 * syncPeriod);
}
}
//if ((ROOT_ID == TOS_LOCAL_ADDRESS) && ((int8_t)(msg->seqNum - outgoingMsg->seqNum) > 0)) {
// outgoingMsg->seqNum = msg->seqNum;
//}
if ((ROOT_ID != TOS_LOCAL_ADDRESS)&& (int8_t)(msg->seqNum - outgoingMsg->seqNum) > 0) {
outgoingMsg->seqNum = msg->seqNum;
outgoingMsg->lastParent = msg->nodeID;
if (msg->syncPeriod > 0) {
atomic {
syncPeriod = msg->syncPeriod;
outgoingMsg->syncPeriod = syncPeriod;
}
compensationPropagationTime = msg->propagationTime;
/*
ptr=msg;
for (i=0;i<26;i++)
trace(DBG_USR1,"%x ",*ptr++);
trace(DBG_USR1,"\r\n",*ptr++);
trace(DBG_USR1,"receive propTime=%d\r\n",msg->propagationTime);
*/
addNewEntry(msg);
if (numEntries>3)
calcSkew(&skew, table, numEntries);
signal TimeSyncNotify.msg_received();
}
}
state &= ~STATE_PROCESSING;
}
event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr p)
{
uint32_t rxtimeLow, rxtimeHigh;
TimeSyncMsg* ptr;
if( (state & STATE_PROCESSING) == 0 ) {
TOS_MsgPtr old = processedMsg;
//trace (DBG_USR1,"TimeSync.receive\r\n");
call Leds.greenToggle();
processedMsg = p;
ptr = (TimeSyncMsg*)(processedMsg->data);
//#define TEST_MULTIHOP 1
#ifdef TEST_MULTIHOP
if (TOS_LOCAL_ADDRESS == 0xa6 && ptr->nodeID != 0xbb && ptr->nodeID != 0xbe)
return p; // make 0xa6 2 hops
if (TOS_LOCAL_ADDRESS == 0xbe && ptr->nodeID != 0xa6 && ptr->nodeID != 0xb4)
return p; // make 0xbe 3 hops
if (TOS_LOCAL_ADDRESS == 0xb4 && ptr->nodeID != 0xbe)
return p; // make 0xb4 4 hops
#endif
call TimeStamping.getStamp(&rxtimeLow, &rxtimeHigh);
ptr->arrivalTime = rxtimeLow;
ptr->arrivalTimeHigh = rxtimeHigh;
state |= STATE_PROCESSING;
post processMsg();
return old;
}
return p;
}
#define ENOUGH_FAST_SYNCS 20
task void sendMsg()
{
uint32_t localTime, localTimeHigh, globalTime, globalTimeHigh;
uint8_t this_neighborhood_synced, lo, hi;
uint8_t *ptr, i;
call GlobalTime.getLocalTime(&localTime, &localTimeHigh);
globalTime = localTime; globalTimeHigh = localTimeHigh;
call GlobalTime.local2Global(&globalTime, &globalTimeHigh);
outgoingMsg->propagationTimeThisPacket=compensationPropagationTime;
if (is_synced() == 0)
this_neighborhood_synced = 0;
else {
if (syncCounter==0)
this_neighborhood_synced = 1;
else
if (syncCounter2<4) {
this_neighborhood_synced = 0;
syncCounter2=0;
}
else
this_neighborhood_synced = 1;
}
syncCounter2++;
if (ROOT_ID==TOS_LOCAL_ADDRESS) {
if (syncCounter>0)
Nburst=0;
atomic {
if (Nburst>=ENOUGH_FAST_SYNCS)
syncPeriod = slowSyncPeriod;
else {
syncPeriod = fastSyncPeriod;
Nburst++;
}
outgoingMsg->syncPeriod = syncPeriod;
}
outgoingMsg->isSynced = 1;
} else
outgoingMsg->isSynced = this_neighborhood_synced;
syncCounter=0;
outgoingMsg->sendingTime = globalTime - localTime;
outgoingMsg->sendingTimeHigh = globalTimeHigh - localTimeHigh;
/*ptr=outgoingMsg;
for (i=0;i<26;i++)
trace(DBG_USR1,"%x ",*ptr++);
trace(DBG_USR1,"\r\n",*ptr++);
trace(DBG_USR1,"send propTime=%d st=%d sth=%d\r\n",
outgoingMsg->propagationTime, outgoingMsg->sendingTime, outgoingMsg->sendingTimeHigh);
*/
if( call SendMsg.send(TOS_BCAST_ADDR, TIMESYNCMSG_LEN, &outgoingMsgBuffer) != SUCCESS ){
state &= ~STATE_SENDING;
signal TimeSyncNotify.msg_sent();
}
else {
call ComputeByteOffset(&lo, &hi);
call TimeStamping.addStamp2(&outgoingMsgBuffer, lo, hi);
//call TimeStamping.addStamp2(&outgoingMsgBuffer, offsetof(TimeSyncMsg,sendingTime)+2,
// offsetof(TimeSyncMsg,sendingTimeHigh)+2);
}
}
event result_t SendMsg.sendDone(TOS_MsgPtr ptr, result_t success)
{
if (ptr != &outgoingMsgBuffer)
return SUCCESS;
if( success )
{
//trace (DBG_USR1,"TimeSync.sendDone\r\n");
//call Leds.redToggle();
lastSeqNumSent = outgoingMsg->seqNum;
if( ROOT_ID == TOS_LOCAL_ADDRESS ){
if (syncPeriod == fastSyncPeriod)
(outgoingMsg->seqNum) = outgoingMsg->seqNum + 20;
else
++(outgoingMsg->seqNum);
}
}
state &= ~STATE_SENDING;
signal TimeSyncNotify.msg_sent();
return SUCCESS;
}
void timeSyncMsgSend()
{
if( (state & STATE_SENDING) == 0 ) {
state |= STATE_SENDING;
post sendMsg();
}
}
event result_t Timer.fired()
{
if (mode == TS_TIMER_MODE)
timeSyncMsgSend();
else
call Timer.stop();
tableEntries = 0;
call Timer.start(TIMER_ONE_SHOT,(uint32_t)1000 * syncPeriod);
return SUCCESS;
}
command result_t TimeSyncMode.setMode(uint8_t mode_){
if (mode == mode_)
return SUCCESS;
if (mode_ == TS_USER_MODE){
if (call Timer.start(TIMER_ONE_SHOT, (uint32_t)1000 * syncPeriod) == FAIL)
return FAIL;
}
else if (call Timer.stop() == FAIL)
return FAIL;
mode = mode_;
return SUCCESS;
}
command uint8_t TimeSyncMode.getMode(){
return mode;
}
command result_t TimeSyncMode.send(){
if (mode == TS_USER_MODE){
timeSyncMsgSend();
return SUCCESS;
}
return FAIL;
}
command result_t StdControl.init()
{
atomic{
skew = 0.0;
localAverage = 0;
offsetAverage = 0;
};
clearTable();
call Leds.init();
outgoingMsg->rootID = ROOT_ID;
outgoingMsg->seqNum = 2;
outgoingMsg->lastParent = ROOT_ID;
lastSeqNumSent = 0;
processedMsg = &processedMsgBuffer;
state = STATE_INIT;
calculatedPropagationTime = 0;
compensationPropagationTime = 0;
outgoingMsg->propagationTime = calculatedPropagationTime;
slowSyncPeriod = 10;
fastSyncPeriod = 1;
syncPeriod = fastSyncPeriod;
syncCounter = 0; syncCounter2 = 4; Nburst=0;
return SUCCESS;
}
command result_t StdControl.start()
{
mode = TS_TIMER_MODE;
heartBeats = 0;
outgoingMsg->nodeID = TOS_LOCAL_ADDRESS;
//if (ROOT_ID!=TOS_LOCAL_ADDRESS)
// outgoingMsg->reset = 1;
call Timer.start(TIMER_ONE_SHOT, (uint32_t)1000 * syncPeriod);
return SUCCESS;
}
command result_t StdControl.stop()
{
call Timer.stop();
return SUCCESS;
}
async command float TimeSyncInfo.getSkew() { return ((float)skew); }
async command uint32_t TimeSyncInfo.getOffset() { return offsetAverage; }
async command uint32_t TimeSyncInfo.getSyncPoint() { return localAverage; }
async command uint16_t TimeSyncInfo.getRootID() { return outgoingMsg->lastParent; }
async command uint8_t TimeSyncInfo.getSeqNum() { return outgoingMsg->seqNum; }
async command uint8_t TimeSyncInfo.getNumEntries() { return numEntries; }
async command uint8_t TimeSyncInfo.getHeartBeats() { return heartBeats; }
async command uint16_t TimeSyncInfo.getSyncPeriod() { return syncPeriod; }
default event void TimeSyncNotify.msg_received(){};
default event void TimeSyncNotify.msg_sent(){};
}
--- NEW FILE: TimeSyncMode.nc ---
/*
* Copyright (c) 2002-2004, Vanderbilt University
* All rights reserved.
*
* Author: Brano Kusy (kusy at isis.vanderbilt.edu)
Barbara Hohlt
* Date last modified: Oct/04
*/
/**
* the time sync module can work in two modes:
* - TS_TIMER_MODE (default): TS msgs sent period. from the timer
* - TS_USER_MODE: TS msgs sent only when explic. asked by user
* via TimeSyncMode.send() command, TimeSync.Timer
* is stopped in this mode
*/
interface TimeSyncMode
{
/**
* Sets the current mode of the TimeSync module.
* returns FAIL if didn't succeed
*/
command result_t setMode(uint8_t mode);
/**
* Gets the current mode of the TimeSync module.
*/
command uint8_t getMode();
/**
* command to send out time synchronization message.
* returns FAIL if TimeSync not in TS_USER_MODE
*/
command result_t send();
}
--- NEW FILE: TimeSyncMsg.h ---
/*
* Copyright (c) 2002, 2003 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: Brano Kusy, Miklos Maroti
* Date last modified: 05/20/03
*/
typedef struct TimeSyncMsg
{
uint16_t rootID; // the node id of the synchronization root
uint16_t nodeID; // the node if of the sender
uint8_t seqNum; // sequence number for the root
uint8_t isSynced;
uint16_t lastParent;
int16_t propagationTime;
int16_t propagationTimeThisPacket;
uint16_t syncPeriod;
/* This field is initially set to the offset between global time and local
* time. The TimeStamping component will add the current local time when the
* message is actually transmitted. Thus the receiver will receive the
* global time of the sender when the message is actually sent. */
uint32_t sendingTime;
uint32_t sendingTimeHigh;
//just for convenience - not transmitted
uint32_t arrivalTime;
uint32_t arrivalTimeHigh;
}__attribute((packed)) TimeSyncMsg;
enum {
AM_TIMESYNCMSG = 0xAA,
TIMESYNCMSG_LEN = sizeof(TimeSyncMsg) - 2*sizeof(uint32_t),
TS_TIMER_MODE = 0, // see TimeSyncMode interface
TS_USER_MODE = 1, // see TimeSyncMode interface
};
--- NEW FILE: TimeSyncNotify.nc ---
/*
* Copyright (c) 2002-2004, Vanderbilt University
* All rights reserved.
*
* Author: Brano Kusy (kusy at isis.vanderbilt.edu)
* Barbara Hohlt
* Date last modified: Oct/04
*/
/**
* time sync module (TimeSyncM) provides notification of arriving
* and transmitted time-sync msgs through TimeSyncNotify interface:
*/
interface TimeSyncNotify
{
/**
* fired when time-sync msg is received and accepted
*/
event void msg_received();
/**
* fired when time-sync msg is sent by TimeSyncM or the sending did not
* succeed
*/
event void msg_sent();
}
- Previous message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/imote2/tos/lib/TimeSync - New directory
- Next message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/imote2/tos/lib/FlashLogger
BlockStorage.h, NONE, 1.1 FileMount.nc, NONE, 1.1 FileRead.nc,
NONE, 1.1 FileStorage.nc, NONE, 1.1 FileWrite.nc, NONE,
1.1 FlashLoggerC.nc, NONE, 1.1 FlashLoggerM.nc, NONE,
1.1 Storage.h, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-contrib-commits
mailing list