自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

鴻蒙輕內(nèi)核M核源碼分析系列六任務(wù)及任務(wù)調(diào)度(2)任務(wù)模塊

開發(fā)
本文帶領(lǐng)大家一起剖析了鴻蒙輕內(nèi)核任務(wù)模塊的源代碼,包含任務(wù)模塊的結(jié)構(gòu)體,任務(wù)初始化過程源代碼,任務(wù)常用操作的源代碼。

[[399389]]

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

任務(wù)是操作系統(tǒng)一個(gè)重要的概念,是競(jìng)爭(zhēng)系統(tǒng)資源的最小運(yùn)行單元。任務(wù)可以使用或等待CPU、使用內(nèi)存空間等系統(tǒng)資源,并獨(dú)立于其它任務(wù)運(yùn)行。鴻蒙輕內(nèi)核的任務(wù)模塊可以給用戶提供多個(gè)任務(wù),實(shí)現(xiàn)任務(wù)間的切換,幫助用戶管理業(yè)務(wù)程序流程。

接下來,我們看下任務(wù)模塊的結(jié)構(gòu)體,任務(wù)初始化,任務(wù)常用操作的源代碼。

1、任務(wù)模塊的結(jié)構(gòu)體定義

在文件kernel\include\los_task.h定義的任務(wù)控制塊結(jié)構(gòu)體LosTaskCB,源代碼如下,結(jié)構(gòu)體成員的解釋見注釋部分。

  1. typedef struct { 
  2.     VOID                        *stackPointer;            /* 任務(wù)棧指針 */ 
  3.     UINT16                      taskStatus;               /* 任務(wù)狀態(tài) */ 
  4.     UINT16                      priority;                 /* 任務(wù)優(yōu)先級(jí) */ 
  5.     INT32                       timeSlice;                /* 剩余的時(shí)間片 */ 
  6.     UINT32                      waitTimes; 
  7.     SortLinkList                sortList;                 /* 任務(wù)超時(shí)排序鏈表節(jié)點(diǎn) */ 
  8.     UINT64                      startTime; 
  9.     UINT32                      stackSize;                /* 任務(wù)棧大小 */ 
  10.     UINT32                      topOfStack;               /* 棧頂指針 */ 
  11.     UINT32                      taskID;                   /* 任務(wù)編號(hào)Id */ 
  12.     TSK_ENTRY_FUNC              taskEntry;                /* 任務(wù)入口函數(shù) */ 
  13.     VOID                        *taskSem;                 /* 任務(wù)持有的信號(hào)量 */ 
  14.     VOID                        *taskMux;                 /* 導(dǎo)致任務(wù)阻塞的互斥鎖 */ 
  15.     UINT32                      arg;                      /* 任務(wù)入口函數(shù)的參數(shù) */ 
  16.     CHAR                        *taskName;                /* 任務(wù)名稱 */ 
  17.     LOS_DL_LIST                 pendList;                 /* 就緒隊(duì)列等鏈表節(jié)點(diǎn) */ 
  18.     LOS_DL_LIST                 timerList;                /* 任務(wù)超時(shí)排序鏈表節(jié)點(diǎn) */ 
  19.     EVENT_CB_S                  event; 
  20.     UINT32                      eventMask;                /* 事件掩碼 */ 
  21.     UINT32                      eventMode;                /* 事件模式 */ 
  22.     VOID                        *msg;                     /* 分給給隊(duì)列的內(nèi)存*/ 
  23.     INT32                       errorNo; 
  24. } LosTaskCB; 

 另外一個(gè)比較重要的結(jié)構(gòu)體是TSK_INIT_PARAM_S,創(chuàng)建任務(wù)時(shí),需要指定任務(wù)初始化的參數(shù)。源代碼如下,結(jié)構(gòu)體成員的解釋見注釋部分。

  1. typedef struct tagTskInitParam { 
  2.     TSK_ENTRY_FUNC       pfnTaskEntry;              /** 任務(wù)入口函數(shù) */ 
  3.     UINT16               usTaskPrio;                /** 任務(wù)參數(shù)  */ 
  4.     UINT32               uwStackSize;               /** 任務(wù)棧大小 */ 
  5.     CHAR                 *pcName;                   /** 任務(wù)名稱  */ 
  6.     UINT32               uwResved;                  /** 保留  */ 
  7. } TSK_INIT_PARAM_S; 

 2、任務(wù)模塊初始化

在系統(tǒng)啟動(dòng)時(shí),在kernel\src\los_init.c中調(diào)用OsTaskInit()進(jìn)行任務(wù)模塊初始化,還會(huì)調(diào)用OsIdleTaskCreate()創(chuàng)建空閑任務(wù)。

2.1 任務(wù)模塊初始化

函數(shù)OsTaskInit()定義在kernel\src\los_task.c,我們分析下這個(gè)函數(shù)的執(zhí)行過程。

⑴處代碼根據(jù)開發(fā)板配置的最大任務(wù)數(shù)g_taskMaxNum,計(jì)算需要申請(qǐng)的內(nèi)存大小size,為任務(wù)控制塊TCB數(shù)組(也叫作任務(wù)池)g_taskCBArray申請(qǐng)內(nèi)存。為什么比最大任務(wù)數(shù)多申請(qǐng)一個(gè)呢?在刪除任務(wù)時(shí)會(huì)使用。下文分析刪除任務(wù)的源碼時(shí)再詳細(xì)講解其用意。

⑵處代碼初始化雙向鏈表g_losFreeTask用作空閑的任務(wù)鏈表、g_taskRecyleList可以回收的任務(wù)鏈表。

⑶處循環(huán)初始化每一個(gè)任務(wù),任務(wù)狀態(tài)未使用OS_TASK_STATUS_UNUSED,初始化任務(wù)Id,并把任務(wù)掛在空閑任務(wù)鏈表上。

⑷處初始化全局變量LosTask g_losTask,該全局變量維護(hù)當(dāng)前運(yùn)行的任務(wù)和要調(diào)度執(zhí)行的任務(wù)。初始化任務(wù)池時(shí),設(shè)置當(dāng)前運(yùn)行的任務(wù)為g_taskCBArray[g_taskMaxNum]。⑸處空閑任務(wù)編號(hào)暫時(shí)設(shè)置為無效值,后續(xù)創(chuàng)建空閑任務(wù)時(shí)再設(shè)置空閑任務(wù)編號(hào)。

優(yōu)先級(jí)隊(duì)列,詳細(xì)的代碼實(shí)現(xiàn)剖析,參見之前的源碼剖析文章。⑸處互斥鎖死鎖檢測(cè)的調(diào)測(cè)特性的,后續(xù)系列文章專題進(jìn)行講解。⑹處代碼初始化排序鏈表,詳細(xì)的代碼實(shí)現(xiàn)剖析,參見之前的源碼剖析文章。⑺處如果開啟了惰性棧,計(jì)算TCB的成員變量stackFrame在其結(jié)構(gòu)體中的偏移量g_stackFrameOffLenInTcb。

  1. LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID) 
  2.     UINT32 size
  3.     UINT32 index
  4.  
  5. ⑴  size = (g_taskMaxNum + 1) * sizeof(LosTaskCB); 
  6.     g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size); 
  7.     if (g_taskCBArray == NULL) { 
  8.         return LOS_ERRNO_TSK_NO_MEMORY; 
  9.     } 
  10.     (VOID)memset_s(g_taskCBArray, size, 0, size); 
  11.  
  12. ⑵  LOS_ListInit(&g_losFreeTask); 
  13.     LOS_ListInit(&g_taskRecyleList); 
  14. ⑶  for (index = 0; index <= LOSCFG_BASE_CORE_TSK_LIMIT; index++) { 
  15.         g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED; 
  16.         g_taskCBArray[index].taskID = index
  17.         LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList); 
  18.     } 
  19.  
  20.     // Ignore the return code when matching CSEC rule 6.6(4). 
  21. ⑷  (VOID)memset_s((VOID *)(&g_losTask), sizeof(g_losTask), 0, sizeof(g_losTask)); 
  22.     g_losTask.runTask = &g_taskCBArray[g_taskMaxNum]; 
  23.     g_losTask.runTask->taskID = index
  24.     g_losTask.runTask->taskStatus = (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_RUNNING); 
  25.     g_losTask.runTask->priority = OS_TASK_PRIORITY_LOWEST + 1; 
  26.  
  27. ⑸  g_idleTaskID = OS_INVALID; 
  28. ⑹  return OsSchedInit(); 

 2.2 創(chuàng)建空閑任務(wù)IdleCore000

除了初始化任務(wù)池,在系統(tǒng)啟動(dòng)階段還會(huì)創(chuàng)建idle空閑任務(wù)。⑴處設(shè)置任務(wù)初始化參數(shù)時(shí),空閑任務(wù)的入口執(zhí)行函數(shù)為OsIdleTask()。⑵處調(diào)用函數(shù)把空閑任務(wù)狀態(tài)設(shè)置為就緒狀態(tài)。

  1. LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) 
  2.     UINT32 retVal; 
  3.     TSK_INIT_PARAM_S taskInitParam; 
  4.     // Ignore the return code when matching CSEC rule 6.6(4). 
  5.     (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); 
  6. ⑴  taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask; 
  7.     taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE; 
  8.     taskInitParam.pcName = "IdleCore000"
  9.     taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST; 
  10.     retVal = LOS_TaskCreateOnly(&g_idleTaskID, &taskInitParam); 
  11.  
  12.     if (retVal != LOS_OK) { 
  13.         return retVal; 
  14.     } 
  15.  
  16. ⑵  OsSchedSetIdleTaskSchedPartam(OS_TCB_FROM_TID(g_idleTaskID)); 
  17.     return LOS_OK; 

 我們看下空閑任務(wù)的入口執(zhí)行函數(shù)為OsIdleTask(),它調(diào)用OsRecyleFinishedTask()回收任務(wù)棧資源,后文會(huì)分析如何回收任務(wù)資源。

  1. LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID) 
  2.     while (1) { 
  3.         OsRecyleFinishedTask(); 
  4.         HalEnterSleep(OS_SYS_DEEP_SLEEP); 
  5.     } 

 3、任務(wù)模塊常用操作

3.1 創(chuàng)建和刪除任務(wù)

3.1.1 創(chuàng)建任務(wù)

鴻蒙輕內(nèi)核提供了2個(gè)創(chuàng)建任務(wù)的函數(shù),有LOS_TaskCreate、LOS_TaskCreateOnly。LOS_TaskCreate和LOS_TaskCreateOnly的區(qū)別是,前者創(chuàng)建任務(wù)完畢就使任務(wù)進(jìn)入就緒狀態(tài),并觸發(fā)調(diào)度,如果就緒隊(duì)列中沒有更高優(yōu)先級(jí)的任務(wù),則運(yùn)行該任務(wù)。后者只創(chuàng)建任務(wù),設(shè)置任務(wù)狀態(tài)為阻塞suspend狀態(tài),需要開發(fā)者去調(diào)用LOS_TaskResume使該任務(wù)進(jìn)入ready狀態(tài)。

函數(shù)LOS_TaskCreate代碼如下,可以看出創(chuàng)建任務(wù)的時(shí)候,調(diào)用⑴處的函數(shù)LOS_TaskCreateOnly()來創(chuàng)建任務(wù)。創(chuàng)建任務(wù)后,執(zhí)行⑵處的代碼使任務(wù)進(jìn)入ready就緒隊(duì)列,如果系統(tǒng)啟動(dòng)完成,允許任務(wù)調(diào)度,則執(zhí)行⑶觸發(fā)任務(wù)調(diào)度。如果新創(chuàng)建的任務(wù)優(yōu)先級(jí)最高,則會(huì)被調(diào)度運(yùn)行。 

  1. LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *taskInitParam) 
  2.     UINT32 retVal; 
  3.     UINTPTR intSave; 
  4.     LosTaskCB *taskCB = NULL
  5.  
  6. ⑴  retVal = LOS_TaskCreateOnly(taskID, taskInitParam); 
  7.     if (retVal != LOS_OK) { 
  8.         return retVal; 
  9.     } 
  10.     taskCB = OS_TCB_FROM_TID(*taskID); 
  11.  
  12.     intSave = LOS_IntLock(); 
  13. #if (LOSCFG_BASE_CORE_CPUP == 1) 
  14.     g_cpup[taskCB->taskID].cpupID = taskCB->taskID; 
  15.     g_cpup[taskCB->taskID].status = taskCB->taskStatus; 
  16. #endif 
  17.  
  18. ⑵  OsSchedTaskEnQueue(taskCB); 
  19.     LOS_IntRestore(intSave); 
  20.  
  21. ⑶  if (g_taskScheduled) { 
  22.         LOS_Schedule(); 
  23.     } 
  24.  
  25.     return LOS_OK; 

