web-dev-qa-db-ja.com

Arduinoの `yield()`関数の秘密は何ですか?

Arduinoのドキュメントでは、 https://www.arduino.cc/en/Reference/Scheduler でDueに関してyield()を説明しています。どうやら、それはスケジューラライブラリの一部です。

_#include <Scheduler.h>
_

ただし、スケジューラライブラリを含めずにNanoまたはESP8266でyield()を呼び出すことはできますが、インクルードファイル内ではなく、メインプログラムでのみ呼び出すことができます。また、インクルードは私のデュース以外では機能しません。

yield()について私が見逃している秘密は何ですか?または、Due以外のArduinoプラットフォームでyield()は何をしますか?

15
andig

ただし、スケジューラライブラリを含めずに、NanoまたはESP8266でyield()を呼び出すことができます

yield()関数もESP8266ライブラリ内に実装されています。

降伏

これは、ESP8266と従来のArduinoマイクロコントローラーの最も重要な違いの1つです。 ESP8266は、バックグラウンドで多くのユーティリティ機能を実行します。WiFiの接続を維持し、TCP/IPスタックを管理し、その他の業務を実行します。これらの機能の実行をブロックすると、ESP8266がクラッシュしてリセットされる可能性があります。これらの不可解なリセットを回避するには、スケッチ内の長いブロッキングループを回避します。

ESP8266 Arduinoライブラリのすばらしい作成者は、yield()functionも実装しました。

そのため、ESP8266ヘッダーが含まれているメインプログラム内からyield()を呼び出すことができます。

ESP8266 Thing Hookup Guide を参照してください。

更新

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_がない限り)何もしません。

28
Danny_ds

yieldは、AVRのArduinoコアからの「弱い」関数です。 Wiring.c内で1つの呼び出しが表示されます。

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

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

これは、遅延関数のループ中にyield()関数が実行されることを意味します。したがって、遅延が終了する間のバックグラウンド処理やタイムアウト機能を使用した機能の実行にyieldが使用されます。

注:収量はアプリケーション/スケッチで定義する必要があります

更新:この質問により、少し arduinoコアのyieldおよびその他の隠された機能に関する投稿 を作成することに興奮しました。

2
yahya tawil