In this new program, we create two tasks that are always running. When task 1 is created, it has a higher priority than task 2, so theoretically, it should always occupy the "Running" state. However, upon examining the screen output, we see that this is not the case because task 1 itself elevates the priority of task 2, allowing task 2 to enter the "Running" state. Task 2 then reduces its own priority below that of task 1, causing task 1 to start running again, and the cycle repeats continuously.

Code Example:

#include "bsp.h"

static TaskHandle_t xTask2Handle;           /* Variable to store task Priority */

static void vTask1( void *pvParameters );   /* Declaration of Task 1 function */
static void vTask2( void *pvParameters );   /* Declaration of Task 2 function */

int main( void )
{
    HAL_Init( );
    /*enable RTT and system view*/
    SEGGER_SYSVIEW_Conf( );
    SEGGER_SYSVIEW_Start( );

    xTaskCreate(vTask1, "task1", 240, NULL, 2, NULL);           /* Register on Kernel Task1 with a priority of 2 */
    xTaskCreate(vTask2, "task2", 240, NULL, 1, &xTask2Handle);  /* Register on Kernel Task2 with a priority of 1 and pass a parameter TaskHandler */
    
    vTaskStartScheduler();                                      /* Execute the kernel */
}

static void vTask1( void *pvParameters )
{
    UBaseType_t uxPriority;                                                 /* Variable to sotre the current priority */
    uxPriority = uxTaskPriorityGet( NULL );                                 /* Extract the task priority */ 
 
    for(;;)
    {
        SEGGER_RTT_printf( 0, "Tarea 1 ejecutandose\n" );                  /* Print a message of execution of task in Terminal */
        SEGGER_RTT_printf( 0, "Aumentando prioridad de Tarea 2\n" );       /* Print a message of change priority to Terminal */  
        
        vTaskPrioritySet( xTask2Handle, (uxPriority + 1) );                 /* Increment Task priority of Task 2 above Task 1 */
    }
}

static void vTask2( void *pvParameters )
{
    UBaseType_t uxPriority;                                                 /* Variable to sotre the current priority */
    uxPriority = uxTaskPriorityGet( NULL );                                 /* Extract the task priority */ 

    for(;;)
    {
        SEGGER_RTT_printf( 0, "Tarea 2 ejecutandose\n" );                     /* Print a message of execution of task in Terminal */
        SEGGER_RTT_printf( 0, "Disminuyendo la prioridad de la Tarea 2\n" );  /* Print a message of change priority to Terminal */

        vTaskPrioritySet( NULL, (uxPriority - 2));                          /* Decrease the Task priority 2 values */
    }
}

In the file FreeRTOSConfig.h, identify the following lines and change their values from zero to one:

#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskPrioritySet 1

Task 1 can modify the priority of task 2 using a "Task Handler." This task handler is assigned to task 2 when the task is created, as seen in the sixth parameter of the xTaskCreate function. Whenever a task needs to modify its behavior based on others, it must have an assigned "Handler."

💡
Before proceeding: Investigate what type of data task handlers are. What is the difference between using NULL and xTask2Handle for both tasks in the above code?

SystemView Output

Terminal shows the Task 1 execution to after increasing the priority of Task 2 which is executed after, changing his own priority to execute Task 1 again.

Document

TimeLine:

The timeline shows the task execution, where first Task1 is executed because has the higher priority, inside Task 1 priority of Task 2 is increased a value above that Task 1.

The new priority of the task allows it to be executed when Task 1 ends. When Task 2 starts execution, the task prints a message to after increase to the default value of priority. Executing Task 1 again.

Document