我們接著分析下如何使用函數(shù)UINT32 LOS_TaskCreateOnly()創(chuàng)建任務(wù)。⑴處調(diào)用OsTaskInitParamCheck()檢測(cè)創(chuàng)建任務(wù)的參數(shù)的合法性。⑵處調(diào)用函數(shù)回收釋放的任務(wù)。⑶處如果任務(wù)池為空,無法創(chuàng)建任務(wù),返回錯(cuò)誤碼。⑷處從任務(wù)池獲取一個(gè)空閑的任務(wù)控制塊taskCB,然后從空閑任務(wù)鏈表中刪除。⑸處根據(jù)指定的任務(wù)棧大小為任務(wù)棧申請(qǐng)內(nèi)存,⑹處判斷任務(wù)棧內(nèi)存申請(qǐng)釋放成功,如果申請(qǐng)失敗,則把任務(wù)控制塊歸還到空閑任務(wù)鏈表中,并返回錯(cuò)誤碼。⑺處調(diào)用函數(shù)初始化任務(wù)棧,更新任務(wù)控制塊成員信息。詳細(xì)見后面對(duì)該函數(shù)的分析。 

  1. LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *taskInitParam) 
  2.     UINTPTR intSave; 
  3.     VOID  *topOfStack = NULL
  4.     LosTaskCB *taskCB = NULL
  5.     UINT32 retVal; 
  6.  
  7.     if (taskID == NULL) { 
  8.         return LOS_ERRNO_TSK_ID_INVALID; 
  9.     } 
  10.  
  11. ⑴  retVal = OsTaskInitParamCheck(taskInitParam); 
  12.     if (retVal != LOS_OK) { 
  13.         return retVal; 
  14.     } 
  15.  
  16. ⑵  OsRecyleFinishedTask(); 
  17.  
  18.     intSave = LOS_IntLock(); 
  19. ⑶  if (LOS_ListEmpty(&g_losFreeTask)) { 
  20.         retVal = LOS_ERRNO_TSK_TCB_UNAVAILABLE; 
  21.         OS_GOTO_ERREND(); 
  22.     } 
  23.  
  24. ⑷  taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_losFreeTask)); 
  25.     LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask)); 
  26.  
  27.     LOS_IntRestore(intSave); 
  28.  
  29. #if (LOSCFG_EXC_HRADWARE_STACK_PROTECTION == 1) 
  30.     UINTPTR stackPtr = (UINTPTR)LOS_MemAllocAlign(OS_TASK_STACK_ADDR, taskInitParam->uwStackSize + 
  31.         OS_TASK_STACK_PROTECT_SIZE, OS_TASK_STACK_PROTECT_SIZE); 
  32.     topOfStack = (VOID *)(stackPtr + OS_TASK_STACK_PROTECT_SIZE); 
  33. #else 
  34. ⑸      topOfStack = (VOID *)LOS_MemAllocAlign(OS_TASK_STACK_ADDR, taskInitParam->uwStackSize, 
  35.         LOSCFG_STACK_POINT_ALIGN_SIZE); 
  36. #endif 
  37. ⑹  if (topOfStack == NULL) { 
  38.         intSave = LOS_IntLock(); 
  39.         LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); 
  40.         LOS_IntRestore(intSave); 
  41.         return LOS_ERRNO_TSK_NO_MEMORY; 
  42.     } 
  43.  
  44. ⑺  retVal = OsNewTaskInit(taskCB, taskInitParam, topOfStack); 
  45.     if (retVal != LOS_OK) { 
  46.         return retVal; 
  47.     } 
  48.  
  49.     *taskID = taskCB->taskID; 
  50.     OsHookCall(LOS_HOOK_TYPE_TASK_CREATE, taskCB); 
  51.     return retVal; 
  52.  
  53. LOS_ERREND: 
  54.     LOS_IntRestore(intSave); 
  55.     return retVal; 

 我們看下創(chuàng)建任務(wù)函數(shù)調(diào)用的函數(shù)OsRecyleFinishedTask(),該函數(shù)在系統(tǒng)進(jìn)入空閑時(shí)也會(huì)調(diào)用。刪除運(yùn)行狀態(tài)的任務(wù)時(shí),會(huì)把任務(wù)掛在雙向鏈表里g_taskRecyleList。任務(wù)回收函數(shù)就用來回收此類任務(wù),實(shí)現(xiàn)任務(wù)資源回收。我們分析下它的代碼。⑴處循環(huán)遍歷回收鏈表,⑵從回收鏈表獲取第一個(gè)任務(wù)taskCB,從回收鏈表刪除并插入到空閑任務(wù)鏈表里。任務(wù)棧保護(hù)在后續(xù)系列再深入分析,繼續(xù)往下看代碼,⑶處獲取任務(wù)棧棧頂指針,接著調(diào)用內(nèi)存釋放函數(shù)來釋放任務(wù)棧占用的內(nèi)存,并設(shè)置任務(wù)棧的棧頂為空。

  1. STATIC VOID OsRecyleFinishedTask(VOID) 
  2.     LosTaskCB *taskCB = NULL
  3.     UINTPTR intSave; 
  4.     UINTPTR stackPtr; 
  5.  
  6.     intSave = LOS_IntLock(); 
  7. ⑴  while (!LOS_ListEmpty(&g_taskRecyleList)) { 
  8. ⑵      taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecyleList)); 
  9.         LOS_ListDelete(LOS_DL_LIST_FIRST(&g_taskRecyleList)); 
  10.         LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); 
  11. #if (LOSCFG_EXC_HRADWARE_STACK_PROTECTION == 1) 
  12.         stackPtr = taskCB->topOfStack - OS_TASK_STACK_PROTECT_SIZE; 
  13. #else 
  14. ⑶      stackPtr = taskCB->topOfStack; 
  15. #endif 
  16.         (VOID)LOS_MemFree(OS_TASK_STACK_ADDR, (VOID *)stackPtr); 
  17.         taskCB->topOfStack = (UINT32)NULL
  18.     } 
  19.     LOS_IntRestore(intSave); 

 我們繼續(xù)分析下函數(shù)OsNewTaskInit(),⑴處調(diào)用函數(shù)初始化任務(wù)棧,上一系列已經(jīng)分析過該函數(shù),代碼的其余部分用來更新任務(wù)控制塊的成員信息,比如⑵處任務(wù)狀態(tài)設(shè)置為阻塞狀態(tài)。

  1. LITE_OS_SEC_TEXT_INIT UINT32 OsNewTaskInit(LosTaskCB *taskCB, TSK_INIT_PARAM_S *taskInitParam, VOID *topOfStack) 
  2. ⑴  taskCB->stackPointer    = HalTskStackInit(taskCB->taskID, taskInitParam->uwStackSize, topOfStack); 
  3.     taskCB->arg             = taskInitParam->uwArg; 
  4.     taskCB->topOfStack      = (UINT32)(UINTPTR)topOfStack; 
  5.     taskCB->stackSize       = taskInitParam->uwStackSize; 
  6.     taskCB->taskSem         = NULL
  7.     taskCB->taskMux         = NULL
  8. ⑵  taskCB->taskStatus      = OS_TASK_STATUS_SUSPEND; 
  9.     taskCB->priority        = taskInitParam->usTaskPrio; 
  10.     taskCB->timeSlice       = 0; 
  11.     taskCB->waitTimes       = 0; 
  12.     taskCB->taskEntry       = taskInitParam->pfnTaskEntry; 
  13.     taskCB->event.uwEventID = OS_NULL_INT; 
  14.     taskCB->eventMask       = 0; 
  15.     taskCB->taskName        = taskInitParam->pcName; 
  16.     taskCB->msg             = NULL
  17.     SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME); 
  18.     return LOS_OK; 

 3.1.2 刪除任務(wù)UINT32 LOS_TaskDelete()

該函數(shù)根據(jù)傳入的參數(shù)UINT32 taskId刪除任務(wù)。我們分析下刪除任務(wù)的源代碼,⑴處檢驗(yàn)傳入的參數(shù),⑵處如果任務(wù)還未創(chuàng)建,返回錯(cuò)誤碼。⑶處如果刪除的任務(wù)正在運(yùn)行,又處于鎖任務(wù)調(diào)度情況下,打印信息,告訴用戶不推薦在鎖任務(wù)調(diào)度期間進(jìn)行任務(wù)刪除,然后執(zhí)行⑷,把全局變量賦值0來解鎖任務(wù)調(diào)度。

⑸處調(diào)用函數(shù)處理任務(wù)狀態(tài),如果處于就緒狀態(tài)設(shè)置為非就緒狀態(tài),并從就緒隊(duì)列刪除。如果處于阻塞狀態(tài),從阻塞隊(duì)列中刪除。如果任務(wù)處于超時(shí)等待狀態(tài),從超時(shí)排序鏈表中刪除。⑹恢復(fù)任務(wù)控制塊事件相關(guān)的成員信息。⑺如果任務(wù)正在運(yùn)行,設(shè)置任務(wù)為未使用狀態(tài),接著調(diào)用函數(shù)OsRunningTaskDelete()把任務(wù)放入回收鏈表,然后主動(dòng)觸發(fā)任務(wù)調(diào)度,稍后詳細(xì)分析該函數(shù)。如果刪除的任務(wù)不是出于運(yùn)行狀態(tài),則執(zhí)行⑻,設(shè)置任務(wù)為未使用狀態(tài),接著把任務(wù)回收到空閑任務(wù)鏈表里,然后獲取任務(wù)棧的棧頂指針,調(diào)用內(nèi)存釋放函數(shù)釋放任務(wù)棧的內(nèi)存。

  1. LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID) 
  2.     UINTPTR intSave; 
  3.     LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); 
  4.     UINTPTR stackPtr; 
  5.  
  6. ⑴  UINT32 ret = OsCheckTaskIDValid(taskID); 
  7.     if (ret != LOS_OK) { 
  8.         return ret; 
  9.     } 
  10.  
  11.     intSave = LOS_IntLock(); 
  12.  
  13. ⑵  if ((taskCB->taskStatus) & OS_TASK_STATUS_UNUSED) { 
  14.         LOS_IntRestore(intSave); 
  15.         return LOS_ERRNO_TSK_NOT_CREATED; 
  16.     } 
  17.  
  18.     /* If the task is running and scheduler is locked then you can not delete it */ 
  19. ⑶  if (((taskCB->taskStatus) & OS_TASK_STATUS_RUNNING) && (g_losTaskLock != 0)) { 
  20.         PRINT_INFO("In case of task lock, task deletion is not recommended\n"); 
  21. ⑷      g_losTaskLock = 0; 
  22.     } 
  23.  
  24.     OsHookCall(LOS_HOOK_TYPE_TASK_DELETE, taskCB); 
  25. ⑸  OsSchedTaskExit(taskCB); 
  26.  
  27. ⑹  taskCB->event.uwEventID = OS_NULL_INT; 
  28.     taskCB->eventMask = 0; 
  29. #if (LOSCFG_BASE_CORE_CPUP == 1) 
  30.     // Ignore the return code when matching CSEC rule 6.6(4). 
  31.     (VOID)memset_s((VOID *)&g_cpup[taskCB->taskID], sizeof(OsCpupCB), 0, sizeof(OsCpupCB)); 
  32. #endif 
  33.     if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { 
  34. ⑺      taskCB->taskStatus = OS_TASK_STATUS_UNUSED; 
  35.         OsRunningTaskDelete(taskID, taskCB); 
  36.         LOS_IntRestore(intSave); 
  37.         LOS_Schedule(); 
  38.         return LOS_OK; 
  39.     } else { 
  40. ⑻       taskCB->taskStatus = OS_TASK_STATUS_UNUSED; 
  41.         LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); 
  42. #if (LOSCFG_EXC_HRADWARE_STACK_PROTECTION == 1) 
  43.         stackPtr = taskCB->topOfStack - OS_TASK_STACK_PROTECT_SIZE; 
  44. #else 
  45.         stackPtr = taskCB->topOfStack; 
  46. #endif 
  47.         (VOID)LOS_MemFree(OS_TASK_STACK_ADDR, (VOID *)stackPtr); 
  48.         taskCB->topOfStack = (UINT32)NULL
  49.     } 
  50.  
  51.     LOS_IntRestore(intSave); 
  52.     return LOS_OK; 

 我們看下函數(shù)OsRunningTaskDelete()的源碼。⑴處把當(dāng)前運(yùn)行的任務(wù)放入待回收鏈表里,然后執(zhí)行⑵把當(dāng)前運(yùn)行的任務(wù)放入任務(wù)池的最后一個(gè)位置g_taskCBArray[g_taskMaxNum]。為什么這么操作呢?等后續(xù)分析源碼的時(shí)候再來解答。

  1. LITE_OS_SEC_TEXT_INIT STATIC_INLINE VOID OsRunningTaskDelete(UINT32 taskID, LosTaskCB *taskCB) 
  2. ⑴  LOS_ListTailInsert(&g_taskRecyleList, &taskCB->pendList); 
  3. ⑵  g_losTask.runTask = &g_taskCBArray[g_taskMaxNum]; 
  4.     g_losTask.runTask->taskID = taskID; 
  5.     g_losTask.runTask->taskStatus = taskCB->taskStatus | OS_TASK_STATUS_RUNNING; 
  6.     g_losTask.runTask->topOfStack = taskCB->topOfStack; 
  7.     g_losTask.runTask->taskName = taskCB->taskName; 

 3.2 控制任務(wù)狀態(tài)

