Skip to content

Should schedule_function() call esp_schedule()? #7661

Open
@matthijskooijman

Description

@matthijskooijman

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 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.

#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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions