#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;
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);
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;
}
(說明:以下是對事件控制塊的操作,會在以後的章節介紹)
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 */
}
(說明:以下是對事件标志結點的操作,以後的章節會介紹)
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