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;
18 class SystemClockCoroutineTest_runCoroutine;
49 template <
typename T_SCCI,
typename T_CRCI>
50 class SystemClockCoroutineTemplate :
51 public SystemClockTemplate<T_SCCI>,
52 public ace_routine::CoroutineTemplate<T_CRCI, uint16_t> {
71 explicit SystemClockCoroutineTemplate(
72 Clock* referenceClock ,
74 uint16_t syncPeriodSeconds = 3600,
75 uint16_t initialSyncPeriodSeconds = 5,
76 uint16_t requestTimeoutMillis = 1000,
77 ace_common::TimingStats* timingStats =
nullptr):
78 SystemClockTemplate<T_SCCI>(referenceClock, backupClock),
79 ace_routine::CoroutineTemplate<T_CRCI, uint16_t>(),
80 mSyncPeriodSeconds(syncPeriodSeconds),
81 mRequestTimeoutMillis(requestTimeoutMillis),
82 mTimingStats(timingStats),
83 mCurrentSyncPeriodSeconds(initialSyncPeriodSeconds) {}
101 int runCoroutine()
override {
103 if (this->getReferenceClock() ==
nullptr)
return 0;
105 uint32_t nowMillis = this->clockMillis();
109 this->getReferenceClock()->sendRequest();
110 mRequestStartMillis = this->coroutineMillis();
111 mRequestStatus = kStatusSent;
112 this->setPrevSyncAttemptMillis(nowMillis);
113 this->setNextSyncAttemptMillis(
114 nowMillis + mCurrentSyncPeriodSeconds * (uint32_t) 1000);
118 if (this->getReferenceClock()->isResponseReady()) {
119 mRequestStatus = kStatusOk;
127 uint16_t waitMillis =
128 (uint16_t) this->coroutineMillis() - mRequestStartMillis;
129 if (waitMillis >= mRequestTimeoutMillis) {
130 mRequestStatus = kStatusTimedOut;
131 this->setSyncStatusCode(this->kSyncStatusTimedOut);
140 if (mRequestStatus == kStatusOk) {
141 acetime_t nowSeconds = this->getReferenceClock()->readResponse();
142 if (mTimingStats !=
nullptr) {
143 uint16_t elapsedMillis =
144 (uint16_t) this->coroutineMillis() - mRequestStartMillis;
145 mTimingStats->update(elapsedMillis);
148 if (nowSeconds == this->kInvalidSeconds) {
149 this->setSyncStatusCode(this->kSyncStatusError);
151 mRequestStatus = kStatusUnknown;
153 this->syncNow(nowSeconds);
154 mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
155 this->setSyncStatusCode(this->kSyncStatusOk);
160 this->setNextSyncAttemptMillis(
161 nowMillis + mCurrentSyncPeriodSeconds * (uint32_t) 1000);
163 mWaitCount < mCurrentSyncPeriodSeconds;
166 COROUTINE_DELAY(1000);
172 if (mRequestStatus != kStatusOk) {
173 if (mCurrentSyncPeriodSeconds >= mSyncPeriodSeconds / 2) {
174 mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
176 mCurrentSyncPeriodSeconds *= 2;
183 uint8_t getRequestStatus()
const {
return mRequestStatus; }
187 SystemClockCoroutineTemplate() {}
190 friend class ::SystemClockCoroutineTest;
191 friend class ::SystemClockCoroutineTest_runCoroutine;
194 static const uint8_t kStatusUnknown = 0;
197 static const uint8_t kStatusSent = 1;
200 static const uint8_t kStatusOk = 2;
203 static const uint8_t kStatusTimedOut = 3;
206 SystemClockCoroutineTemplate(
const SystemClockCoroutineTemplate&) =
delete;
207 SystemClockCoroutineTemplate& operator=(
208 const SystemClockCoroutineTemplate&) =
delete;
210 uint16_t
const mSyncPeriodSeconds = 3600;
211 uint16_t
const mRequestTimeoutMillis = 1000;
212 ace_common::TimingStats*
const mTimingStats =
nullptr;
214 uint16_t mRequestStartMillis;
215 uint16_t mCurrentSyncPeriodSeconds = 5;
217 uint8_t mRequestStatus = kStatusUnknown;
258 using SystemClockCoroutine = SystemClockCoroutineTemplate<
259 hw::ClockInterface, ace_routine::ClockInterface