首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

UCOS任务管理(9)

UCOS任务管理(9)

程序清单 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 ..        */
        /*  用户代码                    */
    }
}
继承事业,薪火相传
返回列表