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

📄 refclock_msfees.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 4 页
字号:
/* refclock_ees - clock driver for the EES M201 receiver */#ifdef HAVE_CONFIG_H#include <config.h>#endif#if defined(REFCLOCK) && defined(CLOCK_MSFEES) && defined(PPS)/* Currently REQUIRES STREAM and PPSCD. CLK and CBREAK modes * were removed as the code was overly hairy, they weren't in use * (hence probably didn't work).  Still in RCS file at cl.cam.ac.uk */#include "ntpd.h"#include "ntp_io.h"#include "ntp_refclock.h"#include "ntp_unixtime.h"#include "ntp_calendar.h"#include <ctype.h>#if defined(HAVE_BSD_TTYS)#include <sgtty.h>#endif /* HAVE_BSD_TTYS */#if defined(HAVE_SYSV_TTYS)#include <termio.h>#endif /* HAVE_SYSV_TTYS */#if defined(HAVE_TERMIOS)#include <termios.h>#endif#if defined(STREAM)#include <stropts.h>#endif#ifdef HAVE_SYS_TERMIOS_H# include <sys/termios.h>#endif#ifdef HAVE_SYS_PPSCLOCK_H# include <sys/ppsclock.h>#endif#include "ntp_stdlib.h"/*	fudgefactor	= fudgetime1;	os_delay	= fudgetime2;	   offset_fudge	= os_delay + fudgefactor + inherent_delay;	stratumtouse	= fudgeval1 & 0xf	debug		= fudgeval2;	sloppyclockflag	= flags & CLK_FLAG1;		1	  log smoothing summary when processing sample		4	  dump the buffer from the clock		8	  EIOGETKD the last n uS time stamps	if (flags & CLK_FLAG2 && unitinuse) ees->leaphold = 0;	ees->dump_vals	= flags & CLK_FLAG3;	ees->usealldata	= flags & CLK_FLAG4;	bug->values[0] = (ees->lasttime) ? current_time - ees->lasttime : 0;	bug->values[1] = (ees->clocklastgood)?current_time-ees->clocklastgood:0;	bug->values[2] = (u_long)ees->status;	bug->values[3] = (u_long)ees->lastevent;	bug->values[4] = (u_long)ees->reason;	bug->values[5] = (u_long)ees->nsamples;	bug->values[6] = (u_long)ees->codestate;	bug->values[7] = (u_long)ees->day;	bug->values[8] = (u_long)ees->hour;	bug->values[9] = (u_long)ees->minute;	bug->values[10] = (u_long)ees->second;	bug->values[11] = (u_long)ees->tz;	bug->values[12] = ees->yearstart;	bug->values[13] = (ees->leaphold > current_time) ?				ees->leaphold - current_time : 0;	bug->values[14] = inherent_delay[unit].l_uf;	bug->values[15] = offset_fudge[unit].l_uf;	bug->times[0] = ees->reftime;	bug->times[1] = ees->arrvtime;	bug->times[2] = ees->lastsampletime;	bug->times[3] = ees->offset;	bug->times[4] = ees->lowoffset;	bug->times[5] = ees->highoffset;	bug->times[6] = inherent_delay[unit];	bug->times[8] = os_delay[unit];	bug->times[7] = fudgefactor[unit];	bug->times[9] = offset_fudge[unit];	bug->times[10]= ees->yearstart, 0;	*//* This should support the use of an EES M201 receiver with RS232 * output (modified to transmit time once per second). * * For the format of the message sent by the clock, see the EESM_ * definitions below. * * It appears to run free for an integral number of minutes, until the error * reaches 4mS, at which point it steps at second = 01. * It appears that sometimes it steps 4mS (say at 7 min interval), * then the next minute it decides that it was an error, so steps back. * On the next minute it steps forward again :-( * This is typically 16.5uS/S then 3975uS at the 4min re-sync, * or 9.5uS/S then 3990.5uS at a 7min re-sync, * at which point it may lose the "00" second time stamp. * I assume that the most accurate time is just AFTER the re-sync. * Hence remember the last cycle interval, * * Can run in any one of: * *	PPSCD	PPS signal sets CD which interupts, and grabs the current TOD *	(sun)		*in the interupt code*, so as to avoid problems with *			the STREAMS scheduling. * * It appears that it goes 16.5 uS slow each second, then every 4 mins it * generates no "00" second tick, and gains 3975 uS. Ho Hum ! (93/2/7) *//* Definitions */#ifndef	MAXUNITS#define	MAXUNITS	4	/* maximum number of EES units permitted */#endif#ifndef	EES232#define	EES232	"/dev/ees%d"	/* Device to open to read the data */#endif/* Other constant stuff */#ifndef	EESPRECISION#define	EESPRECISION	(-10)		/* what the heck - 2**-10 = 1ms */#endif#ifndef	EESREFID#define	EESREFID	"MSF\0"		/* String to identify the clock */#endif#ifndef	EESHSREFID#define	EESHSREFID	(0x7f7f0000 | ((REFCLK_MSF_EES) << 8)) /* Numeric refid */#endif/* Description of clock */#define	EESDESCRIPTION		"EES M201 MSF Receiver"/* Speed we run the clock port at. If this is changed the UARTDELAY * value should be recomputed to suit. */#ifndef	SPEED232#define	SPEED232	B9600	/* 9600 baud */#endif/* What is the inherent delay for this mode of working, i.e. when is the * data time stamped. */#define	SAFETY_SHIFT	10	/* Split the shift to avoid overflow */#define	BITS_TO_L_FP(bits, baud) \(((((bits)*2 +1) << (FRACTION_PREC-SAFETY_SHIFT)) / (2*baud)) << SAFETY_SHIFT)#define	INH_DELAY_CBREAK	BITS_TO_L_FP(119, 9600)#define	INH_DELAY_PPS		BITS_TO_L_FP(  0, 9600)#ifndef	STREAM_PP1#define	STREAM_PP1	"ppsclocd\0<-- patch space for module name1 -->"#endif#ifndef	STREAM_PP2#define	STREAM_PP2	"ppsclock\0<-- patch space for module name2 -->"#endif     /* Offsets of the bytes of the serial line code.  The clock gives * local time with a GMT/BST indication. The EESM_ definitions * give offsets into ees->lastcode. */#define EESM_CSEC	 0	/* centiseconds - always zero in our clock  */#define EESM_SEC	 1	/* seconds in BCD			    */#define EESM_MIN	 2	/* minutes in BCD			    */#define EESM_HOUR	 3	/* hours in BCD				    */#define EESM_DAYWK	 4	/* day of week (Sun = 0 etc)		    */#define EESM_DAY	 5	/* day of month in BCD			    */#define EESM_MON	 6	/* month in BCD				    */#define EESM_YEAR	 7	/* year MOD 100 in BCD			    */#define EESM_LEAP	 8	/* 0x0f if leap year, otherwise zero        */#define EESM_BST	 9	/* 0x03 if BST, 0x00 if GMT		    */#define EESM_MSFOK	10	/* 0x3f if radio good, otherwise zero	    */				/* followed by a frame alignment byte (0xff) /				/  which is not put into the lastcode buffer*//* Length of the serial time code, in characters.  The first length * is less the frame alignment byte. */#define	LENEESPRT	(EESM_MSFOK+1)#define	LENEESCODE	(LENEESPRT+1)     /* Code state. */#define	EESCS_WAIT	0       /* waiting for start of timecode */#define	EESCS_GOTSOME	1	/* have an incomplete time code buffered */     /* Default fudge factor and character to receive */#define	DEFFUDGETIME	0	/* Default user supplied fudge factor */#ifndef	DEFOSTIME#define	DEFOSTIME	0	/* Default OS delay -- passed by Make ? */#endif#define	DEFINHTIME	INH_DELAY_PPS /* inherent delay due to sample point*/     /* Limits on things.  Reduce the number of samples to SAMPLEREDUCE by median * elimination.  If we're running with an accurate clock, chose the BESTSAMPLE * as the estimated offset, otherwise average the remainder. */#define	FULLSHIFT	6			/* NCODES root 2 */#define NCODES		(1<< FULLSHIFT)		/* 64 */#define	REDUCESHIFT	(FULLSHIFT -1)		/* SAMPLEREDUCE root 2 */     /* Towards the high ( Why ?) end of half */#define	BESTSAMPLE	((samplereduce * 3) /4)	/* 24 */     /* Leap hold time.  After a leap second the clock will no longer be * reliable until it resynchronizes.  Hope 40 minutes is enough. */#define	EESLEAPHOLD	(40 * 60)#define	EES_STEP_F	(1 << 24) /* the receiver steps in units of about 4ms */#define	EES_STEP_F_GRACE (EES_STEP_F/8) /*Allow for slop of 1/8 which is .5ms*/#define	EES_STEP_NOTE	(1 << 21)/* Log any unexpected jumps, say .5 ms .... */#define	EES_STEP_NOTES	50	/* Only do a limited number */#define	MAX_STEP	16	/* Max number of steps to remember */     /* debug is a bit mask of debugging that is wanted */#define	DB_SYSLOG_SMPLI		0x0001#define	DB_SYSLOG_SMPLE		0x0002#define	DB_SYSLOG_SMTHI		0x0004#define	DB_SYSLOG_NSMTHE	0x0008#define	DB_SYSLOG_NSMTHI	0x0010#define	DB_SYSLOG_SMTHE		0x0020#define	DB_PRINT_EV		0x0040#define	DB_PRINT_CDT		0x0080#define	DB_PRINT_CDTC		0x0100#define	DB_SYSLOG_KEEPD		0x0800#define	DB_SYSLOG_KEEPE		0x1000#define	DB_LOG_DELTAS		0x2000#define	DB_PRINT_DELTAS		0x4000#define	DB_LOG_AWAITMORE	0x8000#define	DB_LOG_SAMPLES		0x10000#define	DB_NO_PPS		0x20000#define	DB_INC_PPS		0x40000#define	DB_DUMP_DELTAS		0x80000     struct eesunit {			/* EES unit control structure. */	     struct peer *peer;		/* associated peer structure */	     struct refclockio io;		/* given to the I/O handler */	     l_fp	reftime;		/* reference time */	     l_fp	lastsampletime;		/* time as in txt from last EES msg */	     l_fp	arrvtime;		/* Time at which pkt arrived */	     l_fp	codeoffsets[NCODES];	/* the time of arrival of 232 codes */	     l_fp	offset;			/* chosen offset        (for clkbug) */	     l_fp	lowoffset;		/* lowest sample offset (for clkbug) */	     l_fp	highoffset;		/* highest   "     "    (for clkbug) */	     char	lastcode[LENEESCODE+6];	/* last time code we received */	     u_long	lasttime;		/* last time clock heard from */	     u_long	clocklastgood;		/* last time good radio seen */	     u_char	lencode;		/* length of code in buffer */	     u_char	nsamples;		/* number of samples we've collected */	     u_char	codestate;		/* state of 232 code reception */	     u_char	unit;			/* unit number for this guy */	     u_char	status;			/* clock status */	     u_char	lastevent;		/* last clock event */	     u_char	reason;			/* reason for last abort */	     u_char	hour;			/* hour of day */	     u_char	minute;			/* minute of hour */	     u_char	second;			/* seconds of minute */	     char	tz;			/* timezone from clock */	     u_char	ttytype;		/* method used */	     u_char	dump_vals;		/* Should clock values be dumped */	     u_char	usealldata;		/* Use ALL samples */	     u_short	day;			/* day of year from last code */	     u_long	yearstart;		/* start of current year */	     u_long	leaphold;		/* time of leap hold expiry */	     u_long	badformat;		/* number of bad format codes */	     u_long	baddata;		/* number of invalid time codes */	     u_long	timestarted;		/* time we started this */	     long	last_pps_no;		/* The serial # of the last PPS */	     char	fix_pending;		/* Is a "sync to time" pending ? */	     /* Fine tuning - compensate for 4 mS ramping .... */	     l_fp	last_l;			/* last time stamp */	     u_char	last_steps[MAX_STEP];	/* Most recent n steps */	     int	best_av_step;		/* Best guess at average step */	     char	best_av_step_count;	/* # of steps over used above */	     char	this_step;		/* Current pos in buffer */	     int	last_step_late;		/* How late the last step was (0-59) */	     long	jump_fsecs;		/* # of fractions of a sec last jump */	     u_long	last_step;		/* time of last step */	     int	last_step_secs;		/* Number of seconds in last step */	     int	using_ramp;		/* 1 -> noemal, -1 -> over stepped */     };#define	last_sec	last_l.l_ui#define	last_sfsec	last_l.l_f#define	this_uisec	((ees->arrvtime).l_ui)#define	this_sfsec	((ees->arrvtime).l_f)#define	msec(x)		((x) / (1<<22))#define	LAST_STEPS	(sizeof ees->last_steps / sizeof ees->last_steps[0])#define	subms(x)	((((((x < 0) ? (-(x)) : (x)) % (1<<22))/2) * 625) / (1<<(22 -5)))/* Bitmask for what methods to try to use -- currently only PPS enabled */#define	T_CBREAK	1#define	T_PPS		8/* macros to test above */#define	is_cbreak(x)	((x)->ttytype & T_CBREAK)#define	is_pps(x)	((x)->ttytype & T_PPS)#define	is_any(x)	((x)->ttytype)#define	CODEREASON	20	/* reason codes *//* Data space for the unit structures.  Note that we allocate these on * the fly, but never give them back. */static struct eesunit *eesunits[MAXUNITS];static u_char unitinuse[MAXUNITS];/* Keep the fudge factors separately so they can be set even * when no clock is configured. */static l_fp inherent_delay[MAXUNITS];		/* when time stamp is taken */static l_fp fudgefactor[MAXUNITS];		/* fudgetime1 */static l_fp os_delay[MAXUNITS];			/* fudgetime2 */static l_fp offset_fudge[MAXUNITS];		/* Sum of above */static u_char stratumtouse[MAXUNITS];static u_char sloppyclockflag[MAXUNITS];static int deltas[60];static l_fp acceptable_slop; /* = { 0, 1 << (FRACTION_PREC -2) }; */static l_fp onesec; /* = { 1, 0 }; */#ifndef	DUMP_BUF_SIZE	/* Size of buffer to be used by dump_buf */#define	DUMP_BUF_SIZE	10112#endif/* ees_reset - reset the count back to zero */#define	ees_reset(ees) (ees)->nsamples = 0; \(ees)->codestate = EESCS_WAIT/* ees_event - record and report an event */#define	ees_event(ees, evcode) if ((ees)->status != (u_char)(evcode)) \ees_report_event((ees), (evcode))     /* Find the precision of the system clock by reading it */#define	USECS	1000000#define	MINSTEP	5	/* some systems increment uS on each call */#define	MAXLOOPS (USECS/9)/* * Function prototypes */static	int	msfees_start	P((int unit, struct peer *peer));static	void	msfees_shutdown	P((int unit, struct peer *peer));static	void	msfees_poll	P((int unit, struct peer *peer));static	void	msfees_init	P((void));static	void	dump_buf	P((l_fp *coffs, int from, int to, char *text));static	void	ees_report_event P((struct eesunit *ees, int code));static	void	ees_receive	P((struct recvbuf *rbufp));static	void	ees_process	P((struct eesunit *ees));#ifdef QSORT_USES_VOID_Pstatic	int	offcompare	P((const void *va, const void *vb));#elsestatic	int	offcompare	P((const l_fp *a, const l_fp *b));#endif /* QSORT_USES_VOID_P *//* * Transfer vector */struct	refclock refclock_msfees = {	msfees_start,		/* start up driver */	msfees_shutdown,	/* shut down driver */	msfees_poll,		/* transmit poll message */	noentry,		/* not used */	msfees_init,		/* initialize driver */

⌨️ 快捷键说明

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