Setting and Updating Absolute Time in Zephyr Application Using time_t Epoch

I am trying to configure the absolute time in my application, which at some point receives the time_t epoch value from an external source and should update it internally so that at any time I can retrieve the actual epoch to use in my application. I have tried to update the epoch using the function

void Set_Time( time_t epochTime )
{
    int ret;
    struct timespec ts;

    ts.tv_sec = epochTime;
    ts.tv_nsec = 0;
    ret = clock_settime( CLOCK_REALTIME, &ts );

    if ( ret < 0 )
    {
        LOG_WRN( "clock_settime returned error" );
    }
}

and then read it through the function time(NULL), but the latter always returns the value -1. Does anyone have any suggestions for implementing what I want?

Parents
  • Does time(NULL) return -1 even if you do not call your function Set_Time()? 

    I was thinking that it is better to maintain an epoch offset rather than trying to set the time itself, something like below

    void Set_Time(time_t epochTime)
    {
        epoch_offset = epochTime - (k_uptime_get() / 1000);
        LOG_INF("Time set to: %d (offset: %d)", epochTime, epoch_offset);
    }
    
    
    time_t Get_Time(void)
    {
        return epoch_offset + (k_uptime_get() / 1000);
    }
    

  • Thank you for your response. In the meantime, I solved the issue by no longer using the time() function, which seemed to be linked to a different library than I had expected. I believe the -1 value was due to it not being initialized. I resolved the problem by implementing custom functions that use clock_settime() and clock_gettime().

    void Set_Time( time_t epoch )
    {
        int ret;
        struct timespec ts;
    
        ts.tv_sec = epoch;
        ts.tv_nsec = 0;
        ret = clock_settime( CLOCK_REALTIME, &ts );
    
        if ( ret < 0 )
        {
            LOG_WRN( "clock_settime returned error" );
        }
    }
    
    time_t Get_Time( void )
    {
        struct timespec ts;
    	int ret;
    
    	ret = clock_gettime( CLOCK_REALTIME, &ts );
    
    	if ( ret < 0 )
        {
    		return (time_t) -1;
    	}
    
    	return ts.tv_sec;
    }

    This way, I can update and read the absolute epoch.

  • Sounds reasonable Andrea, thanks for letting us know.

  • Hi  ,

    I was also evaluating the same thing, This is pretty simple way of time keeping in zephyr.

    I have a question, Have you figured out the backend for this implementation? Is is RTC based on Timer based? 

    I'm suspecting in system OFF mode we will loose this clock source and we need to sync up the time again from the external source? 

    Thanks,

    Mayank

  • I have a question, Have you figured out the backend for this implementation? Is is RTC based on Timer based? 

    I'm suspecting in system OFF mode we will loose this clock source and we need to sync up the time again from the external source? 

    If I'm not mistaken, the CLOCK_REALTIME parameter refers to the RTC of the Zephyr kernel, so you should check how it behaves in different power-down scenarios. I suppose that one possible solution is to use an external RTC. However, in my case, I don't have this issue since I only need to obtain the epoch value when connecting via BLE to the central device that provides it.

Reply
  • I have a question, Have you figured out the backend for this implementation? Is is RTC based on Timer based? 

    I'm suspecting in system OFF mode we will loose this clock source and we need to sync up the time again from the external source? 

    If I'm not mistaken, the CLOCK_REALTIME parameter refers to the RTC of the Zephyr kernel, so you should check how it behaves in different power-down scenarios. I suppose that one possible solution is to use an external RTC. However, in my case, I don't have this issue since I only need to obtain the epoch value when connecting via BLE to the central device that provides it.

Children
Related