Task isn't yielding on vTaskdelay duration

Config Settings: Preemption is enabled
Time slicing is disabled
Should yield is enabled

I have created two tasks should trigger every 1ms and 5ms
In 1ms task , I am trying toggling gpio pin

void Task1ms(void *pvParameters)
{
(void)pvParameters;

for (;;)
{
	 result3 = add_variable - 5;
     --add_variable;
   
    toggleP15_1();
    vTaskDelay(pdMS_TO_TICKS(2));
   
}

}
which continuously toggling before completion of time delay, it should toggle after every given delay but it is toggling continuously , that means task is coming back before given delay

Please suggest what is going wrong

How many more times do you want to ask the same question? We have answered that to you only a perceived half million times, pointing you to numerous explanations.

1 Like

@RAC Before answering the question please look into my question, if you are trying answer please answer with practical scenario what i posted otherwise leave it , theory part also i knew it…you always provide some links but not actual solution.
This problem is practical and different
which continuously toggling before completion of time delay, it should toggle after every given delay but it is toggling continuously , that means task is coming back before given delay

Have you really setup your system for a 1ms tick granularity? Normally it is 5 or 10ms which means that pdMS_TO_TICKS(2) may resolve to 0 which would be no wait.

@RAC Yes, I setup the system tick 1ms only

from the description it is appearing like, task is not yeilding as per defined delay, it is continuously coming to ready state even before wait period is finishing. this is not tick issue. any one freertos port expert who can comment on this?

@RAc it is not mandatory how much delay should be, there are not defined count to be given, it is dependent on task periodic wake up time required by the application.

Please read this - Tick Resolution - FreeRTOS™. How did you confirm that the task is not yielding? Did you use Tracelyzer?

@aggarg thank you for sharing the link, I am already aware about this. and yes, we have used DSO, where we have observed task is continuously executing even before its waiting period finishes, we saw it with toggeling the io, instead of one time toggle it toggeled for defined tick rate example 1ms and then went on block for wating time defined. it proves it is not yielding, actually it is mixed behaviour, it is working like time sliced tasks, with priority defined, the problem is we have disabled time slicing in config, and enabled preemption, so this behaviour is not acceptable.

is this a custom port or one shipped with FreeRTOS? What is your target platform?

The descriptions are not very clear and you need to help us decipher these. Lets start with the task definition you provided in the first post:

void Task1ms(void *pvParameters)
{
  (void)pvParameters;
  
  for (;;)
  {
  	 result3 = add_variable - 5;
       --add_variable;
     
      toggleP15_1();
      vTaskDelay(pdMS_TO_TICKS(2));
     
  }
}

The above code does the following:

  1. It calls toggleP15_1.
  2. It enters the blocked state by calling vTaskDelay. It will unblock on the 2nd tick interrupt.
  3. The moment it blocks, the scheduler picks the next highest priority ready task to run.
  4. On the 2nd tick interrupt, this task unblocks and runs again (assuming no other higher priority task has become ready).

Do you observe this behavior or something else? What behavior do you expect? Let me also explain time slicing.

Time Slicing - Time slicing is used to share processing time between tasks of equal priority, even when the tasks do not explicitly yield or enter the Blocked state. Time Slicing selects a new task to run at the end of each time slice if there are other Ready state tasks that have the same priority as the Running task.

Lets say there are 2 equal priority tasks which never block:

uint32_t task1Counter = 0;
uint32_t task2Counter = 0;

void task1( void * param )
{
    for( ;; )
    {
        task1Counter++;
    }
}

void task2( void * param )
{
    for( ;; )
    {
        task2Counter++;
    }
}

Note that these tasks never enter blocked state.

  1. If you turn on time slicing, these tasks will take turns.
  2. If you turn off time slicing, one of these tasks will run forever.

I also recommend reading the following tutorials: