Description
Basic Infos
- This issue complies with the issue POLICY doc.
- I have read the documentation at readthedocs and the issue is not addressed there.
- I have tested that the issue is present in current master branch (aka latest git).
I tried, but the latest master requires GCC10 and I'm not sure how to get this installed. - I have searched the issue tracker for a similar issue.
- I have filled out all fields below.
Platform
- Hardware: Feather Huzzah ESP8266
- Core Version: 2.7.4
- Development Env: Arduino IDE
- Operating System: Ubuntu
Settings in IDE
-fqbn=esp8266:esp8266:huzzah:xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Serial,lvl=CORE,wipe=none,baud=460800
Problem Description
I'm building a sketch that essentially always sleeps, but needs to wakeup on a pin interrupt and then do some network traffic.
Some observations & assumptions:
- When using light sleep, AFAIU I need to put
esp_yield()
in my loop for when it has nothing left to do (to ensure the CPU can sleep, rather than continuously having to keep callingloop()
). - A sketch can be woken up from sleep by an interrupt using
attachInterrupt()
with e.g. theONHIGH_WE
. - You cannot do real work from an ISR (e.g. do network traffic), this must be done from the main loop (or another task). This can be done using
schedule_function
to call some code after the next loop iteration. - In the main loop function, the
esp_yield()
, will not return untilesp_schedule()
is called elsewhere. - So to make this work, from the interrupt handler, I now have to call both
schedule_function()
to schedule some code to run later, andesp_schedule()
to actually make sure the loop function continues and the scheduled function can run. - When using other code that calls
schedule_function()
(e.g.Ticker.once_scheduled()
) that I have no control over, this breaks (so e.g. for Ticker I have to do a non-scheduledTicker.once()
with a function that calls bothschedule_function()
andesp_schedule()
, but that might not be always possible with other interfaces).
Maybe I'm misunderstanding how to approach my original problem, but if the above approach is correct, then maybe it would be good if schedule_function()
would just always call esp_schedule()
? (or, if it is harmful to call it when already inside the loop, then maybe the call can be done only when outside the main loop, e.g. by checking can_yield()
or so?).
Doing so would mean that schedule_function()
would just always work to ensure the given function is called, even when the mainloop is not currently running?
Sketch
To illustrate the problem, here's something that I think should turn the led on pin 0 on (LOW
), and schedule a function that turns the led off after 5 seconds. I left out the actual sleeping and interrupt handling out, to simplify the example. If it helps to clarify, I can provide a more complete example with those as well.
#include <Arduino.h>
#include <Ticker.h>
Ticker ticker;
void setup() {
pinMode(0, OUTPUT);
digitalWrite(0, LOW);
}
extern "C" void esp_yield(void);
void loop() {
ticker.once_scheduled(5, [](){ digitalWrite(0, HIGH); });
esp_yield();
}
Debug Messages
SDK:2.2.2-dev(38a443e)/Core:2.7.3-3-g2843a5ac=20703003/lwIP:STABLE-2_1_2_RELEASE/glue:1.2-30-g92add50/BearSSL:5c771be
(nothing else appears on serial)