- UID
- 1029342
- 性别
- 男
|
程序清单 L 4.16 OSTaskSuspend().
INT8U OSTaskSuspend (INT8U prio)
{
BOOLEAN self;
OS_TCB *ptcb;
if (prio == OS_IDLE_PRIO) { (1)
return (OS_TASK_SUSPEND_IDLE);
}
if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { (2)
return (OS_PRIO_INVALID);
}
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) { (3)
prio = OSTCBCur->OSTCBPrio;
self = TRUE;
} else if (prio == OSTCBCur->OSTCBPrio) { (4)
self = TRUE;
} else {
self = FALSE;
}
if ((ptcb = OSTCBPrioTbl[prio]) == (OS_TCB *)0) { (5)
OS_EXIT_CRITICAL();
return (OS_TASK_SUSPEND_PRIO);
} else {
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { (6)
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
ptcb->OSTCBStat |= OS_STAT_SUSPEND; (7)
OS_EXIT_CRITICAL();
if (self == TRUE) { (8)
OSSched();
}
return (OS_NO_ERR);
}
} 恢复任务,OSTaskResume()
在上一节中曾提到过,被挂起的任务只有通过调用OSTaskResume()才能恢复。OSTaskResume()函数的代码如程序清单 L4.17所示。因为OSTaskSuspend()不能挂起空闲任务,所以必须得确认用户的应用程序不是在恢复空闲任务[L4.17(1)]。注意,这 个测试也可以确保用户不是在恢复优先级为OS_PRIO_SELF的任务(OS_PRIO_SELF被定义为0xFF,它总是比 OS_LOWEST_PRIO大)。
要恢复的任务必须是存在的,因为用户要需要操作它的任务控制块OS_TCB[L4.17(2)],并且该任 务必须是被挂起的[L4.17(3)]。OSTaskResume()是通过清除OSTCBStat域中的OS_STAT_SUSPEND位来取消挂起的 [L4.17(4)]。要使任务处于就绪状态,OS_TCBDly域必须为0[L4.17(5)],这是因为在OSTCBStat中没有任何标志表明任务 正在等待延时的期满。只有当以上两个条件都满足的时候,任务才处于就绪状态[L4.17(6)]。最后,任务调度程序会检查被恢复的任务拥有的优先级是否 比调用本函数的任务的优先级高[L4.17(7)]。
程序清单 L 4.17 OSTaskResume().
INT8U OSTaskResume (INT8U prio)
{
OS_TCB *ptcb;
If (prio >= OS_LOWEST_PRIO) { (1)
return (OS_PRIO_INVALID);
}
OS_ENTER_CRITICAL();
If ((ptcb = OSTCBPrioTbl[prio]) == (OS_TCB *)0) { (2)
OS_EXIT_CRITICAL();
return (OS_TASK_RESUME_PRIO);
} else {
if (ptcb->OSTCBStat & OS_STAT_SUSPEND) { (3)
if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) && (4)
(ptcb->OSTCBDly == 0)) { (5)
OSRdyGrp |= ptcb->OSTCBBitY; (6)
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
OSSched(); (7)
} else {
OS_EXIT_CRITICAL();
}
return (OS_NO_ERR);
} else {
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_SUSPENDED);
}
}
}
获得有关任务的信息,OSTaskQuery()
用户的应用程序可以通过调用OSTaskQuery()来获得自身或其它应用任务的信息。实际上,OSTaskQuery()获得的是对应任务的 OS_TCB中内容的拷贝。用户能访问的OS_TCB的数据域的多少决定于用户的应用程序的配置(参看OS_CFG.H)。由于µC/OS-Ⅱ是可裁剪 的,它只包括那些用户的应用程序所要求的属性和功能。
要调用OSTaskQuery(),如程序清单 L4.18中所示的那样,用户的应用程序必须要为OS_TCB分配存储空间。这个OS_TCB与µC/OS-Ⅱ分配的OS_TCB是完全不同的数据空间。 在调用了OSTaskQuery()后,这个OS_TCB包含了对应任务的OS_TCB的副本。用户必须十分小心地处理OS_TCB中指向其它 OS_TCB的指针(即OSTCBNext与OSTCBPrev);用户不要试图去改变这些指针!一般来说,本函数只用来了解任务正在干什么——本函数是 有用的调试工具。
程序清单 L 4.18 得到任务的信息
OS_TCB MyTaskData;
void MyTask (void *pdata)
{
pdata = pdata;
for (;;) {
/* 用户代码 */
err = OSTaskQuery(10, &MyTaskData);
/* Examine error code .. */
/* 用户代码 */
}
} |
|