您的位置:首页 > 其它

uC/OS-ii内核源码理解(五)创建任务函数

2017-02-17 22:53 393 查看
创建任务函数有两个:OSTaskCreate和OSTaskCreateExt。

OSTaskCreate有4个参数。

OSTaskCreateExt在OSTaskCreate基础上增加了一些功能参数,有9个参数。其中4个参数和OSTaskCreate一样。

这里就只讲解OSTaskCreateExt。

#if OS_TASK_CREATE_EXT_EN > 0u //选通开关

INT8U  OSTaskCreateExt (void   (*task)(void *p_arg),//函数指针

                        void    *p_arg, //任意类型指针

                        OS_STK  *ptos, //栈顶指针

                        INT8U    prio, //优先级

                        INT16U   id, //任务ID

                        OS_STK  *pbos, //栈底指针

                        INT32U   stk_size,//任务堆栈大小

                        void    *pext, //指向用户提供的内存

                        INT16U   opt) //用户操作选项参数

{

    OS_STK    *psp;

    INT8U      err;

#if OS_CRITICAL_METHOD == 3u                 /* Allocate storage for CPU status register               */

    OS_CPU_SR  cpu_sr = 0u;

#endif

1.task 指向函数的指针,传递的是一个函数

在main函数中调用OSTaskCreateExt传递的参数是"start_task",就是应用程序的名字。

2.p_arg

传递参数的指针,是一个任意类型的参数。当我们需要传递某些参数给函数时,可以通过该参数进行传递。

在main函数中调用OSTaskCreateExt传递的参数是"(void*)0",就是传递一个"空指针"给函数(没有参数,就传递一个空指针)。

3.ptos

指向任务堆栈栈顶指针。

这个参数和第六个参数pbos对应,根据栈的增长方向"OS_STK_GROWTH"来决定。具体见os_cpu.h文件54行中OS_STK_GROWTH的宏定义,

//定义栈的增长方向.

//CM3中,栈是由高地址向低地址增长的,所以OS_STK_GROWTH设置为1

#define  OS_STK_GROWTH        1      /* Stack grows from HIGH to LOW memory on ARM    */

我们定义栈的增长方向为从高地址往低地址增长,因此,在main函数中调用OSTaskCreateExt我们传递的参数是"START_TASK_STK[TaskStkLengh-1]",

也就是栈的高地址为栈顶。

4.prio

优先级唯一,优先级决定该任务指向的优先权利(值越小,优先级越高)。

5.ID

任务的ID

给每一个创建的任务分配一个ID编号,相当于一篇文章的每章节号。

我们在创建的任务中以"优先级"作为编号,所以在参数中,可以看到连续两个参数都是优先级。

6.pbos

指向栈底的指针。

这个参数和第3个参数ptos类似和栈的增长方向有关。

根据栈的增长方向#define  OS_STK_GROWTH        1 是从高地址往低地址增长,在main函数调用OSTaskCreateExt中传递的参数是START_TASK_STK[0]。

7.stk_size

任务堆栈大小。

这个参数与app_cfg.h文件中定义的"堆栈变量"有关,我们需要传递的大小就是堆栈数组的大小值。

8.pext

指向用户提供的内存(指针)。

这个参数用作TCB扩展的参数。

9.opt

用户操作选项参数

这个参数用户创建任务时需要处理一些额外信息(操作)的参数。在注解中opt参数主要有三个

*                        OS_TASK_OPT_STK_CHK      Stack checking to be allowed for the task检测参数是否可用

*                        OS_TASK_OPT_STK_CLR      Clear the stack when the task is created清除堆栈(创建任务时清除堆栈)

*                        OS_TASK_OPT_SAVE_FP      If the CPU has floating-point registers, save them(保存浮点指针)

*                                                 during a context switch.(进行上下文切换时)

参数是宏定义在ucos_ii.h中,210--213行:

#define  OS_TASK_OPT_NONE          0x0000u  /* NO option selected无操作选项                             */

#define  OS_TASK_OPT_STK_CHK       0x0001u  /* Enable stack checking for the task使能参数检查            */

#define  OS_TASK_OPT_STK_CLR       0x0002u  /* Clear the stack when the task is create使能清除堆栈         */

#define  OS_TASK_OPT_SAVE_FP       0x0004u  /* Save the contents of any floating-point registers使能保存浮点指针*/

就是调用了某一个宏定义,那个宏定义的功能就使能了。

在main函数中调用OSTaskCreateExt传递的参数是"OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR",进行参数检查和堆栈清除。

3.创建任务时的堆栈

#if OS_TASK_CREATE_EXT_EN > 0u

INT8U  OSTaskCreateExt (void   (*task)(void *p_arg),

                        void    *p_arg,

                        OS_STK  *ptos,

                        INT8U    prio,

                        INT16U   id,

                        OS_STK  *pbos,

                        INT32U   stk_size,

                        void    *pext,

                        INT16U   opt)

{

    OS_STK    *psp;

    INT8U      err;

#if OS_CRITICAL_METHOD == 3u                 /* Allocate storage for CPU status register               */

    OS_CPU_SR  cpu_sr = 0u;

#endif

#ifdef OS_SAFETY_CRITICAL_IEC61508

    if (OSSafetyCriticalStartFlag == OS_TRUE) {

        OS_SAFETY_CRITICAL_EXCEPTION();

    }

#endif

#if OS_ARG_CHK_EN > 0u

    if (prio > OS_LOWEST_PRIO) {             /* Make sure priority is within allowable range 确保优先级在指定范围内*/

        return (OS_ERR_PRIO_INVALID);

    }

#endif

    OS_ENTER_CRITICAL();

    if (OSIntNesting > 0u) {                 /* Make sure we don't create the task from within an ISR确保我们不会从ISR中创建任务*/

        OS_EXIT_CRITICAL();

        return (OS_ERR_TASK_CREATE_ISR);

    }

    if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority确保任务优先级未被使用*/

        OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ...保留这个优先级,*/

                                             /* ... the same thing until task is created.防止再次创建相同优先级的任务*/

        OS_EXIT_CRITICAL();

#if (OS_TASK_STAT_STK_CHK_EN > 0u)

        OS_TaskStkClr(pbos, stk_size, opt);                    /* Clear the task stack (if needed)清除使用到的堆栈*/

#endif

        psp = OSTaskStkInit(task, p_arg, ptos, opt);           /* Initialize the task's stack初始化任务堆栈*/

        err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);

        if (err == OS_ERR_NONE) {

            if (OSRunning == OS_TRUE) {                        /* Find HPT if multitasking has started如果多任务已经开始,找到HPT使其运行*/

                OS_Sched();

            }

        } else { //创建TCB不成功

            OS_ENTER_CRITICAL();

            OSTCBPrioTbl[prio] = (OS_TCB *)0;                  /* Make this priority avail. to others使这个优先级有效,留给其他任务使用*/

            OS_EXIT_CRITICAL();

        }

        return (err);

    }

    OS_EXIT_CRITICAL();

    return (OS_ERR_PRIO_EXIST);

}

#endif

(1)OS_TaskStkClr

创建任务时清除堆栈。

这个函数需要在os_cfg.h中使能OS_TASK_STAT_STK_CHK_EN这个参数。

清除堆栈的顺序与栈的增长方向有关。看到源代码可以理解为清除堆栈,就是初始化时情况一下堆栈空间。

(2)OSTaskInit

初始化创建任务的堆栈。

这个函数位于os_cpu_c.c文件中,这个函数主要的参数是"ptos"栈顶,我们需要分配并保存堆栈。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: