LiteOS-任務篇-源碼分析-刪除任務函數
前言
- 20201009
- LiteOS 2018
- 需要會通用鏈表
筆錄草稿
源碼分析
LOS_TaskDelete函數源碼分析
完整源碼
- 進入處理前,需要進入任務臨界
- 通過任務ID來獲取任務句柄
- 根據各種狀態進行處理
- 處於 OS_TASK_STATUS_UNUSED (未使用) 狀態
- 處於 OS_TASK_STATUS_RUNNING (運行態) 且調度被鎖定了
- 處於 就緒態 或 阻塞態 或 阻塞隊列態
- 處於 OS_TASK_STATUS_READY (就緒態)
- 處於 OS_TASK_STATUS_PEND(阻塞態) 或 OS_TASK_STATUS_PEND_QUEUE(阻塞隊列態)
- 處於 OS_TASK_STATUS_DELAY (延時態)或 OS_TASK_STATUS_TIMEOUT(超時態)
- 被刪除的任務需要做一些複位處理
- 被刪除的任務s是否處於運行態
- 是
- 不能完全刪除該任務,因為,調度過程中需要該任務參與
- 把當前任務插入到回收列表中,待運行創建任務函數時在進行回收處理。(其它RTOS都是在空閑任務中處理)
- 把當前任務(被刪除的任務)copy到最低優先順序的任務中,即是比空閑任務還低一個優先順序的備用任務中,被賦給 g_stLosTask.pstRunTask,用於下main調度使用
- 解鎖中斷
- 調度
- 否
- 標記為未使用狀態
- 直接放到空閑列表中
- 釋放任務堆空間
- 初始化棧頂指針
- 解鎖中斷
/*****************************************************************************
Function : LOS_TaskDelete
Description : Delete a task
Input : uwTaskID --- Task ID
Output : None
Return : LOS_OK on success or error code on failure
*****************************************************************************/
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 uwTaskID)
{
UINTPTR uvIntSave;
LOS_TASK_CB *pstTaskCB;
UINT16 usTempStatus;
UINT32 uwErrRet = OS_ERROR;
CHECK_TASKID(uwTaskID); // 檢查任務 ID
uvIntSave = LOS_IntLock(); // 鎖中斷
pstTaskCB = OS_TCB_FROM_TID(uwTaskID); // 通過任務 ID 獲取任務控制塊句柄
usTempStatus = pstTaskCB->usTaskStatus; // 獲取任務狀態
/* 判斷任務狀態是否處於 UNUSED (即未被創建) 狀態,若是則退出*/
if (OS_TASK_STATUS_UNUSED & usTempStatus)
{
uwErrRet = LOS_ERRNO_TSK_NOT_CREATED;
OS_GOTO_ERREND();
}
/* If the task is running and scheduler is locked then you can not delete it */
if ((OS_TASK_STATUS_RUNNING & usTempStatus) && (g_usLosTaskLock != 0))
{
PRINT_INFO("In case of task lock, task deletion is not recommended\n");
g_usLosTaskLock = 0;
}
/* 判斷任務狀態是否處於 READY (即就緒態) 狀態*/
if (OS_TASK_STATUS_READY & usTempStatus) // 處於就緒態
{
osPriqueueDequeue(&pstTaskCB->stPendList); // 從對應鏈表中刪除該任務節點
pstTaskCB->usTaskStatus &= (~OS_TASK_STATUS_READY); // 取消就緒態
}
else if ((OS_TASK_STATUS_PEND & usTempStatus) || (OS_TASK_STATUS_PEND_QUEUE & usTempStatus)) // 處於阻塞態
{
LOS_ListDelete(&pstTaskCB->stPendList); // 從對應鏈表中刪除該任務節點
}
if ((OS_TASK_STATUS_DELAY | OS_TASK_STATUS_TIMEOUT) & usTempStatus) // 處於任務延時會或超時狀態
{
osTimerListDelete(pstTaskCB); // 從對應鏈表中刪除該任務節點
}
pstTaskCB->usTaskStatus &= (~(OS_TASK_STATUS_SUSPEND)); // 取消掛起態
pstTaskCB->usTaskStatus |= OS_TASK_STATUS_UNUSED; // 標為未使用狀態
pstTaskCB->uwEvent.uwEventID = 0xFFFFFFFF; // 複位時間ID
pstTaskCB->uwEventMask = 0;
#if (LOSCFG_BASE_CORE_CPUP == YES)
(VOID)memset((VOID *)&g_pstCpup[pstTaskCB->uwTaskID], 0, sizeof(OS_CPUP_S));
#endif
g_stLosTask.pstNewTask = LOS_DL_LIST_ENTRY(osPriqueueTop(), LOS_TASK_CB, stPendList); /*lint !e413*/ // 在就緒列表中尋找最高優先順序的任務,標為下一個需要運行的任務
if (OS_TASK_STATUS_RUNNING & pstTaskCB->usTaskStatus) // 如果被刪除的任務為運行態
{
/*
* 如果刪除的任務為運行態時,就不能完全刪除該任務,因為,調度過程中需要當前任務參與。
* 需要把當前任務插入到回收列表中,待運行創建任務函數時在進行回收處理。(其它RTOS都是在空閑任務中處理)
*/
LOS_ListTailInsert(&g_stTskRecyleList, &pstTaskCB->stPendList); // 把該任務插入回收列表
g_stLosTask.pstRunTask = &g_pstTaskCBArray[g_uwTskMaxNum];
g_stLosTask.pstRunTask->uwTaskID = uwTaskID;
g_stLosTask.pstRunTask->usTaskStatus = pstTaskCB->usTaskStatus;
g_stLosTask.pstRunTask->uwTopOfStack = pstTaskCB->uwTopOfStack;
g_stLosTask.pstRunTask->pcTaskName = pstTaskCB->pcTaskName;
pstTaskCB->usTaskStatus = OS_TASK_STATUS_UNUSED;
(VOID)LOS_IntRestore(uvIntSave); // 解鎖中斷
osSchedule(); // 調度
return LOS_OK;
}
else // 如果不為運行態
{
pstTaskCB->usTaskStatus = OS_TASK_STATUS_UNUSED; // 標為未使用
LOS_ListAdd(&g_stLosFreeTask, &pstTaskCB->stPendList); // 插入到可用列表
(VOID)LOS_MemFree(m_aucSysMem0, (VOID *)pstTaskCB->uwTopOfStack); // 釋放任務堆空間記憶體
pstTaskCB->uwTopOfStack = (UINT32)NULL; // 標記棧頂為空
}
(VOID)LOS_IntRestore(uvIntSave); // 解鎖中斷
return LOS_OK;
LOS_ERREND: // 錯誤
(VOID)LOS_IntRestore(uvIntSave);
return uwErrRet;
}
參考
鏈接