UC/OS基础知识之任务的删除

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()的流程图如下图所示:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值