#if OS_TASK_DEL_EN > 0
INT8U OSTaskDel (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
#if OS_EVENT_EN > 0
OS_EVENT *pevent;
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
OS_FLAG_NODE *pnode;
#endif
OS_TCB *ptcb;
(說明:OSIntNesting用來記錄是否有中斷服務程式正在運行。OSIntNesting為0表示沒有,非0數表示有中斷在運行。則返回OS_TASK_DEL_ISR)
if (OSIntNesting > 0) {
return (OS_TASK_DEL_ISR);
}
#if OS_ARG_CHK_EN > 0
(說明:以下是對優先順序的各種可能情況作判斷)
if (prio == OS_IDLE_PRIO) { //不能刪除空閑任務
return (OS_TASK_DEL_IDLE);
}
if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { //非法的優先順序
return (OS_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) {
prio = OSTCBCur->OSTCBPrio; //獲得當前任務的優先順序的值
}
//就緒表刪除任務
if ((ptcb = OSTCBPrioTbl[prio]) != (OS_TCB *)0) {
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
(說明:以下是對事件控制塊的操作,會在以後的章節介紹)
#if OS_EVENT_EN > 0
pevent = ptcb->OSTCBEventPtr;
if (pevent != (OS_EVENT *)0) { /* If task is waiting on event */
if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { /* ... remove task from */
pevent->OSEventGrp &= ~ptcb->OSTCBBitY; /* ... event ctrl block */
}
}
#endif
(說明:以下是對事件標誌結點的操作,以後的章節會介紹)
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
pnode = ptcb->OSTCBFlagNode;
if (pnode != (OS_FLAG_NODE *)0) {
OS_FlagUnlink(pnode);
}
#endif
(說明:OSTCBDly是TCB控制塊的元素。當需要把任務延時若干時鐘節拍時,或者需要把任務掛起一段時間以等待某事件的發生時,須用到這個變數。表示任務允許等待事件發生的最多時鐘節拍數。如果為0,表示任務不延時或者表示等待事件發生的時間沒有限制。OSTCBStat表示任務的狀態。OS_STAT_RDY表示就緒狀態。可以設定的各種狀態可以參見P79-表4-2)
ptcb->OSTCBDly = 0; //延時設定為0
ptcb->OSTCBStat = OS_STAT_RDY; //狀態設定為就緒
(說明:為了使用者可對調度器的工作進行控制,提供了兩個系統函數OSSchedLock()和OSSchedUnlock()。前者實現的功能是為調度器上鎖,後者的作用是位調度器解鎖。OSLockNesting為全域變數。加鎖時,OSLockNesting加1,解鎖時,OS
LockNesting-1。每次調度器在判斷是否進行調度時,查看OSLockNesting的值是否為0,非0則不能調度)
if (OSLockNesting < 255) {
OSLockNesting++;
}
(說明:為了盡量減少中斷的執行時間,在這裡開中斷。可以使其他任務執行)
OS_EXIT_CRITICAL(); //關中斷
(說明:OS_Dummy()沒有進行實質性的操作。目的是保證處理器在中斷開著的情況下至少執行一條指令。許多處理器開中斷後,CPU會強制執行下一條指令,然後才開中斷。也就是說,直到執行完下一條指令後,才會真正開中斷。)
OS_Dummy();
OS_ENTER_CRITICAL(); //開中斷
if (OSLockNesting > 0) {
OSLockNesting--;
}
OSTaskDelHook(ptcb); //調用OSTaskDelHook(),實行使用者刪除時的處理
OSTaskCtr--; //任務計數器-1
(說明:以下實現刪除任務控制塊。需要修改的包括:OSTCBPrioTbl[prio]、OSTCBNext、OSTCBPrev、OSTCBFreeList、OSTCBList)
OSTCBPrioTbl[prio] = (OS_TCB *)0;
if (ptcb->OSTCBPrev == (OS_TCB *)0) {
ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
OSTCBList = ptcb->OSTCBNext;
} else {
ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
}
ptcb->OSTCBNext = OSTCBFreeList;
OSTCBFreeList = ptcb;
OS_EXIT_CRITICAL();
OS_Sched(); //任務調度,找到新的最高優先順序任務
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL();
return (OS_TASK_DEL_ERR);
}
#endif