From 3d7bf493a66868a4594a7aec763012803238ea3b Mon Sep 17 00:00:00 2001 From: david gauchard Date: Mon, 11 Jan 2021 17:52:16 +0100 Subject: [PATCH 1/7] rename yield-related functions, yield is now optimistic_yield --- cores/esp8266/Arduino.h | 2 +- cores/esp8266/Esp.cpp | 8 ++- cores/esp8266/HardwareSerial.cpp | 2 +- cores/esp8266/Schedule.cpp | 4 +- cores/esp8266/cont.h | 2 +- cores/esp8266/cont_util.cpp | 2 +- cores/esp8266/core_esp8266_i2s.cpp | 6 +-- cores/esp8266/core_esp8266_main.cpp | 50 +++++++++++-------- cores/esp8266/core_esp8266_wiring.cpp | 9 ++-- cores/esp8266/core_esp8266_wiring_pulse.cpp | 2 +- cores/esp8266/coredecls.h | 11 ++-- cores/esp8266/flash_hal.cpp | 6 +-- cores/esp8266/uart.cpp | 2 +- .../ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 8 ++- .../ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp | 4 +- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 3 -- libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp | 8 ++- libraries/ESP8266WiFi/src/WiFiClient.cpp | 2 +- .../src/WiFiClientSecureBearSSL.cpp | 6 +-- libraries/ESP8266WiFi/src/WiFiServer.cpp | 2 +- .../src/WiFiServerSecureBearSSL.cpp | 2 +- libraries/ESP8266WiFi/src/WiFiUdp.cpp | 4 +- .../ESP8266WiFi/src/include/ClientContext.h | 10 ++-- .../ESP8266WiFi/src/include/UdpContext.h | 8 +-- libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp | 4 +- libraries/Wire/Wire.cpp | 2 +- tests/host/common/Arduino.cpp | 4 +- tests/host/common/include/ClientContext.h | 4 +- tests/host/common/include/UdpContext.h | 2 +- tests/host/common/user_interface.cpp | 2 +- 30 files changed, 88 insertions(+), 93 deletions(-) diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index b484a3765a..4fd7dba0b5 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -191,7 +191,7 @@ void loop(void); void yield(void); -void optimistic_yield(uint32_t interval_us); +void optimistic_yield(uint32_t interval_us) __attribute__ ((deprecated("use yield()"))); #define _PORT_GPIO16 1 #define digitalPinToPort(pin) (((pin)==16)?(_PORT_GPIO16):(0)) diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp index 51bdfe8e12..0317e736ea 100644 --- a/cores/esp8266/Esp.cpp +++ b/cores/esp8266/Esp.cpp @@ -115,20 +115,18 @@ void EspClass::wdtFeed(void) system_soft_wdt_feed(); } -extern "C" void esp_yield(); - void EspClass::deepSleep(uint64_t time_us, WakeMode mode) { system_deep_sleep_set_option(static_cast(mode)); system_deep_sleep(time_us); - esp_yield(); + esp_suspend_from_cont(); } void EspClass::deepSleepInstant(uint64_t time_us, WakeMode mode) { system_deep_sleep_set_option(static_cast(mode)); system_deep_sleep_instant(time_us); - esp_yield(); + esp_suspend_from_cont(); } //this calculation was taken verbatim from the SDK api reference for SDK 2.1.0. @@ -200,7 +198,7 @@ void EspClass::reset(void) void EspClass::restart(void) { system_restart(); - esp_yield(); + esp_suspend_from_cont(); } uint16_t EspClass::getVcc(void) diff --git a/cores/esp8266/HardwareSerial.cpp b/cores/esp8266/HardwareSerial.cpp index 26383dd43e..715139d8c4 100644 --- a/cores/esp8266/HardwareSerial.cpp +++ b/cores/esp8266/HardwareSerial.cpp @@ -109,7 +109,7 @@ int HardwareSerial::available(void) { int result = static_cast(uart_rx_available(_uart)); if (!result) { - optimistic_yield(10000); + yield(); } return result; } diff --git a/cores/esp8266/Schedule.cpp b/cores/esp8266/Schedule.cpp index b1230ed675..1123c89b49 100644 --- a/cores/esp8266/Schedule.cpp +++ b/cores/esp8266/Schedule.cpp @@ -165,7 +165,7 @@ void run_scheduled_functions() { // because scheduled functions might last too long for watchdog etc, // this is yield() in cont stack: - esp_schedule(); + esp_request_for_cont(); cont_yield(g_pcont); } } @@ -242,7 +242,7 @@ void run_scheduled_recurrent_functions() { // because scheduled functions might last too long for watchdog etc, // this is yield() in cont stack: - esp_schedule(); + esp_request_for_cont(); cont_yield(g_pcont); } } while (current && !done); diff --git a/cores/esp8266/cont.h b/cores/esp8266/cont.h index 21ecad2806..a6d75094f3 100644 --- a/cores/esp8266/cont.h +++ b/cores/esp8266/cont.h @@ -72,7 +72,7 @@ int cont_get_free_stack(cont_t* cont); // Check if yield() may be called. Returns true if we are running inside // continuation stack -bool cont_can_yield(cont_t* cont); +bool __esp_is_in_cont(cont_t* cont); // Repaint the stack from the current SP to the end, to allow individual // routines' stack usages to be calculated by re-painting, checking current diff --git a/cores/esp8266/cont_util.cpp b/cores/esp8266/cont_util.cpp index d21a064e35..75072913f9 100644 --- a/cores/esp8266/cont_util.cpp +++ b/cores/esp8266/cont_util.cpp @@ -62,7 +62,7 @@ int cont_get_free_stack(cont_t* cont) { return freeWords * 4; } -bool ICACHE_RAM_ATTR cont_can_yield(cont_t* cont) { +bool ICACHE_RAM_ATTR __esp_is_in_cont(cont_t* cont) { return !ETS_INTR_WITHINISR() && cont->pc_ret != 0 && cont->pc_yield == 0; } diff --git a/cores/esp8266/core_esp8266_i2s.cpp b/cores/esp8266/core_esp8266_i2s.cpp index dccd7c1df8..acba4648a6 100644 --- a/cores/esp8266/core_esp8266_i2s.cpp +++ b/cores/esp8266/core_esp8266_i2s.cpp @@ -304,7 +304,7 @@ static bool _i2s_write_sample(uint32_t sample, bool nb) { if (tx->slc_queue_len > 0) { break; } else { - optimistic_yield(10000); + yield(); } } } @@ -353,7 +353,7 @@ static uint16_t _i2s_write_buffer(int16_t *frames, uint16_t frame_count, bool mo if (tx->slc_queue_len > 0) { break; } else { - optimistic_yield(10000); + yield(); } } } @@ -413,7 +413,7 @@ bool i2s_read_sample(int16_t *left, int16_t *right, bool blocking) { if (rx->slc_queue_len > 0){ break; } else { - optimistic_yield(10000); + yield(); } } } diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index 417c3f26e8..9e3de91c5e 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -104,42 +104,40 @@ extern "C" void __preloop_update_frequency() { extern "C" void preloop_update_frequency() __attribute__((weak, alias("__preloop_update_frequency"))); -extern "C" bool can_yield() { - return cont_can_yield(g_pcont); +extern "C" bool esp_is_in_cont() { + return __esp_is_in_cont(g_pcont); } -static inline void esp_yield_within_cont() __attribute__((always_inline)); -static void esp_yield_within_cont() { +static inline void esp_suspend_from_cont_within_cont() __attribute__((always_inline)); +static void esp_suspend_from_cont_within_cont() { cont_yield(g_pcont); s_cycles_at_yield_start = ESP.getCycleCount(); run_scheduled_recurrent_functions(); } -extern "C" void __esp_yield() { - if (can_yield()) { - esp_yield_within_cont(); +extern "C" void esp_suspend_from_cont() { + if (esp_is_in_cont()) { + esp_suspend_from_cont_within_cont(); } } -extern "C" void esp_yield() __attribute__ ((weak, alias("__esp_yield"))); - -extern "C" IRAM_ATTR void esp_schedule() { +extern "C" IRAM_ATTR void esp_request_for_cont() { ets_post(LOOP_TASK_PRIORITY, 0, 0); } extern "C" void __yield() { - if (can_yield()) { - esp_schedule(); - esp_yield_within_cont(); + if (esp_is_in_cont()) { + esp_request_for_cont(); + esp_suspend_from_cont_within_cont(); } +#ifdef DEBUG_ESP_PORT else { - panic(); + DEBUGV("yield() should not be called from SYS ctx\n"); } +#endif } -extern "C" void yield(void) __attribute__ ((weak, alias("__yield"))); - -extern "C" void optimistic_yield(uint32_t interval_us) { +extern "C" void __optimistic_yield(uint32_t interval_us) { const uint32_t intvl_cycles = interval_us * #if defined(F_CPU) clockCyclesPerMicrosecond(); @@ -147,12 +145,18 @@ extern "C" void optimistic_yield(uint32_t interval_us) { ESP.getCpuFreqMHz(); #endif if ((ESP.getCycleCount() - s_cycles_at_yield_start) > intvl_cycles && - can_yield()) + esp_is_in_cont()) { - yield(); + __yield(); } } +extern "C" void optimistic_yield(uint32_t interval_us) __attribute__ ((alias("__optimistic_yield"))); +extern "C" void yield() { + // at least 1ms between two consecutive yields + __optimistic_yield(1000); +} + // Replace ets_intr_(un)lock with nestable versions extern "C" void IRAM_ATTR ets_intr_lock() { if (ets_intr_lock_stack_ptr < ETS_INTR_LOCK_NEST_MAX) @@ -161,6 +165,10 @@ extern "C" void IRAM_ATTR ets_intr_lock() { xt_rsil(3); } +extern "C" void esp_yield() __attribute__ ((alias("esp_suspend_from_cont"))); +extern "C" void esp_schedule() __attribute__ ((alias("esp_request_for_cont"))); +extern "C" bool can_yield() __attribute__ ((alias("esp_is_in_cont"))); + extern "C" void IRAM_ATTR ets_intr_unlock() { if (ets_intr_lock_stack_ptr > 0) xt_wsr_ps(ets_intr_lock_stack[--ets_intr_lock_stack_ptr]); @@ -201,7 +209,7 @@ static void loop_wrapper() { if (serialEventRun) { serialEventRun(); } - esp_schedule(); + esp_request_for_cont(); } static void loop_task(os_event_t *events) { @@ -260,7 +268,7 @@ void init_done() { gdb_init(); std::set_terminate(__unhandled_exception_cpp); do_global_ctors(); - esp_schedule(); + esp_request_for_cont(); ESP.setDramHeap(); } diff --git a/cores/esp8266/core_esp8266_wiring.cpp b/cores/esp8266/core_esp8266_wiring.cpp index 64b80aed10..3a3520d21c 100644 --- a/cores/esp8266/core_esp8266_wiring.cpp +++ b/cores/esp8266/core_esp8266_wiring.cpp @@ -24,12 +24,11 @@ #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_schedule(); -extern void esp_yield(); static os_timer_t delay_timer; static os_timer_t micros_overflow_timer; @@ -40,7 +39,7 @@ static uint32_t micros_overflow_count = 0; void delay_end(void* arg) { (void) arg; - esp_schedule(); + esp_request_for_cont(); } void __delay(unsigned long ms) { @@ -48,9 +47,9 @@ void __delay(unsigned long ms) { os_timer_setfn(&delay_timer, (os_timer_func_t*) &delay_end, 0); os_timer_arm(&delay_timer, ms, ONCE); } else { - esp_schedule(); + esp_request_for_cont(); } - esp_yield(); + esp_suspend_from_cont(); if(ms) { os_timer_disarm(&delay_timer); } diff --git a/cores/esp8266/core_esp8266_wiring_pulse.cpp b/cores/esp8266/core_esp8266_wiring_pulse.cpp index 8e124ac312..6fb5045749 100644 --- a/cores/esp8266/core_esp8266_wiring_pulse.cpp +++ b/cores/esp8266/core_esp8266_wiring_pulse.cpp @@ -31,7 +31,7 @@ extern uint32_t xthal_get_ccount(); if (xthal_get_ccount() - start_cycle_count > timeout_cycles) { \ return 0; \ } \ - optimistic_yield(5000); \ + yield(); \ } // max timeout is 27 seconds at 160MHz clock and 54 seconds at 80MHz clock diff --git a/cores/esp8266/coredecls.h b/cores/esp8266/coredecls.h index 7186662f0f..591d6e5bd1 100644 --- a/cores/esp8266/coredecls.h +++ b/cores/esp8266/coredecls.h @@ -12,9 +12,14 @@ extern "C" { #include #include // g_pcont declaration -bool can_yield(); -void esp_yield(); -void esp_schedule(); +bool esp_is_in_cont(); +void esp_suspend_from_cont(); +void esp_request_for_cont(); + +void esp_yield() __attribute__ ((deprecated("use esp_suspend_from_cont()"))); +void esp_schedule() __attribute__ ((deprecated("use esp_request_for_cont()"))); +bool can_yield() __attribute__ ((deprecated("esp_is_in_cont()"))); + void tune_timeshift64 (uint64_t now_us); void disable_extra4k_at_link_time (void) __attribute__((noinline)); bool sntp_set_timezone_in_seconds(int32_t timezone); diff --git a/cores/esp8266/flash_hal.cpp b/cores/esp8266/flash_hal.cpp index 986d3745d6..80939a7150 100644 --- a/cores/esp8266/flash_hal.cpp +++ b/cores/esp8266/flash_hal.cpp @@ -30,7 +30,7 @@ extern "C" { } int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) { - optimistic_yield(10000); + yield(); // We use flashRead overload that handles proper alignment if (ESP.flashRead(addr, dst, size)) { @@ -41,7 +41,7 @@ int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) { } int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t *src) { - optimistic_yield(10000); + yield(); // We use flashWrite overload that handles proper alignment if (ESP.flashWrite(addr, src, size)) { @@ -60,7 +60,7 @@ int32_t flash_hal_erase(uint32_t addr, uint32_t size) { const uint32_t sector = addr / SPI_FLASH_SEC_SIZE; const uint32_t sectorCount = size / SPI_FLASH_SEC_SIZE; for (uint32_t i = 0; i < sectorCount; ++i) { - optimistic_yield(10000); + yield(); if (!ESP.flashEraseSector(sector + i)) { DEBUGV("_spif_erase addr=%x size=%d i=%d\r\n", addr, size, i); return FLASH_HAL_ERASE_ERROR; diff --git a/cores/esp8266/uart.cpp b/cores/esp8266/uart.cpp index 47e7243abf..08cad49c22 100644 --- a/cores/esp8266/uart.cpp +++ b/cores/esp8266/uart.cpp @@ -508,7 +508,7 @@ uart_write(uart_t* uart, const char* buf, size_t size) const int uart_nr = uart->uart_nr; while (size--) { uart_do_write_char(uart_nr, pgm_read_byte(buf++)); - optimistic_yield(10000UL); + yield(); } return ret; diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index fb23b35e85..29237c4add 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -48,9 +48,7 @@ extern "C" { #include "WiFiUdp.h" #include "debug.h" #include "include/WiFiState.h" - -extern "C" void esp_schedule(); -extern "C" void esp_yield(); +#include // ----------------------------------------------------------------------------------------------------------------------- @@ -448,7 +446,7 @@ bool ESP8266WiFiGenericClass::mode(WiFiMode_t m, WiFiState* state) { //Only wait if in CONT context. If this were called from SYS, it's up to the user to serialize //tasks to wait correctly. constexpr unsigned int timeoutValue = 1000; //1 second - if(can_yield()) { + if(esp_is_in_cont()) { using oneShot = esp8266::polledTimeout::oneShotFastMs; oneShot timeout(timeoutValue); while(wifi_get_opmode() != (uint8) m && !timeout) @@ -716,7 +714,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 + esp_request_for_cont(); // interrupt delay in 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..0f8979251a 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp @@ -70,7 +70,7 @@ bool ESP8266WiFiSTAClass::beginWPSConfig(void) { return false; } - esp_yield(); + esp_suspend_from_cont(); // will resume when wifi_wps_status_cb fires return true; @@ -107,5 +107,5 @@ void wifi_wps_status_cb(wps_cb_status status) { } // TODO user function to get status - esp_schedule(); // resume beginWPSConfig + esp_request_for_cont(); // resume beginWPSConfig } diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index a75c115c26..afc531fd17 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 65878a3d5b..a067b9041f 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,7 +96,7 @@ int8_t ESP8266WiFiScanClass::scanNetworks(bool async, bool show_hidden, uint8 ch return WIFI_SCAN_RUNNING; } - esp_yield(); // will resume when _scanDone fires + esp_suspend_from_cont(); // will resume when _scanDone fires return ESP8266WiFiScanClass::_scanCount; } else { return WIFI_SCAN_FAILED; @@ -323,7 +321,7 @@ void ESP8266WiFiScanClass::_scanDone(void* result, int status) { ESP8266WiFiScanClass::_scanComplete = true; if(!ESP8266WiFiScanClass::_scanAsync) { - esp_schedule(); // resume scanNetworks + esp_request_for_cont(); // resume scanNetworks } else if (ESP8266WiFiScanClass::_onComplete) { ESP8266WiFiScanClass::_onComplete(ESP8266WiFiScanClass::_scanCount); ESP8266WiFiScanClass::_onComplete = nullptr; diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index 5aa09b8874..6b883d00a0 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -249,7 +249,7 @@ int WiFiClient::available() int result = _client->getSize(); if (!result) { - optimistic_yield(100); + yield(); } return result; } diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 48dc531a5f..c3b3c5f778 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -267,7 +267,7 @@ size_t WiFiClientSecureCtx::_write(const uint8_t *buf, size_t size, bool pmem) { do { // Ensure we yield if we need multiple fragments to avoid WDT if (sent_bytes) { - optimistic_yield(1000); + yield(); } // Get BearSSL to a state where we can send @@ -436,7 +436,7 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { esp8266::polledTimeout::oneShotMs loopTimeout(_timeout); for (int no_work = 0; blocking || no_work < 2;) { - optimistic_yield(100); + yield(); if (loopTimeout) { DEBUG_BSSL("_run_until: Timeout\n"); @@ -562,7 +562,7 @@ bool WiFiClientSecureCtx::_wait_for_handshake() { if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { _handshake_done = true; } - optimistic_yield(1000); + yield(); } return _handshake_done; } diff --git a/libraries/ESP8266WiFi/src/WiFiServer.cpp b/libraries/ESP8266WiFi/src/WiFiServer.cpp index 644f8b45d1..8a91b9e8b1 100644 --- a/libraries/ESP8266WiFi/src/WiFiServer.cpp +++ b/libraries/ESP8266WiFi/src/WiFiServer.cpp @@ -126,7 +126,7 @@ WiFiClient WiFiServer::available(byte* status) { return result; } - optimistic_yield(1000); + yield(); return WiFiClient(); } diff --git a/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp index 5f7bcac072..d5040a2785 100644 --- a/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp @@ -97,7 +97,7 @@ WiFiClientSecure WiFiServerSecure::available(uint8_t* status) { } // Something weird, return a no-op object - optimistic_yield(1000); + yield(); return WiFiClientSecure(); } diff --git a/libraries/ESP8266WiFi/src/WiFiUdp.cpp b/libraries/ESP8266WiFi/src/WiFiUdp.cpp index fc4bfe324e..74bded4b54 100644 --- a/libraries/ESP8266WiFi/src/WiFiUdp.cpp +++ b/libraries/ESP8266WiFi/src/WiFiUdp.cpp @@ -118,7 +118,7 @@ int WiFiUDP::available() { if (!result) { // yielding here will not make more data "available", // but it will prevent the system from going into WDT reset - optimistic_yield(1000); + yield(); } return result; @@ -195,7 +195,7 @@ int WiFiUDP::parsePacket() return 0; if (!_ctx->next()) { - optimistic_yield(100); + yield(); return 0; } diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index 8095e402a2..23d40f958b 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -26,9 +26,7 @@ class WiFiClient; typedef void (*discard_cb_t)(void*, ClientContext*); -extern "C" void esp_yield(); -extern "C" void esp_schedule(); - +#include #include "DataSource.h" bool getDefaultPrivateGlobalSyncValue (); @@ -448,7 +446,7 @@ class ClientContext if (_connect_pending || _send_waiting) { _send_waiting = false; _connect_pending = false; - esp_schedule(); // break delay in connect or _write_from_source + esp_request_for_cont(); // interrupt delay in connect or _write_from_source } } @@ -550,7 +548,7 @@ class ClientContext { if (_send_waiting) { _send_waiting = false; - esp_schedule(); // break delay in _write_from_source + esp_request_for_cont(); // interrupt delay in _write_from_source } } @@ -638,7 +636,7 @@ class ClientContext assert(pcb == _pcb); if (_connect_pending) { _connect_pending = false; - esp_schedule(); // break delay in connect + esp_request_for_cont(); // interrupt delay in connect } return ERR_OK; } diff --git a/libraries/ESP8266WiFi/src/include/UdpContext.h b/libraries/ESP8266WiFi/src/include/UdpContext.h index 0c43cd2adb..5e2453c585 100644 --- a/libraries/ESP8266WiFi/src/include/UdpContext.h +++ b/libraries/ESP8266WiFi/src/include/UdpContext.h @@ -23,12 +23,8 @@ class UdpContext; -extern "C" { -void esp_yield(); -void esp_schedule(); #include -} - +#include #include #include @@ -177,7 +173,7 @@ class UdpContext } // warning: handler is called from tcp stack context - // esp_yield and non-reentrant functions which depend on it will fail + // esp_suspend_from_cont and non-reentrant functions which depend on it will fail void onRx(rxhandler_t handler) { _on_rx = handler; } diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp index 677456fcc5..cce05afa26 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp @@ -702,7 +702,7 @@ bool MDNSResponder::_parseResponse(const MDNSResponder::stcMDNS_MsgHeader& p_Msg for (uint16_t qd=0; ((bDumpResult) && (qdflush(); diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index 3aa3604ab0..e3f123692a 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -226,7 +226,7 @@ int TwoWire::available(void) { // yielding here will not make more data "available", // but it will prevent the system from going into WDT reset - optimistic_yield(1000); + yield(); } return result; diff --git a/tests/host/common/Arduino.cpp b/tests/host/common/Arduino.cpp index c02457f1a5..ae5772465b 100644 --- a/tests/host/common/Arduino.cpp +++ b/tests/host/common/Arduino.cpp @@ -43,7 +43,7 @@ extern "C" void yield() { } -extern "C" bool can_yield() +extern "C" bool esp_is_in_cont() { return true; } @@ -53,7 +53,7 @@ extern "C" void optimistic_yield (uint32_t interval_us) (void)interval_us; } -extern "C" void esp_yield() +extern "C" void esp_suspend_from_cont() { } diff --git a/tests/host/common/include/ClientContext.h b/tests/host/common/include/ClientContext.h index 31366ac0dd..faeb1f2a2b 100644 --- a/tests/host/common/include/ClientContext.h +++ b/tests/host/common/include/ClientContext.h @@ -24,10 +24,8 @@ class ClientContext; class WiFiClient; -extern "C" void esp_yield(); -extern "C" void esp_schedule(); - #include +#include bool getDefaultPrivateGlobalSyncValue (); diff --git a/tests/host/common/include/UdpContext.h b/tests/host/common/include/UdpContext.h index bf104bc40f..7d1d37c4e5 100644 --- a/tests/host/common/include/UdpContext.h +++ b/tests/host/common/include/UdpContext.h @@ -112,7 +112,7 @@ class UdpContext } // warning: handler is called from tcp stack context - // esp_yield and non-reentrant functions which depend on it will fail + // esp_suspend_from_cont and non-reentrant functions which depend on it will fail void onRx(rxhandler_t handler) { _on_rx = handler; diff --git a/tests/host/common/user_interface.cpp b/tests/host/common/user_interface.cpp index b3a302df18..f86f6b103a 100644 --- a/tests/host/common/user_interface.cpp +++ b/tests/host/common/user_interface.cpp @@ -498,7 +498,7 @@ extern "C" (void)intr; } - void esp_schedule(void) + void esp_request_for_cont(void) { } From 0e22bb221b755b5ad525d13c4765c1a9e8f2f0a7 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 31 Mar 2021 02:00:59 +0200 Subject: [PATCH 2/7] update recent PRs to this API change --- cores/esp8266/StreamSend.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cores/esp8266/StreamSend.cpp b/cores/esp8266/StreamSend.cpp index f743889b62..a1eb5c86b7 100644 --- a/cores/esp8266/StreamSend.cpp +++ b/cores/esp8266/StreamSend.cpp @@ -130,7 +130,7 @@ size_t Stream::SendGenericPeekBuffer(Print* to, const ssize_t len, const int rea break; } - optimistic_yield(1000); + yield(); } if (getLastSendReport() == Report::Success && maxLen > 0) @@ -215,7 +215,7 @@ size_t Stream::SendGenericRegularUntil(Print* to, const ssize_t len, const int r break; } - optimistic_yield(1000); + yield(); } if (getLastSendReport() == Report::Success && maxLen > 0) @@ -308,7 +308,7 @@ size_t Stream::SendGenericRegular(Print* to, const ssize_t len, const esp8266::p break; } - optimistic_yield(1000); + yield(); } if (getLastSendReport() == Report::Success && maxLen > 0) From d6d1d81aed3432e5e6463ea44e1f72362116ba35 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 31 Mar 2021 02:47:24 +0200 Subject: [PATCH 3/7] undeprecate optimistic_yield() but ignore the parameter --- cores/esp8266/Arduino.h | 2 +- cores/esp8266/core_esp8266_main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index 083bbbbe76..2aab5770c9 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -192,7 +192,7 @@ void loop(void); void yield(void); -void optimistic_yield(uint32_t interval_us) __attribute__ ((deprecated("use yield()"))); +void optimistic_yield(uint32_t interval_us); #define _PORT_GPIO16 1 #define digitalPinToPort(pin) (((pin)==16)?(_PORT_GPIO16):(0)) diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index f6b8b9964b..b5350bcc8a 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -152,7 +152,7 @@ extern "C" void __optimistic_yield(uint32_t interval_us) { } } -extern "C" void optimistic_yield(uint32_t interval_us) __attribute__ ((alias("__optimistic_yield"))); +extern "C" void optimistic_yield(uint32_t interval_us) __attribute__ ((alias("yield"))); extern "C" void yield() { // at least 1ms between two consecutive yields __optimistic_yield(1000); From dabe25c4166b69758046d4907a3b1ae22983937e Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 31 Mar 2021 02:56:38 +0200 Subject: [PATCH 4/7] ditto --- cores/esp8266/core_esp8266_main.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index b5350bcc8a..c73f56c381 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -39,6 +39,8 @@ extern "C" { #include #include "core_esp8266_vm.h" +constexpr auto DelayBetweenRealYield_MS = 1000; + #define LOOP_TASK_PRIORITY 1 #define LOOP_QUEUE_SIZE 1 @@ -152,10 +154,14 @@ extern "C" void __optimistic_yield(uint32_t interval_us) { } } -extern "C" void optimistic_yield(uint32_t interval_us) __attribute__ ((alias("yield"))); +extern "C" void optimistic_yield(uint32_t interval_us) { + (void)interval_us; + __optimistic_yield(DelayBetweenRealYield_MS); +} + extern "C" void yield() { // at least 1ms between two consecutive yields - __optimistic_yield(1000); + __optimistic_yield(DelayBetweenRealYield_MS); } // Replace ets_intr_(un)lock with nestable versions From 3d89baf96ead8edd2ad2596d2715d000f42fe311 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 31 Mar 2021 12:42:15 +0200 Subject: [PATCH 5/7] unit in name was wrong (ms -> us) --- cores/esp8266/core_esp8266_main.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index c73f56c381..ecb0ed96db 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -39,7 +39,11 @@ extern "C" { #include #include "core_esp8266_vm.h" -constexpr auto DelayBetweenRealYield_MS = 1000; +/* + iaμs = 1000000 / (bwMiBitsps / 8 * 1024 * 1024 / packet-size-bytes) + => 1114 μs, 1460 bytes, 10Mibits/s +*/ +constexpr auto DelayBetweenRealYield_usec = 1000; #define LOOP_TASK_PRIORITY 1 @@ -156,12 +160,12 @@ extern "C" void __optimistic_yield(uint32_t interval_us) { extern "C" void optimistic_yield(uint32_t interval_us) { (void)interval_us; - __optimistic_yield(DelayBetweenRealYield_MS); + __optimistic_yield(DelayBetweenRealYield_usec); } extern "C" void yield() { // at least 1ms between two consecutive yields - __optimistic_yield(DelayBetweenRealYield_MS); + __optimistic_yield(DelayBetweenRealYield_usec); } // Replace ets_intr_(un)lock with nestable versions From a26b2d6256463995a43cb75ccad6cfe6e2f3f310 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 7 Apr 2021 23:32:12 +0200 Subject: [PATCH 6/7] restore legacy yield(), add minimal_yield(), highlight missing keywords --- cores/esp8266/Arduino.h | 4 ++-- cores/esp8266/HardwareSerial.cpp | 2 +- cores/esp8266/StreamSend.cpp | 6 +++--- cores/esp8266/core_esp8266_i2s.cpp | 6 +++--- cores/esp8266/core_esp8266_main.cpp | 9 +++++---- cores/esp8266/core_esp8266_wiring_pulse.cpp | 2 +- cores/esp8266/flash_hal.cpp | 6 +++--- cores/esp8266/uart.cpp | 2 +- libraries/ESP8266WiFi/src/WiFiClient.cpp | 2 +- libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp | 6 +++--- libraries/ESP8266WiFi/src/WiFiServer.cpp | 2 +- libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp | 2 +- libraries/ESP8266WiFi/src/WiFiUdp.cpp | 4 ++-- libraries/Wire/Wire.cpp | 2 +- libraries/esp8266/keywords.txt | 2 ++ 15 files changed, 30 insertions(+), 27 deletions(-) diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index 2aab5770c9..eea5205688 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -191,8 +191,8 @@ void setup(void); void loop(void); void yield(void); - -void optimistic_yield(uint32_t interval_us); +void minimal_yield(); +void optimistic_yield(uint32_t interval_us); // parameter ignored, is minimal_yield() #define _PORT_GPIO16 1 #define digitalPinToPort(pin) (((pin)==16)?(_PORT_GPIO16):(0)) diff --git a/cores/esp8266/HardwareSerial.cpp b/cores/esp8266/HardwareSerial.cpp index 715139d8c4..d34a12d9e0 100644 --- a/cores/esp8266/HardwareSerial.cpp +++ b/cores/esp8266/HardwareSerial.cpp @@ -109,7 +109,7 @@ int HardwareSerial::available(void) { int result = static_cast(uart_rx_available(_uart)); if (!result) { - yield(); + minimal_yield(); } return result; } diff --git a/cores/esp8266/StreamSend.cpp b/cores/esp8266/StreamSend.cpp index a1eb5c86b7..a4ba4d12bf 100644 --- a/cores/esp8266/StreamSend.cpp +++ b/cores/esp8266/StreamSend.cpp @@ -130,7 +130,7 @@ size_t Stream::SendGenericPeekBuffer(Print* to, const ssize_t len, const int rea break; } - yield(); + minimal_yield(); } if (getLastSendReport() == Report::Success && maxLen > 0) @@ -215,7 +215,7 @@ size_t Stream::SendGenericRegularUntil(Print* to, const ssize_t len, const int r break; } - yield(); + minimal_yield(); } if (getLastSendReport() == Report::Success && maxLen > 0) @@ -308,7 +308,7 @@ size_t Stream::SendGenericRegular(Print* to, const ssize_t len, const esp8266::p break; } - yield(); + minimal_yield(); } if (getLastSendReport() == Report::Success && maxLen > 0) diff --git a/cores/esp8266/core_esp8266_i2s.cpp b/cores/esp8266/core_esp8266_i2s.cpp index e98016c1f1..6b3a4e0bfe 100644 --- a/cores/esp8266/core_esp8266_i2s.cpp +++ b/cores/esp8266/core_esp8266_i2s.cpp @@ -313,7 +313,7 @@ static bool _i2s_write_sample(uint32_t sample, bool nb) { if (tx->slc_queue_len > 0) { break; } else { - yield(); + minimal_yield(); } } } @@ -362,7 +362,7 @@ static uint16_t _i2s_write_buffer(const int16_t *frames, uint16_t frame_count, b if (tx->slc_queue_len > 0) { break; } else { - yield(); + minimal_yield(); } } } @@ -422,7 +422,7 @@ bool i2s_read_sample(int16_t *left, int16_t *right, bool blocking) { if (rx->slc_queue_len > 0){ break; } else { - yield(); + minimal_yield(); } } } diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index ecb0ed96db..b88ba29be8 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -144,6 +144,8 @@ extern "C" void __yield() { #endif } +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 * #if defined(F_CPU) @@ -158,13 +160,12 @@ extern "C" void __optimistic_yield(uint32_t interval_us) { } } -extern "C" void optimistic_yield(uint32_t interval_us) { - (void)interval_us; +extern "C" void minimal_yield() { __optimistic_yield(DelayBetweenRealYield_usec); } -extern "C" void yield() { - // at least 1ms between two consecutive yields +extern "C" void optimistic_yield(uint32_t interval_us) { + (void)interval_us; __optimistic_yield(DelayBetweenRealYield_usec); } diff --git a/cores/esp8266/core_esp8266_wiring_pulse.cpp b/cores/esp8266/core_esp8266_wiring_pulse.cpp index 6fb5045749..1fd5f031d0 100644 --- a/cores/esp8266/core_esp8266_wiring_pulse.cpp +++ b/cores/esp8266/core_esp8266_wiring_pulse.cpp @@ -31,7 +31,7 @@ extern uint32_t xthal_get_ccount(); if (xthal_get_ccount() - start_cycle_count > timeout_cycles) { \ return 0; \ } \ - yield(); \ + minimal_yield(); \ } // max timeout is 27 seconds at 160MHz clock and 54 seconds at 80MHz clock diff --git a/cores/esp8266/flash_hal.cpp b/cores/esp8266/flash_hal.cpp index 80939a7150..6778634d84 100644 --- a/cores/esp8266/flash_hal.cpp +++ b/cores/esp8266/flash_hal.cpp @@ -30,7 +30,7 @@ extern "C" { } int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) { - yield(); + minimal_yield(); // We use flashRead overload that handles proper alignment if (ESP.flashRead(addr, dst, size)) { @@ -41,7 +41,7 @@ int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) { } int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t *src) { - yield(); + minimal_yield(); // We use flashWrite overload that handles proper alignment if (ESP.flashWrite(addr, src, size)) { @@ -60,7 +60,7 @@ int32_t flash_hal_erase(uint32_t addr, uint32_t size) { const uint32_t sector = addr / SPI_FLASH_SEC_SIZE; const uint32_t sectorCount = size / SPI_FLASH_SEC_SIZE; for (uint32_t i = 0; i < sectorCount; ++i) { - yield(); + minimal_yield(); if (!ESP.flashEraseSector(sector + i)) { DEBUGV("_spif_erase addr=%x size=%d i=%d\r\n", addr, size, i); return FLASH_HAL_ERASE_ERROR; diff --git a/cores/esp8266/uart.cpp b/cores/esp8266/uart.cpp index 83f3babb9a..7d6e163378 100644 --- a/cores/esp8266/uart.cpp +++ b/cores/esp8266/uart.cpp @@ -543,7 +543,7 @@ uart_write(uart_t* uart, const char* buf, size_t size) const int uart_nr = uart->uart_nr; while (size--) { uart_do_write_char(uart_nr, pgm_read_byte(buf++)); - yield(); + minimal_yield(); } return ret; diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index af0c902afa..49fc5d0fd6 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -256,7 +256,7 @@ int WiFiClient::available() int result = _client->getSize(); if (!result) { - yield(); + minimal_yield(); } return result; } diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 7d7367f6d7..7117758965 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -294,7 +294,7 @@ size_t WiFiClientSecureCtx::_write(const uint8_t *buf, size_t size, bool pmem) { do { // Ensure we yield if we need multiple fragments to avoid WDT if (sent_bytes) { - yield(); + minimal_yield(); } // Get BearSSL to a state where we can send @@ -479,7 +479,7 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { esp8266::polledTimeout::oneShotMs loopTimeout(_timeout); for (int no_work = 0; blocking || no_work < 2;) { - yield(); + minimal_yield(); if (loopTimeout) { DEBUG_BSSL("_run_until: Timeout\n"); @@ -605,7 +605,7 @@ bool WiFiClientSecureCtx::_wait_for_handshake() { if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { _handshake_done = true; } - yield(); + minimal_yield(); } return _handshake_done; } diff --git a/libraries/ESP8266WiFi/src/WiFiServer.cpp b/libraries/ESP8266WiFi/src/WiFiServer.cpp index 8a91b9e8b1..f1597038cf 100644 --- a/libraries/ESP8266WiFi/src/WiFiServer.cpp +++ b/libraries/ESP8266WiFi/src/WiFiServer.cpp @@ -126,7 +126,7 @@ WiFiClient WiFiServer::available(byte* status) { return result; } - yield(); + minimal_yield(); return WiFiClient(); } diff --git a/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp index 1eb8e9568a..15ea754b4c 100644 --- a/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp @@ -97,7 +97,7 @@ WiFiClientSecure WiFiServerSecure::available(uint8_t* status) { } // Something weird, return a no-op object - yield(); + minimal_yield(); return WiFiClientSecure(); } diff --git a/libraries/ESP8266WiFi/src/WiFiUdp.cpp b/libraries/ESP8266WiFi/src/WiFiUdp.cpp index 74bded4b54..c2f56e571c 100644 --- a/libraries/ESP8266WiFi/src/WiFiUdp.cpp +++ b/libraries/ESP8266WiFi/src/WiFiUdp.cpp @@ -118,7 +118,7 @@ int WiFiUDP::available() { if (!result) { // yielding here will not make more data "available", // but it will prevent the system from going into WDT reset - yield(); + minimal_yield(); } return result; @@ -195,7 +195,7 @@ int WiFiUDP::parsePacket() return 0; if (!_ctx->next()) { - yield(); + minimal_yield(); return 0; } diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index e3f123692a..d8d186b150 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -226,7 +226,7 @@ int TwoWire::available(void) { // yielding here will not make more data "available", // but it will prevent the system from going into WDT reset - yield(); + minimal_yield(); } return result; diff --git a/libraries/esp8266/keywords.txt b/libraries/esp8266/keywords.txt index 75afea9ade..259a308f61 100644 --- a/libraries/esp8266/keywords.txt +++ b/libraries/esp8266/keywords.txt @@ -27,6 +27,8 @@ ChaCha20Poly1305 KEYWORD1 # Methods and Functions (KEYWORD2) ####################################### +optimistic_yield KEYWORD2 +minimal_yield KEYWORD2 wdtEnable KEYWORD2 wdtDisable KEYWORD2 wdtFeed KEYWORD2 From d3c13e8547be5571ed674cc447644514c496c9f1 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 7 Apr 2021 23:47:02 +0200 Subject: [PATCH 7/7] emulation on host --- tests/host/common/Arduino.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/host/common/Arduino.cpp b/tests/host/common/Arduino.cpp index 69a7406e9e..0705d69cb9 100644 --- a/tests/host/common/Arduino.cpp +++ b/tests/host/common/Arduino.cpp @@ -48,6 +48,10 @@ extern "C" bool esp_is_in_cont() return true; } +extern "C" void minimal_yield () +{ +} + extern "C" void optimistic_yield (uint32_t interval_us) { (void)interval_us;