Mbed-os: time_t vs timeval operation.

Created on 23 May 2018  路  13Comments  路  Source: ARMmbed/mbed-os

Description

using a K64F board with GCC compiler (gcc-arm-none-eabi-7-2017-q4-major) and wanting to get usec using gettimeofday() using the tv_usec member. Noticed it isn't working. I implemented a simple program:

#include "mbed.h"

#include <stdio.h>
#include <sys/time.h>
#include <time.h>

int main ()
{
  struct timeval tv;
  time_t  rawtime1, rawtime2;
  time_t  seconds;

  time(&rawtime1);

  while(1) {
    time(&rawtime2);
    seconds = time(NULL);
    gettimeofday(&tv, NULL);
    printf("Start time is: %s\r\n",ctime(&rawtime1));
    printf("current time:  %s\r\n",ctime(&rawtime2));
    printf("basic time   : %s\r\n",ctime(&seconds));
    printf("gettimeofday sec=%lld, usec=%ld\r\n\r\n",tv.tv_sec, tv.tv_usec);
    wait(10);
    }
}

and when it runs, it reports:

Start time is: Wed Oct 28 13:11:06 2009
current time: Wed Oct 28 13:14:19 2009
basic time : Wed Oct 28 13:14:19 2009
gettimeofday sec=47386374176768, usec=0

Start time is: Wed Oct 28 13:11:06 2009
current time: Wed Oct 28 13:14:30 2009
basic time : Wed Oct 28 13:14:30 2009
gettimeofday sec=47386374176768, usec=0

Start time is: Wed Oct 28 13:11:06 2009
current time: Wed Oct 28 13:14:40 2009
basic time : Wed Oct 28 13:14:40 2009
gettimeofday sec=47386374176768, usec=0

why is gettimeofday() not functioning as expected?

Issue request type

[X ] Question
[ ] Enhancement
[ ] Bug

CLOSED drivers mirrored

Most helpful comment

@jflynn129 I completely agree. Anyway for a millisecond counter, use rtos::Kernel::get_ms_count().
[Mirrored to Jira]

All 13 comments

@janjongboom Jan, I saw you previously were mentioned on a time related question and was hoping you could answer this questions, hopefully it is something I am doing wrong...
[Mirrored to Jira]

I do not recall is in retarget or anywhere else we have this implemented. Isn't this posix function only?

@ARMmbed/mbed-os-core Please review
[Mirrored to Jira]

yes, https://www.unix.com/man-page/POSIX/3posix/gettimeofday/
to get around this, I did the following:

void onMillisecondTicker(void)
{
    mscount++;
}

void mbed_gettimeofday(struct timeval *now)
{
    uint32_t cnt = mscount;
    now->tv_sec = time(NULL);
    now->tv_usec= cnt - ((long)cnt/1000)*1000;
}

it isn't microseconds, but i couldn't find access to a microsecond counter (but I didn't try real hard either). I only needed millisecond resolution for my needs. But I thought it would have been implemented in mbed.
[Mirrored to Jira]

You need to implement it for your target. A good example is here https://github.com/ARMmbed/mbed-time (for older Mbed Os version).

For GCC ARM, this function needs to be implemented int _gettimeofday_r(struct _reent* unused, struct timeval *tp, void *tzp).
[Mirrored to Jira]

@0xc0170, should we be implementing this in our retarget layer?
[Mirrored to Jira]

IMO (for what it is worth), not having this functionality is a big miss for the Mbed-OS. At the very least, it should pop out an '#error' saying that it isn't currently implemented and providing some info on how a user would implement on their own. Leaving it for a user like me to figure out on their own is not good.
[Mirrored to Jira]

@jflynn129 I completely agree. Anyway for a millisecond counter, use rtos::Kernel::get_ms_count().
[Mirrored to Jira]

@0xc0170, do you have any docs on GCC_ARM's implementation of int _gettimeofday_r(struct _reent* unused, struct timeval *tp, void *tzp) ? I wasn't able to find anything outside of the GNU standard and my toolchain was unable to find either that or the non-reentrant variation. Without the toolchain implementations of those functions, gettimeofday/settimeofday would likely just be wrappers for the Time class in the retargeting layer.
[Mirrored to Jira]

You can check sources for GCC ARM, there should be implementation (in the syscalls code file).

See for instance https://github.com/32bitmicro/newlib-nano-1.0/blob/master/newlib/libc/sys/arm/syscalls.c#L562
[Mirrored to Jira]

@0xc0170 Would it not be easier to use mbed_rtc_time to work on all compiler chains? Or for targets that don't have a RTC Kernel::get_ms_count() as Jan mentioned would work for device uptime. Unfortunately there's no way to get Epoch time from either of those unless you have a network connection or manually set the current time.

Would gettimeofday not just be a wrapper for time(NULL) I suppose is what I'm asking since newlib does not contain a clock and requires an implementation in Mbed OS?

 int gettimeofday(struct timeval *tp, struct timezone *tzp) {
     tp->tv_sec = time(NULL);

     // timezone struct is deprecated
     if (tzp) {
         MBED_WARNING(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM,  MBED_ERROR_CODE_INVALID_ARGUMENT), 
             "timezone parameter not null, argument has been deprecated and will not be modified");
         return 1;
     }

     return 0;
 }

[Mirrored to Jira]

Would gettimeofday not just be a wrapper for time(NULL) I suppose is what I'm asking since newlib does not contain a clock and requires an implementation in Mbed OS?

Looks fine to me. @marcuschangarm Can you review above proposal?
[Mirrored to Jira]

It used to be that time would invoke gettimeofday so I think it is the other way around.

When I look at the old code you linked it goes: time calls gettimeofday calls lp_ticker through a custom function, getTimeval.

getTimeval would return the current uptime plus an offset, which could be adjusted using settimeofday so time would return a UNIX timestamp.
[Mirrored to Jira]

Internal Jira reference: https://jira.arm.com/browse/IOTCORE-96

Was this page helpful?
0 / 5 - 0 ratings

Related issues

neilt6 picture neilt6  路  4Comments

ashok-rao picture ashok-rao  路  4Comments

DuyTrandeLion picture DuyTrandeLion  路  3Comments

sarahmarshy picture sarahmarshy  路  4Comments

drahnr picture drahnr  路  4Comments