FreeRTOS Arduino: Changing the Priority of a Task

In this series of FreeRTOS with Arduino tutorials, today we will learn how to change task priority during program execution or after the scheduler has been started. Last tutorial, we have seen how to create tasks with FreeRTOS API and Arduino. We have seen we can also define task priority while creating a task with vCreateTask() function. But during program execution, we may also want to change the priority using FreeRTOS API.

vTaskPrioritySet() API Function

vTaskPrioritySet() is used to set task priority after the scheduler has been started.

Before using this API, make sure that INCLUDE_vTaskPrioritySet is set to 1 in FreeRTOSConfig.h header file.

The first argument is a handle to the task which priority we want to change. While creating a task with xTaskCreate() API function, priority is also defined. Alternatively, a task can change its own priority by passing NULL in place of a valid task handle.

The second argument defines the task’s priority level. The maximum priority a task can attain is set with (configMAX_PRIORITIES – 1. Here configMAX_PRIORITIES is constant that can be set using FreeRTOSConfig.h header file.

Acquiring Task Priority

uxTaskPriorityGet() API function can be used to get the level task priority.

Before using this API, make sure that INCLUDE_uxTaskPriorityGet is set to 1 in FreeRTOSConfig.h header file.

This is a prototype of a task priority get function. Similar to vTaskPrioritySet(), we pass handler as a input to this function to which priority we want to know.

UBaseType_t uxTaskPriorityGet( TaskHandle_t pxTask );

Tasks Priority Changing Example Arduino

In this example, we use two tasks in order to demonstrate the use of vTaskPrioritySet() API function. We create two task one with higher priority and one with low priority. We change their priorities using their reference handlers.

First, these lines adds libraries of FreeRTOS and tasks. We also define prototypes for two tasks such as Task1 and Task2.

This code creates two tasks with different priorities. Task1 has the highest and Task2 has the lowest priority. Hence, Task1 will be the first one in the running state selected by the FreeRTOS scheduler.

This routine defines Task1. Firstly, we get the priority of the task using uxTaskPriorityGet() and store it in uxPriority variable of type UBaseType_t. After that inside the while(1) loop, it prints a string “Task1 is running and about to raise Task2 Priority”. In the end, we call vTaskPrioritySet() to raise the priority of Task2 by one higher than Task1.

Therefore, Task2 priority will become higher than the Task1. In response, Task1 enters the Ready state and Task2 enters the running state.

This routine defines Task2. Firstly, we get the priority of the task2 using uxTaskPriorityGet() and store it in uxPriority variable of type UBaseType_t. After that inside the while(1) loop, it prints a string “Task2 is running and about to lower Task2 Priority”. In the end, we call vTaskPrioritySet() to lower the priority of Task2 by one.

Therefore, Task1 priority will become higher than the Task2 again. In response, Task2 enters the Ready state, and Task2 enters the running state.

Arduino Serial Monitor Output

Now copy this code to Arduino IDE and upload code to Arduino. After that open, Arduino Serial monitor, you will see output like this on Arduino Serial monitor:

How Priority Changing Code works?

At the start, Task1 being the highest priority run first and enters the running state. After that, it prints out strings before raising the priority of Task2 to above its own priority. Because now Task2 runs and Task1 waits in the ready state.

Task2 enters the Running state as soon as it has the highest relative priority. Only one task can be in the Running state at any one time, so when Task 2 is in the Running state, Task1 is in the Ready state.

Task2 prints out “Task2 is running and about to lower Task2 Priority” before setting its own priority back down to below that of Task1.

Task2 setting its priority back down means Task 1 is once again the highest priority task, so Task1 re-enters the Running state, forcing Task 2 back into the Ready state.