Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 67c027c

Browse files
egnorpedrominatel
andauthored
Add documentation on threading issues with WiFi.onEvent() to examples (#8081)
* Compile error if CONFIG_FREERTOS_HZ != 1000 * add a check at the CMake level, per feedback * fix a punctuation glitch * Remove `_Static_assert` per feedback * add documentation on threading issues with WiFi.onEvent() * more comments * thin out comments, add docs * Update WiFiProv.ino merge conflict issue fixed * Added the CLK type and MAC from eFuse to Ethernet begin * Fixed the order and arguments on the Ethernet begin function --------- Co-authored-by: Pedro Minatel <pedro.minatel@espressif.com> Co-authored-by: Pedro Minatel <pminatel@gmail.com>
1 parent 7ecde87 commit 67c027c

File tree

15 files changed

+148
-33
lines changed

15 files changed

+148
-33
lines changed

‎docs/source/api/wifi.rst

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,102 @@ Common API
5050

5151
Here are the common APIs that are used for both modes, AP and STA.
5252

53+
onEvent (and removeEvent)
54+
*************************
55+
56+
Registers a caller-supplied function to be called when WiFi events
57+
occur. Several forms are available.
58+
59+
Function pointer callback taking the event ID:
60+
61+
.. code-block:: arduino
62+
63+
typedef void (*WiFiEventCb)(arduino_event_id_t);
64+
wifi_event_id_t onEvent(WiFiEventCb, arduino_event_id_t = ARDUINO_EVENT_MAX);
65+
66+
Function pointer callback taking an event-ID-and-info struct:
67+
68+
.. code-block:: arduino
69+
70+
typedef struct{
71+
arduino_event_id_t event_id;
72+
arduino_event_info_t event_info;
73+
} arduino_event_t;
74+
75+
typedef void (*WiFiEventSysCb)(arduino_event_t *);
76+
wifi_event_id_t onEvent(WiFiEventSysCb, arduino_event_id_t = ARDUINO_EVENT_MAX);
77+
78+
Callback using ``std::function`` taking event ID and info separately:
79+
80+
.. code-block:: arduino
81+
82+
typedef std::function<void(arduino_event_id_t, arduino_event_info_t)> WiFiEventFuncCb;
83+
wifi_event_id_t onEvent(WiFiEventFuncCb, arduino_event_id_t = ARDUINO_EVENT_MAX);
84+
85+
A similar set of functions are available to remove callbacks:
86+
87+
.. code-block:: arduino
88+
89+
void removeEvent(WiFiEventCb, arduino_event_id_t = ARDUINO_EVENT_MAX);
90+
void removeEvent(WiFiEventSysCb, arduino_event_id_t = ARDUINO_EVENT_MAX);
91+
void removeEvent(wifi_event_id_t = ARDUINO_EVENT_MAX);
92+
93+
In all cases, the subscribing function accepts an optional event type to
94+
invoke the callback only for that specific event; with the default
95+
``ARDUINO_EVENT_MAX``, the callback will be invoked for all WiFi events.
96+
97+
Any callback function is given the event type in a parameter.
98+
Some of the possible callback function formats also take an
99+
``arduino_event_info_t`` (or use ``arduino_event_t`` which includes both
100+
ID and info) which is a union of structs with additional information
101+
about different event types.
102+
103+
See
104+
`WiFiGeneric.h <https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/src/WiFiGeneric.h>`_
105+
for the list of event types and "info" substructures, and also see a full
106+
example of event handling: `events example`_.
107+
108+
.. warning::
109+
110+
Event callback functions are invoked on a separate
111+
`thread <https://en.wikipedia.org/wiki/Thread_(computing)>`_
112+
(`FreeRTOS task <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos_idf.html#tasks>`_)
113+
independent of the main application thread that runs ``setup()`` and
114+
``loop()``. Callback functions must therefore be
115+
`thread-safe <https://en.wikipedia.org/wiki/Thread_safety>`_;
116+
they must not access shared/global variables directly without locking,
117+
and must only call similarly thread-safe functions.
118+
119+
Some core operations like ``Serial.print()`` are thread-safe but many
120+
functions are not. Notably, ``WiFi.onEvent()`` and ``WiFi.removeEvent()``
121+
are not thread-safe and should never be invoked from a callback thread.
122+
123+
setHostname (and getHostname)
124+
*****************************
125+
126+
Sets the name the DHCP client uses to identify itself. In a typical network
127+
setup this will be the name that shows up in the Wi-Fi router's device list.
128+
The hostname must be no longer than 32 characters.
129+
130+
.. code-block:: arduino
131+
132+
setHostname(const char *hostname);
133+
134+
If the hostname is never specified, a default one will be assigned based
135+
on the chip type and MAC address. The current hostname (default or custom)
136+
may be retrieved:
137+
138+
.. code-block:: arduino
139+
140+
const char *getHostname();
141+
142+
.. warning::
143+
144+
The ``setHostname()`` function must be called BEFORE WiFi is started with
145+
``WiFi.begin()``, ``WiFi.softAP()``, ``WiFi.mode()``, or ``WiFi.run()``.
146+
To change the name, reset WiFi with ``WiFi.mode(WIFI_MODE_NULL)``,
147+
then proceed with ``WiFi.setHostname(...)`` and restart WiFi from scratch.
148+
53149
useStaticBuffers
54150
****************
55151

@@ -552,6 +648,8 @@ To see how to use the ``WiFiScan``, take a look at the ``WiFiScan.ino`` example
552648
Examples
553649
--------
554650

651+
`Complete list of WiFi examples <https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi/examples>`_.
652+
555653
.. _ap example:
556654

557655
Wi-Fi AP Example
@@ -568,5 +666,10 @@ Wi-Fi STA Example
568666
.. literalinclude:: ../../../libraries/WiFi/examples/WiFiClient/WiFiClient.ino
569667
:language: arduino
570668

571-
References
572-
----------
669+
.. _events example:
670+
671+
Wi-Fi Events Example
672+
********************
673+
674+
.. literalinclude:: ../../../libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino
675+
:language: arduino

‎libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@
1616

1717
static bool eth_connected = false;
1818

19-
void onEvent(arduino_event_id_t event, arduino_event_info_t info)
19+
// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)!
20+
void WiFiEvent(WiFiEvent_t event)
2021
{
2122
switch (event) {
2223
case ARDUINO_EVENT_ETH_START:
2324
Serial.println("ETH Started");
24-
//set eth hostname here
25+
// The hostname must be set after the interface is started, but needs
26+
// to be set before DHCP, so set it from the event handler thread.
2527
ETH.setHostname("esp32-ethernet");
2628
break;
2729
case ARDUINO_EVENT_ETH_CONNECTED:
@@ -72,11 +74,10 @@ void testClient(const char * host, uint16_t port)
7274
void setup()
7375
{
7476
Serial.begin(115200);
75-
WiFi.onEvent(onEvent);
77+
WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread.
7678
ETH.begin();
7779
}
7880

79-
8081
void loop()
8182
{
8283
if (eth_connected) {

‎libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,23 @@
55

66
#include <ETH.h>
77

8-
#define ETH_TYPE ETH_PHY_TLK110
9-
#define ETH_ADDR 31
10-
#define ETH_MDC_PIN 23
11-
#define ETH_MDIO_PIN 18
12-
#define ETH_POWER_PIN 17
13-
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
8+
#define ETH_TYPE ETH_PHY_TLK110
9+
#define ETH_ADDR 31
10+
#define ETH_MDC_PIN 23
11+
#define ETH_MDIO_PIN 18
12+
#define ETH_POWER_PIN 17
13+
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
1414

1515
static bool eth_connected = false;
1616

17-
void onEvent(arduino_event_id_t event, arduino_event_info_t info)
17+
// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)!
18+
void WiFiEvent(WiFiEvent_t event)
1819
{
1920
switch (event) {
2021
case ARDUINO_EVENT_ETH_START:
2122
Serial.println("ETH Started");
22-
//set eth hostname here
23+
// The hostname must be set after the interface is started, but needs
24+
// to be set before DHCP, so set it from the event handler thread.
2325
ETH.setHostname("esp32-ethernet");
2426
break;
2527
case ARDUINO_EVENT_ETH_CONNECTED:
@@ -70,7 +72,7 @@ void testClient(const char * host, uint16_t port)
7072
void setup()
7173
{
7274
Serial.begin(115200);
73-
WiFi.onEvent(onEvent);
75+
WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread.
7476
ETH.begin(ETH_TYPE, ETH_ADDR, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_POWER_PIN, ETH_CLK_MODE);
7577
}
7678

‎libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ bool dimmer_state = true;
2424
// But, you can also define custom devices using the 'Device' base class object, as shown here
2525
static Device *my_device = NULL;
2626

27+
// WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)!
2728
void sysProvEvent(arduino_event_t *sys_event)
2829
{
2930
switch (sys_event->event_id) {
@@ -105,7 +106,7 @@ void setup()
105106

106107
RMaker.start();
107108

108-
WiFi.onEvent(sysProvEvent);
109+
WiFi.onEvent(sysProvEvent);// Will call sysProvEvent() from another thread.
109110
#if CONFIG_IDF_TARGET_ESP32S2
110111
WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
111112
#else

‎libraries/RainMaker/examples/RMakerCustomAirCooler/RMakerCustomAirCooler.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ bool power_state = true;
4040
// But, you can also define custom devices using the 'Device' base class object, as shown here
4141
static Device *my_device = NULL;
4242

43+
// WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)!
4344
void sysProvEvent(arduino_event_t *sys_event)
4445
{
4546
switch (sys_event->event_id) {
@@ -170,7 +171,7 @@ void setup()
170171

171172
RMaker.start();
172173

173-
WiFi.onEvent(sysProvEvent);
174+
WiFi.onEvent(sysProvEvent);// Will call sysProvEvent() from another thread.
174175
#if CONFIG_IDF_TARGET_ESP32S2
175176
WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
176177
#else

‎libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ LightSwitch switch_ch2 = {gpio_switch2, false};
3434
static Switch *my_switch1 = NULL;
3535
static Switch *my_switch2 = NULL;
3636

37+
// WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)!
3738
void sysProvEvent(arduino_event_t *sys_event)
3839
{
3940
switch (sys_event->event_id) {
@@ -160,7 +161,7 @@ void setup()
160161
Serial.printf("\nStarting ESP-RainMaker\n");
161162
RMaker.start();
162163

163-
WiFi.onEvent(sysProvEvent);
164+
WiFi.onEvent(sysProvEvent);// Will call sysProvEvent() from another thread.
164165
#if CONFIG_IDF_TARGET_ESP32
165166
WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
166167
#else

‎libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ bool switch_state = true;
2525
// fan, temperaturesensor.
2626
static Switch *my_switch = NULL;
2727

28+
// WARNING: sysProvEvent is called from a separate FreeRTOS task (thread)!
2829
void sysProvEvent(arduino_event_t *sys_event)
2930
{
3031
switch (sys_event->event_id) {
@@ -107,7 +108,7 @@ void setup()
107108

108109
RMaker.start();
109110

110-
WiFi.onEvent(sysProvEvent);
111+
WiFi.onEvent(sysProvEvent);// Will call sysProvEvent() from another thread.
111112
#if CONFIG_IDF_TARGET_ESP32S2
112113
WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE,
113114
WIFI_PROV_SECURITY_1, pop, service_name);

‎libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ SemaphoreHandle_t ftmSemaphore;
2828
bool ftmSuccess = true;
2929

3030
// FTM report handler with the calculated data from the round trip
31+
// WARNING: This function is called from a separate FreeRTOS task (thread)!
3132
void onFtmReport(arduino_event_t *event) {
3233
const char * status_str[5] = {"SUCCESS", "UNSUPPORTED", "CONF_REJECTED", "NO_RESPONSE", "FAIL"};
3334
wifi_event_ftm_report_t * report = &event->event_info.wifi_ftm_report;
@@ -62,7 +63,7 @@ void setup() {
6263
// Create binary semaphore (initialized taken and can be taken/given from any thread/ISR)
6364
ftmSemaphore = xSemaphoreCreateBinary();
6465

65-
// Listen for FTM Report events
66+
// Will call onFtmReport() from another thread with FTM Report events.
6667
WiFi.onEvent(onFtmReport, ARDUINO_EVENT_WIFI_FTM_REPORT);
6768

6869
// Connect to AP that has FTM Enabled

‎libraries/WiFi/examples/WPS/WPS.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ String wpspin2string(uint8_t a[]){
6161
return (String)wps_pin;
6262
}
6363

64+
// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)!
6465
void WiFiEvent(WiFiEvent_t event, arduino_event_info_t info){
6566
switch(event){
6667
case ARDUINO_EVENT_WIFI_STA_START:
@@ -103,7 +104,7 @@ void setup(){
103104
Serial.begin(115200);
104105
delay(10);
105106
Serial.println();
106-
WiFi.onEvent(WiFiEvent);
107+
WiFi.onEvent(WiFiEvent);// Will call WiFiEvent() from another thread.
107108
WiFi.mode(WIFI_MODE_STA);
108109
Serial.println("Starting WPS");
109110
wpsInitConfig();

‎libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ void onButton(){
7373
delay(100);
7474
}
7575

76+
// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)!
7677
void WiFiEvent(WiFiEvent_t event){
7778
switch(event) {
7879
case ARDUINO_EVENT_WIFI_AP_START:
@@ -112,7 +113,7 @@ void WiFiEvent(WiFiEvent_t event){
112113
void setup() {
113114
Serial.begin(115200);
114115
pinMode(0, INPUT_PULLUP);
115-
WiFi.onEvent(WiFiEvent);
116+
WiFi.onEvent(WiFiEvent);// Will call WiFiEvent() from another thread.
116117
Serial.print("ESP32 SDK: ");
117118
Serial.println(ESP.getSdkVersion());
118119
Serial.println("Press the button to select the next mode");

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /