UCOSII 中的OSTaskResume 应用
INT8UOSTaskResume (INT8U prio)KCREENTRANT{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SRcpu_sr;
#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();
if ((ptcb = OSTCBPrioTbl) == (OS_TCB *)0) { /* Task to suspend must exist */
OS_EXIT_CRITICAL();
return (OS_TASK_RESUME_PRIO);
}
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != 0x00) { /* Task must be suspended */
if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) && /* Remove suspension */
(ptcb->OSTCBDly== 0)) { /* Must not be delayed */
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */
OSRdyTbl |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
OS_Sched();
} else {
OS_EXIT_CRITICAL();
}
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_SUSPENDED);
}
以上源码中,if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) && (ptcb->OSTCBDly== 0)) 该判断条件需要判断ptcb->OSTCBDly为0,如果该任务在挂起之前,调用了OSTimeDly()相关函数,此时在调用OSTaskResume(),ptcb->OSTCBDly不为0,该函数怎么运行?大侠们给分析一下,我哪里分析错了 调用()这个函数后,此时的Task已经被切换到别的Task去了, 也就不会执行OSTimeDly()后面的函数OSTaskResume()。当OSTimeDly()的延时时间到了以后,在切换到当前Task再去执行OSTaskResume() feelhyq 发表于 2016-12-26 10:42
调用()这个函数后,此时的Task已经被切换到别的Task去了, 也就不会执行OSTimeDly()后面的函数OSTaskResume( ...
如果该任务A调用了OSTimeDly()函数,此时任务B调用OSTaskSuspend(任务A的优先级),任务A的ptcb->OSTCBDly不为0,怎么用其他任务恢复任务A 明白你的意思了,任务B调用OSTaskSuspend(任务A的优先级)后,再执行OSTaskResume(任务A的优先级)。虽然A时间片还有,但是任务A状态已经从suspend标记为ready状态。
while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) { /* Go through all TCBs in TCB list */
OS_ENTER_CRITICAL();
if (ptcb->OSTCBDly != 0u) { /* No, Delayed or waiting for event with TO */
ptcb->OSTCBDly--; /* Decrement nbr of ticks to end of delay */
if (ptcb->OSTCBDly == 0u) { /* Check for timeout */
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
ptcb->OSTCBStat&= (INT8U)~(INT8U)OS_STAT_PEND_ANY; /* Yes, Clear status flag */
ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout */
} else {
ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
}
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {/* Is task suspended? */
OSRdyGrp |= ptcb->OSTCBBitY; /* No,Make ready */
OSRdyTbl |= ptcb->OSTCBBitX;
}
}
}
这个是时间片的代码,可以看到当A任务的时间片用完了后,会将其放入OSRdyGrp ,OSRdyTbl 。然后再调用OSIntExit进行调度 feelhyq 发表于 2016-12-26 13:25
明白你的意思了,任务B调用OSTaskSuspend(任务A的优先级)后,再执行OSTaskResume(任务A的优先级)。虽然 ...
咱们的版本应该不一样,你看看我这版本
oidOSTimeTick (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SRcpu_sr;
#endif
OS_TCB *ptcb;
OSTimeTickHook(); /* Call user definable hook */
#if OS_TIME_GET_SET_EN > 0
OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */
OSTime++;
OS_EXIT_CRITICAL();
#endif
ptcb = OSTCBList; /* Point at first TCB in TCB list */
while (ptcb->OSTCBPrio != OS_IDLE_PRIO) { /* Go through all TCBs in TCB list */
OS_ENTER_CRITICAL();
if (ptcb->OSTCBDly != 0) { /* Delayed or waiting for event with TO */
if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == 0x00) { /* Is task suspended? */
OSRdyGrp |= ptcb->OSTCBBitY; /* No,Make task Rdy to Run (timed out)*/
OSRdyTbl |= ptcb->OSTCBBitX;
} else { /* Yes, Leave 1 tick to prevent ... */
ptcb->OSTCBDly = 1; /* ... loosing the task when the ... */
} /* ... suspension is removed. */
}
}
ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */
OS_EXIT_CRITICAL();
}
}
这个版本ptcb->OSTCBDly = 1; 该值一直赋值为1,怎么恢复 没有什么问题呀,你调用OSTaskResume函数后,任务A的状态就不是OS_STAT_SUSPEND状态了所以 if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == 0x00)条件判断成立。 if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != 0x00) { /* Task must be suspended */
if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) && /* Remove suspension */
(ptcb->OSTCBDly== 0)) { /* Must not be delayed */
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */
OSRdyTbl |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
OS_Sched();
} else {
OS_EXIT_CRITICAL();
}
return (OS_NO_ERR);
}
恢复挂起函数中,下面这个判断要
if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) && (ptcb->OSTCBDly== 0))
中ptcb->OSTCBDly== 0第一次判断此时肯定不成立,因为时间片中把该值总赋值为1(当挂起状态)。 挂起恢复函数仅仅是消除任务A的 OS_STAT_SUSPEND状态,任务A时间片消耗完后,再systick中断函数里面会执行
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl |= ptcb->OSTCBBitX;
不分析代码了,建议把重点放在OS状态机这块 一般情况下不要使用Suspend和Resume函数,带来很多隐患。需要任务暂停执行的方式很多且很安全,比如信号量,消息等等。
页:
[1]