time.h functions: setting C's concept of the time

Suppose you have an embedded microcontroller based system with a nice C implemtation and standard library. How does one hook up the uC tick counter to be used with the time.h functions? That is, I it is 15:19

15-Jan-2004 at 0x0000'0349 ticks of the time base register, how can I "initialize" the C time functions to return calendar time based upon this knowledge?

Thanks.

--
- Mark ->
--
Reply to
Mark A. Odell
Loading thread data ...

Mark...

If your library is open source, you dive right into the library source. If it isn't open source, see if time.h (or any headers it includes) provides a means to inform it of time scale and/or ticks. If none of the above, dig through the documentation for the vendor/maintainer contact info.

--
Morris Dovey
West Des Moines, Iowa USA
C links at http://www.iedu.com/c
Read my lips: The apple doesn't fall far from the tree.
Reply to
Morris Dovey

These functions will be part of either the kernel, if your system has one, or provided by libstdC. Note both of these are implementation (i.e hardware) dependent.

Ian

Reply to
Ian Bell

Ian Bell wrote in news:40070222_1@mk- nntp-1.news.uk.worldonline.com:

The Diab compiler for PowerPC and the kernel (RTOS) doesn't supply this. So I have found time.c and time.h from Diab and it looks like I have to modify these.

Thanks.

--
- Mark ->
--
Reply to
Mark A. Odell

Morris Dovey wrote in news:CNCNb.53$ snipped-for-privacy@news.uswest.net:

Thanks Morris. Taking your advice I found time.c (and time.h) from the vendor (Diab). I guess I don't normally expect the library sources with an implementation. Hopefully I can hook my timer into Diab's time library.

Regards,

--
- Mark ->
--
Reply to
Mark A. Odell

Mark, assuming that you have an ANSI compliant time implementation.

Please check the controller specific implementation below: It assumes a clock divider of CLOCKS_PER_SEC. 100 clocks per sec or 100 Hertz Interrupt seems reasonable. The interrupt servic routine counts the long integer representing the ANSI time counter.

source file:

============== SNIP SNIP ===================== /* $Id$ * $Revision$ * $Date$ * * ANSI_time.c * * time functions using a timer interrupt and the associated * ANSI library functions to set and get time & date as string * */

/* * $Log$ */ #define ANSI_TIME_C

/************** time.h/time.c functions to create a system clock **********/ #include #include #include #include "ANSI_time.h"

/***************************** ANSI library functions

***********************/

static time_t _initial = (time_t)-1; /* Not initialized */

/* time.h */ time_t time( time_t *timer ) { clock_t clk = clock(); time_t elapsed; if (clk == (clock_t)-1 || _initial == (time_t)-1) { elapsed = (time_t)-1; } else { elapsed = _initial + (time_t) (clk / CLOCKS_PER_SEC); } if ( timer ) { *timer = elapsed; } return elapsed; }

/* time.h */ void _stime( time_t *s ) { clock_t clk = clock(); _initial = (clk == (clock_t)-1) ? *s : *s - (time_t)(clk / CLOCKS_PER_SEC); } /* time.h */ clock_t clock ( void ) { return (clock_t) ANSIclocktick; }

/***************************************************************************

*/

void ANSI_timer_tick_handler(void) /* to be called by ISR */ { ++sysclocktick; ++ANSIclocktick; if ((sysclocktick % CLOCKS_PER_SEC) == 0) { ++ANSICalendarclock; } if (sysclocktick > 65000) { sysclocktick = 1; } }

void ANSI_timer_init(void) /* interrupt handler must be defined by application */ { TB5MR = 0x40; /* Use f8 with Fosc = 16 MHz */ TB5 = ((CPU_CLOCK / CLOCKS_PER_SEC) / 8); /* ((Xin / CLOCKS_PER_SEC) [Hz / Hz] / 8 ) - 1. */ TB5IC = 5; /* Set interrupt priority. */ /* Replaced _fset with __fset */ /* Replaced _I with __I */ __fset(__I); TB5S = 1; /* Go! */ }

/* extract compilation time from macro and use as power-up initialization time * of application */ void ANSI_time_init(void) { typedef enum {Error_ = -1, Success_, False_ = 0, True_} Boolean_T; typedef enum {USA, ISO, EUROPE} Syntax_T; Boolean_T parse_date(const char *str, unsigned *year, unsigned *month, unsigned *day, Syntax_T syntax);

unsigned int month,day,year; char date_str[20];

parse_date(__DATE__,&year,&month,&day,USA); sprintf(date_str,"%d-%d-%d",(int) year,(int) month,(int) day); ANSI_setdate(date_str); ANSI_settime((char *)__TIME__);

}

int ANSI_settime(char *s) { int hour, minute, second; int conversion = -1; time_t calendar_time;

conversion = sscanf(s,"%d:%d:%d",&hour,&minute,&second); if(conversion < 3) return(-1); if(hour > 23) return(-2); if(minute > 59) return(-3); if(second >59) return(-4); ANSI_time.tm_hour = hour; ANSI_time.tm_min = minute; ANSI_time.tm_sec = second;

calendar_time = mktime(&ANSI_time); ANSI_setclock(calendar_time);

return(1); }

