-->
Page 1 of 1

Cooperative multitasking?

PostPosted: Thu Mar 17, 2016 1:47 am
by malachi
Is anyone able to achieve cooperative multitasking? Nothing I've tried short of hacking cont_run and cont_init seem to work out. I want a behavior like https://github.com/mikaelpatel/Arduino-Scheduler -- any ideas? I got punted off arduino.stackexchange.com for asking this question, so I am feeling like a real rebel now =)

Re: Cooperative multitasking?

PostPosted: Sat Mar 26, 2016 11:09 am
by mrburnette
malachi wrote:Is anyone able to achieve cooperative multitasking?


I suspect you have read this thread, it discusses with examples the eSP8266 in an Arduino environment with simplistic Preemptive/Cooperative examples. I'm not really pleased with the example implementations, but it is a start.

I suspect that one could roll-their-own methodology based on a state-machine and the ms timer. The major problem with getting too fancy is that one must absolutely yield often so that the currently implemented "multitask" Arduino-on-ESP8266 can service the RF section of the binary; this means using delay(0) or yield() or ensuring that the loop() function completes no longer than approximately 20mS --50mS max.

WiFi and TCP/IP libraries get a chance to handle any pending events each time the loop() function completes, OR when delay is called. If you have a loop somewhere in your sketch that takes a lot of time (>50ms) without calling delay, you might consider adding a call to delay function to keep the WiFi stack running smoothly.
...
There is also a yield() function which is equivalent to delay(0). The delayMicroseconds function, on the other hand, does not yield to other tasks, so using it for delays more than 20 milliseconds is not recommended.

https://github.com/esp8266/Arduino/blob/master/doc/reference.md

So, if you set up your tasks something like:
Code: Select allvoid loop()
{
     task1();
     task2();
     task3();
}


... and you profile all three tasks (that is, the total time to process loop() and it takes less than 20mS, there is nothing to worry about. The top of the loop will automatically call yield().
... or, if you profile all three tasks and the time is > 20mS, you can put a yield() between two of the tasks; or simply put a yield() after task1, after task2 remembering that there is an implied yield() after task3 (end of loop == top of loop for timing.)

So, thinking like the above, you have the following:
Code: Select allvoid loop()
{
     task1();
     yield();
     task2();
     yield();
     task3();
     // yield() // implied
}


To be super safe, profile each taskx and make certain none are over 50mS maximum!


Ray

Re: Cooperative multitasking?

PostPosted: Sat Jul 13, 2019 6:43 am
by heweb123
I 've started the thread you linked to.

You are right: it is very important to do yield() inside a task very often - and that can be ugly.
But EVERY cooperative multitasking - no matter how it is implemented - has this drawback!
If you can live with this cooperating multitasking can be a powerful tool.

Here is a full example for ESP8266 with WIFI , interrupts, skeleton of a debugger:

https://github.com/MacLeod-D/ESP8266-Mu ... ing-CoopOS