-
Notifications
You must be signed in to change notification settings - Fork 7.6k
light_sleep in v3.0-dev has several issues #908
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi Tom, I am working also on sleep code with the ESP32, I am using as well direct programmed 64-bit timers for wakeup and time counting, here are come comments from an ESP32 beginner. a) Check out that you are using chip revision 1 (ESP.getChipRevision()) b) 32KHz RTC crystal clock c) Estimating sleep duration Another fact is that a reset (EN low/high) will reset the RTC to zero even a battery is connected. For more accurate time an external temperature compensated RTC chip may be needed, e.g. DS3231. Regards Helmut
|
Hi Tom, I was testing your sample code and got the problem you are describing. Two symptoms I have seen: (rev1 DevKit)
|
I checked and the chip revision of my WROOM-32 is 1, so it's not the old version of the chip. |
Yes. Understand. I've added a call to yield() -- which I'm pretty sure just calls vPortYield() on the ESP32 -- immediately after esp_light_sleep_start() and my test program has been running for an hour now, so a good sign. Needs more testing but my fingers are crossed. Just to be clear, my suspend() function is now...
EDIT: Well, no change in behavior. Test program hung after running for a couple of hours, same as before. |
I decided to simplify the test program that calls the suspend() function posted above and not do any serial output at all. Instead I just flash a LED every 1 second or so, then call suspend() again. This has now been running ~6 hours without hanging! So I'm now thinking that serial output to the USB bridge plays a role in causing the hangs I described in my first post above. |
What I do for another MCU (STM32L4 mbed), before I go to deep sleep I wait that the serial output is flushed to avoid problems. I have not looked into the details of the serial output implementation of the ESP32 for Arduino. For the Arduino D21 (SAMD) the code it is being a synchronous output. I also noticed that an ESP32 interrupt routing print on the serial may hang sometimes, looks like the prints go async. |
Okay, after doing a lot more testing I've reached the conclusion that the fundamental problem of the ESP32 hanging during light_sleep has nothing to do with serial I/O. I think it is related to calling the gettimeofday() function. I've provided a new test case below that is essentially Espressif's own unit test code, except instead of calling the light_sleep function only once I call it repeatedly. As noted in my original post above, how long the program sleeps for has a direct bearing on how long this code runs before hanging. Long sleep times rarely hang, while short sleep times will hang the ESP32 within a couple minutes. The test code here will hang in an indeterminate processor state within a minute or two.
|
I also have experienced this problem. Does anyone have an update on this issue? |
I am seeing exact same issue when esp_light_sleep_start() is called. I am typically calling with a delay less than 1000ms set with the esp_sleep_enable_timer_wakeup(microseconds) function. Periodically at random the esp_light_sleep_start() function blocks and never returns to the calling code. Even worst, the esp_light_sleep_start() function is enabling and disabling the hardware watchdog timer, and the hardware watchdog timer is sometimes in the disabled state when the block occurs, which means that the CPU effectively stalls with no hardware WDT reset or autonomous recovery from an error state. Calling the esp_light_sleep_start() function once every second the ESP32 becomes unusable after a few (1-3) hours and a manual reset is then required to recover. This makes the ESP32 unsuitable for tasks requiring remote operation if light sleep is required and hardware WDT is not guaranteed to operate. |
This is a critical issue for anyone considering the use of the ESP32 with light sleep mode. |
In sleep_modes.c in esp_light_sleep_start() function, after the code which potentially blocks, the hardware WDT is enabled with a fixed 1 second timeout:
The above means that light sleeps greater than one second will trigger the hardware WDT watchdog timer and cause a reset, so above code does not take into account the length of the light sleep which may be longer than 1 second. After the light sleep the function calls: The above is called before: Not sure if the above can block?? If it does the hardware WDT is disabled. Also after this point the users code is no longer protected by the hardware WDT if they wanted to use that feature. |
Note that Espressif is planning on implementing "automatic" light sleep in the IDF soon, as mentioned here: #1165 (comment) |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions. |
This stale issue has been automatically closed. Thank you for your contributions. |
Hardware:
Board: Adafruit Huzzah32
Core Installation/update date: 6/dec/2017 (v3.0-dev-1325-ge5b2c1cf)
IDE name: Arduino IDE 1.8.5
Flash Frequency: 80MHz
Upload Speed: 115200
Description:
There are several problems with the current implementation of light_sleep. Since these are all related I'm including them together in one ticket.
Synopsis:
Details:
timer-based light_sleep sometimes never wakes up: calling suspend() in the sketch below will eventually cause esp_light_sleep_start() to never return. Small values of sleep (e.g., 10ms) will usually cause the hang to happen within a few minutes. Larger values (e.g., 1000ms) may take a few hours before the hang occurs. To me, this behavior is indicative of a race condition in esp_light_sleep_start() that is "tickled" the more frequently the function is called. I have tried several fixes for this issue without success and its root cause remains elusive.
millis() timer doesn't tick during light_sleep: When light_sleep stalls the cpus, normal timers don't tick, including the timer used for the millis() function, and this can often lead to unexpected behavior in programs. The IDF provides the needed hooks to correct millis()'s notion of time (see adjustedMillis() in attached source code), but IMHO it would be much better if the underlying implementation of millis() incorporated this timing correction.
light_sleep causes getimeofday() and time() to tick too fast: The sample output below provides the values of several time counters each second. Over an interval of a couple hours, these differ from real time by ~8 seconds on my WROOM-32 module. To see this, run the sketch and compare its output with the stopwatch on your smartphone. This behavior may be a byproduct of the different oscillator used for the RTC during light_sleep mode, but trying to re-sync the ESP32 TOD clock via NTP doesn't seem to work because the difference between the real (NTP) time and ESP32 TOD clock keeps growing. If the TOD clock cannot be made more accurate, then at least it needs to be correctable by LWIP's sntp module. [An example of attempting to re-sync the TOD clock via NTP is not included here but can be furnished on request.]
Sketch:
Program source:
programSource.txt
Debug Messages:
Sample output:
sampleOutput.txt
The text was updated successfully, but these errors were encountered: