⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_task.c

📁 avr ucos 代码 测试环境:source insight WINAVR 4个进程
💻 C
📖 第 1 页 / 共 4 页
字号:
#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];//取出已建立TCB的指针表
    if (ptcb != (OS_TCB *)0) {                                       /* Task to delete must exist      */
		//如果不为空,表示指针存在
        if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {  /* Make task not ready            */
            OSRdyGrp &= ~ptcb->OSTCBBitY;//就绪表中清空,保证不被挂起。
        }//如果任务在就绪表中,则将其在就绪表中删除
#if OS_EVENT_EN > 0
		//能使队列代码产生&&申请队列控制块最大数不为零||能使邮箱代码产生||
		//能使信号量代码产生||能使互斥量代码产生 

        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 */
            }//将任务从事件控制块中删除,
        }
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
		//OS版本大于等于251,能使事件标志,事件标志最在值大于零

        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  */
//删除任务后,将任务时钟节拍延迟数清0,确保自己重新开中断
//时,中断服务子程序ISR不会使该任务就绪
        ptcb->OSTCBStat = OS_STAT_RDY;                          /* Prevent task from being resumed     */
//任务状态设为就绪态,OSTaskDel()置任务的OSTCBStat标志为OS_STAT_RDY
//OSTaskDel()并不试图使任务处于就绪态,只是阻止其它任务或者中断服务
//程序让该任务重新开始执行(通过调用OSTaskResume()).若不设置任务的OSTCBStat标
//志为OS_STAT_RDY,也可以清除OS_STAT_SUSPEND() 。
		if (OSLockNesting < 255) {//多任务处理结点嵌套数小于255
            OSLockNesting++;//嵌套数加一
		}
//至此,被删除的任务就不会被其它任务或者中断服务子程序置于就绪态
//因为该任务已经从就绪任务表中被删了,为了在室删除任务目的,任务
//被置于休眠状态,正因为任务处于休眠状态,OSTaskDel()要防止任务调度
//程序在删除过程中切换到其它任务中去,因为当前任务如果正在被删除,
//是不可能被再次调度。
        OS_EXIT_CRITICAL();                                     /* Enabling INT. ignores next instruc. */
//重新开中断,以缩短响应时间,这样,OSTaskDel()就能够处理中断了,但是
//由于给OSLockNesting加了一,ISR执行完后,会返回到被中断了的任务,从而
//继续任务的删除工作。
        OS_Dummy();                                             /* ... Dummy ensures that INTs will be */
//开中断指令到来后要再执行一条指令才真正开中断,所以执行一条空指令。
        OS_ENTER_CRITICAL();                                    /* ... disabled HERE!                  */
		//能使中断,忽略下一条指令,虚假函数保证了中断在这里不能使
		if (OSLockNesting > 0) {//如果多任务处理结点嵌套大于零
            OSLockNesting--;//嵌套数减一
		}//可以继续执行删除工作了,在OSTaskDel()重新关中断后,它通过锁定嵌套
		 //计数器减一,重新允许任务调度。
        OSTaskDelHook(ptcb);                                    /* Call user defined hook              */
		 //调用自定义删除任务接口函数,可在这里删除或者释放自定义的
		 //TCB附加数据域
        OSTaskCtr--;                                            /* One less task being managed         */
		 //任务计数器减一,表明管理的任务减少了一个。
        OSTCBPrioTbl[prio] = (OS_TCB *)0;                       /* Clear old priority entry            */
		 //OSTaskDel()函数简单地指向被删除任务的TCB的指针置为NULL,就从优先级
		 //表中把OS_TCB给删除了。
        if (ptcb->OSTCBPrev == (OS_TCB *)0) {                   /* Remove from TCB chain               */
		//从以OSTCBList开头的OS_TCB双向链表中删除被删任务的TCB,
            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         */
		//被删任务的OS_TCB被退回到空闲的OS_TCB中,供其它任务使用
        OSTCBFreeList   = ptcb;//ptcb变成新的表头
        OS_EXIT_CRITICAL();
        OS_Sched();                                             /* Find new highest priority task      */
        //任务调度,看此函数开中断时,ESR时否曾使更高优先级的任务进入
        //了就绪态
        return (OS_NO_ERR);//删除成功
    }
    OS_EXIT_CRITICAL();
    return (OS_TASK_DEL_ERR);//如果指针为空,删除出现错误
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*                                    REQUEST THAT A TASK DELETE ITSELF
*
* Description: This function is used to:
*                   a) notify a task to delete itself.
*                   b) to see if a task requested that the current task delete itself.
*              This function is a little tricky to understand.  Basically, you have a task that needs
*              to be deleted however, this task has resources that it has allocated (memory buffers,
*              semaphores, mailboxes, queues etc.).  The task cannot be deleted otherwise these
*              resources would not be freed.  The requesting task calls OSTaskDelReq() to indicate that
*              the task needs to be deleted.  Deleting of the task is however, deferred to the task to
*              be deleted.  For example, suppose that task #10 needs to be deleted.  The requesting task
*              example, task #5, would call OSTaskDelReq(10).  When task #10 gets to execute, it calls
*              this function by specifying OS_PRIO_SELF and monitors the returned value.  If the return
*              value is OS_TASK_DEL_REQ, another task requested a task delete.  Task #10 would look like
*              this:
*
*                   void Task(void *data)
*                   {
*                       .
*                       .
*                       while (1) {
*                           OSTimeDly(1);
*                           if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) {
*                               Release any owned resources;
*                               De-allocate any dynamic memory;
*                               OSTaskDel(OS_PRIO_SELF);
*                           }
*                       }
*                   }
*
* Arguments  : prio    is the priority of the task to request the delete from
*
* Returns    : OS_NO_ERR          if the task exist and the request has been registered
*              OS_TASK_NOT_EXIST  if the task has been deleted.  This allows the caller to know whether
*                                 the request has been executed.
*              OS_TASK_DEL_IDLE   if you requested to delete uC/OS-II's idle task
*              OS_PRIO_INVALID    if the priority you specify is higher that the maximum allowed
*                                 (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
*              OS_TASK_DEL_REQ    if a task (possibly another task) requested that the running task be
*                                 deleted.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
                                                 任务请求删除自己
描述:此函数功能用于:
          a、通知任务删除自己。
          b、查看是否一个任务请求当前任务要删除它自己。
          这个函数要比较灵活去理解。基本上,你有一个任务需要删除,但是它还有分配的资源(比          如: 存储器缓冲区、信号量、邮箱、队列等),这些任务不能被删除,否则这些资源将被释          放。请求任务调用OSTaskDelReq()去表明当前任务需要被删除,然而删除任务将被延迟,比 
          如:假设任务十将被删除,请求任务(比如五)将调用OSTaskDelReq(10)。当任务十运行的            时候,它将调用此函数中的OS_PRIO_SELF再监视返回值,如果返回的值是OS_TASK_DEL_REQ
          另外一个任务请求删除任务,任务十将看成这样:
*                   void Task(void *data)
*                   {
*                       .
*                       .
*                       while (1) {
*                           OSTimeDly(1);
*                           if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) {
*                               Release any owned resources;
*                               De-allocate any dynamic memory;
*                               OSTaskDel(OS_PRIO_SELF);
*                           }
*                       }
*                   }//不明白什么意思
参数:   prio:请求删除任务的优先级
返回值: OS_NO_ERR :如果任务存在,且请求通过。
             OS_TASK_NOT_EXIST:如果任务已经删除,这需要请求者知道请求是否已经执行
             OS_TASK_DEL_IDLE :如果要删除空闲任务
             OS_PRIO_INVALID:如果优先级数值大于最大允许值,或者不是指向OS_PRIO_SELF.
             OS_TASK_DEL_REQ:如果一个任务(也许是其它任务)请求正在运行的任务要删除。