3.2.1 恢復(fù)掛起的任務(wù)LOS_TaskResume()

恢復(fù)掛起的任務(wù),使該任務(wù)進(jìn)入就緒狀態(tài),和下文中的LOS_TaskSuspend()成對(duì)使用。⑴處獲取任務(wù)的TCB,⑵處對(duì)任務(wù)狀態(tài)進(jìn)行判斷,如果任務(wù)未創(chuàng)建或者非阻塞狀態(tài),則返回錯(cuò)誤碼。執(zhí)行⑶設(shè)置任務(wù)狀態(tài)為非掛起狀態(tài)。⑶處獲取任務(wù)的狀態(tài)進(jìn)行判斷,如果任務(wù)沒有創(chuàng)建或者不是掛起狀態(tài),則返回相應(yīng)的錯(cuò)誤碼。 ⑷檢查任務(wù)狀態(tài)是否為OS_CHECK_TASK_BLOCK,即(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND | OS_TASK_STATUS_SUSPEND)中的一種,這幾個(gè)狀態(tài)影響恢復(fù)掛起的任務(wù)。如果非上述幾個(gè)狀態(tài),執(zhí)行⑸調(diào)用函數(shù),把任務(wù)狀態(tài)改為就緒狀態(tài),插入任務(wù)就緒隊(duì)列。如果支持支持調(diào)度,則執(zhí)行⑹觸發(fā)調(diào)度。

  1. LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID) 
  2.     UINTPTR intSave; 
  3.     LosTaskCB *taskCB = NULL
  4.     UINT16 tempStatus; 
  5.     UINT32 retErr = OS_ERROR; 
  6.  
  7.     if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) { 
  8.         return LOS_ERRNO_TSK_ID_INVALID; 
  9.     } 
  10.  
  11. ⑴  taskCB = OS_TCB_FROM_TID(taskID); 
  12.     intSave = LOS_IntLock(); 
  13.     tempStatus = taskCB->taskStatus; 
  14.  
  15. ⑵  if (tempStatus & OS_TASK_STATUS_UNUSED) { 
  16.         retErr = LOS_ERRNO_TSK_NOT_CREATED; 
  17.         OS_GOTO_ERREND(); 
  18.     } else if (!(tempStatus & OS_TASK_STATUS_SUSPEND)) { 
  19.         retErr = LOS_ERRNO_TSK_NOT_SUSPENDED; 
  20.         OS_GOTO_ERREND(); 
  21.     } 
  22.  
  23. ⑶  taskCB->taskStatus &= (~OS_TASK_STATUS_SUSPEND); 
  24. ⑷  if (!(taskCB->taskStatus & OS_CHECK_TASK_BLOCK)) { 
  25. ⑸      OsSchedTaskEnQueue(taskCB); 
  26.         if (g_taskScheduled) { 
  27.             LOS_IntRestore(intSave); 
  28. ⑹          LOS_Schedule(); 
  29.             return LOS_OK; 
  30.         } 
  31.     } 
  32.  
  33.     LOS_IntRestore(intSave); 
  34.     return LOS_OK; 
  35.  
  36. LOS_ERREND: 
  37.     LOS_IntRestore(intSave); 
  38.     return retErr; 

 3.2.2 掛起指定的任務(wù)LOS_TaskSuspend()

