-
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
delay() refactoring #6212
delay() refactoring #6212
Conversation
Refactoring delay to allow to run esp_schedule() and esp_yield() periodically (not only on delay ends). This will be helpfull in implementation of Ethernet dirver.
Per this detailed explanation, This is used in some places in the core, so we also need to
However this PR is very nice for recurrent scheduled functions to be called when some libraries or sketches call (edit: link to ethernet thread) |
This delay is supposed to be interrupted by
|
delay() replaced with code simular to #6213
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.
Are there really no other delays that are meant to be interrupted anywhere in the code? I thought some of the TCP timeouts would be like that (WiFiClient or ClientContext etc)
Other delays (in ClientContext) updated during #6213 |
@devyte Please, with all due respect, this PR right now is a horrible idea from my POV, given that it would, depending on how exactly it's fixed, either terribly break or at least work against the (cooperative multi-loop() multitasking/multithreading library CoopTask](https://github.com/dok-net/CoopTask). I cannot be sure to claim that CoopTask is sufficiently evolved to handle what #6213 needs (believing it does so fine is another thing ;-) ), but letting other code run during |
@dok-net |
@d-a-v @devyte I think it's not as simple as that, because it's not the delays, but the breaking from the delays that is troubling: libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp:657: esp_schedule(); // resume the hostByName function
libraries/ESP8266WiFi/src/ESP8266WiFiScan.cpp:326: esp_schedule();
libraries/ESP8266WiFi/src/ESP8266WiFiSTA-WPS.cpp:110: esp_schedule(); // resume the beginWPSConfig function
libraries/ESP8266WiFi/src/include/ClientContext.h:438: esp_schedule(); // break current delay()
libraries/ESP8266WiFi/src/include/ClientContext.h:539: esp_schedule(); // break current delay()
libraries/ESP8266WiFi/src/include/ClientContext.h:615: esp_schedule(); // break current delay() Once there are multiple concurrent delays in multitasking, the concept of "current delay()" no longer applies. Add on top that the esp_scheduler follows only a minimal 2 task design, sys and cont, and there is no off-the-shelf solution to this problem. // Following delay will be interrupted by connect callback
for (decltype(_timeout_ms) i = 0; _connect_pending && i < _timeout_ms; i++) {
// Give scheduled functions a chance to run (e.g. Ethernet uses recurrent)
delay(1);
} would work without the |
I think you don't understand @dok-net We can modify the delay(1) loop that you cite above to call a function that does the same job, and make it weak. So you can redefine it with whatever you think is good for your library. You know we can adapt, and we often do, so every use case has its chance to live and work. We can do that for both function delay and delay_interruptible, both can be weak. So you don't need to be so much concerned about that. Ethernet is not yet merged and this PR will probably happen afterwards. |
@d-a-v Each time there is code that expects |
I'd like to point out that the changes in this PR are contradictory and there's a lack of separation of concern. The change in ESP8266WiFiGeneric.cpp has nothing to do with the delay()/interruptable_delay() changes, as the use of delay(1) is simply made a bit less efficient due to the oneShotMs loop guard. Also it's interruptible (with an I). |
Dear all, I am in early stage to use ethernet driver in my esp8266 and it appears that I faced some issue with the name resolution which takes much longer than via WIFI. Seems that the delay used in the "hostByName" function could be one of the cause. I propose to change it to a non blocking delay using the following patch: diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp
b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cppba07e07 100644
+++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp
@@ -632,7 +632,8 @@ int ESP8266WiFiGenericClass::hostByName(const char*
aHostname, IPAddress& aResul
aResult = IPAddress(&addr);
} else if(err == ERR_INPROGRESS) {
_dns_lookup_pending = true;
- delay(timeout_ms);
+ for (int i = 0; i < timeout_ms && !aResult.isSet(); i++)
+ delay(1);
// will resume on timeout or when wifi_dns_found_callback fires
_dns_lookup_pending = false;
// will return here when dns_found_callback fires |
Hello @d-a-v , |
@MassiPi I'm afraid we'll have to wait a bit more, |
esp_yield() now also calls esp_schedule(), original esp_yield() function renamed to esp_suspend(). Don't use delay(0) in the Core internals, libraries and examples. Use yield() when the code is supposed to be called from CONT, use esp_yield() when the code can be called from either CONT or SYS. Clean-up esp_yield() and esp_schedule() declarations across the code and use coredecls.h instead. Implement helper functions for libraries that were previously using esp_yield(), esp_schedule() and esp_delay() directly to wait for certain SYS context tasks to complete. Correctly use esp_delay() for timeouts, make sure scheduled functions have a chance to run (e.g. LwIP_Ethernet uses recurrent) Related issues: - #6107 - discussion about the esp_yield() and esp_delay() usage in ClientContext - #6212 - discussion about replacing delay() with a blocking loop - #6680 - pull request introducing LwIP-based Ethernet - #7146 - discussion that originated UART code changes - #7969 - proposal to remove delay(0) from the example code - #8291 - discussion related to the run_scheduled_recurrent_functions() usage in LwIP Ethernet - #8317 - yieldUntil() implementation, similar to the esp_delay() overload with a timeout and a 0 interval
Closing via #7148 |
Refactoring delay to allow to run esp_schedule() and esp_yield()
periodically (not only on delay ends).
This will be helpfull in implementation of Ethernet dirver.