UC/OS基础知识之任务的删除
所谓的删除一个任务,就是把任务处于睡眠状态。具体状态就是把删除的任务从任务控制块链表中山删除,并归还给空任务控制块链表,然后在任务就绪表中把该任务的状态位置0,于是该任务就不能被调度器所调用了。在任务中可以调用函数OSTaskDel()来删除空闲任务以外的任务。
#if OS_TASK_DEL_EN > 0
INT8U OSTaskDel (INT8U prio)
{
#if OS_EVENT_EN
OS_EVENT *pevent;
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
OS_FLAG_NODE *pnode;
#endif
OS_TCB *ptcb;
INT8U y;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
if (OSIntNesting > 0) { /* See if trying to delete from ISR */
return (OS_TASK_DEL_ISR);
}
if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to delete idle task */
return (OS_TASK_DEL_IDLE);
}
#if OS_ARG_CHK_EN > 0
if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */
if (prio != OS_PRIO_SELF) {
return (OS_PRIO_INVALID);
}
}
#endif
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) { /* See if requesting to delete self */
prio = OSTCBCur->OSTCBPrio; /* Set priority to delete to current */
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_EXIST);
}
if (ptcb == (OS_TCB *)1) { /* Must not be assigned to Mutex */
OS_EXIT_CRITICAL();
return (OS_TASK_DEL_ERR);
}
y = ptcb->OSTCBY;
OSRdyTbl[y] &= ~ptcb->OSTCBBitX;
if (OSRdyTbl[y] == 0) { /* Make task not ready */
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
#if OS_EVENT_EN
pevent = ptcb->OSTCBEventPtr;
if (pevent != (OS_EVENT *)0) { /* If task is waiting on event */
pevent->OSEventTbl[y] &= ~ptcb->OSTCBBitX;
if (pevent->OSEventTbl[y] == 0) { /* ... remove task from ... */
pevent->OSEventGrp &= ~ptcb->OSTCBBitY; /* ... event ctrl block */
}
}
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
pnode = ptcb->OSTCBFlagNode;
if (pnode != (OS_FLAG_NODE *)0) { /* If task is waiting on event flag */
OS_FlagUnlink(pnode); /* Remove from wait list */
}
#endif
ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from updating */
ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed */
ptcb->OSTCBPendTO = OS_FALSE;
if (OSLockNesting < 255u) { /* Make sure we don't context switch */
OSLockNesting++;
}
OS_EXIT_CRITICAL(); /* Enabling INT. ignores next instruc. */
OS_Dummy(); /* ... Dummy ensures that INTs will be */
OS_ENTER_CRITICAL(); /* ... disabled HERE! */
if (OSLockNesting > 0) { /* Remove context switch lock */
OSLockNesting--;
}
OSTaskDelHook(ptcb); /* Call user defined hook */
OSTaskCtr--; /* One less task being managed */
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Clear old priority entry */
if (ptcb->OSTCBPrev == (OS_TCB *)0) { /* Remove from TCB chain */
ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
OSTCBList = ptcb->OSTCBNext;
} else {
ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
}
ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list */
OSTCBFreeList = ptcb;
#if OS_TASK_NAME_SIZE > 1
ptcb->OSTCBTaskName[0] = '?'; /* Unknown name */
ptcb->OSTCBTaskName[1] = OS_ASCII_NUL;
#endif
OS_EXIT_CRITICAL();
OS_Sched(); /* Find new highest priority task */
return (OS_NO_ERR);
}
#endif
有时任务会占用一些动态的内存或者信号量之类的资源,这时如果有个任务删除了,那么被删除任务所占用的一些资源就会因为没有被释放而丢失,这是任何系统都无法接受的,因此删除一个占用资源的任务时,一定要谨慎。集体办法是,提出删除任务请求的任务只负责提出删除任务请求,而删除工作则由删除任务自己来完成,,这样,被删除任务就可以根据自身的具体情况来决定何时删除自身同时在删除之前把占用的资源释放掉。删除请求函数OSTaskDelReq()可以实现以上功能
#if OS_TASK_DEL_EN > 0
INT8U OSTaskDelReq (INT8U prio)
{
INT8U stat;
OS_TCB *ptcb;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to delete idle task */
return (OS_TASK_DEL_IDLE);
}
#if OS_ARG_CHK_EN > 0
if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */
if (prio != OS_PRIO_SELF) {
return (OS_PRIO_INVALID);
}
}
#endif
if (prio == OS_PRIO_SELF) { /* See if a task is requesting to ... */
OS_ENTER_CRITICAL(); /* ... this task to delete itself */
stat = OSTCBCur->OSTCBDelReq; /* Return request status to caller */
OS_EXIT_CRITICAL();
return (stat);
}
OS_ENTER_CRITICAL();
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_EXIST); /* Task must already be deleted */
}
if (ptcb == (OS_TCB *)1) { /* Must NOT be assigned to a Mutex */
OS_EXIT_CRITICAL();
return (OS_TASK_DEL_ERR);
}
ptcb->OSTCBDelReq = OS_TASK_DEL_REQ; /* Set flag indicating task to be DEL. */
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif
删除请求函数OSTaskDelReq()的流程图如下图所示: