6 #ifndef ACE_TIME_SYSTEM_CLOCK_COROUTINE_H
7 #define ACE_TIME_SYSTEM_CLOCK_COROUTINE_H
10 #ifdef ACE_ROUTINE_VERSION
13 #include <AceCommon.h>
14 #include <AceRoutine.h>
15 #include "SystemClock.h"
17 class SystemClockCoroutineTest_runCoroutine;
33 class SystemClockCoroutine:
public SystemClock,
public ace_routine::Coroutine {
36 static const uint8_t kStatusUnknown = 0;
39 static const uint8_t kStatusSent = 1;
42 static const uint8_t kStatusOk = 2;
45 static const uint8_t kStatusTimedOut = 3;
63 explicit SystemClockCoroutine(
64 Clock* referenceClock ,
66 uint16_t syncPeriodSeconds = 3600,
67 uint16_t initialSyncPeriodSeconds = 5,
68 uint16_t requestTimeoutMillis = 1000,
69 ace_common::TimingStats* timingStats =
nullptr):
70 SystemClock(referenceClock, backupClock),
71 mSyncPeriodSeconds(syncPeriodSeconds),
72 mRequestTimeoutMillis(requestTimeoutMillis),
73 mTimingStats(timingStats),
74 mCurrentSyncPeriodSeconds(initialSyncPeriodSeconds) {}
83 int runCoroutine()
override {
85 if (mReferenceClock ==
nullptr)
return 0;
89 mReferenceClock->sendRequest();
90 mRequestStartMillis = coroutineMillis();
91 mRequestStatus = kStatusSent;
95 if (mReferenceClock->isResponseReady()) {
96 mRequestStatus = kStatusOk;
104 uint16_t waitMillis =
105 (uint16_t) coroutineMillis() - mRequestStartMillis;
106 if (waitMillis >= mRequestTimeoutMillis) {
107 mRequestStatus = kStatusTimedOut;
116 if (mRequestStatus == kStatusOk) {
117 acetime_t nowSeconds = mReferenceClock->readResponse();
118 if (mTimingStats !=
nullptr) {
119 uint16_t elapsedMillis =
120 (uint16_t) coroutineMillis() - mRequestStartMillis;
121 mTimingStats->update(elapsedMillis);
124 mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
127 COROUTINE_DELAY_SECONDS(mCurrentSyncPeriodSeconds);
132 if (mRequestStatus == kStatusTimedOut) {
133 if (mCurrentSyncPeriodSeconds >= mSyncPeriodSeconds / 2) {
134 mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
136 mCurrentSyncPeriodSeconds *= 2;
143 uint8_t getRequestStatus()
const {
return mRequestStatus; }
146 friend class ::SystemClockCoroutineTest_runCoroutine;
149 SystemClockCoroutine(
const SystemClockCoroutine&) =
delete;
150 SystemClockCoroutine& operator=(
const SystemClockCoroutine&) =
delete;
152 uint16_t
const mSyncPeriodSeconds;
153 uint16_t
const mRequestTimeoutMillis;
154 ace_common::TimingStats*
const mTimingStats;
156 uint16_t mRequestStartMillis;
157 uint16_t mCurrentSyncPeriodSeconds;
158 uint8_t mRequestStatus = kStatusUnknown;