任务的删除意味着:
a) 它的任务控制块从OSTCBList链表中移到OSTCBFreeList,这样时钟节拍函数中就不会处理它了,这样调度把它置入就绪表的可能性就没了;
b) 如果它已经处于就绪表中,那么它将被移出,这样调度器函数就不会处理它,这样它被调度运行的机会就没了;
c) 如果任务处于邮箱、消息队列、信号量的等代表中,那么一旦条件满足(譬如邮箱接收到一条消息或者信号量被增1),它就有可能被置入就绪表,为此也要把它移出等待表!这些都完成了,任务就不会有机会占用CPU了,但是他的代码并不会被删除[至少目前这个版本(2.54)不会,如果你让他运行在RAM里面,而且丰富内存处理函数的话,那么可以象Linux那样删除它的代码在RAM中所占用的空间[RR3] ,rom里的不会被删除。其实任务删除函数做的就是让任务失去调度的可能性,它占用的资源并没有释放,为此系统提供了请求删除任务函数,它在可能被删除的任务中被调用,用来释放占用的资源:该任务可能占用那些资源可以从你写的任务代码中看出,所以你该知道怎么去释放!
函数名 |
OSTaskDel |
参数 |
prio删除任务的优先级(0xFF表示当前任务) |
功能描述 |
删除任务 |
函数原型 |
INT8U OSTaskDel(INT8U prio) |
核 心 代 码 |
{ OS_ENTER_CRITICAL(); //进入临界区0 if (prio == OS_PRIO_SELF)//如果调用该函数时使用0XFF表示当前任务 { //就获取当前任务的优先级 prio = OSTCBCur->OSTCBPrio; }
ptcb = OSTCBPrioTbl[prio]; if (ptcb != (OS_TCB *) 0) //判断删除的任务是否存在 { //取消当前删除的任务在就绪表中的登记 if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) { OSRdyGrp &= ~ptcb->OSTCBBitY; }
ptcb->OSTCBDly = 0; //设置等待时间为0,防止系统时钟中断更新此值 ptcb->OSTCBStat = OS_STAT_RDY;//设置状态为OS_STAT_RDY,防止此任务再次回复执行
//调度器加锁 if (OSLockNesting < 255) { OSLockNesting++;//任务调度锁定次数加1 } //(上锁的任务是可以中断)
OS_EXIT_CRITICAL();//退出临界区0 OS_Dummy(); //该函数相当于NOP指令,空执行,等待一个时间周期 //在部分CPU中规定,中断开启后必须这样至少执行一个周期 //如果开启中断后立即关闭将可能导致中断关闭无效
OS_ENTER_CRITICAL();//进入临界区1
//调度器解锁 if (OSLockNesting > 0) { OSLockNesting--;//任务调度锁定次数减1 }
OSTaskCtr--; //任务数减1 OSTCBPrioTbl[prio] = (OS_TCB *) 0; //清除该任务的TCB相关项 if (ptcb->OSTCBPrev == (OS_TCB *) 0)//判断是否位于当前任务TCB位于链头 { ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *) 0;//从TCB链中删除当前任务的TCB OSTCBList = ptcb->OSTCBNext; } else//当前任务TCB不在链表头 { ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext; ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev; }
ptcb->OSTCBNext = OSTCBFreeList;//将删除任务的TCB添加到空闲TCB链表中 OSTCBFreeList = ptcb; //
OS_EXIT_CRITICAL(); //退出临界区1 OS_Sched(); //从就绪表中找出最高优先级并执行对应的代码段
return (OS_NO_ERR); //如果调度器上锁,就执行该语句 } OS_EXIT_CRITICAL();//退出临界区0
return (OS_TASK_DEL_ERR);//删除的任务不存在,返回错误信息 } |