📄 os_task.c
字号:
#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 + -