#if OS_TASK_DEL_EN > 0
INT8U OSTaskDel (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
#if OS_EVENT_EN > 0
OS_EVENT *pevent;
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
OS_FLAG_NODE *pnode;
OS_TCB *ptcb;
(说明:OSIntNesting用来记录是否有中断服务程序正在运行。OSIntNesting为0表示没有,非0数表示有中断在运行。则返回OS_TASK_DEL_ISR)
if (OSIntNesting > 0) {
return (OS_TASK_DEL_ISR);
}
#if OS_ARG_CHK_EN > 0
(说明:以下是对优先级的各种可能情况作判断)
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 (prio == OS_PRIO_SELF) {
prio = OSTCBCur->OSTCBPrio; //获得当前任务的优先级的值
}
//就绪表删除任务
if ((ptcb = OSTCBPrioTbl[prio]) != (OS_TCB *)0) {
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
(说明:以下是对事件控制块的操作,会在以后的章节介绍)
pevent = ptcb->OSTCBEventPtr;
if (pevent != (OS_EVENT *)0) { /* If task is waiting on event */
if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { /* ... remove task from */
pevent->OSEventGrp &= ~ptcb->OSTCBBitY; /* ... event ctrl block */
}
(说明:以下是对事件标志结点的操作,以后的章节会介绍)
pnode = ptcb->OSTCBFlagNode;
if (pnode != (OS_FLAG_NODE *)0) {
OS_FlagUnlink(pnode);
#endif
(说明:OSTCBDly是TCB控制块的元素。当需要把任务延时若干时钟节拍时,或者需要把任务挂起一段时间以等待某事件的发生时,须用到这个变量。表示任务允许等待事件发生的最多时钟节拍数。如果为0,表示任务不延时或者表示等待事件发生的时间没有限制。OSTCBStat表示任务的状态。OS_STAT_RDY表示就绪状态。可以设置的各种状态可以参见P79-表4-2)
ptcb->OSTCBDly = 0; //延时设置为0
ptcb->OSTCBStat = OS_STAT_RDY; //状态设置为就绪
(说明:为了用户可对调度器的工作进行控制,提供了两个系统函数OSSchedLock()和OSSchedUnlock()。前者实现的功能是为调度器上锁,后者的作用是位调度器解锁。OSLockNesting为全局变量。加锁时,OSLockNesting加1,解锁时,OS
LockNesting-1。每次调度器在判断是否进行调度时,查看OSLockNesting的值是否为0,非0则不能调度)
if (OSLockNesting < 255) {
OSLockNesting++;
}
(说明:为了尽量减少中断的执行时间,在这里开中断。可以使其他任务执行)
OS_EXIT_CRITICAL(); //关中断
(说明:OS_Dummy()没有进行实质性的操作。目的是保证处理器在中断开着的情况下至少执行一条指令。许多处理器开中断后,CPU会强制执行下一条指令,然后才开中断。也就是说,直到执行完下一条指令后,才会真正开中断。)
OS_Dummy();
OS_ENTER_CRITICAL(); //开中断
if (OSLockNesting > 0) {
OSLockNesting--;
}
OSTaskDelHook(ptcb); //调用OSTaskDelHook(),实行用户删除时的处理
OSTaskCtr--; //任务计数器-1
(说明:以下实现删除任务控制块。需要修改的包括:OSTCBPrioTbl[prio]、OSTCBNext、OSTCBPrev、OSTCBFreeList、OSTCBList)
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->OSTCBPrev;
ptcb->OSTCBNext = OSTCBFreeList;
OSTCBFreeList = ptcb;
OS_EXIT_CRITICAL();
OS_Sched(); //任务调度,找到新的最高优先级任务
return (OS_NO_ERR);
OS_EXIT_CRITICAL();
return (OS_TASK_DEL_ERR);
#endif