From 896344ddf009290909e47fdf89f02491af937a01 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Fri, 15 Nov 2019 15:42:55 +0100 Subject: [PATCH 01/20] Fix async esp_yield() / esp_schedule() "stop the Arduino world" metaphor --- .../ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 10 +++++++--- .../ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp | 13 +++++++++--- libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp | 14 ++++++++----- .../ESP8266WiFi/src/include/ClientContext.h | 20 +++++++++---------- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index 19da592c76..469317e643 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -671,8 +671,12 @@ int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResul aResult = IPAddress(&addr); } else if(err == ERR_INPROGRESS) { _dns_lookup_pending = true; - delay(timeout_ms); - // will resume on timeout or when wifi_dns_found_callback fires + auto op_start_time = millis(); + // will continue on timeout or when wifi_dns_found_callback fires + while (millis() - op_start_time < timeout_ms && _dns_lookup_pending) { + // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) + yield(); + } _dns_lookup_pending = false; // will return here when dns_found_callback fires if(aResult.isSet()) { @@ -705,7 +709,7 @@ void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *ca if(ipaddr) { (*reinterpret_cast(callback_arg)) = IPAddress(ipaddr); } - esp_schedule(); // break delay in hostByName + _dns_lookup_pending = false; // resume hostByName } uint32_t ESP8266WiFiGenericClass::shutdownCRC (const WiFiState& state) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp index 99d27ba7a3..21f5bb0088 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp @@ -30,6 +30,8 @@ static void wifi_wps_status_cb(wps_cb_status status); +static bool _wps_config_pending = false; + /** * WPS config * so far only WPS_TYPE_PBC is supported (SDK 1.2.0) @@ -70,8 +72,13 @@ bool ESP8266WiFiSTAClass::beginWPSConfig(void) { return false; } - esp_yield(); - // will resume when wifi_wps_status_cb fires + _wps_config_pending = true; + // will continue when wifi_wps_status_cb fires + while (_wps_config_pending) { + // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) + yield(); + } + _wps_config_pending = false; return true; } @@ -107,5 +114,5 @@ void wifi_wps_status_cb(wps_cb_status status) { } // TODO user function to get status - esp_schedule(); // resume beginWPSConfig + _wps_config_pending = false; // resume beginWPSConfig } diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp index 65878a3d5b..53897a55f0 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp @@ -94,11 +94,16 @@ int8_t ESP8266WiFiScanClass::scanNetworks(bool async, bool show_hidden, uint8 ch ESP8266WiFiScanClass::_scanStarted = true; if(ESP8266WiFiScanClass::_scanAsync) { - delay(0); // time for the OS to trigger the scan + yield(); // time for the OS to trigger the scan return WIFI_SCAN_RUNNING; } - esp_yield(); // will resume when _scanDone fires + // will continue when _scanDone fires + while (!ESP8266WiFiScanClass::_scanComplete && ESP8266WiFiScanClass::_scanStarted) + { + yield(); + } + return ESP8266WiFiScanClass::_scanCount; } else { return WIFI_SCAN_FAILED; @@ -319,12 +324,11 @@ void ESP8266WiFiScanClass::_scanDone(void* result, int status) { } + // resume scanNetworks ESP8266WiFiScanClass::_scanStarted = false; ESP8266WiFiScanClass::_scanComplete = true; - if(!ESP8266WiFiScanClass::_scanAsync) { - esp_schedule(); // resume scanNetworks - } else if (ESP8266WiFiScanClass::_onComplete) { + if(ESP8266WiFiScanClass::_scanAsync && ESP8266WiFiScanClass::_onComplete) { ESP8266WiFiScanClass::_onComplete(ESP8266WiFiScanClass::_scanCount); ESP8266WiFiScanClass::_onComplete = nullptr; } diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index a994b5cb1d..c0993b539d 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -145,10 +145,10 @@ class ClientContext } _connect_pending = true; _op_start_time = millis(); - for (decltype(_timeout_ms) i = 0; _connect_pending && i < _timeout_ms; i++) { - // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - delay(1); - // will resume on timeout or when _connected or _notify_error fires + // will continue on timeout or when _connected or _notify_error fires + while (!_is_timeout() && _connect_pending) { + // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) + yield(); } _connect_pending = false; if (!_pcb) { @@ -458,9 +458,9 @@ class ClientContext void _notify_error() { if (_connect_pending || _send_waiting) { + // resume connect or _write_from_source _send_waiting = false; _connect_pending = false; - esp_schedule(); // break delay in connect or _write_from_source } } @@ -487,10 +487,10 @@ class ClientContext } _send_waiting = true; - for (decltype(_timeout_ms) i = 0; _send_waiting && i < _timeout_ms; i++) { + // will continue on timeout or when _write_some_from_cb or _notify_error fires + while (!_is_timeout() && _send_waiting) { // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - delay(1); - // will resume on timeout or when _write_some_from_cb or _notify_error fires + yield(); } _send_waiting = false; } while(true); @@ -561,8 +561,8 @@ class ClientContext void _write_some_from_cb() { if (_send_waiting) { + // resume _write_from_source _send_waiting = false; - esp_schedule(); // break delay in _write_from_source } } @@ -649,8 +649,8 @@ class ClientContext (void) pcb; assert(pcb == _pcb); if (_connect_pending) { + // resume connect _connect_pending = false; - esp_schedule(); // break delay in connect } return ERR_OK; } From dbdc04105684672bb66c464a282fee84bc1813fb Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Fri, 15 Nov 2019 16:38:21 +0100 Subject: [PATCH 02/20] Cleanup obsoleted externals. --- libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 4 ---- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 3 --- libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp | 3 --- libraries/ESP8266WiFi/src/include/ClientContext.h | 3 --- 4 files changed, 13 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index 469317e643..004828fd02 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -49,10 +49,6 @@ extern "C" { #include "debug.h" #include "include/WiFiState.h" -extern "C" void esp_schedule(); -extern "C" void esp_yield(); - - // ----------------------------------------------------------------------------------------------------------------------- // ------------------------------------------------- Generic WiFi function ----------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------- diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index dd910295dd..9b59a90461 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -44,9 +44,6 @@ extern "C" { #include "debug.h" -extern "C" void esp_schedule(); -extern "C" void esp_yield(); - // ----------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------- Private functions ------------------------------------------------ // ----------------------------------------------------------------------------------------------------------------------- diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp index 53897a55f0..e9f43af92b 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp @@ -37,9 +37,6 @@ extern "C" { #include "debug.h" -extern "C" void esp_schedule(); -extern "C" void esp_yield(); - // ----------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------- Private functions ------------------------------------------------ // ----------------------------------------------------------------------------------------------------------------------- diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index c0993b539d..dc2a9f02e3 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -26,9 +26,6 @@ class WiFiClient; typedef void (*discard_cb_t)(void*, ClientContext*); -extern "C" void esp_yield(); -extern "C" void esp_schedule(); - #include #include From 1bd1f250a81c5b306adf163313ae6f9314ddd490 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Sat, 16 Nov 2019 09:58:38 +0100 Subject: [PATCH 03/20] WIP: Revert removal of esp_schedule, prepares for reintroducing preemptible delays and suspending yields. --- libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 3 +++ libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp | 1 + libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp | 10 +++++++--- libraries/ESP8266WiFi/src/include/ClientContext.h | 6 ++++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index 004828fd02..47086f0312 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -49,6 +49,8 @@ extern "C" { #include "debug.h" #include "include/WiFiState.h" +extern "C" void esp_schedule(); + // ----------------------------------------------------------------------------------------------------------------------- // ------------------------------------------------- Generic WiFi function ----------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------- @@ -706,6 +708,7 @@ void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *ca (*reinterpret_cast(callback_arg)) = IPAddress(ipaddr); } _dns_lookup_pending = false; // resume hostByName + esp_schedule(); } uint32_t ESP8266WiFiGenericClass::shutdownCRC (const WiFiState& state) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp index 21f5bb0088..89e7eb1a91 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp @@ -115,4 +115,5 @@ void wifi_wps_status_cb(wps_cb_status status) { // TODO user function to get status _wps_config_pending = false; // resume beginWPSConfig + esp_schedule(); } diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp index e9f43af92b..e6aa740656 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp @@ -37,6 +37,8 @@ extern "C" { #include "debug.h" +extern "C" void esp_schedule(); + // ----------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------- Private functions ------------------------------------------------ // ----------------------------------------------------------------------------------------------------------------------- @@ -91,7 +93,7 @@ int8_t ESP8266WiFiScanClass::scanNetworks(bool async, bool show_hidden, uint8 ch ESP8266WiFiScanClass::_scanStarted = true; if(ESP8266WiFiScanClass::_scanAsync) { - yield(); // time for the OS to trigger the scan + delay(0); // time for the OS to trigger the scan return WIFI_SCAN_RUNNING; } @@ -321,11 +323,13 @@ void ESP8266WiFiScanClass::_scanDone(void* result, int status) { } - // resume scanNetworks ESP8266WiFiScanClass::_scanStarted = false; ESP8266WiFiScanClass::_scanComplete = true; - if(ESP8266WiFiScanClass::_scanAsync && ESP8266WiFiScanClass::_onComplete) { + if (!ESP8266WiFiScanClass::_scanAsync) { + // resume scanNetworks + esp_schedule(); + } else if (ESP8266WiFiScanClass::_onComplete) { ESP8266WiFiScanClass::_onComplete(ESP8266WiFiScanClass::_scanCount); ESP8266WiFiScanClass::_onComplete = nullptr; } diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index dc2a9f02e3..b2751bc34e 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -26,9 +26,12 @@ class WiFiClient; typedef void (*discard_cb_t)(void*, ClientContext*); +extern "C" void esp_schedule(); + #include #include + bool getDefaultPrivateGlobalSyncValue (); class ClientContext @@ -458,6 +461,7 @@ class ClientContext // resume connect or _write_from_source _send_waiting = false; _connect_pending = false; + esp_schedule(); } } @@ -560,6 +564,7 @@ class ClientContext if (_send_waiting) { // resume _write_from_source _send_waiting = false; + esp_schedule(); } } @@ -648,6 +653,7 @@ class ClientContext if (_connect_pending) { // resume connect _connect_pending = false; + esp_schedule(); } return ERR_OK; } From a66ec7561192c4abb54e96eced0b967c69c96b3c Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Sat, 16 Nov 2019 10:34:03 +0100 Subject: [PATCH 04/20] WIP: implement infinite suspension of CONT to SYS (pending esp_schedule) by esp_yield inside guard loop --- cores/esp8266/core_esp8266_main.cpp | 2 +- libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp | 3 +-- libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index b052718d51..28c75c5144 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -138,7 +138,7 @@ extern "C" void __yield() { } } -extern "C" void yield(void) __attribute__ ((weak, alias("__yield"))); +extern "C" void yield() __attribute__ ((weak, alias("__yield"))); extern "C" void optimistic_yield(uint32_t interval_us) { const uint32_t intvl_cycles = interval_us * diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp index 89e7eb1a91..e183338b8c 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp @@ -75,8 +75,7 @@ bool ESP8266WiFiSTAClass::beginWPSConfig(void) { _wps_config_pending = true; // will continue when wifi_wps_status_cb fires while (_wps_config_pending) { - // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - yield(); + esp_yield(); } _wps_config_pending = false; diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp index e6aa740656..b92042c183 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp @@ -38,6 +38,7 @@ extern "C" { #include "debug.h" extern "C" void esp_schedule(); +extern "C" void esp_yield(); // ----------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------- Private functions ------------------------------------------------ @@ -100,7 +101,7 @@ int8_t ESP8266WiFiScanClass::scanNetworks(bool async, bool show_hidden, uint8 ch // will continue when _scanDone fires while (!ESP8266WiFiScanClass::_scanComplete && ESP8266WiFiScanClass::_scanStarted) { - yield(); + esp_yield(); } return ESP8266WiFiScanClass::_scanCount; @@ -327,8 +328,7 @@ void ESP8266WiFiScanClass::_scanDone(void* result, int status) { ESP8266WiFiScanClass::_scanComplete = true; if (!ESP8266WiFiScanClass::_scanAsync) { - // resume scanNetworks - esp_schedule(); + esp_schedule(); // resume scanNetworks } else if (ESP8266WiFiScanClass::_onComplete) { ESP8266WiFiScanClass::_onComplete(ESP8266WiFiScanClass::_scanCount); ESP8266WiFiScanClass::_onComplete = nullptr; From 8e41ff3796febd064ead7acfa2d879dc2b5e45c1 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Sat, 16 Nov 2019 11:43:29 +0100 Subject: [PATCH 05/20] Re-implement preemptible (esp_schedule) delay of CONT by esp_delay inside guard loop --- cores/esp8266/core_esp8266_main.cpp | 30 ++++++++++++++++--- cores/esp8266/core_esp8266_wiring.cpp | 19 ++---------- .../ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 4 +-- .../ESP8266WiFi/src/include/ClientContext.h | 5 ++-- 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index 28c75c5144..69ffbd3c83 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -71,7 +71,6 @@ static uint32_t s_cycles_at_yield_start; static uint16_t ets_intr_lock_stack[ETS_INTR_LOCK_NEST_MAX]; static byte ets_intr_lock_stack_ptr=0; - extern "C" { extern const uint32_t __attribute__((section(".ver_number"))) core_version = ARDUINO_ESP8266_GIT_VER; const char* core_release = @@ -80,6 +79,10 @@ const char* core_release = #else NULL; #endif + +static os_timer_t delay_timer; +#define ONCE 0 +#define REPEAT 1 } // extern "C" void initVariant() __attribute__((weak)); @@ -128,6 +131,27 @@ extern "C" IRAM_ATTR void esp_schedule() { ets_post(LOOP_TASK_PRIORITY, 0, 0); } +void delay_end(void* arg) { + (void)arg; + esp_schedule(); +} + +extern "C" void __esp_delay(unsigned long ms) { + if (ms) { + os_timer_setfn(&delay_timer, (os_timer_func_t*)&delay_end, 0); + os_timer_arm(&delay_timer, ms, ONCE); + } + else { + esp_schedule(); + } + esp_yield(); + if (ms) { + os_timer_disarm(&delay_timer); + } +} + +extern "C" void esp_delay(unsigned long ms) __attribute__((weak, alias("__esp_delay"))); + extern "C" void __yield() { if (can_yield()) { esp_schedule(); @@ -169,7 +193,6 @@ extern "C" void IRAM_ATTR ets_intr_unlock() { xt_rsil(0); } - // Save / Restore the PS state across the rom ets_post call as the rom code // does not implement this correctly. extern "C" bool ets_post_rom(uint8 prio, ETSSignal sig, ETSParam par); @@ -215,8 +238,8 @@ static void loop_task(os_event_t *events) { panic(); } } -extern "C" { +extern "C" { struct object { long placeholder[ 10 ]; }; void __register_frame_info (const void *begin, struct object *ob); extern char __eh_frame[]; @@ -253,7 +276,6 @@ static void __unhandled_exception_cpp() } #endif } - } void init_done() { diff --git a/cores/esp8266/core_esp8266_wiring.cpp b/cores/esp8266/core_esp8266_wiring.cpp index b956cebe43..44ae11524c 100644 --- a/cores/esp8266/core_esp8266_wiring.cpp +++ b/cores/esp8266/core_esp8266_wiring.cpp @@ -28,32 +28,17 @@ extern "C" { extern void ets_delay_us(uint32_t us); -extern void esp_schedule(); extern void esp_yield(); +extern void esp_delay(unsigned long ms); -static os_timer_t delay_timer; static os_timer_t micros_overflow_timer; static uint32_t micros_at_last_overflow_tick = 0; static uint32_t micros_overflow_count = 0; #define ONCE 0 #define REPEAT 1 -void delay_end(void* arg) { - (void) arg; - esp_schedule(); -} - void __delay(unsigned long ms) { - if(ms) { - os_timer_setfn(&delay_timer, (os_timer_func_t*) &delay_end, 0); - os_timer_arm(&delay_timer, ms, ONCE); - } else { - esp_schedule(); - } - esp_yield(); - if(ms) { - os_timer_disarm(&delay_timer); - } + esp_delay(ms); } void delay(unsigned long ms) __attribute__ ((weak, alias("__delay"))); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index 47086f0312..2879a28e35 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -49,6 +49,7 @@ extern "C" { #include "debug.h" #include "include/WiFiState.h" +extern "C" void esp_delay(unsigned long ms); extern "C" void esp_schedule(); // ----------------------------------------------------------------------------------------------------------------------- @@ -672,8 +673,7 @@ int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResul auto op_start_time = millis(); // will continue on timeout or when wifi_dns_found_callback fires while (millis() - op_start_time < timeout_ms && _dns_lookup_pending) { - // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - yield(); + esp_delay(timeout_ms); } _dns_lookup_pending = false; // will return here when dns_found_callback fires diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index b2751bc34e..9732e9802e 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -26,6 +26,7 @@ class WiFiClient; typedef void (*discard_cb_t)(void*, ClientContext*); +extern "C" void esp_delay(unsigned long ms); extern "C" void esp_schedule(); #include @@ -148,7 +149,7 @@ class ClientContext // will continue on timeout or when _connected or _notify_error fires while (!_is_timeout() && _connect_pending) { // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - yield(); + esp_delay(1); } _connect_pending = false; if (!_pcb) { @@ -491,7 +492,7 @@ class ClientContext // will continue on timeout or when _write_some_from_cb or _notify_error fires while (!_is_timeout() && _send_waiting) { // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - yield(); + esp_delay(1); } _send_waiting = false; } while(true); From c2edd9d80501a93adef5977398f86ec3db1fe53a Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Sat, 16 Nov 2019 13:03:10 +0100 Subject: [PATCH 06/20] Add host mockup for esp_delay --- tests/host/common/user_interface.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/host/common/user_interface.cpp b/tests/host/common/user_interface.cpp index b3a302df18..e20aab5ec4 100644 --- a/tests/host/common/user_interface.cpp +++ b/tests/host/common/user_interface.cpp @@ -502,6 +502,10 @@ extern "C" { } +void esp_delay (unsigned long ms) +{ +} + void dns_setserver(u8_t numdns, ip_addr_t *dnsserver) { (void)numdns; From 62a39a3a07afc8a4fd7465a2c96e7f73679903e2 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Mon, 18 Nov 2019 17:19:47 +0100 Subject: [PATCH 07/20] Facilitating reuse of the pattern, implement CONT suspend and delay as esp_yield and esp_delay with function arguments. --- cores/esp8266/core_esp8266_main.cpp | 19 +++++++++++++++++ cores/esp8266/core_esp8266_wiring.cpp | 4 +--- cores/esp8266/coredecls.h | 5 +++++ .../ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 12 +++-------- .../ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp | 7 ++----- libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp | 11 +++------- .../ESP8266WiFi/src/include/ClientContext.h | 21 +++++++------------ 7 files changed, 40 insertions(+), 39 deletions(-) diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index 69ffbd3c83..5b2c2b33c5 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -152,6 +152,25 @@ extern "C" void __esp_delay(unsigned long ms) { extern "C" void esp_delay(unsigned long ms) __attribute__((weak, alias("__esp_delay"))); +void esp_yield(const std::function& blocked) { + do { + esp_yield(); + } while (blocked()); +} + +void esp_delay(const uint32_t timeout_ms, const std::function& blocked, const uint32_t intvl_ms) { + const auto start = millis(); + decltype(millis()) expired; + while ((expired = millis() - start) < timeout_ms && blocked()) { + auto remaining = timeout_ms - expired; + esp_delay(remaining <= intvl_ms ? remaining : intvl_ms); + } +} + +void esp_delay(const uint32_t timeout_ms, const std::function& blocked) { + esp_delay(timeout_ms, blocked, timeout_ms); +} + extern "C" void __yield() { if (can_yield()) { esp_schedule(); diff --git a/cores/esp8266/core_esp8266_wiring.cpp b/cores/esp8266/core_esp8266_wiring.cpp index 44ae11524c..8e2351d618 100644 --- a/cores/esp8266/core_esp8266_wiring.cpp +++ b/cores/esp8266/core_esp8266_wiring.cpp @@ -23,13 +23,11 @@ #include "ets_sys.h" #include "osapi.h" #include "user_interface.h" -#include "cont.h" +#include "coredecls.h" extern "C" { extern void ets_delay_us(uint32_t us); -extern void esp_yield(); -extern void esp_delay(unsigned long ms); static os_timer_t micros_overflow_timer; static uint32_t micros_at_last_overflow_tick = 0; diff --git a/cores/esp8266/coredecls.h b/cores/esp8266/coredecls.h index b9c771df77..60a82f77db 100644 --- a/cores/esp8266/coredecls.h +++ b/cores/esp8266/coredecls.h @@ -14,6 +14,7 @@ extern "C" { bool can_yield(); void esp_yield(); +void esp_delay(unsigned long ms); void esp_schedule(); void tune_timeshift64 (uint64_t now_us); void disable_extra4k_at_link_time (void) __attribute__((noinline)); @@ -35,6 +36,10 @@ using TrivialCB = std::function; void settimeofday_cb (const BoolCB& cb); void settimeofday_cb (const TrivialCB& cb); +void esp_yield(const std::function& blocked); +void esp_delay(const uint32_t timeout_ms, const std::function& blocked); +void esp_delay(const uint32_t timeout_ms, const std::function& blocked, const uint32_t intvl_ms); + #endif // __cplusplus #endif // __COREDECLS_H diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index 2879a28e35..758050c0c5 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -49,9 +49,6 @@ extern "C" { #include "debug.h" #include "include/WiFiState.h" -extern "C" void esp_delay(unsigned long ms); -extern "C" void esp_schedule(); - // ----------------------------------------------------------------------------------------------------------------------- // ------------------------------------------------- Generic WiFi function ----------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------- @@ -620,7 +617,7 @@ int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResul aResult = IPAddress(&addr); } else if(err == ERR_INPROGRESS) { _dns_lookup_pending = true; - delay(timeout_ms); + esp_delay(timeout_ms, []() { return _dns_lookup_pending; }); // will resume on timeout or when wifi_dns_found_callback fires _dns_lookup_pending = false; // will return here when dns_found_callback fires @@ -670,11 +667,8 @@ int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResul aResult = IPAddress(&addr); } else if(err == ERR_INPROGRESS) { _dns_lookup_pending = true; - auto op_start_time = millis(); - // will continue on timeout or when wifi_dns_found_callback fires - while (millis() - op_start_time < timeout_ms && _dns_lookup_pending) { - esp_delay(timeout_ms); - } + // will resume on timeout or when wifi_dns_found_callback fires + esp_delay(timeout_ms, []() { return _dns_lookup_pending; }); _dns_lookup_pending = false; // will return here when dns_found_callback fires if(aResult.isSet()) { diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp index e183338b8c..2e9fa8e654 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp @@ -73,11 +73,8 @@ bool ESP8266WiFiSTAClass::beginWPSConfig(void) { } _wps_config_pending = true; - // will continue when wifi_wps_status_cb fires - while (_wps_config_pending) { - esp_yield(); - } - _wps_config_pending = false; + // will resume when wifi_wps_status_cb fires + esp_yield([]() { return _wps_config_pending; }); return true; } diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp index b92042c183..d08dbafe8d 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp @@ -36,9 +36,7 @@ extern "C" { } #include "debug.h" - -extern "C" void esp_schedule(); -extern "C" void esp_yield(); +#include // ----------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------- Private functions ------------------------------------------------ @@ -98,11 +96,8 @@ int8_t ESP8266WiFiScanClass::scanNetworks(bool async, bool show_hidden, uint8 ch return WIFI_SCAN_RUNNING; } - // will continue when _scanDone fires - while (!ESP8266WiFiScanClass::_scanComplete && ESP8266WiFiScanClass::_scanStarted) - { - esp_yield(); - } + // will resume when _scanDone fires + esp_yield([]() { return !ESP8266WiFiScanClass::_scanComplete && ESP8266WiFiScanClass::_scanStarted; }); return ESP8266WiFiScanClass::_scanCount; } else { diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index 9732e9802e..06587fc926 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -26,12 +26,9 @@ class WiFiClient; typedef void (*discard_cb_t)(void*, ClientContext*); -extern "C" void esp_delay(unsigned long ms); -extern "C" void esp_schedule(); - #include #include - +#include bool getDefaultPrivateGlobalSyncValue (); @@ -146,11 +143,9 @@ class ClientContext } _connect_pending = true; _op_start_time = millis(); - // will continue on timeout or when _connected or _notify_error fires - while (!_is_timeout() && _connect_pending) { - // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - esp_delay(1); - } + // will resume on timeout or when _connected or _notify_error fires + // give scheduled functions a chance to run (e.g. Ethernet uses recurrent) + esp_delay(_timeout_ms, [this]() { return _connect_pending; }, 1); _connect_pending = false; if (!_pcb) { DEBUGV(":cabrt\r\n"); @@ -489,11 +484,9 @@ class ClientContext } _send_waiting = true; - // will continue on timeout or when _write_some_from_cb or _notify_error fires - while (!_is_timeout() && _send_waiting) { - // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - esp_delay(1); - } + // will resume on timeout or when _write_some_from_cb or _notify_error fires + // give scheduled functions a chance to run (e.g. Ethernet uses recurrent) + esp_delay(_timeout_ms, [this]() { return _send_waiting; }, 1); _send_waiting = false; } while(true); From 49563a14934d0720933436477016f93041c33add Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Mon, 18 Nov 2019 19:09:22 +0100 Subject: [PATCH 08/20] Memory footprint optimization by inlining Add host mockup for esp_delay overload --- cores/esp8266/core_esp8266_main.cpp | 10 ---------- cores/esp8266/coredecls.h | 12 ++++++++++-- tests/host/common/user_interface.cpp | 4 ++++ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index 5b2c2b33c5..a1c91846b6 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -152,12 +152,6 @@ extern "C" void __esp_delay(unsigned long ms) { extern "C" void esp_delay(unsigned long ms) __attribute__((weak, alias("__esp_delay"))); -void esp_yield(const std::function& blocked) { - do { - esp_yield(); - } while (blocked()); -} - void esp_delay(const uint32_t timeout_ms, const std::function& blocked, const uint32_t intvl_ms) { const auto start = millis(); decltype(millis()) expired; @@ -167,10 +161,6 @@ void esp_delay(const uint32_t timeout_ms, const std::function& blocked, } } -void esp_delay(const uint32_t timeout_ms, const std::function& blocked) { - esp_delay(timeout_ms, blocked, timeout_ms); -} - extern "C" void __yield() { if (can_yield()) { esp_schedule(); diff --git a/cores/esp8266/coredecls.h b/cores/esp8266/coredecls.h index 60a82f77db..c38fd980c2 100644 --- a/cores/esp8266/coredecls.h +++ b/cores/esp8266/coredecls.h @@ -36,10 +36,18 @@ using TrivialCB = std::function; void settimeofday_cb (const BoolCB& cb); void settimeofday_cb (const TrivialCB& cb); -void esp_yield(const std::function& blocked); -void esp_delay(const uint32_t timeout_ms, const std::function& blocked); +inline void esp_yield(const std::function& blocked) { + do { + esp_yield(); + } while (blocked()); +} + void esp_delay(const uint32_t timeout_ms, const std::function& blocked, const uint32_t intvl_ms); +inline void esp_delay(const uint32_t timeout_ms, const std::function& blocked) { + esp_delay(timeout_ms, blocked, timeout_ms); +} + #endif // __cplusplus #endif // __COREDECLS_H diff --git a/tests/host/common/user_interface.cpp b/tests/host/common/user_interface.cpp index e20aab5ec4..505299469e 100644 --- a/tests/host/common/user_interface.cpp +++ b/tests/host/common/user_interface.cpp @@ -504,6 +504,10 @@ extern "C" void esp_delay (unsigned long ms) { +} + +void esp_delay(const uint32_t timeout_ms, const std::function& blocked) +{ } void dns_setserver(u8_t numdns, ip_addr_t *dnsserver) From 85dbad67e9f0cf3a45a79634d1498165398dd4dc Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Mon, 18 Nov 2019 21:56:01 +0100 Subject: [PATCH 09/20] Fixing host mockups for esp_delay, esp_yield --- tests/host/common/Arduino.cpp | 19 ++++++++++++++++++- tests/host/common/user_interface.cpp | 8 -------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/tests/host/common/Arduino.cpp b/tests/host/common/Arduino.cpp index 780c4adc14..7ffd848bd1 100644 --- a/tests/host/common/Arduino.cpp +++ b/tests/host/common/Arduino.cpp @@ -57,6 +57,23 @@ extern "C" void esp_yield() { } +extern "C" void esp_delay (unsigned long ms) +{ + usleep(ms * 1000); +} + +inline void esp_yield(const std::function& blocked) { +} + +void esp_delay(const uint32_t timeout_ms, const std::function& blocked, const uint32_t intvl_ms) +{ + usleep(ms * 1000); +} + +inline void esp_delay(const uint32_t timeout_ms, const std::function& blocked) +{ + usleep(ms * 1000); +} extern "C" void __panic_func(const char* file, int line, const char* func) { (void)file; @@ -67,7 +84,7 @@ extern "C" void __panic_func(const char* file, int line, const char* func) { extern "C" void delay(unsigned long ms) { - usleep(ms * 1000); + esp_delay(ms); } extern "C" void delayMicroseconds(unsigned int us) diff --git a/tests/host/common/user_interface.cpp b/tests/host/common/user_interface.cpp index 505299469e..b3a302df18 100644 --- a/tests/host/common/user_interface.cpp +++ b/tests/host/common/user_interface.cpp @@ -502,14 +502,6 @@ extern "C" { } -void esp_delay (unsigned long ms) -{ -} - -void esp_delay(const uint32_t timeout_ms, const std::function& blocked) -{ -} - void dns_setserver(u8_t numdns, ip_addr_t *dnsserver) { (void)numdns; From d12245e556edb4005d283e3fa4a2fcc63355fe34 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Mon, 18 Nov 2019 22:11:31 +0100 Subject: [PATCH 10/20] Suppress unused argument warning. --- tests/host/common/Arduino.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/host/common/Arduino.cpp b/tests/host/common/Arduino.cpp index 7ffd848bd1..b4216a44d3 100644 --- a/tests/host/common/Arduino.cpp +++ b/tests/host/common/Arduino.cpp @@ -63,16 +63,20 @@ extern "C" void esp_delay (unsigned long ms) } inline void esp_yield(const std::function& blocked) { + (void)blocked; } void esp_delay(const uint32_t timeout_ms, const std::function& blocked, const uint32_t intvl_ms) { - usleep(ms * 1000); + (void)blocked; + (void)intvl_ms; + usleep(timeout_ms * 1000); } inline void esp_delay(const uint32_t timeout_ms, const std::function& blocked) { - usleep(ms * 1000); + (void)blocked; + usleep(timeout_ms * 1000); } extern "C" void __panic_func(const char* file, int line, const char* func) { From 2f2b0bd0593da243b9f8b2a8b08d730baefd7dd3 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Tue, 19 Nov 2019 00:20:54 +0100 Subject: [PATCH 11/20] Identified another candidate for esp_delay refactoring. --- libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index 758050c0c5..936e57c029 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -434,10 +434,7 @@ bool ESP8266WiFiGenericClass::mode(WiFiMode_t m) { //tasks to wait correctly. constexpr unsigned int timeoutValue = 1000; //1 second if(can_yield()) { - using oneShot = esp8266::polledTimeout::oneShotFastMs; - oneShot timeout(timeoutValue); - while(wifi_get_opmode() != (uint8) m && !timeout) - delay(5); + esp_delay(timeoutValue, [m]() { return wifi_get_opmode() != (uint8)m; }, 5); //if at this point mode still hasn't been reached, give up if(wifi_get_opmode() != (uint8) m) { From b4d1a07060392a743cbaeeeaf6730fd17622d117 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Wed, 30 Dec 2020 16:02:13 +0100 Subject: [PATCH 12/20] Replace std::function by Delegate in esp_yield/esp_delay callback functions. --- cores/esp8266/core_esp8266_main.cpp | 5 ++++- cores/esp8266/coredecls.h | 15 +++++++++------ cores/esp8266/time.cpp | 5 +++++ libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp | 2 +- .../esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino | 2 +- tests/host/common/Arduino.cpp | 6 +++--- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index a1c91846b6..47f6268811 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -24,6 +24,7 @@ //#define CONT_STACKSIZE 4096 #include #include "Schedule.h" +#include "Delegate.h" extern "C" { #include "ets_sys.h" #include "os_type.h" @@ -152,7 +153,9 @@ extern "C" void __esp_delay(unsigned long ms) { extern "C" void esp_delay(unsigned long ms) __attribute__((weak, alias("__esp_delay"))); -void esp_delay(const uint32_t timeout_ms, const std::function& blocked, const uint32_t intvl_ms) { +using IsBlockedCB = Delegate; + +void esp_delay(const uint32_t timeout_ms, const IsBlockedCB& blocked, const uint32_t intvl_ms) { const auto start = millis(); decltype(millis()) expired; while ((expired = millis() - start) < timeout_ms && blocked()) { diff --git a/cores/esp8266/coredecls.h b/cores/esp8266/coredecls.h index c38fd980c2..7dbd703105 100644 --- a/cores/esp8266/coredecls.h +++ b/cores/esp8266/coredecls.h @@ -28,23 +28,26 @@ uint32_t crc32 (const void* data, size_t length, uint32_t crc = 0xffffffff); #ifdef __cplusplus } -#include +#include -using BoolCB = std::function; -using TrivialCB = std::function; +using BoolCB = Delegate; +using TrivialCB = Delegate<>; +void settimeofday_cb (BoolCB&& cb); void settimeofday_cb (const BoolCB& cb); void settimeofday_cb (const TrivialCB& cb); -inline void esp_yield(const std::function& blocked) { +using IsBlockedCB = Delegate; + +inline void esp_yield(const IsBlockedCB& blocked) { do { esp_yield(); } while (blocked()); } -void esp_delay(const uint32_t timeout_ms, const std::function& blocked, const uint32_t intvl_ms); +void esp_delay(const uint32_t timeout_ms, const IsBlockedCB& blocked, const uint32_t intvl_ms); -inline void esp_delay(const uint32_t timeout_ms, const std::function& blocked) { +inline void esp_delay(const uint32_t timeout_ms, const IsBlockedCB& blocked) { esp_delay(timeout_ms, blocked, timeout_ms); } diff --git a/cores/esp8266/time.cpp b/cores/esp8266/time.cpp index b9489c330f..8e997c72d5 100644 --- a/cores/esp8266/time.cpp +++ b/cores/esp8266/time.cpp @@ -214,6 +214,11 @@ void settimeofday_cb (const TrivialCB& cb) _settimeofday_cb = [cb](bool sntp) { (void)sntp; cb(); }; } +void settimeofday_cb (BoolCB&& cb) +{ + _settimeofday_cb = std::move(cb); +} + void settimeofday_cb (const BoolCB& cb) { _settimeofday_cb = cb; diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp index 2e9fa8e654..967173929a 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp @@ -74,7 +74,7 @@ bool ESP8266WiFiSTAClass::beginWPSConfig(void) { _wps_config_pending = true; // will resume when wifi_wps_status_cb fires - esp_yield([]() { return _wps_config_pending; }); + esp_yield([]() { return _wps_config_pending; }); return true; } diff --git a/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino b/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino index f6c2df08fc..ce801dfb72 100644 --- a/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino +++ b/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino @@ -242,7 +242,7 @@ void setup() { // install callback - called when settimeofday is called (by SNTP or user) // once enabled (by DHCP), SNTP is updated every hour by default // ** optional boolean in callback function is true when triggered by SNTP ** - settimeofday_cb(time_is_set); + settimeofday_cb(static_cast(time_is_set)); // setup RTC time // it will be used until NTP server will send us real current time diff --git a/tests/host/common/Arduino.cpp b/tests/host/common/Arduino.cpp index b4216a44d3..79bf1d4427 100644 --- a/tests/host/common/Arduino.cpp +++ b/tests/host/common/Arduino.cpp @@ -62,18 +62,18 @@ extern "C" void esp_delay (unsigned long ms) usleep(ms * 1000); } -inline void esp_yield(const std::function& blocked) { +inline void esp_yield(const IsBlockedCB& blocked) { (void)blocked; } -void esp_delay(const uint32_t timeout_ms, const std::function& blocked, const uint32_t intvl_ms) +void esp_delay(const uint32_t timeout_ms, const IsBlockedCB& blocked, const uint32_t intvl_ms) { (void)blocked; (void)intvl_ms; usleep(timeout_ms * 1000); } -inline void esp_delay(const uint32_t timeout_ms, const std::function& blocked) +inline void esp_delay(const uint32_t timeout_ms, const IsBlockedCB& blocked) { (void)blocked; usleep(timeout_ms * 1000); From b54f63e86c954216e0821a2d48a0b6f681f9fa8f Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Fri, 29 Nov 2019 13:18:19 +0100 Subject: [PATCH 13/20] Delegate now uses function declaration syntax in template type specification --- cores/esp8266/core_esp8266_main.cpp | 2 +- cores/esp8266/coredecls.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index 47f6268811..cf164cee4a 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -153,7 +153,7 @@ extern "C" void __esp_delay(unsigned long ms) { extern "C" void esp_delay(unsigned long ms) __attribute__((weak, alias("__esp_delay"))); -using IsBlockedCB = Delegate; +using IsBlockedCB = Delegate; void esp_delay(const uint32_t timeout_ms, const IsBlockedCB& blocked, const uint32_t intvl_ms) { const auto start = millis(); diff --git a/cores/esp8266/coredecls.h b/cores/esp8266/coredecls.h index 7dbd703105..cb594c05b1 100644 --- a/cores/esp8266/coredecls.h +++ b/cores/esp8266/coredecls.h @@ -31,13 +31,13 @@ uint32_t crc32 (const void* data, size_t length, uint32_t crc = 0xffffffff); #include using BoolCB = Delegate; -using TrivialCB = Delegate<>; +using TrivialCB = Delegate; void settimeofday_cb (BoolCB&& cb); void settimeofday_cb (const BoolCB& cb); void settimeofday_cb (const TrivialCB& cb); -using IsBlockedCB = Delegate; +using IsBlockedCB = Delegate; inline void esp_yield(const IsBlockedCB& blocked) { do { From 8da7ec34f883538450adc262688278446186b778 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Fri, 29 Nov 2019 16:15:29 +0100 Subject: [PATCH 14/20] Use terse function notation - match std::function, the optional 1st argument for C-style FP is now ONLY in 3rd template argument. --- cores/esp8266/core_esp8266_main.cpp | 2 +- cores/esp8266/coredecls.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index cf164cee4a..ed22556cba 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -153,7 +153,7 @@ extern "C" void __esp_delay(unsigned long ms) { extern "C" void esp_delay(unsigned long ms) __attribute__((weak, alias("__esp_delay"))); -using IsBlockedCB = Delegate; +using IsBlockedCB = Delegate; void esp_delay(const uint32_t timeout_ms, const IsBlockedCB& blocked, const uint32_t intvl_ms) { const auto start = millis(); diff --git a/cores/esp8266/coredecls.h b/cores/esp8266/coredecls.h index cb594c05b1..41b8f50f91 100644 --- a/cores/esp8266/coredecls.h +++ b/cores/esp8266/coredecls.h @@ -30,14 +30,14 @@ uint32_t crc32 (const void* data, size_t length, uint32_t crc = 0xffffffff); #include -using BoolCB = Delegate; -using TrivialCB = Delegate; +using BoolCB = Delegate; +using TrivialCB = Delegate; void settimeofday_cb (BoolCB&& cb); void settimeofday_cb (const BoolCB& cb); void settimeofday_cb (const TrivialCB& cb); -using IsBlockedCB = Delegate; +using IsBlockedCB = Delegate; inline void esp_yield(const IsBlockedCB& blocked) { do { From 358f9423ec02f4024776853fb32213259dbb1a2f Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Mon, 2 Dec 2019 17:29:49 +0100 Subject: [PATCH 15/20] Fix for host target --- tests/host/common/Arduino.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/host/common/Arduino.cpp b/tests/host/common/Arduino.cpp index 79bf1d4427..8e62eff261 100644 --- a/tests/host/common/Arduino.cpp +++ b/tests/host/common/Arduino.cpp @@ -15,6 +15,7 @@ #include #include "Arduino.h" +#include #include @@ -62,6 +63,8 @@ extern "C" void esp_delay (unsigned long ms) usleep(ms * 1000); } +using IsBlockedCB = Delegate; + inline void esp_yield(const IsBlockedCB& blocked) { (void)blocked; } From ea5648b67600cbe1d6a9986abb1e5ddfd4e033a4 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Thu, 5 Mar 2020 16:48:23 +0100 Subject: [PATCH 16/20] Avoid Delegate anti-pattern (std::function with capture where C-style ptr with arg is possible). --- libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 2 +- libraries/ESP8266WiFi/src/include/ClientContext.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index 936e57c029..20b8018a1a 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -434,7 +434,7 @@ bool ESP8266WiFiGenericClass::mode(WiFiMode_t m) { //tasks to wait correctly. constexpr unsigned int timeoutValue = 1000; //1 second if(can_yield()) { - esp_delay(timeoutValue, [m]() { return wifi_get_opmode() != (uint8)m; }, 5); + esp_delay(timeoutValue, { [](void* m) { return wifi_get_opmode() != *static_cast(m); }, (void*)&m }, 5); //if at this point mode still hasn't been reached, give up if(wifi_get_opmode() != (uint8) m) { diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index 06587fc926..1acd055195 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -145,7 +145,7 @@ class ClientContext _op_start_time = millis(); // will resume on timeout or when _connected or _notify_error fires // give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - esp_delay(_timeout_ms, [this]() { return _connect_pending; }, 1); + esp_delay(_timeout_ms, { [](void* self) { return static_cast(self)->_connect_pending; }, this }, 1); _connect_pending = false; if (!_pcb) { DEBUGV(":cabrt\r\n"); @@ -486,7 +486,7 @@ class ClientContext _send_waiting = true; // will resume on timeout or when _write_some_from_cb or _notify_error fires // give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - esp_delay(_timeout_ms, [this]() { return _send_waiting; }, 1); + esp_delay(_timeout_ms, { [](void* self) { return static_cast(self)->_send_waiting; }, this }, 1); _send_waiting = false; } while(true); From 5011f88ec6299a15edd827f409bf89fb9917de6a Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Tue, 10 Mar 2020 18:56:29 +0100 Subject: [PATCH 17/20] Rename new esp_yield(...) with blocking predicate argument to more descriptive esp_suspend(...). Provide esp_suspend(void) as wrapper for esp_yield(). --- cores/esp8266/coredecls.h | 8 ++++++-- libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp | 2 +- libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp | 2 +- tests/host/common/Arduino.cpp | 6 +++++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/cores/esp8266/coredecls.h b/cores/esp8266/coredecls.h index 41b8f50f91..749a9b1e88 100644 --- a/cores/esp8266/coredecls.h +++ b/cores/esp8266/coredecls.h @@ -39,9 +39,13 @@ void settimeofday_cb (const TrivialCB& cb); using IsBlockedCB = Delegate; -inline void esp_yield(const IsBlockedCB& blocked) { +inline void esp_suspend() { + esp_yield(); +} + +inline void esp_suspend(const IsBlockedCB& blocked) { do { - esp_yield(); + esp_suspend(); } while (blocked()); } diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp index 967173929a..b93c77da9c 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp @@ -74,7 +74,7 @@ bool ESP8266WiFiSTAClass::beginWPSConfig(void) { _wps_config_pending = true; // will resume when wifi_wps_status_cb fires - esp_yield([]() { return _wps_config_pending; }); + esp_suspend([]() { return _wps_config_pending; }); return true; } diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp index d08dbafe8d..37de0df1c6 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp @@ -97,7 +97,7 @@ int8_t ESP8266WiFiScanClass::scanNetworks(bool async, bool show_hidden, uint8 ch } // will resume when _scanDone fires - esp_yield([]() { return !ESP8266WiFiScanClass::_scanComplete && ESP8266WiFiScanClass::_scanStarted; }); + esp_suspend([]() { return !ESP8266WiFiScanClass::_scanComplete && ESP8266WiFiScanClass::_scanStarted; }); return ESP8266WiFiScanClass::_scanCount; } else { diff --git a/tests/host/common/Arduino.cpp b/tests/host/common/Arduino.cpp index 8e62eff261..c0c32b4968 100644 --- a/tests/host/common/Arduino.cpp +++ b/tests/host/common/Arduino.cpp @@ -65,7 +65,11 @@ extern "C" void esp_delay (unsigned long ms) using IsBlockedCB = Delegate; -inline void esp_yield(const IsBlockedCB& blocked) { +inline void esp_suspend() { + esp_yield(); +} + +inline void esp_suspend(const IsBlockedCB& blocked) { (void)blocked; } From df1460f64bea06919fffd8f906c50f9a51890c46 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Sat, 9 Jan 2021 14:53:05 +0100 Subject: [PATCH 18/20] revert to std::function from Delegate to make easier to accept PR --- cores/esp8266/core_esp8266_main.cpp | 7 ++++--- cores/esp8266/coredecls.h | 8 ++++---- libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 2 +- libraries/ESP8266WiFi/src/include/ClientContext.h | 4 ++-- libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino | 2 +- tests/host/common/Arduino.cpp | 4 ++-- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index ed22556cba..4d259f3688 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -24,7 +24,6 @@ //#define CONT_STACKSIZE 4096 #include #include "Schedule.h" -#include "Delegate.h" extern "C" { #include "ets_sys.h" #include "os_type.h" @@ -72,6 +71,7 @@ static uint32_t s_cycles_at_yield_start; static uint16_t ets_intr_lock_stack[ETS_INTR_LOCK_NEST_MAX]; static byte ets_intr_lock_stack_ptr=0; + extern "C" { extern const uint32_t __attribute__((section(".ver_number"))) core_version = ARDUINO_ESP8266_GIT_VER; const char* core_release = @@ -153,7 +153,7 @@ extern "C" void __esp_delay(unsigned long ms) { extern "C" void esp_delay(unsigned long ms) __attribute__((weak, alias("__esp_delay"))); -using IsBlockedCB = Delegate; +using IsBlockedCB = std::function; void esp_delay(const uint32_t timeout_ms, const IsBlockedCB& blocked, const uint32_t intvl_ms) { const auto start = millis(); @@ -174,7 +174,7 @@ extern "C" void __yield() { } } -extern "C" void yield() __attribute__ ((weak, alias("__yield"))); +extern "C" void yield(void) __attribute__ ((weak, alias("__yield"))); extern "C" void optimistic_yield(uint32_t interval_us) { const uint32_t intvl_cycles = interval_us * @@ -205,6 +205,7 @@ extern "C" void IRAM_ATTR ets_intr_unlock() { xt_rsil(0); } + // Save / Restore the PS state across the rom ets_post call as the rom code // does not implement this correctly. extern "C" bool ets_post_rom(uint8 prio, ETSSignal sig, ETSParam par); diff --git a/cores/esp8266/coredecls.h b/cores/esp8266/coredecls.h index 749a9b1e88..c4ef04a292 100644 --- a/cores/esp8266/coredecls.h +++ b/cores/esp8266/coredecls.h @@ -28,16 +28,16 @@ uint32_t crc32 (const void* data, size_t length, uint32_t crc = 0xffffffff); #ifdef __cplusplus } -#include +#include -using BoolCB = Delegate; -using TrivialCB = Delegate; +using BoolCB = std::function; +using TrivialCB = std::function; void settimeofday_cb (BoolCB&& cb); void settimeofday_cb (const BoolCB& cb); void settimeofday_cb (const TrivialCB& cb); -using IsBlockedCB = Delegate; +using IsBlockedCB = std::function; inline void esp_suspend() { esp_yield(); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index 20b8018a1a..4cb393623f 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -434,7 +434,7 @@ bool ESP8266WiFiGenericClass::mode(WiFiMode_t m) { //tasks to wait correctly. constexpr unsigned int timeoutValue = 1000; //1 second if(can_yield()) { - esp_delay(timeoutValue, { [](void* m) { return wifi_get_opmode() != *static_cast(m); }, (void*)&m }, 5); + esp_delay(timeoutValue, [m]() { return wifi_get_opmode() != m; }, 5); //if at this point mode still hasn't been reached, give up if(wifi_get_opmode() != (uint8) m) { diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index 1acd055195..6707677da5 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -145,7 +145,7 @@ class ClientContext _op_start_time = millis(); // will resume on timeout or when _connected or _notify_error fires // give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - esp_delay(_timeout_ms, { [](void* self) { return static_cast(self)->_connect_pending; }, this }, 1); + esp_delay(_timeout_ms, [this]() { return this->_connect_pending; }, 1); _connect_pending = false; if (!_pcb) { DEBUGV(":cabrt\r\n"); @@ -486,7 +486,7 @@ class ClientContext _send_waiting = true; // will resume on timeout or when _write_some_from_cb or _notify_error fires // give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - esp_delay(_timeout_ms, { [](void* self) { return static_cast(self)->_send_waiting; }, this }, 1); + esp_delay(_timeout_ms, [this]() { return this->_send_waiting; }, 1); _send_waiting = false; } while(true); diff --git a/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino b/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino index ce801dfb72..f6c2df08fc 100644 --- a/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino +++ b/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino @@ -242,7 +242,7 @@ void setup() { // install callback - called when settimeofday is called (by SNTP or user) // once enabled (by DHCP), SNTP is updated every hour by default // ** optional boolean in callback function is true when triggered by SNTP ** - settimeofday_cb(static_cast(time_is_set)); + settimeofday_cb(time_is_set); // setup RTC time // it will be used until NTP server will send us real current time diff --git a/tests/host/common/Arduino.cpp b/tests/host/common/Arduino.cpp index c0c32b4968..1e9758e63d 100644 --- a/tests/host/common/Arduino.cpp +++ b/tests/host/common/Arduino.cpp @@ -15,7 +15,7 @@ #include #include "Arduino.h" -#include +#include #include @@ -63,7 +63,7 @@ extern "C" void esp_delay (unsigned long ms) usleep(ms * 1000); } -using IsBlockedCB = Delegate; +using IsBlockedCB = std::function; inline void esp_suspend() { esp_yield(); From 7417970890831f6d71aed94ff4a2d6b1a1f3677e Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Sat, 23 Jan 2021 21:22:56 +0100 Subject: [PATCH 19/20] Refactor ESP8266WiFiMulti to use esp_delay. Optimisation opportunity: don't thrash the recurrent functions scheduler by using intvl_ms != 0. Keeping the MCU out of the idle task increases power consumption. --- .../ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 2 + .../ESP8266WiFi/src/ESP8266WiFiMulti.cpp | 70 +++++++------------ 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index 4cb393623f..f32ec8fba8 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -434,6 +434,8 @@ bool ESP8266WiFiGenericClass::mode(WiFiMode_t m) { //tasks to wait correctly. constexpr unsigned int timeoutValue = 1000; //1 second if(can_yield()) { + // The final argument, intvl_ms, to esp_delay influences how frequently + // the scheduled recurrent functions (Schedule.h) are probed. esp_delay(timeoutValue, [m]() { return wifi_get_opmode() != m; }, 5); //if at this point mode still hasn't been reached, give up diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp index 8d74f687cb..5bfa13a430 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp @@ -27,6 +27,7 @@ #include "ESP8266WiFiMulti.h" #include #include +#include /** * @brief Print WiFi status @@ -83,36 +84,25 @@ static void printWiFiStatus(wl_status_t status) static wl_status_t waitWiFiConnect(uint32_t connectTimeoutMs) { wl_status_t status; + // The final argument, intvl_ms, to esp_delay influences how frequently + // the scheduled recurrent functions (Schedule.h) are probed. + esp_delay(connectTimeoutMs, + [&status]() { status = WiFi.status(); return status != WL_CONNECTED && status != WL_CONNECT_FAILED; }, 0); - // Set WiFi connect timeout - using esp8266::polledTimeout::oneShotMs; - oneShotMs connectTimeout(connectTimeoutMs); - - // Wait for WiFi status change or timeout - do { - // Refresh watchdog - delay(0); - - // Get WiFi status - status = WiFi.status(); - - // Check status - if (status == WL_CONNECTED) { - // Connected, print WiFi status - printWiFiStatus(status); - - // Return WiFi status - return status; - } else if (status == WL_CONNECT_FAILED) { - DEBUG_WIFI_MULTI("[WIFIM] Connect failed\n"); - - // Return WiFi connect failed - return WL_CONNECT_FAILED; - } - } while (!connectTimeout); + // Check status + if (status == WL_CONNECTED) { + // Connected, print WiFi status + printWiFiStatus(status); - DEBUG_WIFI_MULTI("[WIFIM] Connect timeout\n"); + // Return WiFi status + return status; + } else if (status == WL_CONNECT_FAILED) { + DEBUG_WIFI_MULTI("[WIFIM] Connect failed\n"); + } else { + DEBUG_WIFI_MULTI("[WIFIM] Connect timeout\n"); + } + // Return WiFi connect failed return WL_CONNECT_FAILED; } @@ -242,24 +232,16 @@ int8_t ESP8266WiFiMulti::startScan() // Start wifi scan in async mode WiFi.scanNetworks(true); - // Set WiFi scan timeout - using esp8266::polledTimeout::oneShotMs; - oneShotMs scanTimeout(WIFI_SCAN_TIMEOUT_MS); - // Wait for WiFi scan change or timeout - do { - // Refresh watchdog - delay(0); - - // Check scan timeout which may occur when scan does not report completion - if (scanTimeout) { - DEBUG_WIFI_MULTI("[WIFIM] Scan timeout\n"); - return WIFI_SCAN_FAILED; - } - - // Get scan result - scanResult = WiFi.scanComplete(); - } while (scanResult < 0); + // The final argument, intvl_ms, to esp_delay influences how frequently + // the scheduled recurrent functions (Schedule.h) are probed. + esp_delay(WIFI_SCAN_TIMEOUT_MS, + [&scanResult]() { scanResult = WiFi.scanComplete(); return scanResult < 0; }, 0); + // Check for scan timeout which may occur when scan does not report completion + if (scanResult < 0) { + DEBUG_WIFI_MULTI("[WIFIM] Scan timeout\n"); + return WIFI_SCAN_FAILED; + } // Print WiFi scan result printWiFiScan(); From 6ac4ea4d9a6c686cc49fbbaa5d7aac2d0499e213 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Tue, 20 Jul 2021 18:39:25 +0200 Subject: [PATCH 20/20] Adapt logic to feed scheduled recurrent functions in hostByName from PR #6212 --- libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index f32ec8fba8..6b0b9ba754 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -616,10 +616,12 @@ int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResul aResult = IPAddress(&addr); } else if(err == ERR_INPROGRESS) { _dns_lookup_pending = true; - esp_delay(timeout_ms, []() { return _dns_lookup_pending; }); - // will resume on timeout or when wifi_dns_found_callback fires + // Will resume on timeout or when wifi_dns_found_callback fires. + // The final argument, intvl_ms, to esp_delay influences how frequently + // the scheduled recurrent functions (Schedule.h) are probed; here, to allow + // the ethernet driver perform work. + esp_delay(timeout_ms, []() { return _dns_lookup_pending; }, 1); _dns_lookup_pending = false; - // will return here when dns_found_callback fires if(aResult.isSet()) { err = ERR_OK; }