esp8266 / esp8266/Arduino

Should schedule_function() call esp_schedule()?

Open
#7,661 31 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
16.7k
Forks
13.1k
PR merge metrics
No merged PRs in 30d

Description

### Basic Infos

- [x] This issue complies with the [issue POLICY doc](https://github.com/esp8266/Arduino/blob/master/POLICY.md).
- [x] I have read the documentation at [readthedocs](https://arduino-esp8266.readthedocs.io/en/latest) 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.
- [x] I have searched the issue tracker for a similar issue.
- [x] 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 calling `loop()`).
- A sketch can be woken up from sleep by an interrupt using `attachInterrupt()` with e.g. the `ONHIGH_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 until `esp_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, and `esp_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-scheduled `Ticker.once()` with a function that calls both `schedule_function()` *and* `esp_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.

```cpp
#include
#include

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)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.