函數(shù)用于掛起指定的任務(wù)。⑴處獲取任務(wù)的TCB,⑵處開始獲取任務(wù)的狀態(tài)進(jìn)行判斷,如果任務(wù)沒有創(chuàng)建、任務(wù)已經(jīng)掛起,返回相應(yīng)的錯(cuò)誤碼。⑶處如果任務(wù)是運(yùn)行狀態(tài),并且鎖任務(wù)調(diào)度時(shí),跳轉(zhuǎn)到LOS_ERREND結(jié)束掛起操作。⑷處如果任務(wù)是就緒狀態(tài),調(diào)用函數(shù)從就緒隊(duì)列出隊(duì),并取消任務(wù)的就緒狀態(tài)。⑸處語句設(shè)置任務(wù)狀態(tài)為阻塞狀態(tài)。⑹如果掛起的是當(dāng)前運(yùn)行的任務(wù),則會(huì)主動(dòng)觸發(fā)調(diào)度。

  1. LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID) 
  2.     UINTPTR intSave; 
  3.     LosTaskCB *taskCB = NULL
  4.     UINT16 tempStatus; 
  5.     UINT32 retErr; 
  6.  
  7.     retErr = OsCheckTaskIDValid(taskID); 
  8.     if (retErr != LOS_OK) { 
  9.         return retErr; 
  10.     } 
  11.  
  12. ⑴  taskCB = OS_TCB_FROM_TID(taskID); 
  13.     intSave = LOS_IntLock(); 
  14. ⑵  tempStatus = taskCB->taskStatus; 
  15.     if (tempStatus & OS_TASK_STATUS_UNUSED) { 
  16.         retErr = LOS_ERRNO_TSK_NOT_CREATED; 
  17.         OS_GOTO_ERREND(); 
  18.     } 
  19.  
  20.     if (tempStatus & OS_TASK_STATUS_SUSPEND) { 
  21.         retErr = LOS_ERRNO_TSK_ALREADY_SUSPENDED; 
  22.         OS_GOTO_ERREND(); 
  23.     } 
  24.  
  25. ⑶  if ((tempStatus & OS_TASK_STATUS_RUNNING) && (g_losTaskLock != 0)) { 
  26.         retErr = LOS_ERRNO_TSK_SUSPEND_LOCKED; 
  27.         OS_GOTO_ERREND(); 
  28.     } 
  29.  
  30. ⑷  if (tempStatus & OS_TASK_STATUS_READY) { 
  31.         OsSchedTaskDeQueue(taskCB); 
  32.     } 
  33.  
  34. ⑸  taskCB->taskStatus |= OS_TASK_STATUS_SUSPEND; 
  35.     OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, taskCB); 
  36. ⑹  if (taskID == g_losTask.runTask->taskID) { 
  37.         LOS_IntRestore(intSave); 
  38.         LOS_Schedule(); 
  39.         return LOS_OK; 
  40.     } 
  41.  
  42.     LOS_IntRestore(intSave); 
  43.     return LOS_OK; 
  44.  
  45. LOS_ERREND: 
  46.     LOS_IntRestore(intSave); 
  47.     return retErr; 

 3.2.3 任務(wù)延時(shí)等待LOS_TaskDelay()

任務(wù)延時(shí)等待,釋放CPU,等待時(shí)間到期后該任務(wù)會(huì)重新進(jìn)入就緒狀態(tài)。

⑴處代碼判斷系統(tǒng)處于中斷,如果是,則返回錯(cuò)誤碼,不允許任務(wù)延時(shí)等待。

⑵如果處于鎖任務(wù)調(diào)度期間,則返回錯(cuò)誤碼。

⑶處如果延遲的時(shí)間為0,則執(zhí)行讓權(quán)操作,否則執(zhí)行。

⑷調(diào)用函數(shù)OsSchedDelay()把當(dāng)前任務(wù)設(shè)置為延時(shí)等待狀態(tài),然后調(diào)用LOS_Schedule()觸發(fā)調(diào)度。

  1. LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick) 
  2.     UINTPTR intSave; 
  3.  
  4. ⑴  if (OS_INT_ACTIVE) { 
  5.         return LOS_ERRNO_TSK_DELAY_IN_INT; 
  6.     } 
  7.  
  8. ⑵  if (g_losTaskLock != 0) { 
  9.         return LOS_ERRNO_TSK_DELAY_IN_LOCK; 
  10.     } 
  11.  
  12.     OsHookCall(LOS_HOOK_TYPE_TASK_DELAY, tick); 
  13. ⑶  if (tick == 0) { 
  14.         return LOS_TaskYield(); 
  15.     } else { 
  16.         intSave = LOS_IntLock(); 
  17. ⑷      OsSchedDelay(g_losTask.runTask, tick); 
  18.         OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, g_losTask.runTask); 
  19.         LOS_IntRestore(intSave); 
  20.         LOS_Schedule(); 
  21.     } 
  22.  
  23.     return LOS_OK; 

 另外還提供了函數(shù)LOS_Msleep()和LOS_UDelay(),前者以毫秒為單位進(jìn)行延遲等待。后者也是以毫秒為單位進(jìn)行延遲等待,但是不會(huì)觸發(fā)任務(wù)調(diào)度,當(dāng)前任務(wù)不會(huì)釋放CPU。

  1. LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 mSecs) 
  2.     UINT32 interval; 
  3.  
  4.     if (OS_INT_ACTIVE) { 
  5.         return
  6.     } 
  7.  
  8.     if (mSecs == 0) { 
  9.         interval = 0; 
  10.     } else { 
  11.         interval = LOS_MS2Tick(mSecs); 
  12.         if (interval == 0) { 
  13.             interval = 1; 
  14.         } 
  15.     } 
  16.  
  17.     (VOID)LOS_TaskDelay(interval); 
  18.  
  19. VOID LOS_UDelay(UINT64 microseconds) 
  20.     UINT64 endTime; 
  21.  
  22.     if (microseconds == 0) { 
  23.         return
  24.     } 
  25.  
  26.     endTime = (microseconds / OS_SYS_US_PER_SECOND) * OS_SYS_CLOCK + 
  27.             (microseconds % OS_SYS_US_PER_SECOND) * OS_SYS_CLOCK / OS_SYS_US_PER_SECOND; 
  28.     endTime = LOS_SysCycleGet() + endTime; 
  29.     while (LOS_SysCycleGet() < endTime) { 
  30.     } 
  31.  
  32.     return

 3.2.4 任務(wù)讓權(quán)LOS_TaskYield()

讓權(quán)函數(shù)通過把當(dāng)前任務(wù)時(shí)間片設(shè)置為0,釋放CPU占用,重新調(diào)度給其他高優(yōu)先級(jí)任務(wù)執(zhí)行。⑴處調(diào)用函數(shù)把當(dāng)前任務(wù)時(shí)間片設(shè)置為0,然后執(zhí)行⑵主動(dòng)觸發(fā)任務(wù)調(diào)度。

  1. LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID) 
  2.     UINTPTR intSave; 
  3.  
  4.     intSave = LOS_IntLock(); 
  5. ⑴  OsSchedYield(); 
  6.     LOS_IntRestore(intSave); 
  7. ⑵  LOS_Schedule(); 
  8.     return LOS_OK; 

 接下來看下函數(shù)OsSchedYield()的源碼。代碼很簡(jiǎn)單,獲取當(dāng)前運(yùn)行的任務(wù),然后把其時(shí)間片設(shè)置為0,如下:

  1. VOID OsSchedYield(VOID) 
  2.     LosTaskCB *runTask = g_losTask.runTask; 
  3.  
  4.     runTask->timeSlice = 0; 

 3.3 控制任務(wù)調(diào)度

