μC/OS之OSTaskDel()

INT8 OSTaskDel (INT8U prio)
{
   OS_TCB *ptcb;         /*建立两个局部指针,分别用来指向TCB,和EVENT*/
   OS_EVENT *pevent;
   
   
   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 (OSIntNesting > 0)  /*查看是否处于终端服务子程序状态,删除*/
   {
      OS_EXIT_CRITICAL();
      return (OS_TASK_DEL_ISR);
   }
   
   
   if (prio == OS_PRIO_SELF)  /*查看是否要删除正在执行的任务*/
   {
      prio = OSTCBCur->OSTCBPrio;
   }
   
   if((ptcb = OSTCBPrioTbl[prio] != (OS_TCB *)0
   {
      if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) /*判断任务是否在就绪表中,若在则删除*/
      {
         OSRdyGrp &= ~ptcb->OSTCBBitY;
      }
      
      
      
      if((pevent = ptcb->OSTCBEventPtr) != (OS_EVENT *)0)  /*判断任务是否在邮箱、消息队列或信号量等待表中,若在则删除*/
      {
         if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
         {
            pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
         }
      }
      
      ptcb->OSTCBDly = 0;                /*防止被OSTmieTick()调用,使其进入就绪状态*/               
      ptcb->OSTCBStat = OS_STAT_RDY;      /*防止被OSTaskPesume()调用,使其进入就绪状态,因OSTaskPesume()中有个条件!=OS_STAT_RDY*/
      
      OSLockNesting++; /*关闭任务调度功能,因为此时被删除的任务已经处于休眠状态,不可被任何任务调度了*/
                       /*如果没有关闭任务调度功能,万一在后来的开中断后,进行了任务切换,那么该任务就占用了内存而无法删除了*/
                       
      OS_EXIT_CRITICAL(); /*开中断,以便服务中断事件,减小中断响应时间,*/
      
      OSDummy();    /*这是因为中断允许指令会强制CPU禁止中断直到下一个指令结束!如果没有该指令,则继续执行下条指令,而下条指令是*/
                    /*关中断,导致没有机会响应中断服务程序*/
                    
      OS_ENTER_CRITICAL(); /*中断服从程序执行完毕,返回删除任务函数,继续执行任务剩下部分的删除*/
      OSLockNesting--;     /*允许任务调度*/
      
      OSTaskDelHook(ptcb); /*删除用户为扩展TCB而附加的数据域*/
      OSTaskCtr--;          /*将任务个数减小1*/
      OSTCBPrioTbl[prio] = (OS_TCB *)0; /*将TCB优先级表中对应为置位NULL*/
      
      if (ptcb->OSTCBPrev == (OS_TCB *)0)   /*将任务的TCB从双向TCB链表中删除*/
      {
         ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0; /*被删除任务TCB在TCB链表表头的情况*/
         OSTCBList = ptcb->OSTCBNext;
      }
      else
      {
         ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext; /*在表中的情况*/
         ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
      }                                                /*并没有考虑表尾情况,因为表尾为空任务*/
      
      ptcb->OSTCBNext = OSTCBFreeList;                 /*TCB返回到空TCB链表*/
      OSTCBFreeList = ptcb;
      OS_EXIT_CRITICAL();
      
      OSSched();                                       /*删除完毕调度任务*/
      return (OS_NO_ERR);
   }     
   else
   {
      OS_EXIT_CRITICAL();
      return (OS_TASK_DEL_ERR);
   }
}


小结:OSTaskDel()做了哪些事:
     ①更新5个表中的相关信息;
     ②阻塞两个函数的调度
     ③更新记录任务数的变量;
     ④删除对TCB扩充的数据域;
 步骤:
     ①判断优先级是否为空闲进程,优先级是否有效;
     ②判断任务删除是否在中断服务子程序中进行;
     ③判断所要删除的任务是否存在;
     ④更新就绪表中的信息;更新等待表中的信息;
     ⑤阻塞OSTmieTick(),OSTaskPesume()函数调用;
     ---主要做的就是将任务无法进入就绪状态-----
     ----此时该任务成休眠状态------------
     ⑥关闭任务的调度功能,并运行中断,以便响应中断,减小中断响应;
     ⑦关闭中断继续执行,并打开任务的调度功能。
     ⑧更新TCB优先级表,TCB链表,空闲TCB链表,任务数
     ⑨删除TCB中扩展功能申请的数据域
     ----此部分是更新各个表中的信息-------
     10.任务调度
     
   

你可能感兴趣的:(OS,null,任务调度,扩展,任务,终端)