From 6086b6bd1b22e86825ec6dff82841f5e89a98c22 Mon Sep 17 00:00:00 2001 From: Dan Egnor Date: Thu, 7 Jul 2022 13:07:32 -0700 Subject: [PATCH 01/10] Compile error if CONFIG_FREERTOS_HZ != 1000 --- cores/esp32/esp32-hal-misc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cores/esp32/esp32-hal-misc.c b/cores/esp32/esp32-hal-misc.c index 1a71b0e86f9..ee8bab4f2fc 100644 --- a/cores/esp32/esp32-hal-misc.c +++ b/cores/esp32/esp32-hal-misc.c @@ -175,6 +175,10 @@ unsigned long ARDUINO_ISR_ATTR millis() void delay(uint32_t ms) { + _Static_assert( + portTICK_PERIOD_MS == 1, + "esp32-arduino requires 1ms tick (CONFIG_FREERTOS_HZ=1000)" + ); vTaskDelay(ms / portTICK_PERIOD_MS); } From 47a5c8c0eaa121f17ef179628d659cd8f768ffd5 Mon Sep 17 00:00:00 2001 From: Dan Egnor Date: Fri, 8 Jul 2022 10:30:20 -0700 Subject: [PATCH 02/10] add a check at the CMake level, per feedback --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2518b0be093..83db9c91a53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -216,7 +216,7 @@ idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_incl if(NOT CONFIG_FREERTOS_HZ EQUAL 1000 AND NOT "$ENV{ARDUINO_SKIP_TICK_CHECK}") # See delay() in cores/esp32/esp32-hal-misc.c. message(FATAL_ERROR "esp32-arduino requires CONFIG_FREERTOS_HZ=1000 " - "(currently ${CONFIG_FREERTOS_HZ})") + "(currently ${CONFIG_FREERTOS_HZ}") endif() string(TOUPPER ${CONFIG_ARDUINO_VARIANT} idf_target_caps) From 9d9617b1e915a00bb4c02873d2dfc83f5ab7b4b0 Mon Sep 17 00:00:00 2001 From: Dan Egnor Date: Fri, 8 Jul 2022 10:31:18 -0700 Subject: [PATCH 03/10] fix a punctuation glitch --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 83db9c91a53..2518b0be093 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -216,7 +216,7 @@ idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_incl if(NOT CONFIG_FREERTOS_HZ EQUAL 1000 AND NOT "$ENV{ARDUINO_SKIP_TICK_CHECK}") # See delay() in cores/esp32/esp32-hal-misc.c. message(FATAL_ERROR "esp32-arduino requires CONFIG_FREERTOS_HZ=1000 " - "(currently ${CONFIG_FREERTOS_HZ}") + "(currently ${CONFIG_FREERTOS_HZ})") endif() string(TOUPPER ${CONFIG_ARDUINO_VARIANT} idf_target_caps) From d330c0088fa1b0891d05c322054f6635e15ce1ec Mon Sep 17 00:00:00 2001 From: Dan Egnor Date: Wed, 24 Aug 2022 18:06:23 -0400 Subject: [PATCH 04/10] Remove `_Static_assert` per feedback --- cores/esp32/esp32-hal-misc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cores/esp32/esp32-hal-misc.c b/cores/esp32/esp32-hal-misc.c index ee8bab4f2fc..1a71b0e86f9 100644 --- a/cores/esp32/esp32-hal-misc.c +++ b/cores/esp32/esp32-hal-misc.c @@ -175,10 +175,6 @@ unsigned long ARDUINO_ISR_ATTR millis() void delay(uint32_t ms) { - _Static_assert( - portTICK_PERIOD_MS == 1, - "esp32-arduino requires 1ms tick (CONFIG_FREERTOS_HZ=1000)" - ); vTaskDelay(ms / portTICK_PERIOD_MS); } From 035aed0132f6e046c88e52edd08765bc25ab46da Mon Sep 17 00:00:00 2001 From: Dan Egnor Date: Sat, 15 Apr 2023 21:06:28 -0700 Subject: [PATCH 05/10] add documentation on threading issues with WiFi.onEvent() --- .../Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino | 11 +++++++++-- libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino | 9 ++++++++- .../RainMaker/examples/RMakerCustom/RMakerCustom.ino | 3 +++ .../RMakerCustomAirCooler/RMakerCustomAirCooler.ino | 3 +++ .../RMakerSonoffDualR3/RMakerSonoffDualR3.ino | 3 +++ .../RainMaker/examples/RMakerSwitch/RMakerSwitch.ino | 3 +++ .../WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino | 2 ++ libraries/WiFi/examples/WPS/WPS.ino | 4 ++++ .../WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino | 4 ++++ .../examples/WiFiClientEvents/WiFiClientEvents.ino | 3 +++ libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino | 6 ++++-- .../WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino | 5 ++++- libraries/WiFiProv/examples/WiFiProv/README.md | 7 ++++++- libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino | 4 ++++ 14 files changed, 60 insertions(+), 7 deletions(-) diff --git a/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino b/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino index a3651d9ef98..d54534c0967 100644 --- a/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino +++ b/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino @@ -7,12 +7,19 @@ static bool eth_connected = false; +// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event) { switch (event) { case ARDUINO_EVENT_ETH_START: Serial.println("ETH Started"); - //set eth hostname here + + // FIXME: It's iffy to call ETH.setHostname() from the event thread, + // but is traditional for unknown reasons, likely init sequencing needs. + // See: https://github.com/espressif/arduino-esp32/issues/3398 + // Also: https://github.com/espressif/arduino-esp32/issues/5733 ETH.setHostname("esp32-ethernet"); break; case ARDUINO_EVENT_ETH_CONNECTED: @@ -67,7 +74,7 @@ void testClient(const char * host, uint16_t port) void setup() { Serial.begin(115200); - WiFi.onEvent(WiFiEvent); + WiFi.onEvent(WiFiEvent); // See warnings in WiFiEvent() above. ETH.begin(); } diff --git a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino index c144b6eeb00..1e5671a697a 100644 --- a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino +++ b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino @@ -13,12 +13,19 @@ static bool eth_connected = false; +// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event) { switch (event) { case ARDUINO_EVENT_ETH_START: Serial.println("ETH Started"); - //set eth hostname here + + // FIXME: It's iffy to call ETH.setHostname() from the event thread, + // but is traditional for unknown reasons, likely init sequencing needs. + // See: https://github.com/espressif/arduino-esp32/issues/3398 + // Also: https://github.com/espressif/arduino-esp32/issues/5733 ETH.setHostname("esp32-ethernet"); break; case ARDUINO_EVENT_ETH_CONNECTED: diff --git a/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino b/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino index 04492039519..4af8318952c 100644 --- a/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino +++ b/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino @@ -24,6 +24,9 @@ bool dimmer_state = true; // But, you can also define custom devices using the 'Device' base class object, as shown here static Device *my_device = NULL; +// WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void sysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { diff --git a/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino b/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino index 04c070cf21b..f74a5566cab 100644 --- a/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino +++ b/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino @@ -41,6 +41,9 @@ bool power_state = true; // But, you can also define custom devices using the 'Device' base class object, as shown here static Device *my_device = NULL; +// WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void sysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { diff --git a/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino b/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino index 4cc78f2a0b3..06896bec4a6 100644 --- a/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino +++ b/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino @@ -34,6 +34,9 @@ LightSwitch switch_ch2 = {gpio_switch2, false}; static Switch *my_switch1 = NULL; static Switch *my_switch2 = NULL; +// WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void sysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { diff --git a/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino b/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino index 688feed9bf7..8df23cf3fbb 100644 --- a/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino +++ b/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino @@ -25,6 +25,9 @@ bool switch_state = true; // fan, temperaturesensor. static Switch *my_switch = NULL; +// WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void sysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { diff --git a/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino b/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino index 91c1ba45cb4..879623593dc 100644 --- a/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino +++ b/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino @@ -28,6 +28,8 @@ xSemaphoreHandle ftmSemaphore; bool ftmSuccess = true; // FTM report handler with the calculated data from the round trip +// WARNING: This function is called from a separate FreeRTOS task (thread)! +// See: https://github.com/espressif/arduino-esp32/issues/6947 void onFtmReport(arduino_event_t *event) { const char * status_str[5] = {"SUCCESS", "UNSUPPORTED", "CONF_REJECTED", "NO_RESPONSE", "FAIL"}; wifi_event_ftm_report_t * report = &event->event_info.wifi_ftm_report; diff --git a/libraries/WiFi/examples/WPS/WPS.ino b/libraries/WiFi/examples/WPS/WPS.ino index 606c7787f93..29a1cc6336c 100644 --- a/libraries/WiFi/examples/WPS/WPS.ino +++ b/libraries/WiFi/examples/WPS/WPS.ino @@ -61,7 +61,11 @@ String wpspin2string(uint8_t a[]){ return (String)wps_pin; } +// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event, arduino_event_info_t info){ + // FIXME: It's iffy to call WiFi methods from the event thread. switch(event){ case ARDUINO_EVENT_WIFI_STA_START: Serial.println("Station Mode Started"); diff --git a/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino b/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino index 9f56bb9f786..d04aebab029 100644 --- a/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino +++ b/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino @@ -73,7 +73,11 @@ void onButton(){ delay(100); } +// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event){ + // FIXME: It's iffy to call Wifi methods from the event thread. switch(event) { case ARDUINO_EVENT_WIFI_AP_START: Serial.println("AP Started"); diff --git a/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino b/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino index e705b89e171..e11ed3fcb80 100644 --- a/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino +++ b/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino @@ -42,6 +42,9 @@ const char* ssid = "your-ssid"; const char* password = "your-password"; +// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event) { Serial.printf("[WiFi-event] event: %d\n", event); diff --git a/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino b/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino index 6be60fc2581..41a41756b7f 100644 --- a/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino +++ b/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino @@ -64,16 +64,18 @@ void wifiConnectedLoop(){ delay(9000); } +// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event){ + // FIXME: It's iffy to call WiFi methods from the event thread. switch(event) { - case ARDUINO_EVENT_WIFI_AP_START: //can set ap hostname here WiFi.softAPsetHostname(AP_SSID); //enable ap ipv6 here WiFi.softAPenableIpV6(); break; - case ARDUINO_EVENT_WIFI_STA_START: //set sta hostname here WiFi.setHostname(AP_SSID); diff --git a/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino b/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino index 6fd07caf44e..44e67d059af 100644 --- a/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino +++ b/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino @@ -55,8 +55,11 @@ void connectToWiFi(const char * ssid, const char * pwd){ Serial.println("Waiting for WIFI connection..."); } -//wifi event handler +// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event){ + // FIXME: It's iffy to call udp and Wifi methods from the event thread. switch(event) { case ARDUINO_EVENT_WIFI_STA_GOT_IP: //When connected set diff --git a/libraries/WiFiProv/examples/WiFiProv/README.md b/libraries/WiFiProv/examples/WiFiProv/README.md index bae3eadf297..22c435de86e 100644 --- a/libraries/WiFiProv/examples/WiFiProv/README.md +++ b/libraries/WiFiProv/examples/WiFiProv/README.md @@ -10,7 +10,12 @@ This example allows Arduino user to choose either BLE or SOFTAP as a mode of tra ## WiFi.onEvent() -Using this API user can register to receive WiFi Events and Provisioning Events +Using this API user can register to receive WiFi Events and Provisioning Events. + +WARNING: The event handler is called from a separate FreeRTOS task (thread)! +Serial.print*() is OK but most other library calls are NOT OK unless +actions taken to ensure thread safety. +[https://github.com/espressif/arduino-esp32/issues/6947](See bug 6947.) ## WiFi.beginProvision() diff --git a/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino b/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino index 9d6de5f00f3..7b20a94e8c4 100644 --- a/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino +++ b/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino @@ -1,5 +1,9 @@ #include "WiFiProv.h" #include "WiFi.h" + +// WARNING: SysProvEvent is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void SysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { From f127b82bd032aaa713322ba635f254e811b4c45a Mon Sep 17 00:00:00 2001 From: Dan Egnor Date: Sat, 15 Apr 2023 22:29:32 -0700 Subject: [PATCH 06/10] more comments --- libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino | 2 +- .../RainMaker/examples/RMakerCustom/RMakerCustom.ino | 2 +- .../RMakerCustomAirCooler/RMakerCustomAirCooler.ino | 2 +- .../examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino | 2 +- .../RainMaker/examples/RMakerSwitch/RMakerSwitch.ino | 2 +- .../WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino | 2 +- libraries/WiFi/examples/WPS/WPS.ino | 2 +- .../examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino | 2 +- .../WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino | 8 +++++++- 9 files changed, 15 insertions(+), 9 deletions(-) diff --git a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino index 1e5671a697a..1a777b10929 100644 --- a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino +++ b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino @@ -80,7 +80,7 @@ void testClient(const char * host, uint16_t port) void setup() { Serial.begin(115200); - WiFi.onEvent(WiFiEvent); + WiFi.onEvent(WiFiEvent); // See warnings in WiFiEvent() above. ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE); } diff --git a/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino b/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino index 4af8318952c..8782a1e4d29 100644 --- a/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino +++ b/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino @@ -108,7 +108,7 @@ void setup() RMaker.start(); - WiFi.onEvent(sysProvEvent); + WiFi.onEvent(sysProvEvent); // See warnings in sysProvEvent() above. #if CONFIG_IDF_TARGET_ESP32S2 WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name); #else diff --git a/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino b/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino index f74a5566cab..6ebf2086c0f 100644 --- a/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino +++ b/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino @@ -174,7 +174,7 @@ void setup() RMaker.start(); - WiFi.onEvent(sysProvEvent); + WiFi.onEvent(sysProvEvent); // See warnings in WiFiEvent() above. #if CONFIG_IDF_TARGET_ESP32S2 WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name); #else diff --git a/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino b/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino index 06896bec4a6..01fa109e054 100644 --- a/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino +++ b/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino @@ -163,7 +163,7 @@ void setup() Serial.printf("\nStarting ESP-RainMaker\n"); RMaker.start(); - WiFi.onEvent(sysProvEvent); + WiFi.onEvent(sysProvEvent); // See warnings in sysProvEvent() above. #if CONFIG_IDF_TARGET_ESP32 WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name); #else diff --git a/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino b/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino index 8df23cf3fbb..5e67d229d29 100644 --- a/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino +++ b/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino @@ -110,7 +110,7 @@ void setup() RMaker.start(); - WiFi.onEvent(sysProvEvent); + WiFi.onEvent(sysProvEvent); // See warnings in sysProvEvent() above. #if CONFIG_IDF_TARGET_ESP32S2 WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name); diff --git a/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino b/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino index 879623593dc..4ca262df1be 100644 --- a/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino +++ b/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino @@ -64,7 +64,7 @@ void setup() { // Create binary semaphore (initialized taken and can be taken/given from any thread/ISR) ftmSemaphore = xSemaphoreCreateBinary(); - // Listen for FTM Report events + // Listen for FTM Report events. (See warnings in onFtmReport() above.) WiFi.onEvent(onFtmReport, ARDUINO_EVENT_WIFI_FTM_REPORT); // Connect to AP that has FTM Enabled diff --git a/libraries/WiFi/examples/WPS/WPS.ino b/libraries/WiFi/examples/WPS/WPS.ino index 29a1cc6336c..71d9b3ce250 100644 --- a/libraries/WiFi/examples/WPS/WPS.ino +++ b/libraries/WiFi/examples/WPS/WPS.ino @@ -107,7 +107,7 @@ void setup(){ Serial.begin(115200); delay(10); Serial.println(); - WiFi.onEvent(WiFiEvent); + WiFi.onEvent(WiFiEvent); // See warnings in WiFiEvent() above. WiFi.mode(WIFI_MODE_STA); Serial.println("Starting WPS"); wpsInitConfig(); diff --git a/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino b/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino index d04aebab029..5031f8d96c2 100644 --- a/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino +++ b/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino @@ -116,7 +116,7 @@ void WiFiEvent(WiFiEvent_t event){ void setup() { Serial.begin(115200); pinMode(0, INPUT_PULLUP); - WiFi.onEvent(WiFiEvent); + WiFi.onEvent(WiFiEvent); // See warnings in WiFiEvent() above. Serial.print("ESP32 SDK: "); Serial.println(ESP.getSdkVersion()); Serial.println("Press the button to select the next mode"); diff --git a/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino b/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino index e11ed3fcb80..48f74c1eaa2 100644 --- a/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino +++ b/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino @@ -42,7 +42,7 @@ const char* ssid = "your-ssid"; const char* password = "your-password"; -// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! +// WARNING: This function is called from a separate FreeRTOS task (thread)! // Serial.print*() is OK but most other library calls are NOT OK. // See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event) @@ -135,6 +135,9 @@ void WiFiEvent(WiFiEvent_t event) default: break; }} +// WARNING: This function is called from a separate FreeRTOS task (thread)! +// Serial.print*() is OK but most other library calls are NOT OK. +// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) { Serial.println("WiFi connected"); @@ -152,6 +155,9 @@ void setup() delay(1000); // Examples of different ways to register wifi events + // WARNING: These handlers are called from a separate FreeRTOS thread. + // Serial.print*() is OK but most other library calls are NOT OK. + // See: https://github.com/espressif/arduino-esp32/issues/6947 WiFi.onEvent(WiFiEvent); WiFi.onEvent(WiFiGotIP, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_GOT_IP); WiFiEventId_t eventID = WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info){ From c314b2fac2938da24fc8e3b440932039f1fb34b4 Mon Sep 17 00:00:00 2001 From: Dan Egnor Date: Thu, 20 Apr 2023 23:18:01 -0700 Subject: [PATCH 07/10] thin out comments, add docs --- docs/source/api/wifi.rst | 107 +++++++++++++++++- .../examples/ETH_LAN8720/ETH_LAN8720.ino | 11 +- .../examples/ETH_TLK110/ETH_TLK110.ino | 11 +- .../examples/RMakerCustom/RMakerCustom.ino | 4 +- .../RMakerCustomAirCooler.ino | 4 +- .../RMakerSonoffDualR3/RMakerSonoffDualR3.ino | 4 +- .../examples/RMakerSwitch/RMakerSwitch.ino | 4 +- .../FTM/FTM_Initiator/FTM_Initiator.ino | 3 +- libraries/WiFi/examples/WPS/WPS.ino | 5 +- .../WiFiBlueToothSwitch.ino | 5 +- .../WiFiClientEvents/WiFiClientEvents.ino | 11 +- libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino | 5 +- .../examples/WiFiUDPClient/WiFiUDPClient.ino | 5 +- .../WiFiProv/examples/WiFiProv/README.md | 8 +- .../WiFiProv/examples/WiFiProv/WiFiProv.ino | 2 - 15 files changed, 124 insertions(+), 65 deletions(-) diff --git a/docs/source/api/wifi.rst b/docs/source/api/wifi.rst index 0dbfba2e683..4849c3d1946 100644 --- a/docs/source/api/wifi.rst +++ b/docs/source/api/wifi.rst @@ -50,6 +50,102 @@ Common API Here are the common APIs that are used for both modes, AP and STA. +onEvent (and removeEvent) +************************* + +Registers a caller-supplied function to be called when WiFi events +occur. Several forms are available. + +Function pointer callback taking the event ID: + +.. code-block:: arduino + + typedef void (*WiFiEventCb)(arduino_event_id_t); + wifi_event_id_t onEvent(WiFiEventCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + +Function pointer callback taking an event-ID-and-info struct: + +.. code-block:: arduino + + typedef struct{ + arduino_event_id_t event_id; + arduino_event_info_t event_info; + } arduino_event_t; + + typedef void (*WiFiEventSysCb)(arduino_event_t *); + wifi_event_id_t onEvent(WiFiEventSysCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + +Callback using ``std::function`` taking event ID and info separately: + +.. code-block:: arduino + + typedef std::function WiFiEventFuncCb; + wifi_event_id_t onEvent(WiFiEventFuncCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + +A similar set of functions are available to remove callbacks: + +.. code-block:: arduino + + void removeEvent(WiFiEventCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + void removeEvent(WiFiEventSysCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + void removeEvent(wifi_event_id_t = ARDUINO_EVENT_MAX); + +In all cases, the subscribing function accepts an optional event type to +invoke the callback only for that specific event; with the default +``ARDUINO_EVENT_MAX``, the callback will be invoked for all WiFi events. + +Any callback function is given the event type in a parameter. +Some of the possible callback function formats also take an +``arduino_event_info_t`` (or use ``arduino_event_t`` which includes both +ID and info) which is a union of structs with additional information +about different event types. + +See +`WiFiGeneric.h `_ +for the list of event types and "info" substructures, and also see a full +example of event handling: `events example`_. + +.. warning:: + + Event callback functions are invoked on a separate + `thread `_ + (`FreeRTOS task `_) + independent of the main application thread that runs ``setup()`` and + ``loop()``. Callback functions must therefore be + `thread-safe `_; + they must not access shared/global variables directly without locking, + and must only call similarly thread-safe functions. + + Some core operations like ``Serial.print()`` are thread-safe but many + functions are not. Notably, ``WiFi.onEvent()`` and ``WiFi.removeEvent()`` + are not thread-safe and should never be invoked from a callback thread. + +setHostname (and getHostname) +***************************** + +Sets the name the DHCP client uses to identify itself. In a typical network +setup this will be the name that shows up in the Wi-Fi router's device list. +The hostname must be no longer than 32 characters. + +.. code-block:: arduino + + setHostname(const char *hostname); + +If the hostname is never specified, a default one will be assigned based +on the chip type and MAC address. The current hostname (default or custom) +may be retrieved: + +.. code-block:: arduino + + const char *getHostname(); + +.. warning:: + + The ``setHostname()`` function must be called BEFORE WiFi is started with + ``WiFi.begin()``, ``WiFi.softAP()``, ``WiFi.mode()``, or ``WiFi.run()``. + To change the name, reset WiFi with ``WiFi.mode(WIFI_MODE_NULL)``, + then proceed with ``WiFi.setHostname(...)`` and restart WiFi from scratch. + useStaticBuffers **************** @@ -543,6 +639,8 @@ To see how to use the ``WiFiScan``, take a look at the ``WiFiScan.ino`` example Examples -------- +`Complete list of WiFi examples `_. + .. _ap example: Wi-Fi AP Example @@ -559,5 +657,10 @@ Wi-Fi STA Example .. literalinclude:: ../../../libraries/WiFi/examples/WiFiClient/WiFiClient.ino :language: arduino -References ----------- +.. _events example: + +Wi-Fi Events Example +******************** + +.. literalinclude:: ../../../libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino + :language: arduino diff --git a/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino b/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino index d54534c0967..db99b75de20 100644 --- a/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino +++ b/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino @@ -8,18 +8,13 @@ static bool eth_connected = false; // WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event) { switch (event) { case ARDUINO_EVENT_ETH_START: Serial.println("ETH Started"); - - // FIXME: It's iffy to call ETH.setHostname() from the event thread, - // but is traditional for unknown reasons, likely init sequencing needs. - // See: https://github.com/espressif/arduino-esp32/issues/3398 - // Also: https://github.com/espressif/arduino-esp32/issues/5733 + // The hostname must be set after the interface is started, but needs + // to be set before DHCP, so set it from the event handler thread. ETH.setHostname("esp32-ethernet"); break; case ARDUINO_EVENT_ETH_CONNECTED: @@ -74,7 +69,7 @@ void testClient(const char * host, uint16_t port) void setup() { Serial.begin(115200); - WiFi.onEvent(WiFiEvent); // See warnings in WiFiEvent() above. + WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread. ETH.begin(); } diff --git a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino index 1a777b10929..e7c1a540b92 100644 --- a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino +++ b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino @@ -14,18 +14,13 @@ static bool eth_connected = false; // WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event) { switch (event) { case ARDUINO_EVENT_ETH_START: Serial.println("ETH Started"); - - // FIXME: It's iffy to call ETH.setHostname() from the event thread, - // but is traditional for unknown reasons, likely init sequencing needs. - // See: https://github.com/espressif/arduino-esp32/issues/3398 - // Also: https://github.com/espressif/arduino-esp32/issues/5733 + // The hostname must be set after the interface is started, but needs + // to be set before DHCP, so set it from the event handler thread. ETH.setHostname("esp32-ethernet"); break; case ARDUINO_EVENT_ETH_CONNECTED: @@ -80,7 +75,7 @@ void testClient(const char * host, uint16_t port) void setup() { Serial.begin(115200); - WiFi.onEvent(WiFiEvent); // See warnings in WiFiEvent() above. + WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread. ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE); } diff --git a/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino b/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino index 8782a1e4d29..c7c63c51ed8 100644 --- a/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino +++ b/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino @@ -25,8 +25,6 @@ bool dimmer_state = true; static Device *my_device = NULL; // WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void sysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { @@ -108,7 +106,7 @@ void setup() RMaker.start(); - WiFi.onEvent(sysProvEvent); // See warnings in sysProvEvent() above. + WiFi.onEvent(sysProvEvent); // Will call sysProvEvent() from another thread. #if CONFIG_IDF_TARGET_ESP32S2 WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name); #else diff --git a/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino b/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino index 6ebf2086c0f..ebebb984825 100644 --- a/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino +++ b/libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino @@ -42,8 +42,6 @@ bool power_state = true; static Device *my_device = NULL; // WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void sysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { @@ -174,7 +172,7 @@ void setup() RMaker.start(); - WiFi.onEvent(sysProvEvent); // See warnings in WiFiEvent() above. + WiFi.onEvent(sysProvEvent); // Will call sysProvEvent() from another thread. #if CONFIG_IDF_TARGET_ESP32S2 WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name); #else diff --git a/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino b/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino index 01fa109e054..f69ba14f741 100644 --- a/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino +++ b/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino @@ -35,8 +35,6 @@ static Switch *my_switch1 = NULL; static Switch *my_switch2 = NULL; // WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void sysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { @@ -163,7 +161,7 @@ void setup() Serial.printf("\nStarting ESP-RainMaker\n"); RMaker.start(); - WiFi.onEvent(sysProvEvent); // See warnings in sysProvEvent() above. + WiFi.onEvent(sysProvEvent); // Will call sysProvEvent() from another thread. #if CONFIG_IDF_TARGET_ESP32 WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name); #else diff --git a/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino b/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino index 5e67d229d29..270612774cd 100644 --- a/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino +++ b/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino @@ -26,8 +26,6 @@ bool switch_state = true; static Switch *my_switch = NULL; // WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void sysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { @@ -110,7 +108,7 @@ void setup() RMaker.start(); - WiFi.onEvent(sysProvEvent); // See warnings in sysProvEvent() above. + WiFi.onEvent(sysProvEvent); // Will call sysProvEvent() from another thread. #if CONFIG_IDF_TARGET_ESP32S2 WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name); diff --git a/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino b/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino index 4ca262df1be..7ffc5c7e9dd 100644 --- a/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino +++ b/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino @@ -29,7 +29,6 @@ bool ftmSuccess = true; // FTM report handler with the calculated data from the round trip // WARNING: This function is called from a separate FreeRTOS task (thread)! -// See: https://github.com/espressif/arduino-esp32/issues/6947 void onFtmReport(arduino_event_t *event) { const char * status_str[5] = {"SUCCESS", "UNSUPPORTED", "CONF_REJECTED", "NO_RESPONSE", "FAIL"}; wifi_event_ftm_report_t * report = &event->event_info.wifi_ftm_report; @@ -64,7 +63,7 @@ void setup() { // Create binary semaphore (initialized taken and can be taken/given from any thread/ISR) ftmSemaphore = xSemaphoreCreateBinary(); - // Listen for FTM Report events. (See warnings in onFtmReport() above.) + // Will call onFtmReport() from another thread with FTM Report events. WiFi.onEvent(onFtmReport, ARDUINO_EVENT_WIFI_FTM_REPORT); // Connect to AP that has FTM Enabled diff --git a/libraries/WiFi/examples/WPS/WPS.ino b/libraries/WiFi/examples/WPS/WPS.ino index 71d9b3ce250..687247aa8f8 100644 --- a/libraries/WiFi/examples/WPS/WPS.ino +++ b/libraries/WiFi/examples/WPS/WPS.ino @@ -62,10 +62,7 @@ String wpspin2string(uint8_t a[]){ } // WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event, arduino_event_info_t info){ - // FIXME: It's iffy to call WiFi methods from the event thread. switch(event){ case ARDUINO_EVENT_WIFI_STA_START: Serial.println("Station Mode Started"); @@ -107,7 +104,7 @@ void setup(){ Serial.begin(115200); delay(10); Serial.println(); - WiFi.onEvent(WiFiEvent); // See warnings in WiFiEvent() above. + WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread. WiFi.mode(WIFI_MODE_STA); Serial.println("Starting WPS"); wpsInitConfig(); diff --git a/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino b/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino index 5031f8d96c2..771a531a480 100644 --- a/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino +++ b/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino @@ -74,10 +74,7 @@ void onButton(){ } // WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event){ - // FIXME: It's iffy to call Wifi methods from the event thread. switch(event) { case ARDUINO_EVENT_WIFI_AP_START: Serial.println("AP Started"); @@ -116,7 +113,7 @@ void WiFiEvent(WiFiEvent_t event){ void setup() { Serial.begin(115200); pinMode(0, INPUT_PULLUP); - WiFi.onEvent(WiFiEvent); // See warnings in WiFiEvent() above. + WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread. Serial.print("ESP32 SDK: "); Serial.println(ESP.getSdkVersion()); Serial.println("Press the button to select the next mode"); diff --git a/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino b/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino index 48f74c1eaa2..3d00dd32690 100644 --- a/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino +++ b/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino @@ -41,10 +41,7 @@ const char* ssid = "your-ssid"; const char* password = "your-password"; - // WARNING: This function is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event) { Serial.printf("[WiFi-event] event: %d\n", event); @@ -136,8 +133,6 @@ void WiFiEvent(WiFiEvent_t event) }} // WARNING: This function is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) { Serial.println("WiFi connected"); @@ -154,10 +149,8 @@ void setup() delay(1000); - // Examples of different ways to register wifi events - // WARNING: These handlers are called from a separate FreeRTOS thread. - // Serial.print*() is OK but most other library calls are NOT OK. - // See: https://github.com/espressif/arduino-esp32/issues/6947 + // Examples of different ways to register wifi events; + // these handlers will be called from another thread. WiFi.onEvent(WiFiEvent); WiFi.onEvent(WiFiGotIP, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_GOT_IP); WiFiEventId_t eventID = WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info){ diff --git a/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino b/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino index 41a41756b7f..3dcba56eec2 100644 --- a/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino +++ b/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino @@ -65,10 +65,7 @@ void wifiConnectedLoop(){ } // WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event){ - // FIXME: It's iffy to call WiFi methods from the event thread. switch(event) { case ARDUINO_EVENT_WIFI_AP_START: //can set ap hostname here @@ -108,7 +105,7 @@ void WiFiEvent(WiFiEvent_t event){ void setup(){ Serial.begin(115200); WiFi.disconnect(true); - WiFi.onEvent(WiFiEvent); + WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread. WiFi.mode(WIFI_MODE_APSTA); WiFi.softAP(AP_SSID); WiFi.begin(STA_SSID, STA_PASS); diff --git a/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino b/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino index 44e67d059af..7c5ebc39196 100644 --- a/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino +++ b/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino @@ -47,7 +47,7 @@ void connectToWiFi(const char * ssid, const char * pwd){ // delete old config WiFi.disconnect(true); //register event handler - WiFi.onEvent(WiFiEvent); + WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread. //Initiate connection WiFi.begin(ssid, pwd); @@ -56,10 +56,7 @@ void connectToWiFi(const char * ssid, const char * pwd){ } // WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void WiFiEvent(WiFiEvent_t event){ - // FIXME: It's iffy to call udp and Wifi methods from the event thread. switch(event) { case ARDUINO_EVENT_WIFI_STA_GOT_IP: //When connected set diff --git a/libraries/WiFiProv/examples/WiFiProv/README.md b/libraries/WiFiProv/examples/WiFiProv/README.md index 22c435de86e..e3d605787d8 100644 --- a/libraries/WiFiProv/examples/WiFiProv/README.md +++ b/libraries/WiFiProv/examples/WiFiProv/README.md @@ -10,12 +10,8 @@ This example allows Arduino user to choose either BLE or SOFTAP as a mode of tra ## WiFi.onEvent() -Using this API user can register to receive WiFi Events and Provisioning Events. - -WARNING: The event handler is called from a separate FreeRTOS task (thread)! -Serial.print*() is OK but most other library calls are NOT OK unless -actions taken to ensure thread safety. -[https://github.com/espressif/arduino-esp32/issues/6947](See bug 6947.) +This API can be used to register a function to be called from another +thread for WiFi Events and Provisioning Events. ## WiFi.beginProvision() diff --git a/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino b/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino index 7b20a94e8c4..683d6ac0470 100644 --- a/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino +++ b/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino @@ -2,8 +2,6 @@ #include "WiFi.h" // WARNING: SysProvEvent is called from a separate FreeRTOS task (thread)! -// Serial.print*() is OK but most other library calls are NOT OK. -// See: https://github.com/espressif/arduino-esp32/issues/6947 void SysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { From c9515def225704ad268bab2e386543567697d8e6 Mon Sep 17 00:00:00 2001 From: Pedro Minatel Date: Mon, 4 Dec 2023 04:58:31 +0000 Subject: [PATCH 08/10] Update WiFiProv.ino merge conflict issue fixed --- libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino b/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino index 35b4957af53..72c043cb74f 100644 --- a/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino +++ b/libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino @@ -11,6 +11,12 @@ Note: This sketch takes up a lot of space for the app and may not be able to fla #include "WiFiProv.h" #include "WiFi.h" +// #define USE_SOFT_AP // Uncomment if you want to enforce using the Soft AP method instead of BLE +const char * pop = "abcd1234"; // Proof of possession - otherwise called a PIN - string provided by the device, entered by the user in the phone app +const char * service_name = "PROV_123"; // Name of your device (the Espressif apps expects by default device name starting with "Prov_") +const char * service_key = NULL; // Password used for SofAP method (NULL = no password needed) +bool reset_provisioned = true; // When true the library will automatically delete previously provisioned data. + // WARNING: SysProvEvent is called from a separate FreeRTOS task (thread)! void SysProvEvent(arduino_event_t *sys_event) { From 56c5f23b3e2fee7ce51964845d05cb41283d1c21 Mon Sep 17 00:00:00 2001 From: Pedro Minatel Date: Mon, 4 Dec 2023 10:36:01 +0000 Subject: [PATCH 09/10] Added the CLK type and MAC from eFuse to Ethernet begin --- .../Ethernet/examples/ETH_TLK110/ETH_TLK110.ino | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino index 4a64ea09589..61194cd49b8 100644 --- a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino +++ b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino @@ -5,12 +5,13 @@ #include -#define ETH_TYPE ETH_PHY_TLK110 -#define ETH_ADDR 31 -#define ETH_MDC_PIN 23 -#define ETH_MDIO_PIN 18 -#define ETH_POWER_PIN 17 -#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN +#define ETH_TYPE ETH_PHY_TLK110 +#define ETH_ADDR 31 +#define ETH_MDC_PIN 23 +#define ETH_MDIO_PIN 18 +#define ETH_POWER_PIN 17 +#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN +#define ETH_MAC_FROM_EFUSE 1 static bool eth_connected = false; @@ -73,7 +74,7 @@ void setup() { Serial.begin(115200); WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread. - ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE); + ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE, ETH_MAC_FROM_EFUSE); } From aabe6f667e07ef500a07b426ca8b776d7433bd8a Mon Sep 17 00:00:00 2001 From: Pedro Minatel Date: Mon, 4 Dec 2023 11:04:36 +0000 Subject: [PATCH 10/10] Fixed the order and arguments on the Ethernet begin function --- libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino index 61194cd49b8..3a685994862 100644 --- a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino +++ b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino @@ -11,7 +11,6 @@ #define ETH_MDIO_PIN 18 #define ETH_POWER_PIN 17 #define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN -#define ETH_MAC_FROM_EFUSE 1 static bool eth_connected = false; @@ -74,7 +73,7 @@ void setup() { Serial.begin(115200); WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread. - ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE, ETH_MAC_FROM_EFUSE); + ETH.begin(ETH_TYPE, ETH_ADDR, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_POWER_PIN, ETH_CLK_MODE); }