mbgtools-lx  4.2.8
mbgtime.h
Go to the documentation of this file.
1 
2 /**************************************************************************
3  *
4  * $Id: mbgtime.h 1.31 2019/02/06 10:08:09 martin TRASH $
5  *
6  * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
7  *
8  * Description:
9  * Definitions and prototypes for mbgtime.c.
10  *
11  * -----------------------------------------------------------------------
12  * $Log: mbgtime.h $
13  * Revision 1.31 2019/02/06 10:08:09 martin
14  * Added symbol HNS_PER_MIN.
15  * Revision 1.30 2018/11/26 12:04:44Z martin
16  * Moved definition NTP_FRAC_PER_SEC here.
17  * Revision 1.29 2018/02/28 16:58:10 martin
18  * Removed reference to frac_sec_from_bin().
19  * Revision 1.28 2018/01/15 18:18:49 martin
20  * Renamed symbol NSECS_PER_SEC to NSEC_PER_SEC.
21  * according to namings of similar symbols.
22  * Revision 1.27 2017/11/29 11:14:57 gregoire
23  * Added Multiplier MSEC_TO_NSEC_MULTIPLIER, MSEC_TO_USEC_MULTIPLIER.
24  * Revision 1.26 2017/11/16 13:33:46 philipp
25  * Added USEC_PER_SEC define.
26  * Revision 1.25 2017/08/15 15:48:59 martin
27  * Define NSECS_PER_SEC only if it hasn't been defined before.
28  * Revision 1.24 2017/07/04 14:02:25 martin
29  * Made definitions of some constants signed to avoid
30  * signed/unsigned compiler warnings.
31  * Moved some macros and inline functions for fraction
32  * conversion here. They are excluded from build in kernel
33  * mode, though, since some kernels don't support this properly.
34  * Moved some NANO_TIME- and NANO_TIME_64-related inline
35  * functions to new module nanotime.c.
36  * Renamed PCPS_HRT_BIN_FRAC_SCALE to MBG_FRAC32_UNITS_PER_SEC.
37  * Updated function prototypes.
38  * Doxygen stuff.
39  * Revision 1.23 2017/03/16 12:26:13 martin
40  * Updated function prototypes.
41  * Revision 1.22 2017/01/25 13:10:55 gregoire.diehl
42  * nano_time_64_to_double and double_to_nano_time_64 added
43  * Revision 1.21 2016/12/15 17:44:59Z martin
44  * Changed conditions to include time.h.
45  * Fixed spelling.
46  * Removed trailing spaces.
47  * Revision 1.20 2014/05/27 08:09:19 martin
48  * Added NTP_SEC_BIAS.
49  * Revision 1.19 2013/05/22 16:47:01 martin
50  * Added some useful macros.
51  * Revision 1.18 2012/10/02 18:51:11 martin
52  * Include <time.h> for WIN32 target and firmware only
53  * Fixed build under QNX, DOS, and FreeBSD.
54  * Revision 1.17 2010/08/06 13:03:03 martin
55  * Removed obsolete code.
56  * Revision 1.16 2010/07/16 10:22:07Z martin
57  * Moved definitions of HNS_PER_SEC and HNS_PER_MS here.
58  * Conditionally define FILETIME_1970.
59  * Defined MASK_CLOCK_T for ARM/Cortex.
60  * Revision 1.15 2009/10/23 09:55:21 martin
61  * Added MJD numbers for commonly used epochs.
62  * Revision 1.14 2009/08/12 10:28:12 daniel
63  * Added definition NSECS_PER_SEC.
64  * Revision 1.13 2009/06/12 13:31:44Z martin
65  * Fix build errors with arm-linux-gcc.
66  * Revision 1.12 2009/03/27 14:14:00 martin
67  * Cleanup for CVI.
68  * Revision 1.11 2009/03/13 09:30:06Z martin
69  * Include mystd.h in mbgtime.c rather than here. The bit type used
70  * here is now defined in words.h.
71  * Updated comments for GPS_SEC_BIAS.
72  * Revision 1.10 2008/12/11 10:45:41Z martin
73  * Added clock_t mask for gcc (GnuC).
74  * Revision 1.9 2006/08/25 09:33:46Z martin
75  * Updated function prototypes.
76  * Revision 1.8 2004/12/28 11:29:02Z martin
77  * Added macro _n_days.
78  * Updated function prototypes.
79  * Revision 1.7 2002/09/06 07:15:48Z martin
80  * Added MASK_CLOCK_T for Linux.
81  * Revision 1.6 2002/02/25 08:37:44 Andre
82  * definition MASK_CLOCK_T for ARM added
83  * Revision 1.5 2001/03/02 10:18:10Z MARTIN
84  * Added MASK_CLOCK_T for Watcom C.
85  * Revision 1.4 2000/09/15 07:57:53 MARTIN
86  * Removed outdated function prototypes.
87  * Revision 1.3 2000/07/21 14:05:18 MARTIN
88  * Defined some new constants.
89  *
90  **************************************************************************/
91 
92 #ifndef _MBGTIME_H
93 #define _MBGTIME_H
94 
95 
96 /* Other headers to be included */
97 
98 #include <gpsdefs.h>
99 
100 #if !defined( MBG_TGT_KERNEL ) || defined( MBG_TGT_WIN32 )
101  #include <time.h>
102 #endif
103 
104 
105 #ifdef __cplusplus
106 extern "C" {
107 #endif
108 
109 #ifdef _MBGTIME
110  #define _ext
111  #define _DO_INIT
112 #else
113  #define _ext extern
114 #endif
115 
116 
117 /* Start of header body */
118 
119 
130 #define GPS_SEC_BIAS 315964800UL // ( ( ( 10UL * 365UL ) + 2 + 5 ) * SECS_PER_DAY )
131 
132 
142 #define NTP_SEC_BIAS 2208988800UL
143 
144 #if !defined( MBG_TGT_MISSING_64_BIT_TYPES )
145  #define NTP_FRAC_PER_SEC (uint64_t) 4294967296.0
146 #endif
147 
148 
149 
150 // Modified Julian Day (MJD) numbers for some commonly used epochs.
151 // To compute the MJD for a given date just compute the days since epoch
152 // and add the constant number of days according to the epoch, e.g.:
153 // current_unix_mjd = ( time( NULL ) / SECS_PER_DAY ) + MJD_AT_UNIX_EPOCH;
154 #define MJD_AT_GPS_EPOCH 44244UL // MJD at 1980-01-06
155 #define MJD_AT_UNIX_EPOCH 40587UL // MJD at 1970-01-01
156 #define MJD_AT_NTP_EPOCH 40587UL // MJD at 1900-01-01
157 
158 
159 // The constant below defines the Windows FILETIME number (100 ns intervals
160 // since 1601-01-01) for 1970-01-01, which is usually the epoch for the time_t
161 // type used by the standard C library.
162 #if !defined( FILETIME_1970 )
163  // FILETIME represents a 64 bit number, so we need to defined the
164  // constant with an appendix depending on the compiler.
165  #if MBG_TGT_C99 || defined( __GNUC__ )
166  // syntax introduced by C99 standard
167  #define FILETIME_1970 0x019db1ded53e8000ULL // Epoch offset from FILETIME to UNIX
168  #elif defined( MBG_TGT_WIN32 )
169  // MSC-specific syntax
170  #define FILETIME_1970 0x019db1ded53e8000ui64
171  #endif
172 #endif
173 
174 
175 #if defined( _C166 )
176  #if _C166 >= 50
177  #define MASK_CLOCK_T 0x7FFFFFFFL
178  #else
179  #define MASK_CLOCK_T 0x7FFF /* time.h not shipped with compiler */
180  #endif
181 #endif
182 
183 #if defined( __WATCOMC__ )
184  #define MASK_CLOCK_T 0x7FFFFFFFL
185 #endif
186 
187 #if defined( _CVI ) || defined( _CVI_ )
188  #define MASK_CLOCK_T 0x7FFFFFFFL
189 #endif
190 
191 #if defined( _MSC_VER )
192  #define MASK_CLOCK_T 0x7FFFFFFFL
193 #endif
194 
195 #if defined( __NETWARE_386__ )
196  #define MASK_CLOCK_T 0x7FFFFFFFL
197 #endif
198 
199 #if defined( __ARM )
200  #define MASK_CLOCK_T 0x7FFFFFFFL
201 #endif
202 
203 #if defined( __ARMCC_VERSION )
204  #define MASK_CLOCK_T ( ( (ulong) (clock_t) -1 ) >> 1 )
205 #endif
206 
207 #if defined( __GNUC__ )
208  #if defined( __linux )
209  #define MASK_CLOCK_T ( ( (ulong) (clock_t) -1 ) >> 1 )
210  #else // Windows / MinGW
211  #define MASK_CLOCK_T 0x7FFFFFFFL
212  #endif
213 #endif
214 
215 
216 #if !defined( MASK_CLOCK_T )
217  #if sizeof( clock_t ) == sizeof( short )
218  #define MASK_CLOCK_T 0x7FFF
219  #elif sizeof( clock_t ) == sizeof( long )
220  #define MASK_CLOCK_T 0x7FFFFFFFL
221  #endif
222 #endif
223 
224 typedef struct
225 {
226  clock_t start;
227  clock_t stop;
228  short is_set;
229 
230 } TIMEOUT;
231 
232 
233 #define DAYS_PER_WEEK 7
234 
235 #define SECS_PER_MIN 60
236 #define MINS_PER_HOUR 60
237 #define HOURS_PER_DAY 24
238 #define DAYS_PER_WEEK 7
239 
240 #define MINS_PER_DAY ( MINS_PER_HOUR * HOURS_PER_DAY )
241 
242 #define SECS_PER_HOUR 3600
243 #define SECS_PER_DAY 86400L
244 #define SECS_PER_WEEK 604800L
245 
246 #define SEC100S_PER_SEC 100L
247 #define SEC100S_PER_MIN ( SEC100S_PER_SEC * SECS_PER_MIN )
248 #define SEC100S_PER_HOUR ( SEC100S_PER_SEC * SECS_PER_HOUR )
249 #define SEC100S_PER_DAY ( SEC100S_PER_SEC * SECS_PER_DAY )
250 
251 #if !defined( MSEC_PER_SEC )
252  #define MSEC_PER_SEC 1000L
253 #endif
254 
255 #define MSEC_PER_MIN ( MSEC_PER_SEC * SECS_PER_MIN )
256 #define MSEC_PER_HOUR ( MSEC_PER_SEC * SECS_PER_HOUR )
257 #define MSEC_PER_DAY ( MSEC_PER_SEC * SECS_PER_DAY )
258 
259 #if !defined( USEC_PER_SEC )
260  #define USEC_PER_SEC 1000000L
261 #endif
262 
263 #if !defined( NSEC_PER_SEC )
264  #define NSEC_PER_SEC 1000000000L
265 #endif
266 
267 #if !defined( HNS_PER_SEC )
268  #define HNS_PER_SEC 10000000L
269 #endif
270 
271 #if !defined( HNS_PER_MS )
272  #define HNS_PER_MS 10000L
273 #endif
274 
275 #if !defined( HNS_PER_MIN )
276  #define HNS_PER_MIN ( HNS_PER_SEC * SECS_PER_MIN )
277 #endif
278 
279 #define MSEC_TO_NSEC_MULTIPLIER ( NSEC_PER_SEC / MSEC_PER_SEC )
280 #define MSEC_TO_USEC_MULTIPLIER ( USEC_PER_SEC / MSEC_PER_SEC )
281 
282 
291 typedef char DAYS_OF_MONTH_TABLE[2][12];
292 
293 
297 #define DAYS_OF_MONTH_TABLE_INIT \
298 { \
299  { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, \
300  { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } \
301 }
302 
303 
304 
305 
308 
309 
310 _ext const char *short_time_fmt
311 #ifdef _DO_INIT
312  = "%2i:%02i"
313 #endif
314 ;
315 
316 _ext const char *time_fmt
317 #ifdef _DO_INIT
318  = "%2i:%02i:%02i"
319 #endif
320 ;
321 
322 _ext const char *long_time_fmt
323 #ifdef _DO_INIT
324  = "%2i:%02i:%02i.%02i"
325 #endif
326 ;
327 
328 _ext const char *date_fmt
329 #ifdef _DO_INIT
330  = "%2i.%02i.%04i"
331 #endif
332 ;
333 
334 _ext const char *day_date_fmt
335 #ifdef _DO_INIT
336  = "%s, %2i.%02i.%04i"
337 #endif
338 ;
339 
340 _ext const char *day_name_eng[]
341 #ifdef _DO_INIT
342  = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }
343 #endif
344 ;
345 
346 _ext const char *day_name_ger[]
347 #ifdef _DO_INIT
348  = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" }
349 #endif
350 ;
351 
352 _ext const TM_GPS init_tm
353 #ifdef _DO_INIT
354  = { 1980, 1, 1, 0, 0, 0, 0, 0, 0, 0 }
355 #endif
356 ;
357 
358 
359 _ext DAYS_OF_MONTH_TABLE days_of_month
360 #ifdef _DO_INIT
362 #endif
363 ;
364 
365 
366 // simplify call to n_days with structures
367 #define _n_days( _s ) \
368  n_days( (_s)->mday, (_s)->month, (_s)->year )
369 
370 
371 #define _is_leap_year( _y ) \
372  ( ( ( ( (_y) % 4 ) == 0 ) && ( ( (_y) % 100 ) != 0 ) ) || ( ( (_y) % 400 ) == 0 ) )
373 
374 
375 #define _get_days_of_month( _y, _m ) \
376  days_of_month[ _is_leap_year( _y ) ][_m]
377 
378 
379 
380 #if !defined( MBG_TGT_KERNEL )
381 
389 #if defined( MBG_TGT_MISSING_64_BIT_TYPES )
390  #define MBG_FRAC32_CONVERSION_TYPE double
391 #else
392  #define MBG_FRAC32_CONVERSION_TYPE int64_t
393 #endif
394 
400 #define MBG_FRAC32_UNITS_PER_SEC ( (MBG_FRAC32_CONVERSION_TYPE) 4294967296.0 ) // == 0x100000000
401 
402 
403 
416 static __mbg_inline
417 uint32_t bin_frac_16_to_dec_frac( uint16_t bin, uint32_t scale )
418 {
419  return (uint32_t) ( (MBG_FRAC32_CONVERSION_TYPE) bin * scale
420  / 0x10000UL );
421 
422 } // bin_frac_16_to_dec_frac
423 
424 
425 
438 static __mbg_inline
439 uint32_t bin_frac_32_to_dec_frac( uint32_t bin, uint32_t scale )
440 {
441  return (uint32_t) ( (MBG_FRAC32_CONVERSION_TYPE) bin * scale
443 
444 } // bin_frac_32_to_dec_frac
445 
446 
447 
448 #if !defined( MBG_TGT_MISSING_64_BIT_TYPES )
449 
450 // On targets which don't provide 64 bit data types
451 // MBG_FRAC32_CONVERSION_TYPE is defined as double,
452 // in which case the ">> 1" operation in the 2 functions
453 // below yields an "invalid use of floating point" error.
454 // This could probably be fixed by a different way of
455 // casting, at least for a partial expression.
456 
457 static __mbg_inline
458 uint16_t dec_frac_to_bin_frac_16( uint32_t dec, uint32_t scale )
459 {
460  return (uint16_t) ( ( ( (MBG_FRAC32_CONVERSION_TYPE) dec * 0x20000 / scale ) + 1 ) >> 1 );
461 
462 } // dec_frac_to_bin_frac_16
463 
464 
465 static __mbg_inline
466 uint32_t dec_frac_to_bin_frac_32( uint32_t dec, uint32_t scale )
467 {
468  return (uint32_t) ( ( ( (MBG_FRAC32_CONVERSION_TYPE) dec * MBG_FRAC32_UNITS_PER_SEC * 2 / scale ) + 1 ) >> 1 );
469 
470 } // dec_frac_to_bin_frac_32
471 
472 #endif // !defined( MBG_TGT_MISSING_64_BIT_TYPES )
473 
474 
475 
476 #define bin_frac_32_to_msec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000L )
477 #define bin_frac_32_to_usec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000000L )
478 #define bin_frac_32_to_nsec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000000000L )
479 #define bin_frac_16_to_msec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000L )
480 #define bin_frac_16_to_usec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000000L )
481 #define bin_frac_16_to_nsec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000000000L )
482 
483 
484 #define msec_to_bin_frac_32( _msec ) dec_frac_to_bin_frac_32( (_msec), 1000L )
485 #define usec_to_bin_frac_32( _usec ) dec_frac_to_bin_frac_32( (_usec), 1000000L )
486 #define nsec_to_bin_frac_32( _nsec ) dec_frac_to_bin_frac_32( (_nsec), 1000000000L )
487 #define msec_to_bin_frac_16( _msec ) dec_frac_to_bin_frac_16( (_msec), 1000L )
488 #define usec_to_bin_frac_16( _usec ) dec_frac_to_bin_frac_16( (_usec), 1000000L )
489 #define nsec_to_bin_frac_16( _nsec ) dec_frac_to_bin_frac_16( (_nsec), 1000000000L )
490 
491 
492 
508 static __mbg_inline
509 uint32_t _DEPRECATED_BY( "bin_frac_32_to_dec_frac" ) frac_sec_from_bin( uint32_t b, uint32_t scale )
510 {
511  return bin_frac_32_to_dec_frac( b, scale );
512 
513 } // frac_sec_from_bin
514 
515 
516 
533 static __mbg_inline
534 double dfrac_sec_from_bin( uint32_t b )
535 {
536  return (double) b / (double) MBG_FRAC32_UNITS_PER_SEC;
537 
538 } // dfrac_sec_from_bin
539 
540 #endif // !defined( MBG_TGT_KERNEL )
541 
542 
543 
544 /* ----- function prototypes begin ----- */
545 
546 /* This section was generated automatically */
547 /* by MAKEHDR, do not remove the comments. */
548 
556  void set_timeout( TIMEOUT *t, clock_t clk, clock_t interval ) ;
557 
564  void stretch_timeout( TIMEOUT *t, clock_t interval ) ;
565 
574  bit check_timeout( TIMEOUT *t, clock_t clk ) ;
575 
584  int err_tm( const TM_GPS *tm ) ;
585 
593  TM_GPS *clear_time( TM_GPS *tm ) ;
594 
605  TM_GPS *wsec_to_tm( long wsec, TM_GPS *tm ) ;
606 
618  long tm_to_wsec( const TM_GPS *tm ) ;
619 
627  int is_leap_year( int y ) ;
628 
638  int day_of_year( int day, int month, int year ) ;
639 
647  void date_of_year ( int year, int day_num, TM_GPS *tm ) ;
648 
662  int day_of_week( int day, int month, int year ) ;
663 
672  int days_to_years( long *day_num, int year ) ;
673 
685  long n_days( ushort mday, ushort month, ushort year ) ;
686 
693  int sprint_time( char *s, const TM_GPS *tm ) ;
694 
701  int sprint_short_time( char *s, const TM_GPS *tm ) ;
702 
709  int sprint_date( char *s, const TM_GPS *tm ) ;
710 
717  int sprint_day_date( char *s, const TM_GPS *tm ) ;
718 
725  int sprint_tm( char *s, const TM_GPS *tm ) ;
726 
733  void sscan_time( const char *s, TM_GPS *tm ) ;
734 
741  void sscan_date( char *s, TM_GPS *tm ) ;
742 
743 
744 /* ----- function prototypes end ----- */
745 
746 
747 /* End of header body */
748 
749 
750 #undef _ext
751 #undef _DO_INIT
752 
753 #ifdef __cplusplus
754 }
755 #endif
756 
757 
758 #endif /* _MBGTIME_H */
int sprint_short_time(char *s, const TM_GPS *tm)
Print time with hours, minutes to a string.
TM_GPS dhms
clock_t stop
Definition: mbgtime.h:227
void sscan_date(char *s, TM_GPS *tm)
Extract a date from a string.
clock_t start
Definition: mbgtime.h:226
bit check_timeout(TIMEOUT *t, clock_t clk)
Check if a timeout object has expired.
const char * short_time_fmt
#define MBG_FRAC32_CONVERSION_TYPE
Data type used for intermediate results on 32 bit multiplications.
Definition: mbgtime.h:392
#define _ext
Definition: mbgtime.h:113
Local date and time computed from GPS time.
Definition: gpsdefs.h:2593
const char * long_time_fmt
unsigned short uint16_t
Definition: words.h:213
void sscan_time(const char *s, TM_GPS *tm)
Extract a time from a string.
int day_of_year(int day, int month, int year)
Compute the day-of-year from a given date.
bool bit
Definition: words.h:411
const char * date_fmt
static __mbg_inline uint32_t bin_frac_16_to_dec_frac(uint16_t bin, uint32_t scale)
Convert a 16 bit binary fraction to a scaled decimal.
Definition: mbgtime.h:417
const char * time_fmt
TM_GPS * wsec_to_tm(long wsec, TM_GPS *tm)
Convert second-of-week to day-of-week and time-of-day.
const char * day_name_eng[]
unsigned short ushort
Definition: words.h:282
static __mbg_inline uint32_t frac_sec_from_bin(uint32_t b, uint32_t scale)
Convert a binary fraction to a scaled decimal.
Definition: mbgtime.h:509
TM_GPS datum
void date_of_year(int year, int day_num, TM_GPS *tm)
Compute a date from a given year and day-of-year.
long tm_to_wsec(const TM_GPS *tm)
Compute second-of-week from day-of-week and time-of-day.
void stretch_timeout(TIMEOUT *t, clock_t interval)
Stretch a timeout specified in given timeout object.
TM_GPS * clear_time(TM_GPS *tm)
Set the time in a TM_GPS structure to 00:00:00.000.
int day_of_week(int day, int month, int year)
Compute day-of-week from a given date.
long n_days(ushort mday, ushort month, ushort year)
Compute number of days after Jan 1, 0000 for a given date.
int is_leap_year(int y)
Check if a specific year is a leap year.
static __mbg_inline uint16_t dec_frac_to_bin_frac_16(uint32_t dec, uint32_t scale)
Definition: mbgtime.h:458
int sprint_time(char *s, const TM_GPS *tm)
Print time with hours, minutes, seconds to a string.
static __mbg_inline uint32_t dec_frac_to_bin_frac_32(uint32_t dec, uint32_t scale)
Definition: mbgtime.h:466
void set_timeout(TIMEOUT *t, clock_t clk, clock_t interval)
Set a timeout object to specified interval.
#define MBG_FRAC32_UNITS_PER_SEC
Constant used to convert e.g. PCPS_TIME_STAMP::frac values.
Definition: mbgtime.h:400
char DAYS_OF_MONTH_TABLE[2][12]
A table with the days of month.
Definition: mbgtime.h:291
DAYS_OF_MONTH_TABLE days_of_month
const char * day_name_ger[]
int sprint_tm(char *s, const TM_GPS *tm)
Print day-of-week, date and time to a string.
const TM_GPS init_tm
static __mbg_inline uint32_t bin_frac_32_to_dec_frac(uint32_t bin, uint32_t scale)
Convert a 32 bit binary fraction to a scaled decimal.
Definition: mbgtime.h:439
int sprint_day_date(char *s, const TM_GPS *tm)
Print day-of-week and date to a string.
int sprint_date(char *s, const TM_GPS *tm)
Print date to a string.
int err_tm(const TM_GPS *tm)
Check if a TM_GPS structure contains a valid date and time.
int days_to_years(long *day_num, int year)
Update a year number by a number of days, accounting for leap years.
#define DAYS_OF_MONTH_TABLE_INIT
An initializer for a DAYS_OF_MONTH_TABLE.
Definition: mbgtime.h:297
static __mbg_inline double dfrac_sec_from_bin(uint32_t b)
Convert a binary fraction to "double" fractions.
Definition: mbgtime.h:534
short is_set
Definition: mbgtime.h:228
const char * day_date_fmt