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.任务调度
μC/OS之OSTaskDel()
最新推荐文章于 2023-10-11 14:42:20 发布