转载自:http://blog.youkuaiyun.com/xiaocaichonga/article/details/7463753
- 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.任务调度