*********************************************************************************************************
*/


/*$PAGE*/
#if OS_TASK_DEL_EN > 0
INT8U  OSTaskDelReq (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr;//分配CPU状态寄存器存储空间
#endif
    BOOLEAN    stat;//typedef unsigned char BOOLEAN
    INT8U      err;
    OS_TCB    *ptcb;


#if OS_ARG_CHK_EN > 0//允许参数检测
    if (prio == OS_IDLE_PRIO) {                                 /* Not allowed to delete idle task     */
        return (OS_TASK_DEL_IDLE);//如果想删除空闲任务,这是不允许的。
    }
    if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) {       /* Task priority valid ?               */
        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];//已创建TCB指针表
    if (ptcb != (OS_TCB *)0) {                                  /* Task to delete must exist           */
		//如果需要删除的任务存在
        ptcb->OSTCBDelReq = OS_TASK_DEL_REQ;                    /* Set flag indicating task to be DEL. */
     //如果用优先级而不是用OS_PRIO_SELF指定任务,且任务存在,设置标志表示即将删除
        err               = OS_NO_ERR;//返回成功
    } else {
        err               = OS_TASK_NOT_EXIST;                  /* Task must be deleted                */
    }//需要删除的任务不存在,表明任务可以已经删除自己了
    OS_EXIT_CRITICAL();
    return (err);//其它错误
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*                                        RESUME A SUSPENDED TASK
*
* Description: This function is called to resume a previously suspended task.  This is the only call that
*              will remove an explicit task suspension.
*
* Arguments  : prio     is the priority of the task to resume.
*
* Returns    : OS_NO_ERR                if the requested task is resumed
*              OS_PRIO_INVALID          if the priority you specify is higher that the maximum allowed
*                                       (i.e. >= OS_LOWEST_PRIO)
*              OS_TASK_RESUME_PRIO      if the task to resume does not exist
*              OS_TASK_NOT_SUSPENDED    if the task to resume has not been suspended
*********************************************************************************************************
*/
/*
*********************************************************************************************************
                                               恢复任务:
描述:这个函数功能是去恢复一个先前挂起的任务,这个函数只有在去除挂起时候调用。
          被挂起的任务只有通过调用它才能够被恢复。
参数:prio: 需要恢复函数的优先级
返回:OS_NO_ERR:如果请求的任务被恢复
          OS_PRIO_INVALID:如果优先级无效
          OS_TASK_RESUME_PRIO:如果要恢复的任务优先级不存在
          OS_TASK_NOT_SUSPENDED:如果要恢复的任务没有被挂起

*********************************************************************************************************
*/



#if OS_TASK_SUSPEND_EN > 0//允许包含任务挂起和任务恢复代码
INT8U  OSTaskResume (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr;//分配CPU状态寄存器存储空间
#endif
    OS_TCB    *ptcb;


#if OS_ARG_CHK_EN > 0
    if (prio >= OS_LOWEST_PRIO) {                               /* Make sure task priority is valid    */
        return (OS_PRIO_INVALID);//保证任务优先级有效
    }
#endif
    OS_ENTER_CRITICAL();
    ptcb = OSTCBPrioTbl[prio];//调用此任务的TCB指针
    if (ptcb == (OS_TCB *)0) {                                  /* Task to suspend must exist          */
        OS_EXIT_CRITICAL();//如果任务不存在
        return (OS_TASK_RESUME_PRIO);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -