// Question: How pre-emptive is FreeRTOS ?
// Answer : Fully pre-emptive in every way
// This Wokwi project: https://wokwi.com/projects/403090705288099841
const int pinLedZero = 14;
const int pinLedOne = 27;
const int pinLedTwo = 26;
const int pinLedThree = 25;
volatile unsigned long counterOne;
bool stateOne = false;
void setup()
{
Serial.begin(115200);
Serial.println("Starting");
pinMode(pinLedZero, OUTPUT);
// Not only the priority can be set,
// some systems have a extra "portPRIVILEGE_BIT"
xTaskCreate(taskOne, "One" , 1000, NULL, 1, NULL);
xTaskCreate(taskTwo, "Two" , 1000, NULL, 1, NULL);
xTaskCreate(taskThree, "Three", 1000, NULL, 1, NULL);
}
void loop()
{
Serial.print("Task Zero: counter of task One is = ");
Serial.println(counterOne);
delay(1000);
digitalWrite(pinLedZero, HIGH);
delay(200);
digitalWrite(pinLedZero, LOW);
}
void taskOne(void * pvParameters)
{
pinMode(pinLedOne, OUTPUT);
// Blocking code ! No delay, no wait.
// Comment out the digitalWrite to be 100% sure.
// The other tasks run as well.
for(;;)
{
counterOne++;
if(counterOne % 500000UL == 0)
{
digitalWrite(pinLedOne, stateOne ? HIGH : LOW);
stateOne = !stateOne;
}
}
}
void taskTwo(void * pvParameters)
{
pinMode(pinLedTwo, OUTPUT);
for(;;)
{
digitalWrite(pinLedTwo, HIGH);
delay(1000); // delay calls vTaskDelay
digitalWrite(pinLedTwo, LOW);
delay(1000); // delay calls vTaskDelay
}
}
void taskThree(void * pvParameters)
{
pinMode(pinLedThree, OUTPUT);
for(;;)
{
digitalWrite(pinLedThree, HIGH);
vTaskDelay(500 / portTICK_PERIOD_MS);
digitalWrite(pinLedThree, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}