FreeRTOS – Changing Tasks Priorities

Keywords: Embedded systems, ARM, FreeRTOS, STM32F4, Tasks, Task Priorities

Code Link: Tutorial Source Code Github – Keil

In the previous tutorials we showed how to create FreeRTOS Tasks and pass parameters to it. In this tutorial we will demonstrate two things.

  1. Effect of Task Priority on Task Execution
  2. Changing Task priority on fly

Note: The tutorial assumes Priority based Preemptive Scheduling (The default scheduling algorithm of FreeRTOS) according to which Tasks are executed based on Task priorities. Higher the priority, the first it will be executed.

As we mentioned earlier that scheduler always run the highest priority Ready task (in Priority based Preemptive Scheduling algorithm). In this tutorial we will create two FreeRTOS Tasks (Task-1, Task-2) with equal priorities. After 10 Task Switching iterations, we will rise Task Task-1 priority such that:

Priority of Task-1 > Priority of Task-2

Now that the Task-1 has the higher priority so as per scheduler policy it will keep running forever. This is because each time the scheduler tick interrupt occurs (to switch task), it finds Task-1 as the highest priority Ready task in queue.

Task-1 will keep running until another higher priority task gets ready or the priority of Task-1 is made lower/equal to Task-2. We will let Task-1 keep running for 10 task switching iteration, after that we will lower the Task-1 priority to be equal to Task-2 and vise versa. The process is summarized in Figure-1.

Figure-1: Changing Task-1 Priority after each 10 Task Switching Iterations.

As shown in the Figure-1, for the first 10 iterations both Task-1 and Task-2 runs alternatively as both have equal priority. At 10th iteration, the priority of Task-1 is increased. Now for next 10 iterations we kept Task-1 priority higher than Task-2 so only Task-1 will be allowed to run as per scheduling policy. After 10 iterations (at 20 iteration in total), we again lowered the Task-1 priority to be equal to Task-2. Now as both tasks again have equal priority so both will run alternatively and vise versa.

Task Priority APIs:

Two APIs are used to inquire freeRTOS Tasks Priorities.

  1. UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask );
  2. void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );

uxTaskPriorityGet(…):

This API returns the task priority of handle xTask given as argument. Passing a NULL handle results in the priority of the calling task being returned.

Note: In FreeRTOSConfig.h header file, INCLUDE_vTaskPriorityGet must be defined as 1 for this function to be available.

vTaskPrioritySet(…):

This API sets the task priority of handle xTask given as argument to the new value given in parameter uxNewPriority. Passing a NULL handle results in setting the priority of the calling task.

Note: In FreeRTOSConfig.h header file, INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available.

Let’s jump to programming.

Steps

1. First of all declare TaskHandle_t handler for Task-1 which will be used in Task Priority APIs.

TaskHandle_t hTask1;

2. Next create two FreeRTOS Tasks of equal priorities. As we will change Task-1 priority on fly so we need to refer to Task-1 later in code. For this purpose we need a task handler. we have already declared a global TaskHandle_t handler in previous step. Here we will only pass its pointer to xTaskCreat(...) API.

  const int task_1_Param = 1;
  const int task_2_Param = 2;

  xTaskCreate (vTask, "T1", 150, (void *)&task_1_Param, 1, &hTask1);

  xTaskCreate (vTask, "T2", 150, (void *)&task_2_Param, 1, NULL);

3. Define a counter variable to be used to count number of times tasks being switched.

int counter = 0;

4. Upon 10th iteration, raise the priority of Task-1 by 1. At this point forward only Task-1 will run as it has the higher priority than Task-2.

if (counter == 10) {
      
    printf("Raising Task-1 Priority....\n"); 
    vTaskPrioritySet(hTask1, uxTaskPriorityGet(hTask1)+1);   
}

5. Upon 20th iteration, lower the priority of Task-1 by 1. At this point forward both Tasks will run alternatively as both Tasks have equal priorities.

if (counter == 20) {
     
    printf("Lowering Task-1 Priority....\n");
    vTaskPrioritySet(hTask1, uxTaskPriorityGet(hTask1)-1);
    counter = 0;
}

The complete Task function code is given bellow.

void vTask(void * pvParams) {

  volatile unsigned int i = 0;
  const int * tParam = (const int *)pvParams;
 
  for (;;) {
    
    printf("Task-%d Running.\n", *tParam);  
    
    counter++;
    if (counter == 10) {
      
      printf("Raising Task-1 Priority....\n"); 
      vTaskPrioritySet(hTask1, uxTaskPriorityGet(hTask1)+1);
    
    }else if (counter == 20) {
      
      printf("Lowering Task-1 Priority....\n");
      vTaskPrioritySet(hTask1, uxTaskPriorityGet(hTask1)-1);
      counter = 0;
    }
    
    /*Dummy Delay - Lazy work */
    for (i =0; i < 500000; ++i);
  }
}

5. Start the Scheduler.

  vTaskStartScheduler();

6. Finally Compile source code, connect STM32F4-Discovery board to PC and enter debug mode. Open printf serial window via View -> Serial Windows -> Debug (printf) Viewer. Run the Program, You will see Task execution messages as shown in bellow Video.

Note: We have routed printf messages to ST-Link debugger via ARM-ITM. There is a dedicated tutorial on how to redirect printf messages to debugger. Link to the tutorial is given bellow.

For complete source code refer to Github link given at the start of this tutorial.

Click the full screen button for more clear view.

References:

[1] – FreeRTOS Official Website



65 thoughts on “FreeRTOS – Changing Tasks Priorities”

Leave a Reply

Your email address will not be published. Required fields are marked *