3.3.1 鎖任務(wù)調(diào)度LOS_TaskLock()

鎖任務(wù)調(diào)度LOS_TaskLock()比較簡(jiǎn)單,把任務(wù)鎖調(diào)度計(jì)數(shù)器全局變量增加1即可,代碼如下。

  1. LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID) 
  2.     UINTPTR intSave; 
  3.  
  4.     intSave = LOS_IntLock(); 
  5.     g_losTaskLock++; 
  6.     LOS_IntRestore(intSave); 

 3.3.2 解鎖任務(wù)調(diào)度LOS_TaskUnlock()

我們看看解鎖任務(wù)調(diào)度函數(shù)LOS_TaskUnlock(),⑴處如果任務(wù)鎖調(diào)度計(jì)數(shù)器全局變量數(shù)值大于0,對(duì)其減1。⑵處如果任務(wù)鎖調(diào)度計(jì)數(shù)器等于0,則執(zhí)行⑶處觸發(fā)調(diào)度。代碼如下:

  1. LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID) 
  2.     UINTPTR intSave; 
  3.  
  4.     intSave = LOS_IntLock(); 
  5. ⑴  if (g_losTaskLock > 0) { 
  6.         g_losTaskLock--; 
  7. ⑵      if (g_losTaskLock == 0) { 
  8.             LOS_IntRestore(intSave); 
  9. ⑶          LOS_Schedule(); 
  10.             return
  11.         } 
  12.     } 
  13.  
  14.     LOS_IntRestore(intSave); 

 3.4 控制任務(wù)優(yōu)先級(jí)

LiteOS-M內(nèi)核支持動(dòng)態(tài)設(shè)置任務(wù)的優(yōu)先級(jí),提供了一些操作。

3.4.1 設(shè)置指定任務(wù)的優(yōu)先級(jí)LOS_TaskPriSet

支持設(shè)置指定任務(wù)Id的優(yōu)先級(jí),也支持對(duì)當(dāng)前運(yùn)行任務(wù)進(jìn)行優(yōu)先級(jí)設(shè)置。⑴處開始,做些基礎(chǔ)校驗(yàn),包含檢驗(yàn)傳入的優(yōu)先級(jí)參數(shù)taskPrio,指定任務(wù)的Id,任務(wù)是否未創(chuàng)建等,如果沒有通過參數(shù)校驗(yàn),則返回錯(cuò)誤碼。⑵處調(diào)用函數(shù)設(shè)置任務(wù)優(yōu)先級(jí),稍后分析該函數(shù)。如果任務(wù)處于就緒狀態(tài)或者運(yùn)行狀態(tài),則會(huì)執(zhí)行⑶主動(dòng)觸發(fā)任務(wù)調(diào)度。

  1. LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio) 
  2.     BOOL isReady = FALSE
  3.     UINTPTR intSave; 
  4.     LosTaskCB *taskCB = NULL
  5.     UINT16 tempStatus; 
  6.  
  7. ⑴  if (taskPrio > OS_TASK_PRIORITY_LOWEST) { 
  8.         return LOS_ERRNO_TSK_PRIOR_ERROR; 
  9.     } 
  10.  
  11.     if (taskID == g_idleTaskID) { 
  12.         return LOS_ERRNO_TSK_OPERATE_IDLE; 
  13.     } 
  14.  
  15.     if (taskID == g_swtmrTaskID) { 
  16.         return LOS_ERRNO_TSK_OPERATE_SWTMR; 
  17.     } 
  18.  
  19.     if (OS_CHECK_TSK_PID_NOIDLE(taskID)) { 
  20.         return LOS_ERRNO_TSK_ID_INVALID; 
  21.     } 
  22.  
  23.     taskCB = OS_TCB_FROM_TID(taskID); 
  24.     intSave = LOS_IntLock(); 
  25.     tempStatus = taskCB->taskStatus; 
  26.     if (tempStatus & OS_TASK_STATUS_UNUSED) { 
  27.         LOS_IntRestore(intSave); 
  28.         return LOS_ERRNO_TSK_NOT_CREATED; 
  29.     } 
  30.  
  31. ⑵  isReady = OsSchedModifyTaskSchedParam(taskCB, taskPrio); 
  32.     LOS_IntRestore(intSave); 
  33.     if (isReady) { 
  34. ⑶      LOS_Schedule(); 
  35.     } 
  36.  
  37.     return LOS_OK; 

 接下來,我們分析下函數(shù)OsSchedModifyTaskSchedParam()。⑴處如果任務(wù)處于就緒狀態(tài),需要先出隊(duì)設(shè)置優(yōu)先級(jí),然后入隊(duì)就緒隊(duì)列。如果非就緒狀態(tài),可以直接執(zhí)行⑵處語句修改任務(wù)優(yōu)先級(jí)。如果任務(wù)正在運(yùn)行,需要返回TRUE,標(biāo)記下需要任務(wù)調(diào)度。

  1. BOOL OsSchedModifyTaskSchedParam(LosTaskCB *taskCB, UINT16 priority) 
  2.     if (taskCB->taskStatus & OS_TASK_STATUS_READY) { 
  3. ⑴      OsSchedTaskDeQueue(taskCB); 
  4.         taskCB->priority = priority; 
  5.         OsSchedTaskEnQueue(taskCB); 
  6.         return TRUE
  7.     } 
  8.  
  9. ⑵  taskCB->priority = priority; 
  10.     OsHookCall(LOS_HOOK_TYPE_TASK_PRIMODIFY, taskCB, taskCB->priority); 
  11.     if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { 
  12.         return TRUE
  13.     } 
  14.  
  15.     return FALSE

 3.4.2 獲取指定任務(wù)的優(yōu)先級(jí)LOS_TaskPriGet

