加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 什么是RTOS任務(wù)優(yōu)先級(jí)?
    • RTOS兩任務(wù)優(yōu)先級(jí)相同,誰先執(zhí)行?
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

RTOS兩任務(wù)優(yōu)先級(jí)相同,誰先執(zhí)行?

11/27 09:40
1148
閱讀需 9 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

微信公眾號(hào) | strongerHuang

RTOS兩任務(wù)優(yōu)先級(jí)相同,誰先執(zhí)行?這個(gè)問題把很多初學(xué)的小伙伴難住了,今天就來結(jié)合案例給大家簡(jiǎn)單描述一下。

什么是RTOS任務(wù)優(yōu)先級(jí)?

在RTOS中,每一個(gè)任務(wù)(Task)都會(huì)分配一個(gè)優(yōu)先級(jí),在所有就緒的任務(wù)中,任務(wù)優(yōu)先級(jí)越高就優(yōu)先執(zhí)行。

任務(wù)優(yōu)先級(jí)在我們創(chuàng)建任務(wù)的時(shí)候,就要賦予(設(shè)置)一個(gè)優(yōu)先級(jí)值,比如FreeRTOS創(chuàng)建任務(wù):

/* APP任務(wù)優(yōu)先級(jí) */#define?APP_TASK_PRIORITY?????????6
/* 創(chuàng)建應(yīng)用程序(APP任務(wù)) */xTaskCreate(APP_Task, "APP_Task", 128, NULL, APP_TASK_PRIORITY, NULL);

6 代表?APP_Task?任務(wù)優(yōu)先級(jí)(宏定義為6),在FreeRTOS系統(tǒng)中,這個(gè)數(shù)字越大,優(yōu)先級(jí)越高。

然而,并不是每一款RTOS任務(wù)優(yōu)先級(jí)數(shù)值越大優(yōu)先級(jí)越大,有些RTOS則相反。

比如:UCOS中,優(yōu)先級(jí)數(shù)值越小,優(yōu)先級(jí)則越大。

RTOS兩任務(wù)優(yōu)先級(jí)相同,誰先執(zhí)行?

在FreeRTOS系統(tǒng)中,如果兩個(gè)任務(wù)優(yōu)先級(jí)(數(shù)值)相同,誰先執(zhí)行?

這里結(jié)合代碼,和實(shí)驗(yàn)現(xiàn)象給大家描述一下。

1、創(chuàng)建兩個(gè)相同優(yōu)先級(jí)的任務(wù)

比如:APP_Task1和APP_Task2,優(yōu)先級(jí)都為6

#define APP_TASK1_PRIORITY        6                        //APP任務(wù)1優(yōu)先級(jí)#define APP_TASK2_PRIORITY        6                        //APP任務(wù)1優(yōu)先級(jí)
xTaskCreate(APP_Task1, "APP_Task1", 128, NULL, APP_TASK1_PRIORITY, NULL);xTaskCreate(APP_Task2, "APP_Task2", 128, NULL, APP_TASK2_PRIORITY, NULL);

2、兩個(gè)應(yīng)用程序

比如:都是累加一個(gè)值,并隔一段時(shí)間打印累加值。

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、實(shí)驗(yàn)現(xiàn)象

輪流打印數(shù)值,如下圖:

通過實(shí)驗(yàn)現(xiàn)象,你肯定猜得出結(jié)論:FreeRTOS兩個(gè)優(yōu)先級(jí)相同的任務(wù),它們是按照時(shí)間片輪轉(zhuǎn)的方式進(jìn)行調(diào)度,也就是交替執(zhí)行。

當(dāng)然,這里有一個(gè)前提:任務(wù)要處于就緒狀態(tài)。如果任務(wù)是阻塞狀態(tài),則改任務(wù)不會(huì)被輪轉(zhuǎn)執(zhí)行。

比如:在任務(wù)1中增加系統(tǒng)延時(shí)(阻塞),則任務(wù)1不會(huì)被執(zhí)行,看實(shí)驗(yàn)現(xiàn)象,如下圖:

補(bǔ)充說明

上面只是針對(duì)FreeRTOS實(shí)時(shí)操作系統(tǒng)而言,并不是所有RTOS都是這樣的。

像UCOS就不一樣,創(chuàng)建兩個(gè)相同優(yōu)先級(jí)的任務(wù),只有第一個(gè)(先創(chuàng)建的任務(wù))優(yōu)先被執(zhí)行,第二個(gè)不會(huì)被執(zhí)行。

還是一樣,給大家看類似的源碼和實(shí)驗(yàn)現(xiàn)象。

1、創(chuàng)建兩個(gè)相同優(yōu)先級(jí)的任務(wù)

同樣:APP_Task1和APP_Task2,優(yōu)先級(jí)都為6

#define TASK1_PRIO                             6#define TASK2_PRIO                             6
/* 創(chuàng)建任務(wù)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));
/* 創(chuàng)建任務(wù)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、兩個(gè)應(yīng)用程序

同樣:也是累加一個(gè)值,并隔一段時(shí)間打印累加值。

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、實(shí)驗(yàn)現(xiàn)象

只有先被創(chuàng)建的任務(wù)1有打印數(shù)值,如下圖:

那么,為什么會(huì)出現(xiàn)這樣的情況呢?

答案是:UCOS不允許相同優(yōu)先級(jí)的任務(wù)。

如果某一優(yōu)先級(jí)(如6)的任務(wù)已經(jīng)被創(chuàng)建,再次創(chuàng)建該優(yōu)先級(jí)(6)的任務(wù)會(huì)創(chuàng)建失敗。這里可以找到內(nèi)核源碼:

所以,并不是所有RTOS都可以創(chuàng)建兩個(gè)相同優(yōu)先級(jí)的任務(wù),具體要看RTOS自身的情況。

最后,你明白了嗎?

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

作者黃工,從事嵌入式軟件開發(fā)工作8年有余,高級(jí)嵌入式軟件工程師,業(yè)余維護(hù)公眾號(hào)『strongerHuang』,分享嵌入式軟硬件、單片機(jī)、物聯(lián)網(wǎng)等內(nèi)容。