Skip to content

Commit 95fb104

Browse files
authored
settimeofday_cb: distinguish from user or sntp (#7637)
* settimeofday_cb: distinguish from user or sntp
1 parent ace5e98 commit 95fb104

File tree

12 files changed

+87
-46
lines changed

12 files changed

+87
-46
lines changed

cores/esp8266/coredecls.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ uint32_t crc32 (const void* data, size_t length, uint32_t crc = 0xffffffff);
2828

2929
#include <functional>
3030

31+
using BoolCB = std::function<void(bool)>;
3132
using TrivialCB = std::function<void()>;
3233

33-
void settimeofday_cb (TrivialCB&& cb);
34+
void settimeofday_cb (const BoolCB& cb);
3435
void settimeofday_cb (const TrivialCB& cb);
3536

3637
#endif

cores/esp8266/time.cpp

+19-5
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,14 @@ void configTime(const char* tz, const char* server1, const char* server2, const
204204
sntp_init();
205205
}
206206

207-
static TrivialCB _settimeofday_cb;
207+
static BoolCB _settimeofday_cb;
208208

209-
void settimeofday_cb (TrivialCB&& cb)
209+
void settimeofday_cb (const TrivialCB& cb)
210210
{
211-
_settimeofday_cb = std::move(cb);
211+
_settimeofday_cb = [cb](bool sntp) { (void)sntp; cb(); };
212212
}
213213

214-
void settimeofday_cb (const TrivialCB& cb)
214+
void settimeofday_cb (const BoolCB& cb)
215215
{
216216
_settimeofday_cb = cb;
217217
}
@@ -222,6 +222,20 @@ extern "C" {
222222

223223
int settimeofday(const struct timeval* tv, const struct timezone* tz)
224224
{
225+
bool from_sntp;
226+
if (tz == (struct timezone*)0xFeedC0de)
227+
{
228+
// This special constant is used by lwip2/SNTP calling
229+
// settimeofday(sntp-time, 0xfeedc0de), secretly using the
230+
// obsolete-but-yet-still-there `tz` field.
231+
// It allows to avoid duplicating this function and inform user
232+
// about the source time change.
233+
tz = nullptr;
234+
from_sntp = true;
235+
}
236+
else
237+
from_sntp = false;
238+
225239
if (tz || !tv)
226240
// tz is obsolete (cf. man settimeofday)
227241
return EINVAL;
@@ -230,7 +244,7 @@ int settimeofday(const struct timeval* tv, const struct timezone* tz)
230244
tune_timeshift64(tv->tv_sec * 1000000ULL + tv->tv_usec);
231245

232246
if (_settimeofday_cb)
233-
schedule_recurrent_function_us([](){ _settimeofday_cb(); return false; }, 0);
247+
schedule_recurrent_function_us([from_sntp](){ _settimeofday_cb(from_sntp); return false; }, 0);
234248

235249
return 0;
236250
}

libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino

+63-37
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ static time_t now;
6464
static uint32_t now_ms, now_us;
6565

6666
static esp8266::polledTimeout::periodicMs showTimeNow(60000);
67-
static int time_machine_days = 0; // 0 = now
67+
static int time_machine_days = 0; // 0 = present
6868
static bool time_machine_running = false;
69+
static bool time_machine_run_once = false;
6970

7071
// OPTIONAL: change SNTP startup delay
7172
// a weak function is already defined and returns 0 (RFC violation)
@@ -112,7 +113,7 @@ void showTime() {
112113
// time from boot
113114
Serial.print("clock: ");
114115
Serial.print((uint32_t)tp.tv_sec);
115-
Serial.print("s / ");
116+
Serial.print("s + ");
116117
Serial.print((uint32_t)tp.tv_nsec);
117118
Serial.println("ns");
118119

@@ -125,7 +126,7 @@ void showTime() {
125126
// EPOCH+tz+dst
126127
Serial.print("gtod: ");
127128
Serial.print((uint32_t)tv.tv_sec);
128-
Serial.print("s / ");
129+
Serial.print("s + ");
129130
Serial.print((uint32_t)tv.tv_usec);
130131
Serial.println("us");
131132

@@ -140,7 +141,7 @@ void showTime() {
140141
Serial.print("ctime: ");
141142
Serial.print(ctime(&now));
142143

143-
// LwIP v2 is able to list more details about the currently configured SNTP servers
144+
// lwIP v2 is able to list more details about the currently configured SNTP servers
144145
for (int i = 0; i < SNTP_MAX_SERVERS; i++) {
145146
IPAddress sntp = *sntp_getserver(i);
146147
const char* name = sntp_getservername(i);
@@ -151,48 +152,67 @@ void showTime() {
151152
} else {
152153
Serial.printf("%s ", sntp.toString().c_str());
153154
}
154-
Serial.printf("IPv6: %s Reachability: %o\n",
155+
Serial.printf("- IPv6: %s - Reachability: %o\n",
155156
sntp.isV6() ? "Yes" : "No",
156157
sntp_getreachability(i));
157158
}
158159
}
159160

160161
Serial.println();
161162

162-
// subsecond synchronisation
163-
gettimeofday(&tv, nullptr);
164-
time_t sec = tv.tv_sec;
165-
do {
163+
// show subsecond synchronisation
164+
timeval prevtv;
165+
time_t prevtime = time(nullptr);
166+
gettimeofday(&prevtv, nullptr);
167+
168+
while (true) {
166169
gettimeofday(&tv, nullptr);
167-
Serial.printf("time(): %u gettimeofday(): %u.%06u",
168-
(uint32_t)time(nullptr),
169-
(uint32_t)tv.tv_sec, (uint32_t)tv.tv_usec);
170-
if (tv.tv_sec == sec) {
171-
Serial.println(" second unchanged");
172-
} else {
173-
Serial.println(" <-- second changed");
170+
if (tv.tv_sec != prevtv.tv_sec) {
171+
Serial.printf("time(): %u gettimeofday(): %u.%06u seconds are unchanged\n",
172+
(uint32_t)prevtime,
173+
(uint32_t)prevtv.tv_sec, (uint32_t)prevtv.tv_usec);
174+
Serial.printf("time(): %u gettimeofday(): %u.%06u <-- seconds have changed\n",
175+
(uint32_t)(prevtime = time(nullptr)),
176+
(uint32_t)tv.tv_sec, (uint32_t)tv.tv_usec);
177+
break;
174178
}
179+
prevtv = tv;
175180
delay(50);
176-
} while (tv.tv_sec == sec);
181+
}
177182

178183
Serial.println();
179184
}
180185

181-
void time_is_set_scheduled() {
182-
// everything is allowed in this function
186+
void time_is_set(bool from_sntp /* <= this parameter is optional */) {
187+
// in CONT stack, unlike ISRs,
188+
// any function is allowed in this callback
183189

184190
if (time_machine_days == 0) {
185-
time_machine_running = !time_machine_running;
191+
if (time_machine_running) {
192+
time_machine_run_once = true;
193+
time_machine_running = false;
194+
} else {
195+
time_machine_running = from_sntp && !time_machine_run_once;
196+
}
197+
if (time_machine_running) {
198+
Serial.printf("\n-- \n-- Starting time machine demo to show libc's "
199+
"automatic DST handling\n-- \n");
200+
}
201+
}
202+
203+
Serial.print("settimeofday(");
204+
if (from_sntp) {
205+
Serial.print("SNTP");
206+
} else {
207+
Serial.print("USER");
186208
}
209+
Serial.print(")");
187210

188211
// time machine demo
189212
if (time_machine_running) {
190-
if (time_machine_days == 0)
191-
Serial.printf("---- settimeofday() has been called - possibly from SNTP\n"
192-
" (starting time machine demo to show libc's automatic DST handling)\n\n");
193213
now = time(nullptr);
194214
const tm* tm = localtime(&now);
195-
Serial.printf("future=%3ddays: DST=%s - ",
215+
Serial.printf(": future=%3ddays: DST=%s - ",
196216
time_machine_days,
197217
tm->tm_isdst ? "true " : "false");
198218
Serial.print(ctime(&now));
@@ -207,49 +227,55 @@ void time_is_set_scheduled() {
207227
}
208228
settimeofday(&tv, nullptr);
209229
} else {
210-
showTime();
230+
Serial.println();
211231
}
212232
}
213233

214234
void setup() {
235+
WiFi.persistent(false);
236+
WiFi.mode(WIFI_OFF);
237+
215238
Serial.begin(115200);
216-
Serial.println("\nStarting...\n");
239+
Serial.println("\nStarting in 2secs...\n");
240+
delay(2000);
241+
242+
// install callback - called when settimeofday is called (by SNTP or user)
243+
// once enabled (by DHCP), SNTP is updated every hour by default
244+
// ** optional boolean in callback function is true when triggerred by SNTP **
245+
settimeofday_cb(time_is_set);
217246

218247
// setup RTC time
219248
// it will be used until NTP server will send us real current time
249+
Serial.println("Manually setting some time from some RTC:");
220250
time_t rtc = RTC_UTC_TEST;
221251
timeval tv = { rtc, 0 };
222252
settimeofday(&tv, nullptr);
223253

224-
// install callback - called when settimeofday is called (by SNTP or us)
225-
// once enabled (by DHCP), SNTP is updated every hour
226-
settimeofday_cb(time_is_set_scheduled);
227-
228254
// NTP servers may be overriden by your DHCP server for a more local one
229255
// (see below)
230256

231257
// ----> Here is the ONLY ONE LINE needed in your sketch
232-
233258
configTime(MYTZ, "pool.ntp.org");
259+
// <----
260+
// Replace MYTZ by a value from TZ.h (search for this file in your filesystem).
234261

235-
// Here is the ONLY ONE LINE needed in your sketch <----
236-
// pick a value from TZ.h (search for this file in your filesystem) for MYTZ
237-
238-
// former configTime is still valid, here is the call for 7 hours to the west
262+
// Former configTime is still valid, here is the call for 7 hours to the west
239263
// with an enabled 30mn DST
240264
//configTime(7 * 3600, 3600 / 2, "pool.ntp.org");
241265

242266
// OPTIONAL: disable obtaining SNTP servers from DHCP
243267
//sntp_servermode_dhcp(0); // 0: disable obtaining SNTP servers from DHCP (enabled by default)
244268

269+
// Give now a chance to the settimeofday callback,
270+
// because it is *always* deferred to the next yield()/loop()-call.
271+
yield();
272+
245273
// start network
246-
WiFi.persistent(false);
247274
WiFi.mode(WIFI_STA);
248275
WiFi.begin(STASSID, STAPSK);
249276

250277
// don't wait for network, observe time changing
251278
// when NTP timestamp is received
252-
Serial.printf("Time is currently set by a constant:\n");
253279
showTime();
254280
}
255281

tools/sdk/lib/liblwip2-1460-feat.a

600 KB
Binary file not shown.

tools/sdk/lib/liblwip2-1460.a

48.5 KB
Binary file not shown.

tools/sdk/lib/liblwip2-536-feat.a

600 KB
Binary file not shown.

tools/sdk/lib/liblwip2-536.a

48.5 KB
Binary file not shown.

tools/sdk/lib/liblwip6-1460-feat.a

48.4 KB
Binary file not shown.

tools/sdk/lib/liblwip6-536-feat.a

48.4 KB
Binary file not shown.
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// generated by makefiles/make-lwip2-hash
22
#ifndef LWIP_HASH_H
33
#define LWIP_HASH_H
4-
#define LWIP_HASH_STR "STABLE-2_1_2_RELEASE/glue:1.2-34-gf56e795"
4+
#define LWIP_HASH_STR "STABLE-2_1_2_RELEASE/glue:1.2-43-ge20f213"
55
#endif // LWIP_HASH_H

tools/sdk/lwip2/include/lwipopts.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -3574,7 +3574,7 @@ extern "C" {
35743574

35753575
#define SNTP_SERVER_DNS 1 // enable SNTP support DNS names through sntp_setservername / sntp_getservername
35763576

3577-
#define SNTP_SET_SYSTEM_TIME_US(t,us) do { struct timeval tv = { t, us }; settimeofday(&tv, NULL); } while (0)
3577+
#define SNTP_SET_SYSTEM_TIME_US(t,us) do { struct timeval tv = { t, us }; settimeofday(&tv, (struct timezone*)0xFeedC0de); } while (0)
35783578

35793579
#define SNTP_SUPPRESS_DELAY_CHECK 1
35803580
#define SNTP_UPDATE_DELAY_DEFAULT 3600000 // update delay defined by a default weak function

0 commit comments

Comments
 (0)