diff --git a/include/Clock.h b/include/Clock.h index c78e7b5..be196c3 100644 --- a/include/Clock.h +++ b/include/Clock.h @@ -8,11 +8,14 @@ #include "NetworkInterface.h" #include "sntp.h" +#include #include -void clock_setup(void); +struct timeval microseconds_to_timeval(std::chrono::microseconds val); +std::chrono::microseconds timeval_to_microseconds(struct timeval val); -struct timeval clock_time(void); +void clock_setup(void); +std::chrono::microseconds clock_time(void); SNTPError clock_sync(NetworkInterface &net); diff --git a/src/Clock.cpp b/src/Clock.cpp index a454af0..ec31bb8 100644 --- a/src/Clock.cpp +++ b/src/Clock.cpp @@ -5,49 +5,46 @@ #include "Clock.h" #include "mbed.h" -#include using namespace std::chrono; - typedef time_point kernel_timepoint; Mutex clock_lock; -microseconds clock_offset; +microseconds boot_start; -struct timeval get_rtc_time() { - struct timeval timeval; - timeval.tv_sec = time(NULL); - timeval.tv_usec = 0; - return timeval; -} - -void clock_setup(void) { - microseconds new_offset(0); - struct timeval rtc_time = get_rtc_time(); - kernel_timepoint kernel_time = Kernel::Clock::now(); - microseconds boot_offset = kernel_time.time_since_epoch(); - new_offset += microseconds(rtc_time.tv_usec); - new_offset += seconds(rtc_time.tv_sec); - new_offset -= boot_offset; - clock_lock.lock(); - clock_offset = new_offset; - clock_lock.unlock(); -} - -struct timeval clock_time() { - clock_lock.lock(); - kernel_timepoint kernel_time = Kernel::Clock::now(); - microseconds curr_offset = clock_offset; - clock_lock.unlock(); - microseconds boot_offset = kernel_time.time_since_epoch(); - microseconds offsetted = curr_offset + boot_offset; - uint64_t microsecs = offsetted.count(); +struct timeval microseconds_to_timeval(microseconds val) { + uint64_t microsecs = val.count(); struct timeval time; time.tv_sec = microsecs / 1000000; time.tv_usec = microsecs % 1000000; return time; } +microseconds timeval_to_microseconds(struct timeval val) { + microseconds time(0); + time += seconds(val.tv_sec); + time += microseconds(val.tv_usec); + return time; +} + +void clock_setup(void) { + kernel_timepoint kernel_time = Kernel::Clock::now(); + seconds real_time = seconds(time(NULL)); + microseconds uptime = kernel_time.time_since_epoch(); + clock_lock.lock(); + boot_start = real_time - uptime; + clock_lock.unlock(); +} + +microseconds clock_time(void) { + kernel_timepoint kernel_time = Kernel::Clock::now(); + clock_lock.lock(); + microseconds curr_offset = boot_start; + clock_lock.unlock(); + microseconds uptime = kernel_time.time_since_epoch(); + return boot_start + uptime; +} + SNTPError clock_sync(NetworkInterface &net) { struct timeval time; SNTPError err; @@ -55,14 +52,11 @@ if (err != SNTPSuccess) { return err; } - clock_lock.lock(); - microseconds new_offset(0); kernel_timepoint kernel_time = Kernel::Clock::now(); - microseconds boot_offset = kernel_time.time_since_epoch(); - new_offset += microseconds(time.tv_usec); - new_offset += seconds(time.tv_sec); - new_offset -= boot_offset; - clock_offset = new_offset; + microseconds real_time = timeval_to_microseconds(time); + microseconds uptime = kernel_time.time_since_epoch(); + clock_lock.lock(); + boot_start = real_time - uptime; clock_lock.unlock(); set_time(time.tv_sec); return SNTPSuccess; @@ -85,14 +79,15 @@ } const char *clock_iso8601string(void) { - struct timeval time = clock_time(); - const char *timestring = clock_timestring(time, "%Y-%m-%dT%H:%M:%S"); + microseconds time = clock_time(); + struct timeval val = microseconds_to_timeval(time); + const char *timestring = clock_timestring(val, "%Y-%m-%dT%H:%M:%S"); static char buffer[128]; int buffer_size = sizeof(buffer); int written; written = snprintf( - buffer, buffer_size, "%s.%05li", timestring, time.tv_usec); + buffer, buffer_size, "%s.%05li", timestring, val.tv_usec); if (written >= buffer_size) { // It overflowed, so return something useful