微信公众号 | strongerHuang
RTOS两任务优先级相同,谁先执行?这个问题把很多初学的小伙伴难住了,今天就来结合案例给大家简单描述一下。
什么是RTOS任务优先级?
在RTOS中,每一个任务(Task)都会分配一个优先级,在所有就绪的任务中,任务优先级越高就优先执行。
任务优先级在我们创建任务的时候,就要赋予(设置)一个优先级值,比如FreeRTOS创建任务:
/* APP任务优先级 */
#define APP_TASK_PRIORITY 6
/* 创建应用程序(APP任务) */
xTaskCreate(APP_Task, "APP_Task", 128, NULL, APP_TASK_PRIORITY, NULL);
6 代表 APP_Task 任务优先级(宏定义为6),在FreeRTOS系统中,这个数字越大,优先级越高。
然而,并不是每一款RTOS任务优先级数值越大优先级越大,有些RTOS则相反。
比如:UCOS中,优先级数值越小,优先级则越大。
RTOS两任务优先级相同,谁先执行?
在FreeRTOS系统中,如果两个任务优先级(数值)相同,谁先执行?
这里结合代码,和实验现象给大家描述一下。
1、创建两个相同优先级的任务
比如:APP_Task1和APP_Task2,优先级都为6
#define APP_TASK1_PRIORITY 6 //APP任务1优先级
#define APP_TASK2_PRIORITY 6 //APP任务1优先级
xTaskCreate(APP_Task1, "APP_Task1", 128, NULL, APP_TASK1_PRIORITY, NULL);
xTaskCreate(APP_Task2, "APP_Task2", 128, NULL, APP_TASK2_PRIORITY, NULL);
2、两个应用程序
比如:都是累加一个值,并隔一段时间打印累加值。
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);
}
}
}
//作者: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、实验现象
轮流打印数值,如下图:
通过实验现象,你肯定猜得出结论:FreeRTOS两个优先级相同的任务,它们是按照时间片轮转的方式进行调度,也就是交替执行。
当然,这里有一个前提:任务要处于就绪状态。如果任务是阻塞状态,则改任务不会被轮转执行。
比如:在任务1中增加系统延时(阻塞),则任务1不会被执行,看实验现象,如下图:
补充说明
上面只是针对FreeRTOS实时操作系统而言,并不是所有RTOS都是这样的。
像UCOS就不一样,创建两个相同优先级的任务,只有第一个(先创建的任务)优先被执行,第二个不会被执行。
还是一样,给大家看类似的源码和实验现象。
1、创建两个相同优先级的任务
同样:APP_Task1和APP_Task2,优先级都为6
#define TASK1_PRIO 6
#define TASK2_PRIO 6
/* 创建任务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));
/* 创建任务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、两个应用程序
同样:也是累加一个值,并隔一段时间打印累加值。
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);
}
}
}
//作者:strongerHuang
void APP_Task2(void *pvParameters)
{
OSTimeDly(200);
while(1)
{
Task2_Cnt++;
if(0 == (Task2_Cnt%1000000))
{
printf("Task2_Cnt=%d",Task2_Cnt);
}
}
}
3、实验现象
只有先被创建的任务1有打印数值,如下图:
那么,为什么会出现这样的情况呢?
答案是:UCOS不允许相同优先级的任务。
如果某一优先级(如6)的任务已经被创建,再次创建该优先级(6)的任务会创建失败。这里可以找到内核源码:
所以,并不是所有RTOS都可以创建两个相同优先级的任务,具体要看RTOS自身的情况。
最后,你明白了吗?