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

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
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 ->
--

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

Quoted text here. Click to load it

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
We've slightly trimmed the long signature. Click to see the full one.
Re: time.h functions: setting C's concept of the time

Quoted text here. Click to load it


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 ->
--

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

Quoted text here. Click to load it

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
We've slightly trimmed the long signature. Click to see the full one.
Re: time.h functions: setting C's concept of the time

Quoted text here. Click to load it

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


Re: time.h functions: setting C's concept of the time
nntp-1.news.uk.worldonline.com:

Quoted text here. Click to load it

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 ->
--

Re: time.h functions: setting C's concept of the time
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 <stdio.h>
#include <string.h>
#include <time.h>
#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 <time.h>
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.




Xns94719C102B528CopyrightMarkOdell@130.133.1.4...
Quoted text here. Click to load it



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

Quoted text here. Click to load it

<moderate snippage here>
Quoted text here. Click to load it

Jan...

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

--
Morris Dovey
West Des Moines, Iowa USA
We've slightly trimmed the long signature. Click to see the full one.
Re: time.h functions: setting C's concept of the time

Quoted text here. Click to load it

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 ->
--

Site Timeline