Follow+Star Public Account, don’t miss the exciting content
Author | 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:
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:
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:
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:
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 ————
● 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.