Skip to content

Commit 1cc6960

Browse files
authored
[BREAKING] Disable WiFi at boot by default (#7902)
* Disable WiFi at boot by default * +define WIFI_IS_OFF_AT_BOOT * remove now useless example * mv enableWiFiAtBootTime() to core_esp8266_features.h * sync with master * per @earlephilhower review: a file was missing * doc * WiFi persistence is now false by default * fix doc * ditto * doc: remove sphinx warnings (fix links and formatting) * fix link name * fix doc * legacy: restore persistence * undeprecate preinit() * move force modem up to when mode has changed (per @mcspr review) * do not wake up from sleep when mode if OFF * fix doc per review
1 parent da6ec83 commit 1cc6960

File tree

22 files changed

+107
-142
lines changed

22 files changed

+107
-142
lines changed

cores/esp8266/core_esp8266_features.h

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#define CORE_HAS_UMM
3232

3333
#define WIFI_HAS_EVENT_CALLBACK
34+
#define WIFI_IS_OFF_AT_BOOT
3435

3536
#include <stdlib.h> // malloc()
3637
#include <stddef.h> // size_t
@@ -104,6 +105,8 @@ uint64_t micros64(void);
104105
void delay(unsigned long);
105106
void delayMicroseconds(unsigned int us);
106107

108+
void enableWiFiAtBootTime (void) __attribute__((noinline));
109+
107110
#if defined(F_CPU) || defined(CORE_MOCK)
108111
#ifdef __cplusplus
109112
constexpr

cores/esp8266/core_esp8266_main.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,18 @@ extern "C" void app_entry (void)
332332
extern "C" void preinit (void) __attribute__((weak));
333333
extern "C" void preinit (void)
334334
{
335-
/* do nothing by default */
335+
/* does nothing, kept for backward compatibility */
336+
}
337+
338+
extern "C" void __disableWiFiAtBootTime (void) __attribute__((weak));
339+
extern "C" void __disableWiFiAtBootTime (void)
340+
{
341+
// Starting from arduino core v3: wifi is disabled at boot time
342+
// WiFi.begin() or WiFi.softAP() will wake WiFi up
343+
wifi_set_opmode_current(0/*WIFI_OFF*/);
344+
wifi_fpm_set_sleep_type(MODEM_SLEEP_T);
345+
wifi_fpm_open();
346+
wifi_fpm_do_sleep(0xFFFFFFF);
336347
}
337348

338349
extern "C" void user_init(void) {
@@ -365,6 +376,7 @@ extern "C" void user_init(void) {
365376
umm_init_iram();
366377
#endif
367378
preinit(); // Prior to C++ Dynamic Init (not related to above init() ). Meant to be user redefinable.
379+
__disableWiFiAtBootTime(); // default weak function disables WiFi
368380

369381
ets_task(loop_task,
370382
LOOP_TASK_PRIORITY, s_loop_queue,

cores/esp8266/coredecls.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ void esp_schedule();
1818
void tune_timeshift64 (uint64_t now_us);
1919
void disable_extra4k_at_link_time (void) __attribute__((noinline));
2020
bool sntp_set_timezone_in_seconds(int32_t timezone);
21+
void __disableWiFiAtBootTime (void) __attribute__((noinline));
2122
void __real_system_restart_local() __attribute__((noreturn));
2223

2324
uint32_t sqrt32 (uint32_t n);
@@ -34,6 +35,6 @@ using TrivialCB = std::function<void()>;
3435
void settimeofday_cb (const BoolCB& cb);
3536
void settimeofday_cb (const TrivialCB& cb);
3637

37-
#endif
38+
#endif // __cplusplus
3839

3940
#endif // __COREDECLS_H

doc/esp8266wifi/generic-class.rst

+27
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,33 @@ persistent
4242
4343
WiFi.persistent(persistent)
4444
45+
Starting from version 3 of this core, **persistence is disabled by default
46+
and WiFi does not start automatically at boot** (see PR `#7902 <https://github.com./esp8266/Arduino/pull/7902>`__).
47+
48+
Previously, SDK was automatically starting WiFi at boot. This was probably
49+
intended for the Espressif AT FW which is interactive and preserves WiFi
50+
state accross reboots. This behavior is generally irrelevant with the
51+
Arduino API because sketches start with ``WiFi.begin()`` or
52+
``WiFi.softAP()``.
53+
54+
This change is harmless with standard sketches: Calls to ``WiFi.mode()`` do
55+
enable radio as usual. It also smooths current spikes at boot and decreases
56+
DHCP stress.
57+
58+
Legacy behavior can be restored by calling ``enableWiFiAtBootTime()`` from
59+
anywhere in the code (it is a weak void function intended to play with the
60+
linker).
61+
62+
.. code:: cpp
63+
64+
void setup () {
65+
#ifdef WIFI_IS_OFF_AT_BOOT
66+
enableWiFiAtBootTime(); // can be called from anywhere with the same effect
67+
#endif
68+
....
69+
}
70+
71+
When legacy behavior is restored thanks to this call,
4572
ESP8266 is able to reconnect to the last used WiFi network or establishes the same Access Point upon power up or reset.
4673
By default, these settings are written to specific sectors of flash memory every time they are changed in ``WiFi.begin(ssid, passphrase)`` or ``WiFi.softAP(ssid, passphrase, channel)``, and when ``WiFi.disconnect`` or ``WiFi.softAPdisconnect`` is invoked.
4774
Frequently calling these functions could cause wear on the flash memory (see issue `#1054 <https://github.com./esp8266/Arduino/issues/1054>`__).

doc/esp8266wifi/readme.rst

+1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ WiFi Multi
164164
Example:
165165

166166
.. code:: cpp
167+
167168
#include <ESP8266WiFiMulti.h>
168169
169170
ESP8266WiFiMulti wifiMulti;

doc/faq/a01-espcomm_sync-failed.rst

+2-3
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ following three things right: 1. Module is provided with enough power,
4141
2. GPIO0, GPIO15 and CH\_PD are connected using pull up / pull down
4242
resistors, 3. Module is put into boot loader mode.
4343

44-
For specific details please refer to section on `Generic ESP8266
45-
modules <../boards.rst#generic-esp8266-modules>`__. Example modules
46-
without USB to serial converter on board are shown below.
44+
For specific details please refer to section on `Generic ESP8266 module <../boards.rst#generic-esp8266-module>`__.
45+
Example modules without USB to serial converter on board are shown below.
4746

4847
.. figure:: pictures/a01-example-boards-without-usb.png
4948
:alt: Example ESP8266 modules without USB to serial converter

doc/faq/a04-board-generic-is-unknown.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ follows:
4848
Error compiling for board Generic ESP8266 Module.
4949

5050
Below is an example messages for
51-
`WeMos <../boards.rst#wemos-d1-r2-mini>`__:
51+
`WeMos <../boards.rst#lolin-wemos-d1-r2-mini>`__:
5252

5353
::
5454

doc/faq/readme.rst

+9
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,12 @@ will need to implement an additional (short) deep sleep using
177177
``WAKE_RF_DEFAULT``.
178178

179179
Ref. `#3072 <https://github.com./esp8266/Arduino/issues/3072>`__
180+
181+
My WiFi was previously automatically connected right after booting, but isn't anymore
182+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183+
184+
This was WiFi persistence. Starting from version 3 of this core, WiFi is
185+
indeed off at boot and is powered on only when starting to be used with the
186+
regular API.
187+
188+
Read more at `former WiFi persistent mode <../esp8266wifi/generic-class.rst#persistent>`__.

doc/filesystem.rst

+8-8
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,8 @@ Performs the same operation as ``info`` but allows for reporting greater than
474474
4GB for filesystem size/used/etc. Should be used with the SD and SDFS
475475
filesystems since most SD cards today are greater than 4GB in size.
476476

477-
setTimeCallback(time_t (*cb)(void))
478-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
477+
setTimeCallback(time_t (\*cb)(void))
478+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
479479

480480
.. code:: cpp
481481
@@ -574,8 +574,8 @@ rewind
574574

575575
Resets the internal pointer to the start of the directory.
576576

577-
setTimeCallback(time_t (*cb)(void))
578-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
577+
setTimeCallback(time_t (\*cb)(void))
578+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
579579

580580
Sets the time callback for any files accessed from this Dir object via openNextFile.
581581
Note that the SD and SDFS filesystems only support a filesystem-wide callback and
@@ -693,7 +693,7 @@ Close the file. No other operations should be performed on *File* object
693693
after ``close`` function was called.
694694

695695
openNextFile (compatibiity method, not recommended for new code)
696-
~~~~~~~~~~~~
696+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
697697

698698
.. code:: cpp
699699
@@ -705,7 +705,7 @@ Opens the next file in the directory pointed to by the File. Only valid
705705
when ``File.isDirectory() == true``.
706706

707707
rewindDirectory (compatibiity method, not recommended for new code)
708-
~~~~~~~~~~~~~~~
708+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
709709

710710
.. code:: cpp
711711
@@ -718,8 +718,8 @@ rewindDirectory (compatibiity method, not recommended for new code)
718718
Resets the ``openNextFile`` pointer to the top of the directory. Only
719719
valid when ``File.isDirectory() == true``.
720720

721-
setTimeCallback(time_t (*cb)(void))
722-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
721+
setTimeCallback(time_t (\*cb)(void))
722+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
723723

724724
Sets the time callback for this specific file. Note that the SD and
725725
SDFS filesystems only support a filesystem-wide callback and calls to

doc/libraries.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Some ESP-specific APIs related to deep sleep, RTC and flash memories are availab
8787

8888
``ESP.getHeapFragmentation()`` returns the fragmentation metric (0% is clean, more than ~50% is not harmless)
8989

90-
``ESP.getMaxFreeBlockSize()`` returns the largest contiguous free RAM block in the heap, useful for checking heap fragmentation. **NOTE:** Maximum ``malloc()``able block will be smaller due to memory manager overheads.
90+
``ESP.getMaxFreeBlockSize()`` returns the largest contiguous free RAM block in the heap, useful for checking heap fragmentation. **NOTE:** Maximum ``malloc()`` -able block will be smaller due to memory manager overheads.
9191

9292
``ESP.getChipId()`` returns the ESP8266 chip ID as a 32-bit integer.
9393

doc/mmu.rst

-2
Original file line numberDiff line numberDiff line change
@@ -233,5 +233,3 @@ address range of IRAM or DRAM.
233233
uint8_t mmu_set_uint8(void *p8, const uint8_t val);
234234
uint16_t mmu_set_uint16(uint16_t *p16, const uint16_t val);
235235
int16_t mmu_set_int16(int16_t *p16, const int16_t val);
236-
237-
::

doc/ota_updates/readme.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ If signing is desired, sign the gzip compressed file *after* compression.
161161
Updating apps in the field to support compression
162162
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
163163

164-
If you have applications deployed in the field and wish to update them to support compressed OTA uploads, you will need to first recompile the application, then _upload the uncompressed `.bin` file once_. Attempting to upload a `gzip` compressed binary to a legacy app will result in the Updater rejecting the upload as it does not understand the `gzip` format. After this initial upload, which will include the new bootloader and `Updater` class with compression support, compressed updates can then be used.
164+
If you have applications deployed in the field and wish to update them to support compressed OTA uploads, you will need to first recompile the application, then _upload the uncompressed `.bin` file once. Attempting to upload a `gzip` compressed binary to a legacy app will result in the Updater rejecting the upload as it does not understand the `gzip` format. After this initial upload, which will include the new bootloader and `Updater` class with compression support, compressed updates can then be used.
165165

166166

167167
Safety

libraries/ESP8266WiFi/examples/EarlyDisableWiFi/EarlyDisableWiFi.ino

-59
This file was deleted.

libraries/ESP8266WiFi/examples/WiFiShutdown/WiFiShutdown.ino

-5
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ WiFiState state;
2424
const char* ssid = STASSID;
2525
const char* password = STAPSK;
2626

27-
void preinit(void) {
28-
// Make sure, wifi stays off after boot.
29-
ESP8266WiFiClass::preinitWiFiOff();
30-
}
31-
3227
void setup() {
3328
Serial.begin(74880);
3429
//Serial.setDebugOutput(true); // If you need debug output

libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp

+9-27
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ struct WiFiEventHandlerOpaque
8383

8484
static std::list<WiFiEventHandler> sCbEventList;
8585

86-
bool ESP8266WiFiGenericClass::_persistent = true;
86+
bool ESP8266WiFiGenericClass::_persistent = false;
8787
WiFiMode_t ESP8266WiFiGenericClass::_forceSleepLastMode = WIFI_OFF;
8888

8989
ESP8266WiFiGenericClass::ESP8266WiFiGenericClass()
@@ -418,12 +418,6 @@ bool ESP8266WiFiGenericClass::mode(WiFiMode_t m, WiFiState* state) {
418418
DEBUG_WIFI("core: state is useless without SHUTDOWN or RESUME\n");
419419
}
420420

421-
if (wifi_fpm_get_sleep_type() != NONE_SLEEP_T) {
422-
// wifi may have been put asleep by ESP8266WiFiGenericClass::preinitWiFiOff
423-
wifi_fpm_do_wakeup();
424-
wifi_fpm_close();
425-
}
426-
427421
if(_persistent){
428422
if(wifi_get_opmode() == (uint8) m && wifi_get_opmode_default() == (uint8) m){
429423
return true;
@@ -432,6 +426,12 @@ bool ESP8266WiFiGenericClass::mode(WiFiMode_t m, WiFiState* state) {
432426
return true;
433427
}
434428

429+
if (m != WIFI_OFF && wifi_fpm_get_sleep_type() != NONE_SLEEP_T) {
430+
// wifi starts asleep by default
431+
wifi_fpm_do_wakeup();
432+
wifi_fpm_close();
433+
}
434+
435435
bool ret = false;
436436
ETS_UART_INTR_DISABLE();
437437
if(_persistent) {
@@ -855,25 +855,7 @@ bool ESP8266WiFiGenericClass::resumeFromShutdown (WiFiState* state)
855855
return true;
856856
}
857857

858-
//meant to be called from user-defined ::preinit()
859858
void ESP8266WiFiGenericClass::preinitWiFiOff () {
860-
// https://github.com./esp8266/Arduino/issues/2111#issuecomment-224251391
861-
// WiFi.persistent(false);
862-
// WiFi.mode(WIFI_OFF);
863-
// WiFi.forceSleepBegin();
864-
865-
//WiFi.mode(WIFI_OFF) equivalent:
866-
// datasheet:
867-
// Set Wi-Fi working mode to Station mode, SoftAP
868-
// or Station + SoftAP, and do not update flash
869-
// (not persistent)
870-
wifi_set_opmode_current(WIFI_OFF);
871-
872-
//WiFi.forceSleepBegin(/*default*/0) equivalent:
873-
// sleep forever until wifi_fpm_do_wakeup() is called
874-
wifi_fpm_set_sleep_type(MODEM_SLEEP_T);
875-
wifi_fpm_open();
876-
wifi_fpm_do_sleep(0xFFFFFFF);
877-
878-
// use WiFi.forceSleepWake() to wake WiFi up
859+
// It was meant to be called from user-defined ::preinit()
860+
// It is now deprecated by enableWiFiAtBootTime() and __disableWiFiAtBootTime()
879861
}

libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class ESP8266WiFiGenericClass {
120120

121121
void setOutputPower(float dBm);
122122

123-
void persistent(bool persistent);
123+
static void persistent(bool persistent);
124124

125125
bool mode(WiFiMode_t, WiFiState* state = nullptr);
126126
WiFiMode_t getMode();
@@ -133,7 +133,7 @@ class ESP8266WiFiGenericClass {
133133

134134
static uint32_t shutdownCRC (const WiFiState* state);
135135
static bool shutdownValidCRC (const WiFiState* state);
136-
static void preinitWiFiOff (); //meant to be called in user-defined preinit()
136+
static void preinitWiFiOff () __attribute__((deprecated("WiFi is off by default at boot, use enableWiFiAtBoot() for legacy behavior")));
137137

138138
protected:
139139
static bool _persistent;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* empty wrappers to play with linker and reenable wifi at boot time
3+
*/
4+
5+
#include "coredecls.h"
6+
7+
#include <ESP8266WiFi.h>
8+
9+
extern "C" void enableWiFiAtBootTime()
10+
{
11+
/*
12+
* Called by user from anywhere, does nothing and allows overriding
13+
* the core_esp8266_main.cpp's default disableWiFiAtBootTime() by the
14+
* one below, at link time.
15+
*/
16+
}
17+
18+
extern "C" void __disableWiFiAtBootTime()
19+
{
20+
// overrides the default __disableWiFiAtBootTime:
21+
// Does (almost) nothing: WiFi is enabled by default in nonos-sdk
22+
23+
// ... but restores legacy WiFi credentials persistence to true at boot time
24+
// (can be still overriden by user before setting up WiFi, like before)
25+
26+
// (note: c++ ctors not called yet at this point)
27+
ESP8266WiFiClass::persistent(true);
28+
}

0 commit comments

Comments
 (0)