网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 超前科技开发网 >> 文章中心 >> 实时操作系统 >> uCOS-II开发 >> 文章正文
  [推荐]第4章 任务管理         ★★★ 【字体:
第4章 任务管理
作者:邵贝贝    文章来源:本站原创    点击数:    更新时间:2006-11-29    
LPC2368 开发板(LPC2364/LPC2368).
全功能JLINK ARM仿真器.
USB-Blaster下载电缆(支持ALTERA全系列)
LPC2148开发板.
在前面的章节中,笔者曾说过任务可以是一个无限的循环,也可以是在一次执行完毕后被删除掉。这里要注意的是,任务代码并不是被真正的删除了,而只是µC/OS-Ⅱ不再理会该任务代码,所以该任务代码不会再运行。任务看起来与任何C函数一样,具有一个返回类型和一个参数,只是它从不返回。任务的返回类型必须被定义成void型。在本章中所提到的函数可以在OS_TASK文件中找到。如前所述,任务必须是以下两种结构之一:

 

void YourTask (void *pdata)

{

    for (;;) {

        /* 用户代码 */

        调用µC/OS-Ⅱ的服务例程之一:

            OSMboxPend();

            OSQPend();

            OSSemPend();

            OSTaskDel(OS_PRIO_SELF);

            OSTaskSuspend(OS_PRIO_SELF);

            OSTimeDly();

            OSTimeDlyHMSM();

        /* 用户代码 */

    }

}

 

 

void YourTask (void *pdata)

{

    /* 用户代码 */

    OSTaskDel(OS_PRIO_SELF);

}

 

    本章所讲的内容包括如何在用户的应用程序中建立任务、删除任务、改变任务的优先级、挂起和恢复任务,以及获得有关任务的信息。

    µC/OS-Ⅱ可以管理多达64个任务,并从中保留了四个最高优先级和四个最低优先级的任务供自己使用,所以用户可以使用的只有56个任务。任务的优先级越高,反映优先级的值则越低。在最新的µC/OS-Ⅱ版本中,任务的优先级数也可作为任务的标识符使用。

4.0       建立任务,OSTaskCreate()

       想让µC/OS-Ⅱ管理用户的任务,用户必须要先建立任务。用户可以通过传递任务地址和其它参数到以下两个函数之一来建立任务:OSTaskCreate() 或 OSTaskCreateExt()。OSTaskCreate()与µC/OS是向下兼容的,OSTaskCreateExt()是OSTaskCreate()的扩展版本,提供了一些附加的功能。用两个函数中的任何一个都可以建立任务。任务可以在多任务调度开始前建立,也可以在其它任务的执行过程中被建立。在开始多任务调度(即调用OSStart())前,用户必须建立至少一个任务。任务不能由中断服务程序(ISR)来建立。

    OSTaskCreate()的代码如程序清单 L4.1所述。从中可以知道,OSTaskCreate()需要四个参数:task是任务代码的指针,pdata是当任务开始执行时传递给任务的参数的指针,ptos是分配给任务的堆栈的栈顶指针(参看4.02,任务堆栈),prio是分配给任务的优先级。

 

程序清单 L4.1 OSTaskCreate()

INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)

{

    void   *psp;

    INT8U   err;

 

 

    if (prio > OS_LOWEST_PRIO) {                                             (1)

        return (OS_PRIO_INVALID);

    }

    OS_ENTER_CRITICAL();

    if (OSTCBPrioTbl[prio] == (OS_TCB *)0) {                                (2)

        OSTCBPrioTbl[prio] = (OS_TCB *)1;                                    (3)

        OS_EXIT_CRITICAL();                                                    (4)

        psp = (void *)OSTaskStkInit(task, pdata, ptos, 0);                (5)

        err = OSTCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0);       (6)

        if (err == OS_NO_ERR) {                                               (7)

            OS_ENTER_CRITICAL();

            OSTaskCtr++;                                                        (8)

            OSTaskCreateHook(OSTCBPrioTbl[prio]);                           (9)

            OS_EXIT_CRITICAL();

            if (OSRunning) {                                                  (10)

                OSSched();                                                     (11)

            }

        } else {

            OS_ENTER_CRITICAL();

            OSTCBPrioTbl[prio] = (OS_TCB *)0;                              (12)

            OS_EXIT_CRITICAL();

        }

        return (err);

    } else {

        OS_EXIT_CRITICAL();

        return (OS_PRIO_EXIST);

    }

}

 

    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-

欢迎进入超前MCU技术论坛对 第4章 任务管理进行讨论!

文章录入:armopen    责任编辑:armopen 
  • 上一篇文章:

  • 下一篇文章: 没有了
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    第3章 内核结构(6)
    第3章 内核结构(5)
    第3章 内核结构(4)
    第3章 内核结构(3)
    第3章 内核结构(2)
    第3章 内核结构(1)
    第2章 实时系统概念(9)
    第2章 实时系统概念(8
    第2章 实时系统概念(7)
    第2章 实时系统概念(6)
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    Copyright 2003-2006 www.mcu123.com© All Rights Reserved
    版权所有 © 超前科技开发网
    粤ICP备05005262号