Merge branch 'bugfix/sntp_example_docs' into 'master'

sntp example - updated ntp over dhcp code/comments (GitHub PR)

Closes IDFGH-6147

See merge request espressif/esp-idf!15897
This commit is contained in:
David Čermák 2021-11-25 11:37:34 +00:00
commit 07f502410a
4 changed files with 64 additions and 5 deletions

View File

@ -20,6 +20,16 @@ Open the project configuration menu (`idf.py menuconfig`):
When this example boots first time after ESP32 is reset, it connects to WiFi and obtains time using SNTP.
See `initialize_sntp` function for details.
## Obtaining time using LwIP SNTP-over-DHCP module
NTP server addresses could be automatically aquired via DHCP server option 42. This could be usefull on closed environments where public NTPs are not accessible
or to prefer local servers and reduce traffic to the outer world.
See following menuconfig options:
* `Component config-->LWIP-->SNTP-->Maximum number of NTP servers`
* `Component config-->LWIP-->SNTP-->Request NTP servers from DHCP`
* `Component config-->LWIP-->SNTP-->Maximum number of NTP servers aquired via DHCP`
* `Component config-->LWIP-->Enable LWIP Debug-->Enable SNTP debug messages`
## Timekeeping
Once time is synchronized, ESP32 will perform timekeeping using built-in timers.

View File

@ -15,7 +15,7 @@ def test_examples_sntp(env, extra_data):
dut.expect_all('Time is not set yet. Connecting to WiFi and getting time over NTP.',
'Initializing SNTP',
'Waiting for system time to be set... (1/10)',
re.compile(r'Waiting for system time to be set... \(\d+/\d+\)'),
'Notification of a time synchronization event',
timeout=60)

View File

@ -1,5 +1,11 @@
menu "Example Configuration"
config SNTP_TIME_SERVER
string "SNTP server name"
default "pool.ntp.org"
help
Hostname of the main SNTP server.
choice SNTP_TIME_SYNC_METHOD
prompt "Time synchronization method"
default SNTP_TIME_SYNC_METHOD_IMMED

View File

@ -23,6 +23,10 @@
static const char *TAG = "example";
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 48
#endif
/* Variable holding number of times ESP32 restarted since first boot.
* It is placed into RTC memory using RTC_DATA_ATTR and
* maintains its value when ESP32 wakes from deep sleep.
@ -124,10 +128,15 @@ static void obtain_time(void)
/**
* NTP server address could be aquired via DHCP,
* see LWIP_DHCP_GET_NTP_SRV menuconfig option
* see following menuconfig options:
* 'LWIP_DHCP_GET_NTP_SRV' - enable STNP over DHCP
* 'LWIP_SNTP_DEBUG' - enable debugging messages
*
* NOTE: This call should be made BEFORE esp aquires IP address from DHCP,
* otherwise NTP option would be rejected by default.
*/
#ifdef LWIP_DHCP_GET_NTP_SRV
sntp_servermode_dhcp(1);
sntp_servermode_dhcp(1); // accept NTP offers from DHCP server, if any
#endif
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
@ -142,7 +151,7 @@ static void obtain_time(void)
time_t now = 0;
struct tm timeinfo = { 0 };
int retry = 0;
const int retry_count = 10;
const int retry_count = 15;
while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry < retry_count) {
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
vTaskDelay(2000 / portTICK_PERIOD_MS);
@ -157,10 +166,44 @@ static void initialize_sntp(void)
{
ESP_LOGI(TAG, "Initializing SNTP");
sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_setservername(0, "pool.ntp.org");
/*
* If 'NTP over DHCP' is enabled, we set dynamic pool address
* as a 'secondary' server. It will act as a fallback server in case that address
* provided via NTP over DHCP is not accessible
*/
#if LWIP_DHCP_GET_NTP_SRV && SNTP_MAX_SERVERS > 1
sntp_setservername(1, "pool.ntp.org");
#if LWIP_IPV6 && SNTP_MAX_SERVERS > 2 // statically assigned IPv6 address is also possible
ip_addr_t ip6;
if (ipaddr_aton("2a01:3f7::1", &ip6)) { // ipv6 ntp source "ntp.netnod.se"
sntp_setserver(2, &ip6);
}
#endif /* LWIP_IPV6 */
#else /* LWIP_DHCP_GET_NTP_SRV && (SNTP_MAX_SERVERS > 1) */
// otherwise, use DNS address from a pool
sntp_setservername(0, CONFIG_SNTP_TIME_SERVER);
#endif
sntp_set_time_sync_notification_cb(time_sync_notification_cb);
#ifdef CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH
sntp_set_sync_mode(SNTP_SYNC_MODE_SMOOTH);
#endif
sntp_init();
ESP_LOGI(TAG, "List of configured NTP servers:");
for (uint8_t i = 0; i < SNTP_MAX_SERVERS; ++i){
if (sntp_getservername(i)){
ESP_LOGI(TAG, "server %d: %s", i, sntp_getservername(i));
} else {
// we have either IPv4 or IPv6 address, let's print it
char buff[INET6_ADDRSTRLEN];
ip_addr_t const *ip = sntp_getserver(i);
if (ipaddr_ntoa_r(ip, buff, INET6_ADDRSTRLEN) != NULL)
ESP_LOGI(TAG, "server %d: %s", i, buff);
}
}
}