天天看點

ucos-ii 之OSTaskDel函數

#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           

繼續閱讀