From 92852c959b3ae49bf91ded8c3bb0222b0917f184 Mon Sep 17 00:00:00 2001 From: Sagar Dhawan Date: Wed, 1 Apr 2020 11:28:08 -0700 Subject: [PATCH 1/3] Add SystemTimeSupport utility for device layer --- src/lib/support/TimeUtils.cpp | 491 ++++++++++++++++++++ src/lib/support/TimeUtils.h | 117 +++++ src/platform/FreeRTOS/SystemTimeSupport.cpp | 145 ++++++ 3 files changed, 753 insertions(+) create mode 100644 src/lib/support/TimeUtils.cpp create mode 100644 src/lib/support/TimeUtils.h create mode 100644 src/platform/FreeRTOS/SystemTimeSupport.cpp diff --git a/src/lib/support/TimeUtils.cpp b/src/lib/support/TimeUtils.cpp new file mode 100644 index 00000000000000..1da3156c2b5d37 --- /dev/null +++ b/src/lib/support/TimeUtils.cpp @@ -0,0 +1,491 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2013-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Various utility functions for dealing with time and dates. + * + */ + +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS +#endif +#include + +#include + +#include "TimeUtils.h" + +namespace chip { + +enum { + // Number of days during the invariant part of the year (after the leap day). + kDaysFromMarch1ToDecember31 = 306, + + // Number of years in a Gregorian "cycle", where a cycle is the 400-year period + // over which the Gregorian calendar repeats. + kYearsPerCycle = 400, + + // Total number of days within cycle. + kDaysPerCycle = 146097, + + // Total number of days between 0000/03/01 and 1970/01/01. + kEpochOffsetDays = 719468 +}; + +/* Returns the number of days between January 1st and March 1st for a given year. + */ +static inline uint8_t DaysToMarch1(uint16_t year) +{ + if (IsLeapYear(year)) + return 60; + else + return 59; +} + +/* Converts a March-based month number (0=March, 1=April, etc.) to a March-1st based day of year (0=March 1st, 1=March 2nd, etc.). + * + * NOTE: This is based on the math described in http://howardhinnant.github.io/date_algorithms.html. + */ +static uint16_t MarchBasedMonthToDayOfYear(uint8_t month) +{ + return (153 * month + 2) / 5; +} + +/* Converts a March-1st based day of year (0=March 1st, 1=March 2nd, etc.) to a March-based month number (0=March, 1=April, etc.). + */ +static uint8_t MarchBasedDayOfYearToMonth(uint16_t dayOfYear) +{ + return (5 * dayOfYear + 2) / 153; +} + +/** + * @def IsLeapYear + * + * @brief + * Returns true if the given year is a leap year according to the Gregorian calendar. + * + * @param year + * Gregorian calendar year. + * + */ +bool IsLeapYear(uint16_t year) +{ + return (year % kLeapYearInterval) == 0 && ((year % kYearsPerCentury) != 0 || (year % kYearsPerCycle) == 0); +} + +/** + * @def DaysInMonth + * + * @brief + * Returns the number of days in the given month/year. + * + * @param year + * Gregorian calendar year. + * + * @param month + * Month in standard form (1=January ... 12=December). + * + * @return + * Number of days in the given month. + */ +uint8_t DaysInMonth(uint16_t year, uint8_t month) +{ + static const uint8_t daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + if (month == kFebruary && IsLeapYear(year)) + return 29; + else if (month >= kJanuary && month <= kDecember) + return daysInMonth[month - 1]; + else + return 0; +} + +/** + * @def FirstWeekdayOfYear + * + * @brief + * Returns the day of the week for January 1st of the given year. + * + * @param year + * Gregorian calendar year. + * + * @return + * The day-of-week (0=Sunday...6=Saturday). + */ +uint8_t FirstWeekdayOfYear(uint16_t year) +{ + // Compute the day of the week for the first day of the given year using Gauss' algorithm. + return (1 + 5 * ((year - 1) % kLeapYearInterval) + 4 * ((year - 1) % kYearsPerCentury) + 6 * ((year - 1) % kYearsPerCycle)) % kDaysPerWeek; +} + +/** + * @def OrdinalDateToCalendarDate + * + * @brief + * Convert an ordinal date (year/day-of-year) to a calendar date. + * + * @param year + * Gregorian calendar year. + * + * @param dayOfYear + * Ordinal day of year, base 1 (1=January 1st, 2=January 2nd, etc.). + * + * @param month + * [OUTPUT] Corresponding month in standard form (1=January ... 12=December). + * + * @param dayOfMonth + * [OUTPUT] Corresponding day-of-month in standard form (1=1st, 2=2nd, etc.). + * + */ +void OrdinalDateToCalendarDate(uint16_t year, uint16_t dayOfYear, uint8_t& month, uint8_t& dayOfMonth) +{ + uint8_t daysToMarch1 = DaysToMarch1(year); + + // Make dayOfYear base 0. + dayOfYear -= 1; + + // Adjust dayOfYear to a March 1st base (i.e. 0 = March 1, 1 = March 2, etc.). This numbers January + // and February at the end of the range, with the benefit that day numbering is identical between + // standard and leap years with the exception of the leap day itself. + if (dayOfYear < daysToMarch1) + dayOfYear += kDaysFromMarch1ToDecember31; + else + dayOfYear -= daysToMarch1; + + // Compute a March-based month number (i.e. 0=March...11=February) from the day of year. This is based + // on the logic in http://howardhinnant.github.io/date_algorithms.html. + month = MarchBasedDayOfYearToMonth(dayOfYear); + + // Compute the days from March 1st to the start of the corresponding month. + uint16_t daysFromMarch1ToStartOfMonth = MarchBasedMonthToDayOfYear(month); + + // Compute the day of month in standard form (1=1st, 2=2nd, etc.). + dayOfMonth = dayOfYear - daysFromMarch1ToStartOfMonth + 1; + + // Convert the month number to standard form (1=January...12=December). + month = month + (month < 10 ? 3 : -9); +} + +/** + * @def CalendarDateToOrdinalDate + * + * @brief + * Convert an calendar date to ordinal form (year/day-of-year). + * + * @param year + * Gregorian calendar year. + * + * @param month + * Month in standard form (1=January ... 12=December). + * + * @param dayOfMonth + * Day-of-month in standard form (1=1st, 2=2nd, etc.). + * + * @param dayOfYear + * [OUTPUT] Ordinal day of year, base 1 (1=January 1st, 2=January 2nd, etc.). + * + */ +void CalendarDateToOrdinalDate(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint16_t& dayOfYear) +{ + // Convert month to a March-based month number (i.e. 0=March, 1=April, ...11=February). + month = month + (month > kFebruary ? -3 : 9); + + // Compute the days from March 1st to the start of the corresponding month. + dayOfYear = MarchBasedMonthToDayOfYear(month); + + // Adjust dayOfYear to be January-based (0=January 1st, 1=January 2nd...). + if (dayOfYear < kDaysFromMarch1ToDecember31) + dayOfYear += DaysToMarch1(year); + else + dayOfYear -= kDaysFromMarch1ToDecember31; + + // Add in day of month, converting to base 1 in the process. + dayOfYear += dayOfMonth; +} + +/** + * @def CalendarDateToDaysSinceEpoch + * + * @brief + * Convert a calendar date to the number of days since 1970-01-01. + * + * @param year + * Gregorian calendar year in the range 1970 to 28276. + * + * @param month + * Month in standard form (1=January ... 12=December). + * + * @param dayOfMonth + * Day-of-month in standard form (1=1st, 2=2nd, etc.). + * + * @param daysSinceEpoch + * [OUTPUT] Number of days since 1970-01-01. + * + * @return + * True if the date was converted successfully. False if the given year falls outside the + * representable range. + * + * @note + * This function makes no attempt to verify the correct range of any arguments other than year. + * Therefore callers must make sure the supplied values are valid prior to calling the function. + */ +bool CalendarDateToDaysSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint32_t& daysSinceEpoch) +{ + // NOTE: This algorithm is based on the logic described in http://howardhinnant.github.io/date_algorithms.html. + + // Return immediately if the year is out of range. + if (year < kEpochYear || year > kMaxYearInDaysSinceEpoch32) + { + daysSinceEpoch = UINT32_MAX; + return false; + } + + // Adjust the year and month to be March-based (i.e. 0=March, 1=April, ...11=February). + if (month <= kFebruary) + { + year--; + month += 9; + } + else + month -= 3; + + // Compute the days from March 1st to the start of the specified day. + uint16_t dayOfYear = MarchBasedMonthToDayOfYear(month) + (dayOfMonth - 1); + + // Compute the 400-year Gregorian "cycle" within which the given year falls. + uint16_t cycle = year / kYearsPerCycle; + + // Compute the relative year within the cycle. + uint32_t yearOfCycle = year - (cycle * kYearsPerCycle); + + // Compute the relative day within the cycle, accounting for leap-years. + uint32_t dayOfCycle = (yearOfCycle * kDaysPerStandardYear) + dayOfYear - (yearOfCycle / kYearsPerCentury) + (yearOfCycle / kLeapYearInterval); + + // Compute the total number of days since the start of the logical calendar (0000-03-01). + uint32_t daysSinceCalendarStart = (cycle * kDaysPerCycle) + dayOfCycle; + + // Adjust the days value to be days since 1970-01-01. + daysSinceEpoch = daysSinceCalendarStart - kEpochOffsetDays; + + return true; +} + +/** + * @def DaysSinceEpochToCalendarDate + * + * @brief + * Convert the number of days since 1970-01-01 to a calendar date. + * + * @param daysSinceEpoch + * Number of days since 1970-01-01. + * + * @param year + * [OUTPUT] Gregorian calendar year. + * + * @param month + * [OUTPUT] Month in standard form (1=January ... 12=December). + * + * @param dayOfMonth + * [OUTPUT] Day-of-month in standard form (1=1st, 2=2nd, etc.). + * + */ +void DaysSinceEpochToCalendarDate(uint32_t daysSinceEpoch, uint16_t& year, uint8_t& month, uint8_t& dayOfMonth) +{ + // NOTE: This algorithm is based on the logic described in http://howardhinnant.github.io/date_algorithms.html. + + // Adjust days value to be relative to 0000-03-01. + daysSinceEpoch += kEpochOffsetDays; + + // Compute the 400-year Gregorian cycle in which the given day resides. + uint32_t cycle = daysSinceEpoch / kDaysPerCycle; + + // Compute the relative day within the cycle. + uint32_t dayOfCycle = daysSinceEpoch - (cycle * kDaysPerCycle); + + // Compute the relative year within the cycle, adjusting for leap-years. + uint16_t yearOfCycle = (dayOfCycle - dayOfCycle/1460 + dayOfCycle/36524 - dayOfCycle/146096) / kDaysPerStandardYear; + + // Compute the relative day with the year. + uint16_t dayOfYear = dayOfCycle - (yearOfCycle * kDaysPerStandardYear + yearOfCycle/kLeapYearInterval - yearOfCycle/kYearsPerCentury); + + // Compute a March-based month number (i.e. 0=March...11=February) from the day of year. + month = MarchBasedDayOfYearToMonth(dayOfYear); + + // Compute the days from March 1st to the start of the corresponding month. + uint16_t daysFromMarch1ToStartOfMonth = MarchBasedMonthToDayOfYear(month); + + // Compute the day of month in standard form (1=1st, 2=2nd, etc.). + dayOfMonth = dayOfYear - daysFromMarch1ToStartOfMonth + 1; + + // Convert the month number to standard form (1=January...12=December). + month = month + (month < 10 ? 3 : -9); + + // Compute the year, adjusting for the standard start of year (January). + year = yearOfCycle + cycle * kYearsPerCycle; + if (month <= kFebruary) + year++; +} + +/** + * @def AdjustCalendarDate + * + * @brief + * Adjust a calendar date by a given number of days (positive or negative). + * + * @param year + * [INPUT/OUTPUT] Gregorian calendar year. + * + * @param month + * [INPUT/OUTPUT] Month in standard form (1=January ... 12=December). + * + * @param dayOfMonth + * [INPUT/OUTPUT] Day-of-month in standard form (1=1st, 2=2nd, etc.). + * + * @param relativeDays + * Number of days to add/subtract from given calendar date. + * + * @note + * Given date must be equal to or greater than 1970-01-01. + */ +void AdjustCalendarDate(uint16_t& year, uint8_t& month, uint8_t& dayOfMonth, int32_t relativeDays) +{ + uint32_t daysSinceEpoch; + + CalendarDateToDaysSinceEpoch(year, month, dayOfMonth, daysSinceEpoch); + daysSinceEpoch += relativeDays; + DaysSinceEpochToCalendarDate(daysSinceEpoch, year, month, dayOfMonth); +} + +/** + * @def CalendarTimeToSecondsSinceEpoch + * + * @brief + * Convert a calendar date and time to the number of seconds since 1970-01-01 00:00:00 UTC. + * + * @details + * This function is roughly equivalent to the POSIX gmtime() function with the exception + * that the output time value is limited to positive values up to 2^32-1. This limits the + * representable date range to the year 2105. + * + * @note + * This function makes no attempt to verify the correct range of any arguments other than year. + * Therefore callers must make sure the supplied values are valid prior to invocation. + * + * @param secondsSinceEpoch + * Number of seconds since 1970-01-01 00:00:00 UTC. Note: this value is compatible with + * *positive* values of the POSIX time_t value up to the year 2105. + * + * @param year + * Gregorian calendar year in the range 1970 to 2105. + * + * @param month + * Month in standard form (1=January ... 12=December). + * + * @param dayOfMonth + * Day-of-month in standard form (1=1st, 2=2nd, etc.). + * + * @param hour + * Hour (0-23). + * + * @param minute + * Minute (0-59). + * + * @param second + * Second (0-59). + * + * @return + * True if the date/time was converted successfully. False if the given year falls outside the + * representable range. + */ +bool CalendarTimeToSecondsSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, + uint8_t hour, uint8_t minute, uint8_t second, + uint32_t& secondsSinceEpoch) +{ + uint32_t daysSinceEpoch; + + // Return immediately if the year is out of range. + if (year < kEpochYear || year > kMaxYearInSecondsSinceEpoch32) + { + secondsSinceEpoch = UINT32_MAX; + return false; + } + + CalendarDateToDaysSinceEpoch(year, month, dayOfMonth, daysSinceEpoch); + + secondsSinceEpoch = (daysSinceEpoch * kSecondsPerDay) + (hour * kSecondsPerHour) + (minute * kSecondsPerMinute) + second; + + return true; +} + +/** + * @def SecondsSinceEpochToCalendarTime + * + * @brief + * Convert the number of seconds since 1970-01-01 00:00:00 UTC to a calendar date and time. + * + * @details + * This function is roughly equivalent to the POSIX mktime() function, with the following + * exceptions: + * + * - Input time values are limited to positive values up to 2^32-1. This limits the + * representable date range to the year 2105. + * + * - The output time is always UTC (unlike mktime() which outputs time in the process's + * configured timezone). + * + * @param secondsSinceEpoch + * Number of seconds since 1970-01-01 00:00:00 UTC. Note: this value is compatible with + * *positive* values of the POSIX time_t value up to the year 2105. + * + * @param year + * [OUTPUT] Gregorian calendar year. + * + * @param month + * [OUTPUT] Month in standard form (1=January ... 12=December). + * + * @param dayOfMonth + * [OUTPUT] Day-of-month in standard form (1=1st, 2=2nd, etc.). + * + * @param hour + * [OUTPUT] Hour (0-23). + * + * @param minute + * [OUTPUT] Minute (0-59). + * + * @param second + * [OUTPUT] Second (0-59). + */ +void SecondsSinceEpochToCalendarTime(uint32_t secondsSinceEpoch, + uint16_t& year, uint8_t& month, uint8_t& dayOfMonth, + uint8_t& hour, uint8_t& minute, uint8_t& second) +{ + uint32_t daysSinceEpoch = secondsSinceEpoch / kSecondsPerDay; + uint32_t timeOfDay = secondsSinceEpoch - (daysSinceEpoch * kSecondsPerDay); + + DaysSinceEpochToCalendarDate(daysSinceEpoch, year, month, dayOfMonth); + + hour = (uint8_t)(timeOfDay / kSecondsPerHour); + timeOfDay -= (hour * kSecondsPerHour); + minute = (uint8_t)(timeOfDay / kSecondsPerMinute); + timeOfDay -= (minute * kSecondsPerMinute); + second = (uint8_t)timeOfDay; +} + +} // namespace chip diff --git a/src/lib/support/TimeUtils.h b/src/lib/support/TimeUtils.h new file mode 100644 index 00000000000000..168b80e7943845 --- /dev/null +++ b/src/lib/support/TimeUtils.h @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2013-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Various utility functions for dealing with time and dates. + * + */ + +#ifndef TIMEUTILS_H_ +#define TIMEUTILS_H_ + +#include + +namespace chip { + +enum { + kYearsPerCentury = 100, + kLeapYearInterval = 4, + + kMonthsPerYear = 12, + + kMaxDaysPerMonth = 31, + + kDaysPerWeek = 7, + kDaysPerStandardYear = 365, + kDaysPerLeapYear = kDaysPerStandardYear + 1, + + kHoursPerDay = 24, + kHoursPerWeek = kDaysPerWeek * kHoursPerDay, + + kMinutesPerHour = 60, + kMinutesPerDay = kHoursPerDay * kMinutesPerHour, + + kSecondsPerMinute = 60, + kSecondsPerHour = kSecondsPerMinute * kMinutesPerHour, + kSecondsPerDay = kSecondsPerHour * kHoursPerDay, + kSecondsPerWeek = kSecondsPerDay * kDaysPerWeek, + kSecondsPerStandardYear = kSecondsPerDay * kDaysPerStandardYear, + + kMillisecondPerSecond = 1000, + + kMicrosecondsPerSecond = 1000000 +}; + +enum { + kJanuary = 1, + kFebruary = 2, + kMarch = 3, + kApril = 4, + kMay = 5, + kJune = 6, + kJuly = 7, + kAugust = 8, + kSeptember = 9, + kOctober = 10, + kNovember = 11, + kDecember = 12 +}; + +enum { + // First year of the standard unix epoch. + kEpochYear = 1970, + + // Last fully-representable year that can be stored in an unsigned 32-bit seconds-since-epoch value. + kMaxYearInSecondsSinceEpoch32 = 2105, + + // Last fully-representable year that can be stored in an unsigned 32-bit days-since-epoch value. + kMaxYearInDaysSinceEpoch32 = 28276 +}; + +extern bool IsLeapYear(uint16_t year); +extern uint8_t DaysInMonth(uint16_t year, uint8_t month); +extern uint8_t FirstWeekdayOfYear(uint16_t year); +extern void OrdinalDateToCalendarDate(uint16_t year, uint16_t dayOfYear, uint8_t& month, uint8_t& dayOfMonth); +extern void CalendarDateToOrdinalDate(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint16_t& dayOfYear); +extern bool CalendarDateToDaysSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint32_t& daysSinceEpoch); +extern void DaysSinceEpochToCalendarDate(uint32_t daysSinceEpoch, uint16_t& year, uint8_t& month, uint8_t& dayOfMonth); +extern void AdjustCalendarDate(uint16_t& year, uint8_t& month, uint8_t& dayOfMonth, int32_t relativeDays); +extern bool CalendarTimeToSecondsSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, + uint8_t hour, uint8_t minute, uint8_t second, + uint32_t& secondsSinceEpoch); +extern void SecondsSinceEpochToCalendarTime(uint32_t secondsSinceEpoch, + uint16_t& year, uint8_t& month, uint8_t& dayOfMonth, + uint8_t& hour, uint8_t& minute, uint8_t& second); + +/** + * @def secondsToMilliseconds + * + * @brief + * Convert integer seconds to milliseconds. + * + */ +inline uint32_t secondsToMilliseconds(uint32_t seconds) +{ + return (seconds * kMillisecondPerSecond); +} + +} // namespace chip + +#endif /* TIMEUTILS_H_ */ diff --git a/src/platform/FreeRTOS/SystemTimeSupport.cpp b/src/platform/FreeRTOS/SystemTimeSupport.cpp new file mode 100644 index 00000000000000..e62a46c5bb73ec --- /dev/null +++ b/src/platform/FreeRTOS/SystemTimeSupport.cpp @@ -0,0 +1,145 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides implementations of the CHIP System Layer platform + * time/clock functions based on the FreeRTOS tick counter. + */ + + +#include +#include + +#include "FreeRTOS.h" + +namespace chip { +namespace System { +namespace Platform { +namespace Layer { + +namespace { + +constexpr uint32_t kTicksOverflowShift = (configUSE_16_BIT_TICKS) ? 16 : 32; + +uint64_t sBootTimeUS = 0; + +#ifdef __CORTEX_M +BaseType_t sNumOfOverflows; +#endif +} // unnamed namespace + +/** + * Returns the number of FreeRTOS ticks since the system booted. + * + * NOTE: The default implementation of this function uses FreeRTOS's + * vTaskSetTimeOutState() function to get the total number of ticks, + * irrespective of tick counter overflows. Unfortunately, this function cannot + * be called in interrupt context, no equivalent ISR function exists, and + * FreeRTOS provides no portable way of determining whether a function is being + * called in an interrupt context. Adaptations that need to use the Chip + * Get/SetClock methods from within an interrupt handler must override this + * function with a suitable alternative that works on the target platform. The + * provided version is safe to call on ARM Cortex platforms with CMSIS + * libraries. + */ + +uint64_t FreeRTOSTicksSinceBoot(void) __attribute__((weak)); + +uint64_t FreeRTOSTicksSinceBoot(void) +{ + TimeOut_t timeOut; + +#ifdef __CORTEX_M + if (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) // running in an interrupt context + { + // Note that sNumOverflows may be quite stale, and under those + // circumstances, the function may violate monotonicity guarantees + timeOut.xTimeOnEntering = xTaskGetTickCountFromISR(); + timeOut.xOverflowCount = sNumOfOverflows; + } + else + { +#endif + + vTaskSetTimeOutState(&timeOut); + +#ifdef __CORTEX_M + // BaseType_t is supposed to be atomic + sNumOfOverflows = timeOut.xOverflowCount; + } +#endif + + return static_cast(timeOut.xTimeOnEntering) + + (static_cast(timeOut.xOverflowCount) << kTicksOverflowShift); +} + +uint64_t GetClock_Monotonic(void) +{ + return (FreeRTOSTicksSinceBoot() * kMicrosecondsPerSecond) / configTICK_RATE_HZ; +} + +uint64_t GetClock_MonotonicMS(void) +{ + return (FreeRTOSTicksSinceBoot() * kMillisecondPerSecond) / configTICK_RATE_HZ; +} + +uint64_t GetClock_MonotonicHiRes(void) +{ + return GetClock_Monotonic(); +} + +Error GetClock_RealTime(uint64_t & curTime) +{ + if (sBootTimeUS == 0) + { + return CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED; + } + curTime = sBootTimeUS + GetClock_Monotonic(); + return CHIP_SYSTEM_NO_ERROR; +} + +Error GetClock_RealTimeMS(uint64_t & curTime) +{ + if (sBootTimeUS == 0) + { + return CHIP_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED; + } + curTime = (sBootTimeUS + GetClock_Monotonic()) / 1000; + return CHIP_SYSTEM_NO_ERROR; +} + +Error SetClock_RealTime(uint64_t newCurTime) +{ + uint64_t timeSinceBootUS = GetClock_Monotonic(); + if (newCurTime > timeSinceBootUS) + { + sBootTimeUS = newCurTime - timeSinceBootUS; + } + else + { + sBootTimeUS = 0; + } + return CHIP_SYSTEM_NO_ERROR; +} + +} // namespace Layer +} // namespace Platform +} // namespace System +} // namespace chip From ac99c69014cdddcea8ceb394f236bae5a884487d Mon Sep 17 00:00:00 2001 From: Sagar Dhawan Date: Wed, 1 Apr 2020 14:21:11 -0700 Subject: [PATCH 2/3] Build SystemTimeSupport --- src/platform/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/Makefile.am b/src/platform/Makefile.am index de1974f73d7feb..868762eb5ce6eb 100644 --- a/src/platform/Makefile.am +++ b/src/platform/Makefile.am @@ -97,6 +97,7 @@ libDeviceLayer_a_SOURCES += \ nRF5/nRF5Config.cpp \ nRF5/nRF5Utils.cpp \ nRF5/Logging.cpp \ + FreeRTOS/SystemTimeSupport.cpp \ $(NULL) endif # CHIP_DEVICE_LAYER_TARGET_NRF5 @@ -111,6 +112,7 @@ libDeviceLayer_a_SOURCES += \ EFR32/ConnectivityManagerImpl.cpp \ EFR32/EFR32Config.cpp \ EFR32/Logging.cpp \ + FreeRTOS/SystemTimeSupport.cpp \ $(NULL) endif # CHIP_DEVICE_LAYER_TARGET_EFR32 From 98127673e570bcb7b7afa0e2d86173b6d0342436 Mon Sep 17 00:00:00 2001 From: Sagar Dhawan Date: Wed, 1 Apr 2020 14:33:57 -0700 Subject: [PATCH 3/3] Fix QRCode build failure when building Device Layer --- src/setup_payload/Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/setup_payload/Makefile.am b/src/setup_payload/Makefile.am index c8117f8aa3ce84..24fa05ac5c6c6b 100644 --- a/src/setup_payload/Makefile.am +++ b/src/setup_payload/Makefile.am @@ -32,20 +32,21 @@ libQrCode_adir = $(includedir)/setup_payload libQrCode_a_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/system \ + -I$(top_srcdir)/src/include/ \ $(NULL) libQrCode_a_SOURCES = \ QRCodeSetupPayloadGenerator.cpp \ SetupPayload.cpp \ Base45.cpp \ - QRCodeSetupPayloadParser.cpp \ + QRCodeSetupPayloadParser.cpp \ $(NULL) dist_libQrCode_a_HEADERS = \ QRCodeSetupPayloadGenerator.h \ SetupPayload.h \ Base45.h \ - QRCodeSetupPayloadParser.h \ + QRCodeSetupPayloadParser.h \ $(NULL) $(RECURSIVE_TARGETS): $(lib_LIBRARIES)