int ANSI_setdate(char *s) { int year=0,month=0,day=0; int conversion=-1; time_t calendar_time;

conversion = sscanf(s,"%d-%d-%d",&year,&month,&day); if(conversion < 3) return(-1); if(month > 12) return(-2); if(day > 31) return(-3); ANSI_time.tm_year = year-1900; /* year since 1900

*/ ANSI_time.tm_mon = month-1; /* months since January - [0, 11] */ ANSI_time.tm_mday = day; /* day of the month - [1, 31] */

calendar_time = mktime(&ANSI_time); ANSI_setclock(calendar_time);

return(1); }

void ANSI_setclock(unsigned long t) { /* globaltime * 1000 */ /* the globaltime is the time in seconds since 1.1.1970 */ ANSICalendarclock = t; }

char * ANSI_gettime_str(char *s) { ANSI_gettime(); strftime(s,10,"%H:%M:%S",&ANSI_time); return(s);

}

char * ANSI_getdate_str(char *s) { ANSI_gettime(); strftime(s,12,"%Y-%m-%d",&ANSI_time); return(s);

}

void ANSI_gettime(void) { volatile struct tm *ts;

ts = localtime( (time_t *) &ANSICalendarclock); memcpy(&ANSI_time,ts,sizeof(struct tm)); }

#ifdef TEST_ANSI_time_C #include int system_settime(char *s); int system_setdate(char *s); char * system_gettime(char *s); char * system_getdate(char *s);

void _timer_init(void); char timestr[10]; char datestr[13]; unsigned long l; extern struct tm system_time;

void main(void) {

_timer_init();

ANSI_time_init();

ANSI_setdate("2003.09.04"); ANSI_settime("20:05:01"); ANSI_gettime(timestr); ANSI_getdate(datestr);

for (l=0x003FFFFFUL;l>0;l--) { /* Replaced _nop with __nop */ __nop(); } system_gettime(timestr); }

#endif ==================== SNIP SNIP ================

header file:

=================== SNIP SNIP ================== /* $Id$ * $Revision$ * $Date$ * * system_time.h * * time functions using a timer interrupt and the associated * ANSI library functions to set and get time & date as string * all library ANSI library time processing functions will work * based on these */

/* * $Log$ */ #ifndef ANSI_TIME_H

#ifdef ANSI_TIME_C #define export #else #define export extern #endif export void ANSI_time_init(void); export int ANSI_settime(char *s); export int ANSI_setdate(char *s); export void ANSI_setclock(unsigned long t); export char * ANSI_gettime_str(char *s); export char * ANSI_getdate_str(char *s); export void ANSI_gettime(void); export void ANSI_timer_tick_handler(void);

export volatile unsigned long ANSIclocktick; /* millisecocnds since system start */ export volatile unsigned long ANSICalendarclock; /* ANSI calendar clock: seconds since 1.1.1980 */ export struct tm ANSI_time;

extern volatile unsigned short sysclocktick; /* millisecond clocktick */

#define ANSI_TIME_H #endif =================== SNIP SNIP ==================

the parse date and parse time are taken from Bob Stout's SNIPPETS collection ('97) the ANSI timer init function is specific for an M16C but can be modified for any MCU with a timer unit.

Mark A. Odell schrieb in im Newsbeitrag: Xns94719C102B528CopyrightMarkOdell@130.133.1.4...

Reply to
Jan Homuth

Mark...

I've read enough of your posts to know that you won't have any serious difficulties with this one.

The only vendor I've ever found to be unhelpful with this problem was (of course) Microsoft - with their COBOL-80 compiler.

--
Morris Dovey
West Des Moines, Iowa USA
C links at http://www.iedu.com/c
Read my lips: The apple doesn't fall far from the tree.
Reply to
Morris Dovey

Jan...

Wow! You really know how to answer a question! (-8

--
Morris Dovey
West Des Moines, Iowa USA
C links at http://www.iedu.com/c
Read my lips: The apple doesn't fall far from the tree.
Reply to
Morris Dovey

"Mark A. Odell" wrote in news:Xns94719C102B528CopyrightMarkOdell@130.133.1.4:

Thanks to all for their help. It turns out to be quite simple. I take a seed value from the host over the network and "bind" it to my 64-bit timebase counter. Since I now know what Fri Jan 16 14:18:31 2004 is in

64-bit CPU ticks I just apply a simple ratio for use by time() which I override. That is:

x = time in seconds from C epoch t = seed time in seconds from C epoch k0 = 64-bit count at seed time k1 = 64-bit count now

solving for x:

x t

--- = --- ====> x = t (k1/k0) k1 k0

Actually, I diff the k's and scale the diff back into seconds and add to t to get x but it's the same basic idea. So to summarize for the Diab compiler for the PowerPC:

Create a function that snapshots t and k0 and then override C's time() function to do the above calculation. Since the time() function is an "on demand" function I see no reason to add code to my timer ISR to support calendar time.

Regards.

--
- Mark ->
--
Reply to
Mark A. Odell

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.