user13327: I understand that the official Arduino Scheduler doesn't support Uno, and there are several third-party schedulers to fill the gap, notably, Scheduler, Arduino-Scheduler and TaskScheduler. There are probably many more, though I see that many so-called "task schedulers" are actually just periodic function callers which don't handle context (i.e. they don't support yield()).
I need to make a choice of a scheduler to use in a project (a real one, with yield, not a periodic function caller). Is there any comparison of Arduino task schedulers? I'm specifically interested in the following aspects:

context switching time (the most important one)
RAM/ROM consumption estimation
list of supported boards


user13327: I have just tested vbextreme/Scheduler and Arduino-Scheduler using the following code:
#include <Scheduler.h> 

void setup() {
  pinMode(3, OUTPUT);
  Scheduler.startLoop(loop2);
}

void loop() {
  digitalWrite(3, LOW);
  yield();
  digitalWrite(3, HIGH);
  yield();
}

void loop2() {
  yield();
}

Without any Scheduler lines, the code occupies 734 bytes of ROM, 9 bytes of RAM, and the pin toggles with a period of 8.5 us (117 kHz). The numbers below represent the additional ROM/RAM/execution time:

vbextreme/Scheduler occupies additional 1676 bytes of ROM, 70 bytes of RAM, and the context switch takes 15.5 us (toggle frequency 14.18 kHz). It seems to only support AVR/SAMD boards.

vbextreme/Scheduler with CONFIG_AVR_OPTIMIZE_COOPERATIVE set to 1 occupies additional 1568 bytes of ROM, 70 bytes of RAM, and the context switch takes 11 us (toggle frequency 19.07 kHz).

Arduino-Scheduler occupies additional 578 bytes of ROM, 44 bytes of RAM, and the context switch takes 10.6 us (toggle frequency 19.59 kHz). It supports AVR/SAMD and some of the Teensy/STM32 boards. It seems that this scheduler is not compatible with tasks which use malloc().

CopyThreads occupies an additional 2148 bytes of ROM, 41 bytes of RAM, and the context switch takes 54.5 us (toggle frequency 4.417 kHz). This scheduler claims to have the advantage of using a single stack, so as long as tasks do not yield during peak stack usage, each task has essentially the complete stack at its disposal.


I couldn't get the equivalent code for TaskScheduler to run, I'll be grateful if someone posts an answer featuring schedulers I didn't test.

13327: <p>I understand that the official <a href="https://www.arduino.cc/en/Reference/Scheduler" rel="noreferrer">Arduino Scheduler</a> doesn't support Uno, and there are several third-party schedulers to fill the gap, notably, <a href="https://github.com/vbextreme/Scheduler" rel="noreferrer">Scheduler</a>, <a href="https://github.com/mikaelpatel/Arduino-Scheduler" rel="noreferrer">Arduino-Scheduler</a> and <a href="https://github.com/arkhipenko/TaskScheduler" rel="noreferrer">TaskScheduler</a>. There are probably many more, though I see that many so-called &quot;task schedulers&quot; are actually just periodic function callers which don't handle context (i.e. they don't support <code>yield()</code>).</p>
<p>I need to make a choice of a scheduler to use in a project (a real one, with <code>yield</code>, not a periodic function caller). Is there any comparison of Arduino task schedulers? I'm specifically interested in the following aspects:</p>
<ul>
<li>context switching time (the most important one)</li>
<li>RAM/ROM consumption estimation</li>
<li>list of supported boards</li>
</ul>
 13327: <p>I have just tested <code>vbextreme/Scheduler</code> and <code>Arduino-Scheduler</code> using the following code:</p>
<pre><code>#include &lt;Scheduler.h&gt; 

void setup() {
  pinMode(3, OUTPUT);
  Scheduler.startLoop(loop2);
}

void loop() {
  digitalWrite(3, LOW);
  yield();
  digitalWrite(3, HIGH);
  yield();
}

void loop2() {
  yield();
}
</code></pre>
<p>Without any <code>Scheduler</code> lines, the code occupies 734 bytes of ROM, 9 bytes of RAM, and the pin toggles with a period of 8.5 us (117 kHz). The numbers below represent the additional ROM/RAM/execution time:</p>
<ul>
<li><p><a href="https://github.com/vbextreme/Scheduler" rel="nofollow noreferrer"><code>vbextreme/Scheduler</code></a> occupies additional 1676 bytes of ROM, 70 bytes of RAM, and the context switch takes 15.5 us (toggle frequency 14.18 kHz). It seems to only support AVR/SAMD boards.</p>
</li>
<li><p><code>vbextreme/Scheduler</code> with <code>CONFIG_AVR_OPTIMIZE_COOPERATIVE</code> set to 1 occupies additional 1568 bytes of ROM, 70 bytes of RAM, and the context switch takes 11 us (toggle frequency 19.07 kHz).</p>
</li>
<li><p><a href="https://github.com/mikaelpatel/Arduino-Scheduler" rel="nofollow noreferrer"><code>Arduino-Scheduler</code></a> occupies additional 578 bytes of ROM, 44 bytes of RAM, and the context switch takes 10.6 us (toggle frequency 19.59 kHz). It supports AVR/SAMD and some of the Teensy/STM32 boards. It seems that this scheduler is not compatible with tasks which use <code>malloc()</code>.</p>
</li>
<li><p><a href="https://github.com/jensh/CopyThreads" rel="nofollow noreferrer"><code>CopyThreads</code></a> occupies an additional 2148 bytes of ROM, 41 bytes of RAM, and the context switch takes 54.5 us (toggle frequency 4.417 kHz). This scheduler claims to have the advantage of using a single stack, so as long as tasks do not <code>yield</code> during peak stack usage, each task has essentially the complete stack at its disposal.</p>
</li>
</ul>
<p>I couldn't get the equivalent code for <code>TaskScheduler</code> to run, I'll be grateful if someone posts an answer featuring schedulers I didn't test.</p>