獲取指定任務(wù)的優(yōu)先級(jí)LOS_TaskPriGet()代碼比較簡(jiǎn)單,⑴處如果任務(wù)編號(hào)無效,返回錯(cuò)誤碼。⑵處如果任務(wù)未創(chuàng)建返回錯(cuò)誤碼。如果參數(shù)校驗(yàn)通過,執(zhí)行⑶獲取任務(wù)的優(yōu)先級(jí)數(shù)值。

  1. LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID) 
  2.     UINTPTR intSave; 
  3.     LosTaskCB *taskCB = NULL
  4.     UINT16 priority; 
  5.  
  6. ⑴  if (OS_CHECK_TSK_PID_NOIDLE(taskID)) { 
  7.         return (UINT16)OS_INVALID; 
  8.     } 
  9.  
  10.     taskCB = OS_TCB_FROM_TID(taskID); 
  11.  
  12.     intSave = LOS_IntLock(); 
  13.  
  14. ⑵  if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { 
  15.         LOS_IntRestore(intSave); 
  16.         return (UINT16)OS_INVALID; 
  17.     } 
  18.  
  19. ⑶  priority = taskCB->priority; 
  20.     LOS_IntRestore(intSave); 
  21.     return priority; 

 3.5 任務(wù)阻塞和喚醒

最后,我們分析下函數(shù)OsSchedTaskWait()和OsSchedTaskWake(),這2個(gè)函數(shù)定義在文件kernel\src\los_sched.c中。任務(wù)在申請(qǐng)互斥鎖、信號(hào)量、出入隊(duì)列、讀寫事件時(shí),都可能導(dǎo)致任務(wù)進(jìn)入阻塞狀態(tài),對(duì)應(yīng)地也需要任務(wù)喚醒重新進(jìn)入就緒隊(duì)列狀態(tài)。這2個(gè)函數(shù)就負(fù)責(zé)任務(wù)的阻塞和喚醒,我們分析下他們的代碼。

3.5.1 任務(wù)阻塞

我們分析下任務(wù)阻塞的函數(shù)OsSchedTaskWait(),需要2個(gè)參數(shù):LOS_DL_LIST *list是互斥鎖等資源的阻塞鏈表,阻塞的任務(wù)會(huì)掛這個(gè)鏈表里;UINT32 ticks是任務(wù)阻塞的時(shí)間。分析下具體代碼:

⑴獲取正在請(qǐng)求互斥鎖等資源的當(dāng)前任務(wù),⑵設(shè)置任務(wù)狀態(tài)為阻塞狀態(tài)。⑶把任務(wù)插入互斥鎖等資源的阻塞鏈表的尾部。⑷如果不是永久阻塞等待,任務(wù)的狀態(tài)還需要設(shè)置為:

  1. VOID OsSchedTaskWait(LOS_DL_LIST *list, UINT32 ticks) 
  2. ⑴  LosTaskCB *runTask = g_losTask.runTask; 
  3.  
  4. ⑵  runTask->taskStatus |= OS_TASK_STATUS_PEND; 
  5. ⑶  LOS_ListTailInsert(list, &runTask->pendList); 
  6.  
  7.     if (ticks != LOS_WAIT_FOREVER) { 
  8. ⑷      runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME; 
  9.         runTask->waitTimes = ticks; 
  10.     } 

 3.5.2 任務(wù)喚醒

我們分析下任務(wù)喚醒的函數(shù)OsSchedTaskWake(),需要1個(gè)參數(shù):LosTaskCB *resumedTask是需要喚醒的任務(wù);任務(wù)喚醒函數(shù)會(huì)從阻塞鏈表里刪除并加入就緒隊(duì)列,下面分析下具體代碼:

⑴把要喚醒的任務(wù)從所在的阻塞隊(duì)列中刪除,然后更改狀態(tài)不再為阻塞狀態(tài)。⑵如果任務(wù)不是永久等待,需要從定時(shí)器排序鏈表中刪除,并設(shè)置狀態(tài)不再是等待超時(shí)。⑶如果任務(wù)是阻塞狀態(tài),改為就緒狀態(tài)并加入就緒隊(duì)列。

  1. VOID OsSchedTaskWake(LosTaskCB *resumedTask) 
  2. ⑴  LOS_ListDelete(&resumedTask->pendList); 
  3.     resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND; 
  4.  
  5. ⑵  if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { 
  6.         OsDeleteSortLink(&resumedTask->sortList, OS_SORT_LINK_TASK); 
  7.         resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; 
  8.     } 
  9.  
  10. ⑶  if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPEND)) { 
  11.         OsSchedTaskEnQueue(resumedTask); 
  12.     } 

 小結(jié)

本文帶領(lǐng)大家一起剖析了鴻蒙輕內(nèi)核任務(wù)模塊的源代碼,包含任務(wù)模塊的結(jié)構(gòu)體,任務(wù)初始化過程源代碼,任務(wù)常用操作的源代碼。后續(xù)也會(huì)陸續(xù)推出更多的分享文章,敬請(qǐng)期待。

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2021-05-20 09:50:20

鴻蒙HarmonyOS應(yīng)用

2021-05-13 09:47:08

鴻蒙HarmonyOS應(yīng)用

2021-05-12 09:45:20

鴻蒙HarmonyOS應(yīng)用

2021-05-10 15:05:56

鴻蒙HarmonyOS應(yīng)用

2022-01-10 15:31:44

鴻蒙HarmonyOS應(yīng)用

2022-01-12 10:50:23

鴻蒙HarmonyOS應(yīng)用

2021-06-04 09:57:49

鴻蒙HarmonyOS應(yīng)用

2024-10-25 09:26:56

2021-05-17 09:28:59

鴻蒙HarmonyOS應(yīng)用

2021-06-04 14:15:10

鴻蒙HarmonyOS應(yīng)用

2021-05-08 15:14:50

鴻蒙HarmonyOS應(yīng)用

2021-05-25 09:28:34

鴻蒙HarmonyOS應(yīng)用

2021-10-20 16:08:57

鴻蒙HarmonyOS應(yīng)用

2021-05-31 20:30:55

鴻蒙HarmonyOS應(yīng)用

2022-03-03 18:28:28

Harmony進(jìn)程任務(wù)管理模塊

2022-04-13 11:02:12

鴻蒙事件模塊事件Event

2021-07-06 09:45:03

鴻蒙HarmonyOS應(yīng)用

2021-09-22 14:36:32

鴻蒙HarmonyOS應(yīng)用

2022-03-11 20:23:14

鴻蒙源碼分析進(jìn)程管理

2021-06-09 09:48:01

鴻蒙HarmonyOS應(yīng)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)