esp_netif/lwip: Fix core-locking config

* Fix thread safety issues in non-core locking
* Add option to verify thread safety issues in lwip (core-lock assertion)
* Make esp_sntp.h thread safe API
* Fix sntp examples
* Fix openthread libs

Closes https://github.com/espressif/esp-idf/issues/9908
Closes https://github.com/espressif/esp-idf/issues/10502
Closes https://github.com/espressif/esp-idf/issues/10466
This commit is contained in:
David Cermak
2022-10-27 19:07:07 +02:00
parent 9e24739228
commit a71fa82177
43 changed files with 1219 additions and 339 deletions

View File

@@ -9,10 +9,6 @@
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <netdb.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
@@ -20,6 +16,8 @@
#include "esp_sleep.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"
#include "esp_netif_sntp.h"
#include "lwip/ip_addr.h"
#include "esp_sntp.h"
static const char *TAG = "example";
@@ -35,7 +33,6 @@ static const char *TAG = "example";
RTC_DATA_ATTR static int boot_count = 0;
static void obtain_time(void);
static void initialize_sntp(void);
#ifdef CONFIG_SNTP_TIME_SYNC_METHOD_CUSTOM
void sntp_sync_time(struct timeval *tv)
@@ -121,24 +118,55 @@ void app_main(void)
esp_deep_sleep(1000000LL * deep_sleep_sec);
}
static void print_servers(void)
{
ESP_LOGI(TAG, "List of configured NTP servers:");
for (uint8_t i = 0; i < SNTP_MAX_SERVERS; ++i){
if (esp_sntp_getservername(i)){
ESP_LOGI(TAG, "server %d: %s", i, esp_sntp_getservername(i));
} else {
// we have either IPv4 or IPv6 address, let's print it
char buff[INET6_ADDRSTRLEN];
ip_addr_t const *ip = esp_sntp_getserver(i);
if (ipaddr_ntoa_r(ip, buff, INET6_ADDRSTRLEN) != NULL)
ESP_LOGI(TAG, "server %d: %s", i, buff);
}
}
}
static void obtain_time(void)
{
ESP_ERROR_CHECK( nvs_flash_init() );
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK( esp_event_loop_create_default() );
#if LWIP_DHCP_GET_NTP_SRV
/**
* NTP server address could be aquired via DHCP,
* NTP server address could be acquired via DHCP,
* 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,
* NOTE: This call should be made BEFORE esp acquires IP address from DHCP,
* otherwise NTP option would be rejected by default.
*/
#ifdef LWIP_DHCP_GET_NTP_SRV
sntp_servermode_dhcp(1); // accept NTP offers from DHCP server, if any
ESP_LOGI(TAG, "Initializing SNTP");
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG(CONFIG_SNTP_TIME_SERVER);
config.start = false; // start SNTP service explicitly (after connecting)
config.server_from_dhcp = true; // accept NTP offers from DHCP server, if any (need to enable *before* connecting)
config.renew_servers_after_new_IP = true; // let esp-netif update configured SNTP server(s) after receiving DHCP lease
config.index_of_first_server = 1; // updates from server num 1, leaving server 0 (from DHCP) intact
// configure the event on which we renew servers
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
config.ip_event_to_renew = IP_EVENT_STA_GOT_IP;
#else
config.ip_event_to_renew = IP_EVENT_ETH_GOT_IP;
#endif
config.sync_cb = time_sync_notification_cb; // only if we need the notification function
esp_netif_sntp_init(&config);
#endif /* LWIP_DHCP_GET_NTP_SRV */
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
@@ -146,67 +174,53 @@ static void obtain_time(void)
*/
ESP_ERROR_CHECK(example_connect());
initialize_sntp();
#if LWIP_DHCP_GET_NTP_SRV
ESP_LOGI(TAG, "Starting SNTP");
esp_netif_sntp_start();
#if LWIP_IPV6 && SNTP_MAX_SERVERS > 2
/* This demonstrates using IPv6 address as an additional SNTP server
* (statically assigned IPv6 address is also possible)
*/
ip_addr_t ip6;
if (ipaddr_aton("2a01:3f7::1", &ip6)) { // ipv6 ntp source "ntp.netnod.se"
esp_sntp_setserver(2, &ip6);
}
#endif /* LWIP_IPV6 */
#else
ESP_LOGI(TAG, "Initializing and starting SNTP");
#if CONFIG_LWIP_SNTP_MAX_SERVERS > 1
/* This demonstrates configuring more than one server
*/
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG_MULTIPLE(2,
ESP_SNTP_SERVER_LIST(CONFIG_SNTP_TIME_SERVER, "pool.ntp.org" ) );
#else
/*
* This is the basic default config with one server and starting the service
*/
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG(CONFIG_SNTP_TIME_SERVER);
#endif
config.sync_cb = time_sync_notification_cb; // Note: This is only needed if we want
#ifdef CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH
config.smooth_sync = true;
#endif
esp_netif_sntp_init(&config);
#endif
print_servers();
// wait for time to be set
time_t now = 0;
struct tm timeinfo = { 0 };
int retry = 0;
const int retry_count = 15;
while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry < retry_count) {
while (esp_netif_sntp_sync_wait(2000 / portTICK_PERIOD_MS) == ESP_ERR_TIMEOUT && ++retry < retry_count) {
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
time(&now);
localtime_r(&now, &timeinfo);
ESP_ERROR_CHECK( example_disconnect() );
}
static void initialize_sntp(void)
{
ESP_LOGI(TAG, "Initializing SNTP");
sntp_setoperatingmode(SNTP_OPMODE_POLL);
/*
* 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);
sntp_setservername(1, "pool.ntp.org"); // set the secondary NTP server (will be used only if SNTP_MAX_SERVERS > 1)
#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);
}
}
esp_netif_sntp_deinit();
}