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

UCOS任务管理(2)

UCOS任务管理(2)

OSTaskCreate ()一开始先检测分配给任务的优先级是否有效[L4.1(1)]。任务的优先级必须在0到OS_LOWEST_PRIO之间。接着, OSTaskCreate()要确保在规定的优先级上还没有建立任务[L4.1(2)]。在使用µC/OS-Ⅱ时,每个任务都有特定的优先级。如果某个优 先级是空闲的,µC/OS-Ⅱ通过放置一个非空指针在OSTCBPrioTbl[]中来保留该优先级[L4.1(3)]。这就使得 OSTaskCreate()在设置任务数据结构的其他部分时能重新允许中断[L4.1(4)]。
然后,OSTaskCreate()调用 OSTaskStkInit()[L4.1(5)],它负责建立任务的堆栈。该函数是与处理器的硬件体系相关的函数,可以在OS_CPU_C.C文件中找 到。有关实现OSTaskStkInit()的细节可参看第8章——移植µC/OS-Ⅱ。如果已经有人在你用的处理器上成功地移植了µC/OS-Ⅱ,而你 又得到了他的代码,就不必考虑该函数的实现细节了。OSTaskStkInit()函数返回新的堆栈栈顶(psp),并被保存在任务的0S_TCB中。注 意用户得将传递给OSTaskStkInit()函数的第四个参数opt置0,因为OSTaskCreate()与OSTaskCreateExt()不 同,它不支持用户为任务的创建过程设置不同的选项,所以没有任何选项可以通过opt参数传递给OSTaskStkInit()。
µC/OS-Ⅱ 支持的处理器的堆栈既可以从上(高地址)往下(低地址)递减也可以从下往上递增。用户在调用OSTaskCreate()的时候必须知道堆栈是递增的还是 递减的(参看所用处理器的OS_CPU.H中的OS_STACK_GROWTH),因为用户必须得把堆栈的栈顶传递给OSTaskCreate(),而栈 顶可能是堆栈的最高地址(堆栈从上往下递减),也可能是最低地址(堆栈从下往上长)。
一旦OSTaskStkInit()函数完成了建立堆栈的 任务,OSTaskCreate()就调用OSTCBInit()[L4.1(6)],从空闲的OS_TCB池中获得并初始化一个OS_TCB。 OSTCBInit()的代码如程序清单 L4.2所示,它存在于0S_CORE.C文件中而不是OS_TASK.C文件中。OSTCBInit()函数首先从OS_TCB缓冲池中获得一个 OS_TCB[L4.2(1)],如果OS_TCB池中有空闲的OS_TCB[L4.2(2)],它就被初始化[L4.2(3)]。注意一旦OS_TCB 被分配,该任务的创建者就已经完全拥有它了,即使这时内核又创建了其它的任务,这些新任务也不可能对已分配的OS_TCB作任何操作,所以 OSTCBInit()在这时就可以允许中断,并继续初始化OS_TCB的数据单元。
程序清单 L 4.2 OSTCBInit()
INT8U OSTCBInit (INT8U  prio,     OS_STK *ptos,   OS_STK *pbos, INT16U id,
                 INT16U stk_size, void   *pext,   INT16U  opt)
{
    OS_TCB *ptcb;


    OS_ENTER_CRITICAL();
    ptcb = OSTCBFreeList;                                  (1)
    if (ptcb != (OS_TCB *)0) {                             (2)
        OSTCBFreeList        = ptcb->OSTCBNext;
        OS_EXIT_CRITICAL();
        ptcb->OSTCBStkPtr    = ptos;                       (3)
        ptcb->OSTCBPrio      = (INT8U)prio;
        ptcb->OSTCBStat      = OS_STAT_RDY;
        ptcb->OSTCBDly       = 0;
#if OS_TASK_CREATE_EXT_EN
        ptcb->OSTCBExtPtr    = pext;
        ptcb->OSTCBStkSize   = stk_size;
        ptcb->OSTCBStkBottom = pbos;
        ptcb->OSTCBOpt       = opt;
        ptcb->OSTCBId        = id;
#else
        pext                 = pext;
        stk_size             = stk_size;
        pbos                 = pbos;
        opt                  = opt;
        id                   = id;
#endif

#if OS_TASK_DEL_EN
        ptcb->OSTCBDelReq    = OS_NO_ERR;
#endif

        ptcb->OSTCBY         = prio >> 3;
        ptcb->OSTCBBitY      = OSMapTbl[ptcb->OSTCBY];
        ptcb->OSTCBX         = prio & 0x07;
        ptcb->OSTCBBitX      = OSMapTbl[ptcb->OSTCBX];

#if     OS_MBOX_EN || (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_SEM_EN
        ptcb->OSTCBEventPtr  = (OS_EVENT *)0;
#endif

#if     OS_MBOX_EN || (OS_Q_EN && (OS_MAX_QS >= 2))
        ptcb->OSTCBMsg       = (void *)0;
#endif

        OS_ENTER_CRITICAL();                               (4)
        OSTCBPrioTbl[prio]   = ptcb;                       (5)
        ptcb->OSTCBNext      = OSTCBList;
        ptcb->OSTCBPrev      = (OS_TCB *)0;
        if (OSTCBList != (OS_TCB *)0) {
            OSTCBList->OSTCBPrev = ptcb;
        }
        OSTCBList               = ptcb;
        OSRdyGrp               |= ptcb->OSTCBBitY;         (6)
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        OS_EXIT_CRITICAL();
        return (OS_NO_ERR);                                (7)
    } else {
        OS_EXIT_CRITICAL();
        return (OS_NO_MORE_TCB);
    }
}
继承事业,薪火相传
返回列表