- Tue Dec 03, 2019 9:44 pm
#84809
How to use <cont.h> in Arduino-IDE ?
1)
Code: Select all// This is the base of task switching from espressif:
extern "C" {
#include <cont.h>
}
2) Declare contexts. Each context has a stack space of (cont.h) 4096 Bytes.
My tests show: without WiFi 1024 Bytes are enough
3) then you have to prepare the contexts once:
Code: Select all cont_init( & A); // prepare an own stack for TaskA
cont_init( & B);
cont_init( & C);
4) In a loop call your Tasks:
Code: Select all cont_run( & A, TaskA); // start TaskA from beginning or last cont_yield
cont_run( & B, TaskB); // start TaskB
cont_run( & C, TaskC); // start TaskC
First call cont_run will start the functions from the beginning.
next calls to cont_run(&context) will not start at the beginniing of the function, but where they left with cont_yield
I build a hole multitasking system around it and showed the building in 7 Lessons.
Here is Lesson-1, which shows the principles:
Code: Select all// Esp8266 Wemos D1 R1 and Esp8266-12F Wemos D1 mini
/*
ESP8266_CoopOS_Stack_Lesson1
(C) 2019 Helmut Weber Dph.HelmutWeber.123@gmail.com
Arduino IDE, Esp8266 Wemos D1 R1
The simplest form of Multitasking: (tick time is 1s)
All tasks are called every second from loop
>cont_init( &context ):
reserve a context with a stackspace of 4096 bytes (defined in cont.h)
>cont_run( &context, functionpointer):
switch all registers and PC to the named context - then run the function
1) first time: start the function
2) next times: got to the point of the last cont_yield in the function
>cont_yield( &context):
save context with PC and registers, switch context to caller(where cont_run occured) and return
*/
// This is the base of task switching from espressif:
extern "C" {
#include <cont.h>
}
cont_t A, B, C;
void TaskA() {
static unsigned long cnt;
Serial.println("Start TaskA");
while(1) {
cnt++;
Serial.print("TaskA-1 ");
Serial.println(cnt);
cont_yield(&A);
Serial.print("TaskA-2 ");
Serial.println(cnt);
cont_yield(&A); // save PC and all registers
// get old PC, stack (==loop)
}
}
void TaskB() {
static unsigned long cnt;
Serial.println("Start TaskB");
while(1) {
cnt++;
Serial.print("TaskB-1 ");
Serial.println(cnt);
cont_yield(&B);
Serial.print("TaskB-2 ");
Serial.println(cnt);
cont_yield(&B);
}
}
void TaskC() { // toggle internal LED
static unsigned long cnt;
Serial.println("Start TaskC");
while(1) {
digitalWrite(2,!digitalRead(2));
cont_yield(&C);
}
}
void setup() {
Serial.begin(500000);
pinMode(2,OUTPUT);
cont_init( & A); // prepare an own stack for TaskA
cont_init( & B);
cont_init( & C);
Serial.print("Setup End");
}
void loop() {
Serial.println(" loop");
cont_run( & A, TaskA); // start TaskA from beginning or last cont_yield
cont_run( & B, TaskB); // start TaskB
cont_run( & C, TaskC); // start TaskC
delay(1000);
}
Lesson 7 does 170.000 taskswitches per second, has external interrupts and 100.000 timer interrupts/s
I will publish it at github.
Just now you may look at
https://github.com/MacLeod-D/ESP8266-Multitasking-CoopOSwhich is a CoopOS (based on cont.h) with a webserver.
have fun