What does a delay(0) actually do? - Arduino Stack Exchange
yield(), esp_yield() or delay(0) ?
Yield and Delay
Trying to understand yield()
However, I can call yield() on my Nano or ESP8266 without including the Scheduler lib
The yield() function is also implemented inside the ESP8266 libraries:
Yielding
This is one of the most critical differences between the ESP8266 and a more classical Arduino microcontroller. The ESP8266 runs a lot of utility functions in the background – keeping WiFi connected, managing the TCP/IP stack, and performing other duties. Blocking these functions from running can cause the ESP8266 to crash and reset itself. To avoid these mysterious resets, avoid long, blocking loops in your sketch.
The amazing creators of the ESP8266 Arduino libraries also implemented a yield() function, which calls on the background functions to allow them to do their things.
That's why you can call yield() from within your main program where the ESP8266 header is included.
See ESP8266 Thing Hookup Guide.
Update:
yield() is defined in Arduino.h as:
void yield(void);
yield() is also declared in hooks.h as follows:
/**
* Empty yield() hook.
*
* This function is intended to be used by library writers to build
* libraries or sketches that supports cooperative threads.
*
* Its defined as a weak symbol and it can be redefined to implement a
* real cooperative scheduler.
*/
static void __empty() {
// Empty
}
void yield(void) __attribute__ ((weak, alias("__empty")));
So, on the Nano, it probably does nothing (unless you have other libraries #included).
yield is a "weak" function from Arduino core for AVR. I see one call for it inside wiring.c.
void delay(unsigned long ms)
{
uint32_t start = micros();
while (ms > 0) {
yield();
while ( ms > 0 && (micros() - start) >= 1000) {
ms--;
start += 1000;
}
}
}
This means that the yield() function will be executed during the loop of delay function. Thus, yield would be used for some background processing while the delay ends or for doing a function with timeout feature.
Note: yield must be defined in application/sketch
UPDATE: The question made me excited to make a little post about yield and other hidden features from arduino core.
A task on my core 0 was causing a watchdog reset, so I changed the yield() to a delay(), and that fixed it. But I was under the impression that yield() should be sufficient to whack the watchdog, and I don't really =need= or want a delay here.
Any ideas? Sorry for the messy code, but I wanted to paste it verbatim! All the defines are true, so all the code is included.
void NetworkHandlingLoop(void *)
{
#if ENABLE_WEBSERVER
TFTStatus("Starting Web Server...");
debugI("Starting Web Server...");
g_WebServer.begin();
debugI("Web Server Started!");
#endif
for (;;)
{
#if ENABLE_WIFI
timeval tv;
gettimeofday(&tv, nullptr);
int x = tv.tv_usec / 10000;
x = x % 50; //digitalWrite(BUILTIN_LED_PIN, x <= 5);
static uint32_t lastTimeCheck = 0;
if (millis() - lastTimeCheck > TIME_CHECK_INTERVAL_MS)
{
lastTimeCheck = millis();
debugI("Refreshing Time from Server...");
digitalWrite(BUILTIN_LED_PIN, 1);
g_NtpTimeClient.UnsetClock();
g_NtpTimeClient.UpdateClockFromWeb(&g_Udp);
lastTimeCheck = millis();
#endif
#if ENABLE_OTA
ArduinoOTA.handle();
#endif
#ifdef ENABLE_WIFI
Debug.handle();
#endif
delay(10);
}
}Here's how it's implemented in the Arduino AVR Boards core: https://github.com/arduino/Arduino/blob/1.8.3/hardware/arduino/avr/cores/arduino/hooks.c#L19-L31
void yield(void) __attribute__ ((weak, alias("__empty")));
As the comments in that file explain:
Empty yield() hook. This function is intended to be used by library writers to build libraries or sketches that supports cooperative threads. Its defined as a weak symbol and it can be redefined to implement a real cooperative scheduler.
So you can define yield() in your own code if you like. Otherwise the empty definition will prevent the undefined reference error you encountered.
Of course it's better to write proper non-blocking code rather than using this yield() workaround but you asked how the Arduino IDE handles it and so there you have it.
Although delays, as the commenters suggest, are usually to be avoided, most of us who program bare metal Atmel chips start off with the blinking LED program. It's the "Hello World" of bare-metal embedded programming. A delay is fine for this.
If you will look in you util/delay.h though, you will see functions that are especially written for your chip. Use those instead and do not link in the Arduino versions. You will find a _delay_ms() and _delay_us() functions which are perfect for this first-steps type of program.