有了前面的经历之后,在ucosii里,创建一个任务之后,可以对任务执行以下几种操作
1.删除任务 OSTaskDel()
2.挂起任务 OSTaskSuspend()
3.恢复任务 OSTaskResume()
4.改变任务的优先级OSTaskChangePrio()
5.提取任务信息OSTaskQuery()
今天我们学习一下删除任务,删除任务是说任务将返回并处以休眠状态,任务的代码不再被ucos调用
删除任务不是删除代码,删除任务和挂起任务有些相似,其实有着本质的区别,根本来说,我觉得最大的不同
就是删除任务队任务控制块的操作,我们知道在任务创建的时候,需要给每个任务分配一个任务控制块,这个任务控制块
存储有关这个任务重要的信息,对任务间有至关重要的作用,挂起任务根本不会动任务块,但删除任务就会把任务控制块从
OSTCBList链表移到OSTCBFreeList.下面详细理解删除的实现过程
INT8U OSTaskDel(ITN8U prio)
{
OS_TCB *ptcb;
OS_EVENT *pevent;
if(prio==OS_IDLE_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; (8)
Ptcb->OSTCBStat=OS_STAT_RDY (9)
OSLockNesting++; (10)
OS_EXIT_CRITICAL();
OSDummy();
OS_ENTER_CRITICAL();
OSLockNest--;
OSTaskDelHook(ptcb);
OSTaskCtr--;
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->OSTCBPre;
}
ptcb->OSTCBNext=OSTCBFreeList;
OSTCBFreeList=ptcb;
OS_EXIT_CRITICAL();
OSSched();
return (OS_NO_ERR);
}
else
{
OS_EXIT_CRITICAL();
return (OS_TASK_DEL_ERR);
}
仔细阅读上面的程序,可以看出(1) (2) (3) (4) (5) (6) (7)和挂起任务函数,恢复任务函数基本一样,体现ucos
代码的完整性,整个过程大致如下:
1. 把要删除的任务移除就绪表
2.把要删除的任务移除等待表
3.避免其它任务或ISR调用OSTaskResume()
4.阻止任务调度,以防任务删除过程镇南关切换到其它的任务
5.减少ucso的任务计数器,简单地指向指向被删除的任务的OS_TCB的指针指向NULL,从而达到将OS_TCB从优先级表中移除的目的
6.将被大汗出的任务OS_TCB 从OS_TCB双向链表中移除