Understanding Task Scheduling in RTOS: Who Executes First When Priorities are Equal?

Follow+Star Public Account, don’t miss the exciting content

Understanding Task Scheduling in RTOS: Who Executes First When Priorities are Equal?

Author | strongerHuang

WeChat Official Account | strongerHuang

In an RTOS, when two tasks have the same priority, which one executes first? This question has puzzled many beginners. Today, I will briefly describe it with examples.

What is RTOS Task Priority?

In RTOS, each task (Task) is assigned a priority. Among all ready tasks, the higher the task priority, the sooner it is executed.

When we create a task, we must assign (set) a priority value, for example, in FreeRTOS:

/* APP task priority */#define APP_TASK_PRIORITY         6
/* Create application (APP task) */xTaskCreate(APP_Task, "APP_Task", 128, NULL, APP_TASK_PRIORITY, NULL);

6 represents the APP_Task task priority (defined as 6), in FreeRTOS system, the larger this number, the higher the priority.

However, not every RTOS has a higher priority with a higher numerical value. Some RTOS works the opposite way.

For example, in UCOS, a smaller priority value means a higher priority.

When Two RTOS Tasks Have the Same Priority, Which One Executes First?

In the FreeRTOS system, if two tasks have the same priority (value), who executes first?

Here, I will describe it with code and experimental phenomena.

1. Create Two Tasks with the Same Priority

For example: APP_Task1 and APP_Task2, both with a priority of 6

#define APP_TASK1_PRIORITY        6                        // APP task 1 priority
#define APP_TASK2_PRIORITY        6                        // APP task 2 priority
xTaskCreate(APP_Task1, "APP_Task1", 128, NULL, APP_TASK1_PRIORITY, NULL);
xTaskCreate(APP_Task2, "APP_Task2", 128, NULL, APP_TASK2_PRIORITY, NULL);

2. Two Applications

For example: both accumulate a value and print the accumulated value after a period of time.

static uint32_t Task1_Cnt = 0;static uint32_t Task2_Cnt = 0;
static void APP_Task1(void *pvParameters){  vTaskDelay(100);
  while(1)  {    Task1_Cnt++;
    if(0 == (Task1_Cnt%1000000))    {      printf("Task1_Cnt=%d",Task1_Cnt);    }  }}
// Author: strongerHuang
static void APP_Task2(void *pvParameters){  vTaskDelay(200);
  while(1)  {    Task2_Cnt++;
    if(0 == (Task2_Cnt%1000000))    {      printf("Task2_Cnt=%d",Task2_Cnt);    }  }}

3. Experimental Phenomena

Values are printed alternately, as shown in the figure below:

Understanding Task Scheduling in RTOS: Who Executes First When Priorities are Equal?

From the experimental phenomena, you can definitely draw the conclusion: In FreeRTOS, two tasks with the same priority are scheduled in a time-slicing round-robin fashion, meaning they execute alternately.

Of course, there is a prerequisite: Tasks must be in a ready state. If a task is in a blocked state, that task will not be scheduled for execution.

For example: adding system delay (blocking) in task 1 means that task 1 will not be executed, as shown in the experimental phenomenon below:

Understanding Task Scheduling in RTOS: Who Executes First When Priorities are Equal?

Additional Explanation

The above is only applicable to the FreeRTOS real-time operating system, not all RTOS are like this.

Like UCOS2, it is different. Creating two tasks with the same priority, only the first (the one created first) is prioritized for execution, and the second will not be executed.

Still, let me show you similar source code and experimental phenomena.

1. Create Two Tasks with the Same Priority

Similarly: APP_Task1 and APP_Task2, both with a priority of 6

#define TASK1_PRIO                             6
#define TASK2_PRIO                             6
/* Create Task 1 */OSTaskCreateExt((void (*)(void *)) APP_Task1,                (void           *) 0,                (OS_STK         *)&Task1_Stk[TASK1_STK_SIZE-1],                (INT8U           ) TASK1_PRIO,                (INT16U          ) TASK1_PRIO,                (OS_STK         *)&Task1_Stk[0],                (INT32U          ) TASK1_STK_SIZE,                (void           *) 0,                (INT16U          )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));
/* Create Task 2 */OSTaskCreateExt((void (*)(void *)) APP_Task2,                (void           *) 0,                (OS_STK         *)&Task2_Stk[TASK2_STK_SIZE-1],                (INT8U           ) TASK2_PRIO,                (INT16U          ) TASK2_PRIO,                (OS_STK         *)&Task2_Stk[0],                (INT32U          ) TASK2_STK_SIZE,                (void           *) 0,                (INT16U          )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));

2. Two Applications

Similarly: also accumulate a value and print the accumulated value after a period of time.

static uint32_t Task1_Cnt = 0;static uint32_t Task2_Cnt = 0;
void APP_Task1(void *pvParameters){  OSTimeDly(100);
  while(1)  {    Task1_Cnt++;
    if(0 == (Task1_Cnt%1000000))    {      printf("Task1_Cnt=%d",Task1_Cnt);    }  }}
// Author: strongerHuang
void APP_Task2(void *pvParameters){  OSTimeDly(200);
  while(1)  {    Task2_Cnt++;
    if(0 == (Task2_Cnt%1000000))    {      printf("Task2_Cnt=%d",Task2_Cnt);    }  }}

3. Experimental Phenomena

Only the first created task 1 has printed values, as shown in the figure below:

Understanding Task Scheduling in RTOS: Who Executes First When Priorities are Equal?

So, why does this happen?

The answer is: UCOS2 does not allow tasks with the same priority (of course, UCOS3 supports it).

If a task with a certain priority (such as 6) has already been created, creating another task with the same priority (6) will fail. Here you can find the kernel source code:

Understanding Task Scheduling in RTOS: Who Executes First When Priorities are Equal?

Therefore, not all RTOS allow the creation of two tasks with the same priority. It depends on the specific RTOS.

Finally, do you understand?

———— END ————

Understanding Task Scheduling in RTOS: Who Executes First When Priorities are Equal?

● Column “Embedded Tools”

● Column “Embedded Development”

● Column “Keil Tutorial”

● Selected Tutorials from Embedded Column

Follow the public account reply “Join Group” to join the technical exchange group according to the rules, reply “1024” to see more content.

Click “Read Original” to see more shares.

Leave a Comment

×