В чем секрет функции `yield()` arduino?

Документы Arduino объясняют yield() адресу https://www.arduino.cc/en/Reference/Scheduler в отношении срока оплаты. По-видимому, это часть библиотеки планировщика:

#include <Scheduler.h>

Тем не менее, я могу вызывать yield() на моем Nano или ESP8266 без включения библиотеки планировщика - но только в моей основной программе, а не внутри включаемых файлов. Кроме того, включение не работает на мои не-сборы.

Какой секрет, который мне не хватает в yield() or-, что делает yield() на платформах Arduino, отличных от Due?

Ответ 1

Однако я могу назвать yield() на моем Nano или ESP8266 без включения Планировщик lib

Функция yield() также реализована внутри библиотек ESP8266:

Уступая

Это одно из самых важных различий между ESP8266 и более классический микроконтроллер Arduino. ESP8266 запускает много функции утилит в фоновом режиме - поддержание WiFi, управление стек TCP/IP и выполнение других обязанностей. Блокирование этих функции от запуска могут привести к сбою ESP8266 и resetсам. Чтобы избежать этих таинственных сбросов, избегайте длинных, блокирующих петель в вашем эскизе.

Удивительные создатели библиотек Arduino ESP8266 также реализованы функция yield(), которая требует, чтобы функции фона позволяли им делать свои дела.

Вот почему вы можете вызвать yield() из вашей основной программы, в которую включен заголовок ESP8266.

См. ESP8266 Руководство по настройке Things.

Обновление

yield() определяется в Arduino.h как:

void yield(void);

yield() также объявляется в hooks.h следующим образом:

/**
 * 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")));

Итак, на Nano он, вероятно, ничего не делает (если у вас нет других библиотек #included).

Ответ 2

выход является "слабой" функцией от ядра Arduino для AVR. Я вижу один вызов для него внутри wiring.c.

void delay(unsigned long ms)
{
    uint32_t start = micros();

    while (ms > 0) {
        yield();
        while ( ms > 0 && (micros() - start) >= 1000) {
            ms--;
            start += 1000;
        }
    }
}

Это означает, что функция yield() будет выполняться во время цикла функции задержки. Таким образом, выход будет использоваться для некоторой фоновой обработки, пока заканчивается задержка или для выполнения функции с функцией тайм-аута.

Примечание: выход должен быть определен в приложении/эскизе

ОБНОВЛЕНИЕ: вопрос заставил меня взволнованно сделать небольшую публикацию о урожае и других скрытых функциях от ядра arduino.

Ответ 3

Подробное объяснение о yield() Я нашел это очень подробное объяснение использования yield() в ESP8266. Из того, что я знаю, ESP8266 нужно периодически запускать Wifi Stack, иначе ваш ESP будет выпадать из вашего роутера. Так что с помощью функции yield() ваш стек Wifi будет работать.