Page 1 of 1

Newlib and time()

Posted: Tue Jun 25, 2013 7:53 am
by IanSeyler
Has anyone else ported Newlib to their OS with support for getting the computer date/time? If so, I have a couple of questions:

Is the only requirement gettimeofday()?
gettimeofday only returns the number of seconds elapsed since 00:00:00 on January 1, 1970?

Thanks,
Ian

Re: Newlib and time()

Posted: Fri Jun 28, 2013 2:06 pm
by IanSeyler
Anyone? I would like to get this coded this weekend.

Re: Newlib and time()

Posted: Fri Jun 28, 2013 2:15 pm
by Brynet-Inc
It's not entirely clear what you're asking. If you wanted to know the standard definition of gettimeofday, then check SUSv4.

http://pubs.opengroup.org/onlinepubs/96 ... ofday.html

Re: Newlib and time()

Posted: Fri Jun 28, 2013 2:33 pm
by IanSeyler
No worries. Perhaps I wasn't clear enough but I think I have it working:

This reports the date as Jan 1, 1970 @ 00:00:00

Code: Select all

int gettimeofday(struct timeval *p, void *z)
{
	p->tv_sec = 0;
	p->tv_usec = 0;
	return 0;
}
This reports the date as Jun 28, 2013 @ 16:59:59:

Code: Select all

int gettimeofday(struct timeval *p, void *z)
{
	struct tm t;
	t.tm_year = 2013-1900;
	t.tm_mon = 5;
	t.tm_mday = 28;
	t.tm_hour = 16;
	t.tm_min = 59;
	t.tm_sec = 59;
	t.tm_isdst = -1;

	p->tv_sec = (long) mktime(&t);
	p->tv_usec = 0;

	return 0;
}
So all I need to do now is pull the current data from the RTC to populate that tm struct.

Re: Newlib and time()

Posted: Sat Jun 29, 2013 5:16 am
by jnc100
The RTC only provides 1 second resolution, whereas gettimeofday should return seconds and microseconds, and if you want to use the newer clock_gettime functions you should return seconds and nanoseconds. One way to provide this is to store a 64-bit counter of nanoseconds since the epoch within the kernel (this should cover a date range +/- around 292 years) which is initialised at boot time from an external source (e.g. RTC or NTP) and then incremented with each timer tick. Then, when something requests the time, you work it out from here with the appropriate division (alternatively store both seconds and nano/microseconds). This is also generally faster than reading the IO ports from the CMOS, which may be a significant bottleneck if an application requests the current time frequently.

Note this can suffer from drift for several reasons: 1) if the timer device is not providing ticks as accurately as you expect and 2) if you are missing some timer interrupts due to your ISR taking too long, but bear in mind that the RTC suffers drift too. For this reason, you would ideally want to periodically check against a NTP server to ensure you're still reasonably accurate.

Regards,
John.

Re: Newlib and time()

Posted: Sun Jun 30, 2013 8:41 pm
by gerryg400
Reading the RTC is slow and will need global locking. If you are concerned at all about performance (I'm sure you are) you will only read the RTC once at boot.

Re: Newlib and time()

Posted: Mon Jul 01, 2013 12:01 pm
by sortie
Note that gettimeofday() is an obsolescent API and that microsecond precision isn't good enough these days, where the POSIX standard and others have embraced the nano-precision struct timespec and clock_gettime instead, which offers a far superior API (support for multiple clocks, for instance).

Re: Newlib and time()

Posted: Tue Jul 02, 2013 8:31 am
by IanSeyler
Agreed on all points. For right now my implementation is "good enough"™. For BareMetal Node I'll be using the network to get the time from a central server.

For anyone curious, my Newlib syscalls.c is here: https://github.com/ReturnInfinity/BareM ... syscalls.c