indexpreviousnext

file name: clocksyn.hpp, clocksyn.cpp
classification: simulation
contents: class CClockSync
derived from: class CApplControlledObject, class CNeedInterrupt
friends: class ACClockSyncAlgorithm
use: the main class of clock synchronization application
 

global items used by CClockSync:


local items used by CClockSync:

const int CI_Mode: message transmission mode for the LANCE driver.

enum EMessageMode: Timestamp, DelayMeasurement, DelayMeasurementReply, RateSynchronization, GpsTime
specifies the contents of a message.

enum ERoundStage: BeforeSend, BeforeCV, BeforeResync
specifies all possible round stages.
 

member variables:

int area_: the DMA area of the clock. The user identifies a clock synchronization application through the pair <nodeID, area>.
default: area parameter of the ctor

CClockInterface *clock_: a pointer to the clock object of the node and area. Again, it must be set to a value other than NULL before the module can send synchronization messages.
default: NULL

double computationDelayCompensation_: the time (in seconds) from the execution of the CV to the clock update at the end of the round, cf. Figure 1. This parameter denotes the worst case execution time of the CV. In pure simulation, the execution time of the CV is zero.
default and reset value: DefaultComputationDelayCompensation
 


Figure 1: Timing and Stages of a Synchronization Round

ACClockSyncAlgorithm *csa_: a pointer to the object that implements the clock synchronization algorithm.
default and reset value: a newly created object of the algorithm type FreeRun.

EAlgorithmType csaType_: the type of the currently used clock synchronization algorithm.
default and reset value: FreeRun

double delayCompensation_: the time (in seconds) from the full message exchange (FME) at the beginning of the round to the execution of the convergence function (CV), cf. Figure 1. Again, a duty timer of the UTCSU is used to wait for that time.
default and reset value: DefaultDelayCompensation

INT32 delayCycles_: the period of delay measurement messages (in number of calls to FME). Example: if every n-th message should include delay measurement, set delayCycles to n; n=0 prevents delay measurement.
default and reset value: 0

INT32 delayCounter_: If delay measurement is active, it counts the calls to function BroadcastTime(), and if its value is greater or equal to the value of delayCycles, the message sent in the FME will contain a request for delay measurement and the delay counter is reset to 0.
Note: if delayCycles is changed, delayCounter is always set to be one less than delayCycles. Thus, whenever you activate delay measurement, the next message that is sent will already contain the request.
default and reset value: 0

EBool initCalled_: is set to True by Init(), to False by Dispose().
default and reset value: True

CLance *lance_: a pointer to the lance object of the node and area. It must be set to a value different from NULL before the module can send synchronization messages.
default: NULL

CNodeIdList listOfConnectedNetworks_: all connected networks of the application. There must be at least one entry (which is set by the user) before the module can take part in the synchronization process.
default and reset value: Empty

INT32 rateCycles_:
INT32 rateCounter_: These two are handled exactly like delayCycles and delayCounter, but are used for controlling rate synchronization. Whenever the value of rateCounter exceeds that of rateCycles, rate information of the local clock is included into the message.
default and reset value: 0

EBool reportDelays_: is True if transmission delays for incoming messages should be reported to the evaluation.
default and reset value: False

EBool resynchronizing_: If this variable is set to True, messages are not marked as timestamped (that is, they do not have flag Timestamp in their mode). Also, only delay measurement messages and/or rate synchronization messages are sent. Messages that would only contain the local timestamp are *not* sent. The csa may set the variable to True if it deems the clock value to be wrong.
default: False

double roundPeriod_: the round period (in seconds) of a synchronization round, cf. Figure 1. A duty timer of the UTCSU is used to wait for that time.
default and reset value: DefaultRoundPeriod

INT8 roundStage_: Is needed to store the current stage in a synchronization round. A value of BeforeSend means that the next call to the isr() should broadcast a synchronization message, BeforeCV causes the isr() to execute the CV, and BeforeResync prompts the isr() to resynchronize the clock (see Figure 1).
default and reset value: BeforeSend

