Brief task suspension when using xTaskCreate - FreeRTOS on ESP32

I have boiled a problem I am having down to something really simple - a function toggling a pin high and low very quickly.

If I do not use freeRTOS I get a continuous oscillation on the output pin, see photo.
However if I use the code below I get output on oscilloscope (1ms/div):

Approximately every 1ms, the pin does not toggle for around 1ms

Here is my code:

void task1(void* pvParameters)
{
  for(;;)
  {     
    digitalWrite(27, HIGH);
    digitalWrite(27, LOW);
  }
}

void setup()
{
  pinMode(26,OUTPUT);
  pinMode(27,OUTPUT);

  // creates task to pack adc on core 1 indefinitely (for multithreading)
  xTaskCreatePinnedToCore(task1, "task1", 6080, NULL, 0, NULL, 1);
}

void loop()
{ 
  vTaskDelete(NULL);
}

Any suggestions as to why I get this task suspension and how to remove it will be much appreciated.

Cheers,

Will

Do you have any other tasks on that core?

Is this task’s priority set to zero? [Edit: I see you posted that code – yes, it is set to priority zero.] If so, did you define configIDLE_SHOULD_YIELD to zero?

Is the loop() function you posted relevant to your question?

1 Like

Or you can try increasing the priority of your task.

1 Like

Well that was easy. I thought that priority levels were just relative to each other but I guess it also sets how much the scheduler conducts the task. Much appreciated

No, not in the sense of an OS like Windows where a low priority task will get less time than a higher priority task if both are compute-bound.

Task Priority is STRICTLY observed, if a higher priority task is ready, it will be switched to at the earliest possible allowed instance (depending on things like is pre-emption allowed), and it will be given the CPU until it no longer needs it, or another task of higher priority (or equal if time-slicing is enabled) becomes ready.

There is one task that is ALWAYS ready to run, the idle task, as FreeRTOS doesn’t know how to ‘stop’ a CPU and make it do nothing, so has this idle task to use up any otherwise unneeded CPU time.

To add to Richard’s explanation, any tasks you put at priority zero are time sliced with the idle task. To prevent the idle task from taking an entire timeslice when another task is ready to run at priority zero, set configIDLE_SHOULD_YIELD to 1 (or don’t set it at all, which results in the default setting of 1).