-
Notifications
You must be signed in to change notification settings - Fork 13.3k
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
FunctionalInterrupt/ScheduledFunctions should be in a library, not in core_esp8266_wiring_digital #6038
Conversation
…ndling: - VIP treatment in general attach/detach/handling looks untidy: extern symbols without matching header include but copy&paste special under-the-hood c++ delete support, where everyone else has to do their own resource tracking as usual. - FunctionalInterrupt is not used by anything inside core ESP8266 Arduino for 2 years now, it can be a library, which reduces precious core size for everyone else. Expose attachInterruptArg via Arduino.h.
…th functional interrupts.
It should be decided whether to reinstate these in the core, or make them an optional library.
@hreintke I should not have missed anything, so it's working as before, and bringing back the functional interrupts in one way or the other is basically a matter of changing the locations of the files, and altering #include's "" back to <>. What do you think? What about your review of my exposing attachInterruptArg(), that PR is still pending, causing me some daily grievance in my library work :-) |
@dok-net @devyte Is is correct that in your implementation all support for functional and scheduled scheduled interrupt is removed from core and a "user" needs to create it's own ? (Eventually using the example code) |
Let me first put into perspective what I believe is the state in the present master branch:
I have some reservations regarding the MT safety of the implementation of FunctionalInterrupt.h/ScheduledFunctions.h, especially on ESP32 where there is a possibility to run without core affinity. But even for single core all-userspace interrupts without atomic access, I am not so sure. As regards your question concerning backward compatibility of this PR, only in the context of PR #6003 which fixes the interoperability between FunctionalInterrupt and direct use of attachInterruptArg(), without further work there is a need for the user to use, either one or the other, the attachInterrupt/attachInterrruptArg/detatchInterrupt functions from Arduino.h directly, or stick completely to the FunctionalInterrupt.h wrappers. This is because the interrupt handling in core now has no way of telling what type of objects are behind the arg pointer, thus in general, leaking them on detach. Depending on the outcome of this discussion, it is my understanding, that there is nothing keeping us from creating a new library that provides FunctionalInterrupt and friends. Or if so decided, the files can be moved back into cores/esp8266 after addressing the mentioned shortcomings if any, and pointing the Arduino.h entry points in attachInterrupt et al at implementations in FunctionalInterrupt and "hiding" those in core_exp8266_wiring_digital.*. The same can be applied accordingly to ESP32. My take on the matter is that right now I am perfectly happy with explicitly managing the argument objects's lifetimes in user code. Probably we could also use std::function objects in interrupt_handler_t for a cleaner solution than what I perceive is in core right now. Let me ask a final question, I don't quite seem to understand how ScheduledFunctions works right now without the user code always having to call ScheduledFunctions::runScheduledFunctions() explicitly in loop()? |
It is run there (meaning: at very arduino main |
Scheduled Functions are meant to be run outside from any callback / interrupt state. |
…n attachInterruptArg(). This is sufficient for resource management - the function has static duration anyway.
…late the ISR in ICACHE_RAM rule.
aac1cdd
to
f89b22c
Compare
Any use of std::bind or std::functional objects is not ICACHE_RAM interrupt service routine policy compliant. The whole debate over FunctionalInterrupts, except the scheduled ones, is moot for this reason. Even if the check implemented in attachInterrupt doesn't catch the error, does not mean it's not inherent. |
// Arduino C API: | ||
attachInterruptArg(PIN, [](void* self) { | ||
static_cast<Button*>(self)->isr(); | ||
}, this, FALLING); // works on ESP32; fails on ESP8266: "ISR not in IRAM" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any use of std::bind, std::function or lambdas in the code-path of ISRs in fact is a case of ISR not in IRAM, just like this, only wrapped in some other functions.
//attachInterruptArg(PIN, reinterpret_cast<void(*)(void*)>(&isr_static), this, FALLING); // works on ESP32; works on ESP8266 | ||
// FunctionalInterrupts API: | ||
//attachInterrupt(PIN, [this]() { isr(); }, FALLING); // works on ESP32; works on ESP8266 | ||
//attachScheduledInterrupt(PIN, [this](InterruptInfo ii) { Serial.print("Pin "); Serial.println(ii.pin); isr(); }, FALLING); // works on ESP32; works on ESP8266 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This attachScheduledInterrupt() is a valid use of std::bind, std::function or lambdas, since the actual call is made in the context of the task that runs the scheduler, not in a interrupt service routine.
After mulling over the situation with the pending PR #6003 , I have rewritten the support for std::functional and scheduled interrupts to be less intrusive.
First, the support is revoked. Second, the refactored code is brought back as an example in libraries/esp8266/examples/GPIO/FunctionalInterrupt.
I have unified the code with the ESP32 version: espressif/arduino-esp32#2734