EBool suspended_: If the variable is True, Announce() ignores incoming messages. The member may well become obsolete: if suspension is done right, the Lance object should be suspended first and ignore all messages anyway. If the value is False, the variable has no effect.
default and reset value: False

double timeOfResync_: contains the time of the next resynchronization (m*roundPeriod + delayCompensation + computationDelayCompensation, with m some multiple of the round period). The member is needed to compute the time from the reception of a message until the time the clock is resynchronized. This delay is needed by the clock synchronization algorithm. If it is negative, the time of the next resynchronization is not known.
default and reset value: NoAccount
 

message formats: the format of the message buffer of the messages that are exchanged between the applications. The mode may contain several flags:

DelayMeasurementReply should always stand alone, the other flags may be ored together.

Timestamp, DelayMeasurement (Node P [FME] -> Node Q [Announce]):
Node P: INT32 mode, SINT32 nodeID (P)

RateSynchronization (Node P [FME] -> Node Q [Announce]):
Node P: INT32 mode, SINT32 nodeID (P), double thetaPlus (P), double thetaMinus (P), double u (P)

DelayMeasurementReply (Node Q [ReplyToMessage] -> Node P [Announce]):
Node Q: INT32 mode, SINT32 nodeID (Q), INT32 receiveTimestamp (Q), double thetaMinus (Q), double thetaPlus (Q), INT32 area (P), ti_acx time (P)
 

member functions:

CClockSync (CControllingObject *ctrl, int area): Stores the area, calls SetISR() to set the interrupt vector (duty timer B4) for the ISR (the call is made atomic by calling DisableInterrupts() before and EnableInterrupts() after the statement), sets csa to NULL and initCalled to False, then calls Init().

virtual ~CClockSync (): Disables the interrupts from the duty timer B4 and disables the timers themselves (sets the enable bit to zero). The clock object must not have been deleted at this time! Calls RemoveISR() (again, the call is made atomic), then deletes the dynamic members that were created by the object through a call to Dispose(). The lance and clock objects are not deleted.

void Announce (renvx *renv, STimeData time, char *buf, INT16 msgsize, int if_num, INT32 msgID): Should be called by the Lance if a message has been received. The msgID is the identifier of the message and only needed for the event report. If suspended is False, the function takes over the data, extracts the information (timestamp, delay measurement and rate information) and gives it to csa for further processing. If the message contained a request for delay measurement, the function sends a reply. The function sends event ReceivedMessage to the evaluation, and if member reportDelays is True, then it calls GetTransmitTimestamp() to get the send timestamp for the message, subtracts the receive timestamp in renv->utcsu, and sends event TransmissionDelay with this delay.
Note: currently, the drift of the clock is not considered when computing the transmission delay.

void ApplyConvergenceFunction(): Prompts csa to use the collected data to compute a new clock value. This is the end of stage BeforeCV in the synchronization round (see Figure 1).

void BroadcastTime (): Broadcasts a timestamped message. If resynchronizing is True, messages that only consist of the clock value are not send, and in messages with additional information the timestamp is marked invalid (i.e., the Timestamp flag is not set). The function is called at the end of stage BeforeSend in the synchronization round (see Figure 1). The message is sent to all networks stored in listOfConnectedNetworks, and for each single send, event SendMessage is reported to the evaluation. If the macro ADDITIONAL_PNODE_DATA is defined (compiler option -D) and the CSA is a P-Node, then the data is sent for another ADDITIONAL_PNODE_DATA times.

EBool ChangeAlgorithm (EAlgorithmType newType): Changes the synchronization algorithm (members csa and csaType). The algorithm can be changed on the fly (at any time, the csa pointer is valid). If the algorithm type has not been installed (the algorithm manager does not have a create function), the function returns False and has no effect. Otherwise, the function returns True. Changing the algorithm discards all data that has been collected by the old algorithm, but keeps general configuration information like the number of nodes or the associated network (see csa::operator=() for details). The function can be called if csa is NULL. In that case, it just creates a new object and sets csa to it.

void ComputeDelay (renvx *renv, STimeData& time, SReplyData& data, STimeData& myTime, int if_num): Computes the transmission delay. The function is called by Announce() if a reply to a transmission delay request has been received. The function uses all data to compute the complete delay from the sending of request to the receipt of the reply (in the time of the local clock) and the remote delay from the receipt of the request to the sending of the reply (in the time of the remote clock), and passes these values, together with the clock rate information that has been sent from the remote CSA, to csa for further processing.

virtual void Dispose(): If initCalled is True, all dynamic members are deleted and initCalled is set to False. Since csa is dynamic, it is deleted and all data it has collected is lost. If initCalled is False, the function has no effect.

virtual EBool ExecuteCommand (const SCommand& command): Supported commands:

All other commands are passed to the ExecuteCommand() function of the base class and its value is returned.

virtual EBool GetParameter (SParameter& param) const: Returns True if the parameter could be read. All supported parameters of this class assume that param is of type SSingleParameter. Supported parameters:

All other parameters are passed to the GetParameter() function of the base class and its value is returned.

virtual void Init(): If initCalled is False, the function creates all dynamic members and sets all class members to their reset values. Member initCalled is then set to True. If initCalled is True, the function has no effect.

void InterruptAtMult(): Disables duty timer B4, calls clock->InterruptAtMult() for duty timer B4 with roundPeriod, sets timeOfResync to the time of the next resynchronization, which occurs at the end of stage BeforeResync (see Figure 1). Then B4 is enabled again.

virtual void isr (): The function is called for INTT interrupts. If no interrupt from duty timer B4 is pending, the function returns and has no effect. Otherwise, it clears this interrupt and sends event TimerEvent. The call to the ISR always denotes the end of the current stage as stored in roundStage and the beginning of the next stage. First, if the next stage has a non-zero duration, the function programs the duty timer to trigger an interrupt at its end. Then it calls either BroadcastTime() (end of stage BeforeSend) or ApplyConvergenceFunction() and csa::PreloadNewClockValue() (end of stage BeforeCV). At the end of every stage, roundStage is set to the next stage. If this stage is not BeforeSend and if its duration is zero, then the ISR behaves as if it had been called again at once and handles the new stage.
Note: After the ISR has handled stage BeforeResync, it always calls InterruptAtMult() to set the duty timer to the end of stage BeforeSend and returns. InterruptAtMult() modifies member timeOfResync to contain the time of the end of the next stage BeforeResync.
Note: Stage BeforeResync does not call any functions (amortization is started automatically) and will be removed in future versions.

void ReplyToMessage (renvx *renv, STimeData& time, int if_num): Replies to a request for transmission delay measurement. If either clock or lance are NULL, an assert fails. Otherwise, the function assembles the reply message, reports event SendMessage to the evaluation and sends the message.

virtual int ReportError (EReportType type, char *file, int line, char *expression): Calls the global ReportError() function with the additional information module=ClockSync, nodeID=GetNodeID(), area=area_.

void Resume (): Enables interrupts from duty timer B4 and calls InterruptAtMult() to trigger a duty timer interrupt. If clock is NULL, an assert fails.

void Resynchronize(): Prompts csa to set the clock to the new value. This denotes the end of stage BeforeResync in the synchronization round.

void SetClock (CClockInterface *clock): Sets the internal clock pointer to clock and calls csa::ClockChanged(). You must set the internal pointer to a valid clock object before the object can participate in clock synchronization.

void SetLance (CLance *lance): Sets the lance pointer to lance. You must set the internal pointer to a valid Lance object before the object can send messages.

virtual EBool SetParameter (const SParameter& param): Returns True if the parameter could be set. All supported parameters of this class assume that param is of type SSingleParameter. Supported parameters:

All other parameters are passed to the SetParameter() function of the base class and its value is returned.

void StoreTime (renvx *renv, STimeData& time, int if_num): Passes the clock timestamp of the remote clock and the time difference from the reception of the message until the local clock is resynchronized to csa.

void Suspend (): Disables interrupts from duty timer B4 and sets suspended to True. Incoming messages are ignored, roundStage is set to BeforeSend, timeOfResync is set to NoAccount, and csa::Suspend() is called.


last modified: Fri Feb 5 18:56:06 1999